mirror of
https://github.com/lubosz/overte.git
synced 2025-08-08 02:48:12 +02:00
fix lighting/color grading for everything
This commit is contained in:
parent
c985fc735d
commit
8748a7561b
20 changed files with 260 additions and 255 deletions
|
@ -46,12 +46,7 @@ PolyLineEntityRenderer::PolyLineEntityRenderer(const EntityItemPointer& entity)
|
||||||
|
|
||||||
void PolyLineEntityRenderer::buildPipeline() {
|
void PolyLineEntityRenderer::buildPipeline() {
|
||||||
// FIXME: opaque pipeline
|
// FIXME: opaque pipeline
|
||||||
gpu::ShaderPointer program;
|
gpu::ShaderPointer program = gpu::Shader::createProgram(DISABLE_DEFERRED ? shader::entities_renderer::program::paintStroke_forward : shader::entities_renderer::program::paintStroke);
|
||||||
if (DISABLE_DEFERRED) {
|
|
||||||
program = gpu::Shader::createProgram(shader::entities_renderer::program::paintStroke_forward);
|
|
||||||
} else {
|
|
||||||
program = gpu::Shader::createProgram(shader::entities_renderer::program::paintStroke);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||||
|
|
|
@ -277,16 +277,10 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
||||||
} else if (!useMaterialPipeline(materials)) {
|
} else if (!useMaterialPipeline(materials)) {
|
||||||
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
||||||
outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||||
render::ShapePipelinePointer pipeline;
|
|
||||||
if (_renderLayer == RenderLayer::WORLD && !DISABLE_DEFERRED) {
|
|
||||||
pipeline = outColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
|
||||||
} else {
|
|
||||||
pipeline = outColor.a < 1.0f ? geometryCache->getForwardTransparentShapePipeline() : geometryCache->getForwardOpaqueShapePipeline();
|
|
||||||
}
|
|
||||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES) {
|
if (render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES) {
|
||||||
geometryCache->renderWireShapeInstance(args, batch, geometryShape, outColor, pipeline);
|
geometryCache->renderWireShapeInstance(args, batch, geometryShape, outColor, args->_shapePipeline);
|
||||||
} else {
|
} else {
|
||||||
geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline);
|
geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, args->_shapePipeline);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) {
|
if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) {
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include <DisableDeferred.h>
|
#include <DisableDeferred.h>
|
||||||
|
|
||||||
|
#include "DeferredLightingEffect.h"
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
using namespace render::entities;
|
using namespace render::entities;
|
||||||
|
|
||||||
|
@ -162,7 +164,7 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
||||||
glm::vec4 backgroundColor;
|
glm::vec4 backgroundColor;
|
||||||
Transform modelTransform;
|
Transform modelTransform;
|
||||||
glm::vec3 dimensions;
|
glm::vec3 dimensions;
|
||||||
bool forwardRendered;
|
bool layered;
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
modelTransform = _renderTransform;
|
modelTransform = _renderTransform;
|
||||||
dimensions = _dimensions;
|
dimensions = _dimensions;
|
||||||
|
@ -172,7 +174,7 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
||||||
textColor = EntityRenderer::calculatePulseColor(textColor, _pulseProperties, _created);
|
textColor = EntityRenderer::calculatePulseColor(textColor, _pulseProperties, _created);
|
||||||
backgroundColor = glm::vec4(_backgroundColor, fadeRatio * _backgroundAlpha);
|
backgroundColor = glm::vec4(_backgroundColor, fadeRatio * _backgroundAlpha);
|
||||||
backgroundColor = EntityRenderer::calculatePulseColor(backgroundColor, _pulseProperties, _created);
|
backgroundColor = EntityRenderer::calculatePulseColor(backgroundColor, _pulseProperties, _created);
|
||||||
forwardRendered = _renderLayer != RenderLayer::WORLD || DISABLE_DEFERRED;
|
layered = _renderLayer != RenderLayer::WORLD;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Render background
|
// Render background
|
||||||
|
@ -184,6 +186,11 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
||||||
Q_ASSERT(args->_batch);
|
Q_ASSERT(args->_batch);
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
|
|
||||||
|
// FIXME: we need to find a better way of rendering text so we don't have to do this
|
||||||
|
if (layered) {
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->setupKeyLightBatch(args, batch);
|
||||||
|
}
|
||||||
|
|
||||||
auto transformToTopLeft = modelTransform;
|
auto transformToTopLeft = modelTransform;
|
||||||
transformToTopLeft.setRotation(EntityItem::getBillboardRotation(transformToTopLeft.getTranslation(), transformToTopLeft.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
transformToTopLeft.setRotation(EntityItem::getBillboardRotation(transformToTopLeft.getTranslation(), transformToTopLeft.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
|
||||||
transformToTopLeft.postTranslate(dimensions * glm::vec3(-0.5f, 0.5f, 0.0f)); // Go to the top left
|
transformToTopLeft.postTranslate(dimensions * glm::vec3(-0.5f, 0.5f, 0.0f)); // Go to the top left
|
||||||
|
@ -192,7 +199,7 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
||||||
if (backgroundColor.a > 0.0f) {
|
if (backgroundColor.a > 0.0f) {
|
||||||
batch.setModelTransform(transformToTopLeft);
|
batch.setModelTransform(transformToTopLeft);
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
geometryCache->bindSimpleProgram(batch, false, backgroundColor.a < 1.0f, false, false, false, true, forwardRendered);
|
geometryCache->bindSimpleProgram(batch, false, backgroundColor.a < 1.0f, false, false, false, true, layered);
|
||||||
geometryCache->renderQuad(batch, minCorner, maxCorner, backgroundColor, _geometryID);
|
geometryCache->renderQuad(batch, minCorner, maxCorner, backgroundColor, _geometryID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +210,11 @@ void TextEntityRenderer::doRender(RenderArgs* args) {
|
||||||
batch.setModelTransform(transformToTopLeft);
|
batch.setModelTransform(transformToTopLeft);
|
||||||
|
|
||||||
glm::vec2 bounds = glm::vec2(dimensions.x - (_leftMargin + _rightMargin), dimensions.y - (_topMargin + _bottomMargin));
|
glm::vec2 bounds = glm::vec2(dimensions.x - (_leftMargin + _rightMargin), dimensions.y - (_topMargin + _bottomMargin));
|
||||||
_textRenderer->draw(batch, _leftMargin / scale, -_topMargin / scale, _text, textColor, bounds / scale, forwardRendered);
|
_textRenderer->draw(batch, _leftMargin / scale, -_topMargin / scale, _text, textColor, bounds / scale, layered);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layered) {
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->unsetKeyLightBatch(batch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ float evalOpaqueFinalAlpha(float alpha, float mapAlpha) {
|
||||||
<@include LightingModel.slh@>
|
<@include LightingModel.slh@>
|
||||||
|
|
||||||
void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 emissive, float occlusion, float scattering) {
|
void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 emissive, float occlusion, float scattering) {
|
||||||
if (alpha != 1.0) {
|
if (alpha < 1.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness
|
||||||
}
|
}
|
||||||
|
|
||||||
void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 lightmap) {
|
void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 lightmap) {
|
||||||
if (alpha != 1.0) {
|
if (alpha < 1.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float r
|
||||||
}
|
}
|
||||||
|
|
||||||
void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) {
|
void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) {
|
||||||
if (alpha != 1.0) {
|
if (alpha < 1.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
_fragColor0 = vec4(color, packUnlit());
|
_fragColor0 = vec4(color, packUnlit());
|
||||||
|
@ -64,7 +64,7 @@ void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 albedo, float roughness) {
|
void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 albedo, float roughness) {
|
||||||
if (alpha <= 0.0) {
|
if (alpha < 1.e-6) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
_fragColor0 = vec4(albedo.rgb, alpha);
|
_fragColor0 = vec4(albedo.rgb, alpha);
|
||||||
|
|
|
@ -722,8 +722,6 @@ gpu::ShaderPointer GeometryCache::_unlitFadeShader;
|
||||||
|
|
||||||
render::ShapePipelinePointer GeometryCache::_simpleOpaquePipeline;
|
render::ShapePipelinePointer GeometryCache::_simpleOpaquePipeline;
|
||||||
render::ShapePipelinePointer GeometryCache::_simpleTransparentPipeline;
|
render::ShapePipelinePointer GeometryCache::_simpleTransparentPipeline;
|
||||||
render::ShapePipelinePointer GeometryCache::_forwardSimpleOpaquePipeline;
|
|
||||||
render::ShapePipelinePointer GeometryCache::_forwardSimpleTransparentPipeline;
|
|
||||||
render::ShapePipelinePointer GeometryCache::_simpleOpaqueFadePipeline;
|
render::ShapePipelinePointer GeometryCache::_simpleOpaqueFadePipeline;
|
||||||
render::ShapePipelinePointer GeometryCache::_simpleTransparentFadePipeline;
|
render::ShapePipelinePointer GeometryCache::_simpleTransparentFadePipeline;
|
||||||
render::ShapePipelinePointer GeometryCache::_simpleWirePipeline;
|
render::ShapePipelinePointer GeometryCache::_simpleWirePipeline;
|
||||||
|
@ -803,8 +801,6 @@ void GeometryCache::initializeShapePipelines() {
|
||||||
if (!_simpleOpaquePipeline) {
|
if (!_simpleOpaquePipeline) {
|
||||||
_simpleOpaquePipeline = getShapePipeline(false, false, true, false);
|
_simpleOpaquePipeline = getShapePipeline(false, false, true, false);
|
||||||
_simpleTransparentPipeline = getShapePipeline(false, true, true, false);
|
_simpleTransparentPipeline = getShapePipeline(false, true, true, false);
|
||||||
_forwardSimpleOpaquePipeline = getShapePipeline(false, false, true, false, false, true);
|
|
||||||
_forwardSimpleTransparentPipeline = getShapePipeline(false, true, true, false, false, true);
|
|
||||||
_simpleOpaqueFadePipeline = getFadingShapePipeline(false, false, false, false, false);
|
_simpleOpaqueFadePipeline = getFadingShapePipeline(false, false, false, false, false);
|
||||||
_simpleTransparentFadePipeline = getFadingShapePipeline(false, true, false, false, false);
|
_simpleTransparentFadePipeline = getFadingShapePipeline(false, true, false, false, false);
|
||||||
_simpleWirePipeline = getShapePipeline(false, false, true, true);
|
_simpleWirePipeline = getShapePipeline(false, false, true, true);
|
||||||
|
@ -836,14 +832,6 @@ render::ShapePipelinePointer GeometryCache::getFadingShapePipeline(bool textured
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render::ShapePipelinePointer GeometryCache::getOpaqueShapePipeline(bool isFading) {
|
|
||||||
return isFading ? _simpleOpaqueFadePipeline : _simpleOpaquePipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
render::ShapePipelinePointer GeometryCache::getTransparentShapePipeline(bool isFading) {
|
|
||||||
return isFading ? _simpleTransparentFadePipeline : _simpleTransparentPipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeometryCache::renderShape(gpu::Batch& batch, Shape shape) {
|
void GeometryCache::renderShape(gpu::Batch& batch, Shape shape) {
|
||||||
batch.setInputFormat(getSolidStreamFormat());
|
batch.setInputFormat(getSolidStreamFormat());
|
||||||
_shapes[shape].draw(batch);
|
_shapes[shape].draw(batch);
|
||||||
|
@ -2018,77 +2006,6 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm
|
||||||
batch.draw(gpu::LINES, 2, 0);
|
batch.draw(gpu::LINES, 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GeometryCache::renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
|
|
||||||
const glm::vec4& color, float glowIntensity, float glowWidth, int id) {
|
|
||||||
|
|
||||||
// Disable glow lines on OSX
|
|
||||||
#ifndef Q_OS_WIN
|
|
||||||
glowIntensity = 0.0f;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (glowIntensity <= 0.0f) {
|
|
||||||
if (color.a >= 1.0f) {
|
|
||||||
bindSimpleProgram(batch, false, false, false, true, true);
|
|
||||||
} else {
|
|
||||||
bindSimpleProgram(batch, false, true, false, true, true);
|
|
||||||
}
|
|
||||||
renderLine(batch, p1, p2, color, id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile the shaders
|
|
||||||
static std::once_flag once;
|
|
||||||
std::call_once(once, [&] {
|
|
||||||
auto state = std::make_shared<gpu::State>();
|
|
||||||
auto program = gpu::Shader::createProgram(shader::render_utils::program::glowLine);
|
|
||||||
state->setCullMode(gpu::State::CULL_NONE);
|
|
||||||
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
|
||||||
state->setBlendFunction(true,
|
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
|
||||||
|
|
||||||
PrepareStencil::testMask(*state);
|
|
||||||
_glowLinePipeline = gpu::Pipeline::create(program, state);
|
|
||||||
});
|
|
||||||
|
|
||||||
batch.setPipeline(_glowLinePipeline);
|
|
||||||
|
|
||||||
Vec3Pair key(p1, p2);
|
|
||||||
bool registered = (id != UNKNOWN_ID);
|
|
||||||
BatchItemDetails& details = _registeredLine3DVBOs[id];
|
|
||||||
|
|
||||||
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
|
|
||||||
if (registered && details.isCreated) {
|
|
||||||
Vec3Pair& lastKey = _lastRegisteredLine3D[id];
|
|
||||||
if (lastKey != key) {
|
|
||||||
details.clear();
|
|
||||||
_lastRegisteredLine3D[id] = key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const int NUM_VERTICES = 4;
|
|
||||||
if (!details.isCreated) {
|
|
||||||
details.isCreated = true;
|
|
||||||
details.uniformBuffer = std::make_shared<gpu::Buffer>();
|
|
||||||
|
|
||||||
struct LineData {
|
|
||||||
vec4 p1;
|
|
||||||
vec4 p2;
|
|
||||||
vec4 color;
|
|
||||||
float width;
|
|
||||||
};
|
|
||||||
|
|
||||||
LineData lineData { vec4(p1, 1.0f), vec4(p2, 1.0f), color, glowWidth };
|
|
||||||
details.uniformBuffer->resize(sizeof(LineData));
|
|
||||||
details.uniformBuffer->setSubData(0, lineData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The shader requires no vertices, only uniforms.
|
|
||||||
batch.setUniformBuffer(0, details.uniformBuffer);
|
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, NUM_VERTICES, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) {
|
void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) {
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
std::call_once(once, [&]() {
|
std::call_once(once, [&]() {
|
||||||
|
@ -2282,8 +2199,7 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
|
||||||
_unlitShader = _forwardUnlitShader;
|
_unlitShader = _forwardUnlitShader;
|
||||||
} else {
|
} else {
|
||||||
_simpleShader = gpu::Shader::createProgram(simple_textured);
|
_simpleShader = gpu::Shader::createProgram(simple_textured);
|
||||||
// Use the forward pipeline for both here, otherwise transparents will be unlit
|
_transparentShader = gpu::Shader::createProgram(simple_transparent_textured);
|
||||||
_transparentShader = gpu::Shader::createProgram(forward_simple_textured_transparent);
|
|
||||||
_unlitShader = gpu::Shader::createProgram(simple_textured_unlit);
|
_unlitShader = gpu::Shader::createProgram(simple_textured_unlit);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -181,17 +181,6 @@ public:
|
||||||
|
|
||||||
static void initializeShapePipelines();
|
static void initializeShapePipelines();
|
||||||
|
|
||||||
render::ShapePipelinePointer getOpaqueShapePipeline() { assert(_simpleOpaquePipeline != nullptr); return _simpleOpaquePipeline; }
|
|
||||||
render::ShapePipelinePointer getTransparentShapePipeline() { assert(_simpleTransparentPipeline != nullptr); return _simpleTransparentPipeline; }
|
|
||||||
render::ShapePipelinePointer getForwardOpaqueShapePipeline() { assert(_forwardSimpleOpaquePipeline != nullptr); return _forwardSimpleOpaquePipeline; }
|
|
||||||
render::ShapePipelinePointer getForwardTransparentShapePipeline() { assert(_forwardSimpleTransparentPipeline != nullptr); return _forwardSimpleTransparentPipeline; }
|
|
||||||
render::ShapePipelinePointer getOpaqueFadeShapePipeline() { assert(_simpleOpaqueFadePipeline != nullptr); return _simpleOpaqueFadePipeline; }
|
|
||||||
render::ShapePipelinePointer getTransparentFadeShapePipeline() { assert(_simpleTransparentFadePipeline != nullptr); return _simpleTransparentFadePipeline; }
|
|
||||||
render::ShapePipelinePointer getOpaqueShapePipeline(bool isFading);
|
|
||||||
render::ShapePipelinePointer getTransparentShapePipeline(bool isFading);
|
|
||||||
render::ShapePipelinePointer getWireShapePipeline() { assert(_simpleWirePipeline != nullptr); return GeometryCache::_simpleWirePipeline; }
|
|
||||||
|
|
||||||
|
|
||||||
// Static (instanced) geometry
|
// Static (instanced) geometry
|
||||||
void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
||||||
void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer);
|
||||||
|
@ -317,12 +306,6 @@ public:
|
||||||
void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
|
void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
|
||||||
const glm::vec4& color1, const glm::vec4& color2, int id);
|
const glm::vec4& color1, const glm::vec4& color2, int id);
|
||||||
|
|
||||||
void renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
|
|
||||||
const glm::vec4& color, float glowIntensity, float glowWidth, int id);
|
|
||||||
|
|
||||||
void renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, const glm::vec4& color, int id)
|
|
||||||
{ renderGlowLine(batch, p1, p2, color, 1.0f, 0.05f, id); }
|
|
||||||
|
|
||||||
void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id)
|
void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id)
|
||||||
{ renderDashedLine(batch, start, end, color, 0.05f, 0.025f, id); }
|
{ renderDashedLine(batch, start, end, color, 0.05f, 0.025f, id); }
|
||||||
|
|
||||||
|
@ -478,12 +461,9 @@ private:
|
||||||
static gpu::ShaderPointer _unlitFadeShader;
|
static gpu::ShaderPointer _unlitFadeShader;
|
||||||
static render::ShapePipelinePointer _simpleOpaquePipeline;
|
static render::ShapePipelinePointer _simpleOpaquePipeline;
|
||||||
static render::ShapePipelinePointer _simpleTransparentPipeline;
|
static render::ShapePipelinePointer _simpleTransparentPipeline;
|
||||||
static render::ShapePipelinePointer _forwardSimpleOpaquePipeline;
|
|
||||||
static render::ShapePipelinePointer _forwardSimpleTransparentPipeline;
|
|
||||||
static render::ShapePipelinePointer _simpleOpaqueFadePipeline;
|
static render::ShapePipelinePointer _simpleOpaqueFadePipeline;
|
||||||
static render::ShapePipelinePointer _simpleTransparentFadePipeline;
|
static render::ShapePipelinePointer _simpleTransparentFadePipeline;
|
||||||
static render::ShapePipelinePointer _simpleWirePipeline;
|
static render::ShapePipelinePointer _simpleWirePipeline;
|
||||||
gpu::PipelinePointer _glowLinePipeline;
|
|
||||||
|
|
||||||
static QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
|
static QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
|
||||||
|
|
||||||
|
|
|
@ -67,11 +67,11 @@ float TextRenderer3D::getFontSize() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextRenderer3D::draw(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4& color,
|
void TextRenderer3D::draw(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4& color,
|
||||||
const glm::vec2& bounds, bool forwardRendered) {
|
const glm::vec2& bounds, bool layered) {
|
||||||
// The font does all the OpenGL work
|
// The font does all the OpenGL work
|
||||||
if (_font) {
|
if (_font) {
|
||||||
_color = color;
|
_color = color;
|
||||||
_font->drawString(batch, _drawInfo, str, _color, _effectType, { x, y }, bounds, forwardRendered);
|
_font->drawString(batch, _drawInfo, str, _color, _effectType, { x, y }, bounds, layered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
float getFontSize() const; // Pixel size
|
float getFontSize() const; // Pixel size
|
||||||
|
|
||||||
void draw(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4& color = glm::vec4(1.0f),
|
void draw(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4& color = glm::vec4(1.0f),
|
||||||
const glm::vec2& bounds = glm::vec2(-1.0f), bool forwardRendered = false);
|
const glm::vec2& bounds = glm::vec2(-1.0f), bool layered = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextRenderer3D(const char* family, float pointSize, int weight = -1, bool italic = false,
|
TextRenderer3D(const char* family, float pointSize, int weight = -1, bool italic = false,
|
||||||
|
|
57
libraries/render-utils/src/forward_sdf_text3D.slf
Normal file
57
libraries/render-utils/src/forward_sdf_text3D.slf
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
// sdf_text3D_transparent.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015-02-04
|
||||||
|
// Based on fragment shader code from
|
||||||
|
// https://github.com/paulhoux/Cinder-Samples/blob/master/TextRendering/include/text/Text.cpp
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
<@include DefaultMaterials.slh@>
|
||||||
|
|
||||||
|
<@include ForwardGlobalLight.slh@>
|
||||||
|
<$declareEvalSkyboxGlobalColor()$>
|
||||||
|
|
||||||
|
<@include gpu/Transform.slh@>
|
||||||
|
<$declareStandardCameraTransform()$>
|
||||||
|
|
||||||
|
<@include render-utils/ShaderConstants.h@>
|
||||||
|
|
||||||
|
<@include sdf_text3D.slh@>
|
||||||
|
<$declareEvalSDFSuperSampled()$>
|
||||||
|
|
||||||
|
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
|
||||||
|
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||||
|
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
||||||
|
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
||||||
|
#define _texCoord0 _texCoord01.xy
|
||||||
|
#define _texCoord1 _texCoord01.zw
|
||||||
|
|
||||||
|
layout(location=0) out vec4 _fragColor0;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float a = evalSDFSuperSampled(_texCoord0);
|
||||||
|
|
||||||
|
float alpha = a * _color.a;
|
||||||
|
if (alpha <= 0.0) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransformCamera cam = getTransformCamera();
|
||||||
|
vec3 fragPosition = _positionES.xyz;
|
||||||
|
|
||||||
|
_fragColor0 = vec4(evalSkyboxGlobalColor(
|
||||||
|
cam._viewInverse,
|
||||||
|
1.0,
|
||||||
|
DEFAULT_OCCLUSION,
|
||||||
|
fragPosition,
|
||||||
|
normalize(_normalWS),
|
||||||
|
_color.rgb,
|
||||||
|
DEFAULT_FRESNEL,
|
||||||
|
DEFAULT_METALLIC,
|
||||||
|
DEFAULT_ROUGHNESS),
|
||||||
|
1.0);
|
||||||
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
<@include gpu/Color.slh@>
|
||||||
<@include DefaultMaterials.slh@>
|
<@include DefaultMaterials.slh@>
|
||||||
|
|
||||||
<@include ForwardGlobalLight.slh@>
|
<@include ForwardGlobalLight.slh@>
|
||||||
|
@ -21,10 +22,8 @@
|
||||||
|
|
||||||
<@include render-utils/ShaderConstants.h@>
|
<@include render-utils/ShaderConstants.h@>
|
||||||
|
|
||||||
// the albedo texture
|
|
||||||
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||||
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
||||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
||||||
|
@ -36,7 +35,11 @@ layout(location=0) out vec4 _fragColor0;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 texel = texture(originalTexture, _texCoord0);
|
vec4 texel = texture(originalTexture, _texCoord0);
|
||||||
float colorAlpha = _color.a * texel.a;
|
texel = mix(texel, color_sRGBAToLinear(texel), float(_color.a <= 0.0));
|
||||||
|
vec3 albedo = _color.xyz * texel.xyz;
|
||||||
|
float metallic = DEFAULT_METALLIC;
|
||||||
|
|
||||||
|
vec3 fresnel = getFresnelF0(metallic, albedo);
|
||||||
|
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
vec3 fragPosition = _positionES.xyz;
|
vec3 fragPosition = _positionES.xyz;
|
||||||
|
@ -47,9 +50,9 @@ void main(void) {
|
||||||
DEFAULT_OCCLUSION,
|
DEFAULT_OCCLUSION,
|
||||||
fragPosition,
|
fragPosition,
|
||||||
normalize(_normalWS),
|
normalize(_normalWS),
|
||||||
_color.rgb * texel.rgb,
|
albedo,
|
||||||
DEFAULT_FRESNEL,
|
fresnel,
|
||||||
DEFAULT_METALLIC,
|
metallic,
|
||||||
DEFAULT_ROUGHNESS),
|
DEFAULT_ROUGHNESS),
|
||||||
1.0);
|
1.0);
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
<@include gpu/Color.slh@>
|
||||||
<@include DefaultMaterials.slh@>
|
<@include DefaultMaterials.slh@>
|
||||||
|
|
||||||
<@include ForwardGlobalLight.slh@>
|
<@include ForwardGlobalLight.slh@>
|
||||||
|
@ -21,22 +22,25 @@
|
||||||
|
|
||||||
<@include render-utils/ShaderConstants.h@>
|
<@include render-utils/ShaderConstants.h@>
|
||||||
|
|
||||||
// the albedo texture
|
|
||||||
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
||||||
|
|
||||||
// the interpolated normal
|
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
|
||||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||||
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
||||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
||||||
#define _texCoord0 _texCoord01.xy
|
#define _texCoord0 _texCoord01.xy
|
||||||
#define _texCoord1 _texCoord01.zw
|
#define _texCoord1 _texCoord01.zw
|
||||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
|
|
||||||
|
|
||||||
layout(location=0) out vec4 _fragColor0;
|
layout(location=0) out vec4 _fragColor0;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 texel = texture(originalTexture, _texCoord0);
|
vec4 texel = texture(originalTexture, _texCoord0);
|
||||||
float colorAlpha = _color.a * texel.a;
|
texel = mix(texel, color_sRGBAToLinear(texel), float(_color.a <= 0.0));
|
||||||
|
vec3 albedo = _color.xyz * texel.xyz;
|
||||||
|
float alpha = _color.a * texel.a;
|
||||||
|
float metallic = DEFAULT_METALLIC;
|
||||||
|
|
||||||
|
vec3 fresnel = getFresnelF0(metallic, albedo);
|
||||||
|
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
vec3 fragPosition = _positionES.xyz;
|
vec3 fragPosition = _positionES.xyz;
|
||||||
|
@ -47,10 +51,10 @@ void main(void) {
|
||||||
DEFAULT_OCCLUSION,
|
DEFAULT_OCCLUSION,
|
||||||
fragPosition,
|
fragPosition,
|
||||||
normalize(_normalWS),
|
normalize(_normalWS),
|
||||||
_color.rgb * texel.rgb,
|
albedo,
|
||||||
DEFAULT_FRESNEL,
|
fresnel,
|
||||||
DEFAULT_METALLIC,
|
metallic,
|
||||||
DEFAULT_EMISSIVE,
|
DEFAULT_EMISSIVE,
|
||||||
DEFAULT_ROUGHNESS, colorAlpha),
|
DEFAULT_ROUGHNESS, alpha),
|
||||||
colorAlpha);
|
alpha);
|
||||||
}
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
VERTEX sdf_text3D
|
|
@ -13,54 +13,22 @@
|
||||||
<@include DeferredBufferWrite.slh@>
|
<@include DeferredBufferWrite.slh@>
|
||||||
<@include render-utils/ShaderConstants.h@>
|
<@include render-utils/ShaderConstants.h@>
|
||||||
|
|
||||||
LAYOUT(binding=0) uniform sampler2D Font;
|
<@include sdf_text3D.slh@>
|
||||||
|
<$declareEvalSDFSuperSampled()$>
|
||||||
|
|
||||||
struct TextParams {
|
|
||||||
vec4 color;
|
|
||||||
vec4 outline;
|
|
||||||
};
|
|
||||||
|
|
||||||
LAYOUT(binding=0) uniform textParamsBuffer {
|
|
||||||
TextParams params;
|
|
||||||
};
|
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||||
|
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
||||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
||||||
#define _texCoord0 _texCoord01.xy
|
#define _texCoord0 _texCoord01.xy
|
||||||
#define _texCoord1 _texCoord01.zw
|
#define _texCoord1 _texCoord01.zw
|
||||||
|
|
||||||
#define TAA_TEXTURE_LOD_BIAS -3.0
|
|
||||||
|
|
||||||
const float interiorCutoff = 0.8;
|
|
||||||
const float outlineExpansion = 0.2;
|
|
||||||
const float taaBias = pow(2.0, TAA_TEXTURE_LOD_BIAS);
|
|
||||||
|
|
||||||
float evalSDF(vec2 texCoord) {
|
|
||||||
// retrieve signed distance
|
|
||||||
float sdf = textureLod(Font, texCoord, TAA_TEXTURE_LOD_BIAS).g;
|
|
||||||
sdf = mix(sdf, mix(sdf + outlineExpansion, 1.0 - sdf, float(sdf > interiorCutoff)), float(params.outline.x > 0.0));
|
|
||||||
|
|
||||||
// Rely on TAA for anti-aliasing
|
|
||||||
return step(0.5, sdf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 dxTexCoord = dFdx(_texCoord0) * 0.5 * taaBias;
|
float a = evalSDFSuperSampled(_texCoord0);
|
||||||
vec2 dyTexCoord = dFdy(_texCoord0) * 0.5 * taaBias;
|
|
||||||
|
|
||||||
// Perform 4x supersampling for anisotropic filtering
|
|
||||||
float a;
|
|
||||||
a = evalSDF(_texCoord0);
|
|
||||||
a += evalSDF(_texCoord0 + dxTexCoord);
|
|
||||||
a += evalSDF(_texCoord0 + dyTexCoord);
|
|
||||||
a += evalSDF(_texCoord0 + dxTexCoord + dyTexCoord);
|
|
||||||
a *= 0.25;
|
|
||||||
|
|
||||||
packDeferredFragment(
|
packDeferredFragment(
|
||||||
normalize(_normalWS),
|
normalize(_normalWS),
|
||||||
a * params.color.a,
|
a,
|
||||||
params.color.rgb,
|
_color.rgb,
|
||||||
DEFAULT_ROUGHNESS,
|
DEFAULT_ROUGHNESS,
|
||||||
DEFAULT_METALLIC,
|
DEFAULT_METALLIC,
|
||||||
DEFAULT_EMISSIVE,
|
DEFAULT_EMISSIVE,
|
||||||
|
|
63
libraries/render-utils/src/sdf_text3D.slh
Normal file
63
libraries/render-utils/src/sdf_text3D.slh
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
<!
|
||||||
|
// <$_SCRIBE_FILENAME$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// Created by Sam Gondelman on 3/15/19
|
||||||
|
// Copyright 2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
!>
|
||||||
|
<@if not SDF_TEXT3D_SLH@>
|
||||||
|
<@def SDF_TEXT3D_SLH@>
|
||||||
|
|
||||||
|
LAYOUT(binding=0) uniform sampler2D Font;
|
||||||
|
|
||||||
|
struct TextParams {
|
||||||
|
vec4 color;
|
||||||
|
vec4 outline;
|
||||||
|
};
|
||||||
|
|
||||||
|
LAYOUT(binding=0) uniform textParamsBuffer {
|
||||||
|
TextParams params;
|
||||||
|
};
|
||||||
|
|
||||||
|
<@func declareEvalSDFSuperSampled()@>
|
||||||
|
|
||||||
|
#define TAA_TEXTURE_LOD_BIAS -3.0
|
||||||
|
|
||||||
|
const float interiorCutoff = 0.8;
|
||||||
|
const float outlineExpansion = 0.2;
|
||||||
|
const float taaBias = pow(2.0, TAA_TEXTURE_LOD_BIAS);
|
||||||
|
|
||||||
|
float evalSDF(vec2 texCoord) {
|
||||||
|
// retrieve signed distance
|
||||||
|
float sdf = textureLod(Font, texCoord, TAA_TEXTURE_LOD_BIAS).g;
|
||||||
|
sdf = mix(sdf, mix(sdf + outlineExpansion, 1.0 - sdf, float(sdf > interiorCutoff)), float(params.outline.x > 0.0));
|
||||||
|
|
||||||
|
// Rely on TAA for anti-aliasing
|
||||||
|
return step(0.5, sdf);
|
||||||
|
}
|
||||||
|
|
||||||
|
float evalSDFSuperSampled(vec2 texCoord) {
|
||||||
|
vec2 dxTexCoord = dFdx(texCoord) * 0.5 * taaBias;
|
||||||
|
vec2 dyTexCoord = dFdy(texCoord) * 0.5 * taaBias;
|
||||||
|
|
||||||
|
// Perform 4x supersampling for anisotropic filtering
|
||||||
|
float a;
|
||||||
|
a = evalSDF(texCoord);
|
||||||
|
a += evalSDF(texCoord + dxTexCoord);
|
||||||
|
a += evalSDF(texCoord + dyTexCoord);
|
||||||
|
a += evalSDF(texCoord + dxTexCoord + dyTexCoord);
|
||||||
|
a *= 0.25;
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
<@endfunc@>
|
||||||
|
|
||||||
|
<@endif@>
|
||||||
|
|
|
@ -11,18 +11,23 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include gpu/Inputs.slh@>
|
<@include gpu/Inputs.slh@>
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Color.slh@>
|
||||||
<@include render-utils/ShaderConstants.h@>
|
<@include render-utils/ShaderConstants.h@>
|
||||||
|
|
||||||
|
<@include gpu/Transform.slh@>
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
|
<@include sdf_text3D.slh@>
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
|
||||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
|
||||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
|
||||||
|
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||||
|
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||||
|
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
_texCoord01.xy = inTexCoord0.xy;
|
_texCoord01.xy = inTexCoord0.xy;
|
||||||
|
_color = color_sRGBAToLinear(params.color);
|
||||||
|
|
||||||
// standard transform
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
|
|
|
@ -20,53 +20,22 @@
|
||||||
|
|
||||||
<@include render-utils/ShaderConstants.h@>
|
<@include render-utils/ShaderConstants.h@>
|
||||||
|
|
||||||
LAYOUT(binding=0) uniform sampler2D Font;
|
<@include sdf_text3D.slh@>
|
||||||
|
<$declareEvalSDFSuperSampled()$>
|
||||||
struct TextParams {
|
|
||||||
vec4 color;
|
|
||||||
vec4 outline;
|
|
||||||
};
|
|
||||||
|
|
||||||
LAYOUT(binding=0) uniform textParamsBuffer {
|
|
||||||
TextParams params;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
|
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
|
||||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||||
|
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
||||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
||||||
#define _texCoord0 _texCoord01.xy
|
#define _texCoord0 _texCoord01.xy
|
||||||
#define _texCoord1 _texCoord01.zw
|
#define _texCoord1 _texCoord01.zw
|
||||||
|
|
||||||
layout(location=0) out vec4 _fragColor0;
|
layout(location=0) out vec4 _fragColor0;
|
||||||
|
|
||||||
#define TAA_TEXTURE_LOD_BIAS -3.0
|
|
||||||
|
|
||||||
const float interiorCutoff = 0.8;
|
|
||||||
const float outlineExpansion = 0.2;
|
|
||||||
const float taaBias = pow(2.0, TAA_TEXTURE_LOD_BIAS);
|
|
||||||
|
|
||||||
float evalSDF(vec2 texCoord) {
|
|
||||||
// retrieve signed distance
|
|
||||||
float sdf = textureLod(Font, texCoord, TAA_TEXTURE_LOD_BIAS).g;
|
|
||||||
sdf = mix(sdf, mix(sdf + outlineExpansion, 1.0 - sdf, float(sdf > interiorCutoff)), float(params.outline.x > 0.0));
|
|
||||||
|
|
||||||
// Rely on TAA for anti-aliasing
|
|
||||||
return step(0.5, sdf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 dxTexCoord = dFdx(_texCoord0) * 0.5 * taaBias;
|
float a = evalSDFSuperSampled(_texCoord0);
|
||||||
vec2 dyTexCoord = dFdy(_texCoord0) * 0.5 * taaBias;
|
|
||||||
|
|
||||||
// Perform 4x supersampling for anisotropic filtering
|
float alpha = a * _color.a;
|
||||||
float a;
|
|
||||||
a = evalSDF(_texCoord0);
|
|
||||||
a += evalSDF(_texCoord0 + dxTexCoord);
|
|
||||||
a += evalSDF(_texCoord0 + dyTexCoord);
|
|
||||||
a += evalSDF(_texCoord0 + dxTexCoord + dyTexCoord);
|
|
||||||
a *= 0.25;
|
|
||||||
|
|
||||||
float alpha = a * params.color.a;
|
|
||||||
if (alpha <= 0.0) {
|
if (alpha <= 0.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +49,7 @@ void main() {
|
||||||
DEFAULT_OCCLUSION,
|
DEFAULT_OCCLUSION,
|
||||||
fragPosition,
|
fragPosition,
|
||||||
normalize(_normalWS),
|
normalize(_normalWS),
|
||||||
params.color.rgb,
|
_color.rgb,
|
||||||
DEFAULT_FRESNEL,
|
DEFAULT_FRESNEL,
|
||||||
DEFAULT_METALLIC,
|
DEFAULT_METALLIC,
|
||||||
DEFAULT_EMISSIVE,
|
DEFAULT_EMISSIVE,
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
<@include render-utils/ShaderConstants.h@>
|
<@include render-utils/ShaderConstants.h@>
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
|
||||||
layout(location=RENDER_UTILS_ATTR_NORMAL_MS) out vec3 _normalMS;
|
layout(location=RENDER_UTILS_ATTR_NORMAL_MS) out vec3 _normalMS;
|
||||||
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
layout(location=RENDER_UTILS_ATTR_COLOR) out vec4 _color;
|
||||||
|
|
|
@ -11,31 +11,50 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
<@include DefaultMaterials.slh@>
|
||||||
|
|
||||||
<@include gpu/Color.slh@>
|
<@include gpu/Color.slh@>
|
||||||
<@include DeferredBufferWrite.slh@>
|
|
||||||
|
|
||||||
<@include render-utils/ShaderConstants.h@>
|
<@include render-utils/ShaderConstants.h@>
|
||||||
|
|
||||||
// the albedo texture
|
<@include ForwardGlobalLight.slh@>
|
||||||
|
<$declareEvalGlobalLightingAlphaBlended()$>
|
||||||
|
|
||||||
|
<@include gpu/Transform.slh@>
|
||||||
|
<$declareStandardCameraTransform()$>
|
||||||
|
|
||||||
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
||||||
|
|
||||||
// the interpolated normal
|
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
|
||||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||||
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
layout(location=RENDER_UTILS_ATTR_COLOR) in vec4 _color;
|
||||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
|
||||||
#define _texCoord0 _texCoord01.xy
|
#define _texCoord0 _texCoord01.xy
|
||||||
#define _texCoord1 _texCoord01.zw
|
#define _texCoord1 _texCoord01.zw
|
||||||
|
|
||||||
|
layout(location=0) out vec4 _fragColor0;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 texel = texture(originalTexture, _texCoord0);
|
vec4 texel = texture(originalTexture, _texCoord0);
|
||||||
texel = mix(texel, color_sRGBAToLinear(texel), float(_color.a <= 0.0));
|
texel = mix(texel, color_sRGBAToLinear(texel), float(_color.a <= 0.0));
|
||||||
texel.rgb *= _color.rgb;
|
vec3 albedo = _color.xyz * texel.xyz;
|
||||||
texel.a *= abs(_color.a);
|
float alpha = _color.a * texel.a;
|
||||||
|
float metallic = DEFAULT_METALLIC;
|
||||||
|
|
||||||
packDeferredFragmentTranslucent(
|
vec3 fresnel = getFresnelF0(metallic, albedo);
|
||||||
|
|
||||||
|
TransformCamera cam = getTransformCamera();
|
||||||
|
vec3 fragPosition = _positionES.xyz;
|
||||||
|
|
||||||
|
_fragColor0 = vec4(evalGlobalLightingAlphaBlendedWithHaze(
|
||||||
|
cam._viewInverse,
|
||||||
|
1.0,
|
||||||
|
DEFAULT_OCCLUSION,
|
||||||
|
fragPosition,
|
||||||
normalize(_normalWS),
|
normalize(_normalWS),
|
||||||
texel.a,
|
albedo,
|
||||||
texel.rgb,
|
fresnel,
|
||||||
DEFAULT_ROUGHNESS);
|
metallic,
|
||||||
|
DEFAULT_EMISSIVE,
|
||||||
|
DEFAULT_ROUGHNESS, alpha),
|
||||||
|
alpha);
|
||||||
}
|
}
|
|
@ -13,6 +13,8 @@
|
||||||
#include "FontFamilies.h"
|
#include "FontFamilies.h"
|
||||||
#include "../StencilMaskPass.h"
|
#include "../StencilMaskPass.h"
|
||||||
|
|
||||||
|
#include "DisableDeferred.h"
|
||||||
|
|
||||||
static std::mutex fontMutex;
|
static std::mutex fontMutex;
|
||||||
|
|
||||||
struct TextureVertex {
|
struct TextureVertex {
|
||||||
|
@ -221,25 +223,43 @@ void Font::setupGPU() {
|
||||||
|
|
||||||
// Setup render pipeline
|
// Setup render pipeline
|
||||||
{
|
{
|
||||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::sdf_text3D);
|
{
|
||||||
auto state = std::make_shared<gpu::State>();
|
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::forward_sdf_text3D);
|
||||||
state->setCullMode(gpu::State::CULL_BACK);
|
auto state = std::make_shared<gpu::State>();
|
||||||
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
state->setCullMode(gpu::State::CULL_BACK);
|
||||||
state->setBlendFunction(false,
|
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
state->setBlendFunction(false,
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
PrepareStencil::testMaskDrawShape(*state);
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
_pipeline = gpu::Pipeline::create(program, state);
|
PrepareStencil::testMaskDrawShape(*state);
|
||||||
|
_layeredPipeline = gpu::Pipeline::create(program, state);
|
||||||
|
}
|
||||||
|
|
||||||
gpu::ShaderPointer programTransparent = gpu::Shader::createProgram(shader::render_utils::program::sdf_text3D_transparent);
|
if (DISABLE_DEFERRED) {
|
||||||
auto transparentState = std::make_shared<gpu::State>();
|
_pipeline = _layeredPipeline;
|
||||||
transparentState->setCullMode(gpu::State::CULL_BACK);
|
} else {
|
||||||
transparentState->setDepthTest(true, true, gpu::LESS_EQUAL);
|
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::sdf_text3D);
|
||||||
transparentState->setBlendFunction(true,
|
auto state = std::make_shared<gpu::State>();
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
state->setCullMode(gpu::State::CULL_BACK);
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||||
PrepareStencil::testMask(*transparentState);
|
state->setBlendFunction(false,
|
||||||
_transparentPipeline = gpu::Pipeline::create(programTransparent, transparentState);
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
|
PrepareStencil::testMaskDrawShape(*state);
|
||||||
|
_pipeline = gpu::Pipeline::create(program, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::sdf_text3D_transparent);
|
||||||
|
auto state = std::make_shared<gpu::State>();
|
||||||
|
state->setCullMode(gpu::State::CULL_BACK);
|
||||||
|
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||||
|
state->setBlendFunction(true,
|
||||||
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
|
PrepareStencil::testMask(*state);
|
||||||
|
_transparentPipeline = gpu::Pipeline::create(program, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
|
@ -343,7 +363,7 @@ void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const QString& str, const glm::vec4& color,
|
void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const QString& str, const glm::vec4& color,
|
||||||
EffectType effectType, const glm::vec2& origin, const glm::vec2& bounds, bool forwardRendered) {
|
EffectType effectType, const glm::vec2& origin, const glm::vec2& bounds, bool layered) {
|
||||||
if (str == "") {
|
if (str == "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -370,7 +390,7 @@ void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const QString
|
||||||
}
|
}
|
||||||
// need the gamma corrected color here
|
// need the gamma corrected color here
|
||||||
|
|
||||||
batch.setPipeline(forwardRendered || (color.a < 1.0f) ? _transparentPipeline : _pipeline);
|
batch.setPipeline(color.a < 1.0f ? _transparentPipeline : (layered ? _layeredPipeline : _pipeline));
|
||||||
batch.setInputFormat(_format);
|
batch.setInputFormat(_format);
|
||||||
batch.setInputBuffer(0, drawInfo.verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
batch.setInputBuffer(0, drawInfo.verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
||||||
batch.setResourceTexture(render_utils::slot::texture::TextFont, _texture);
|
batch.setResourceTexture(render_utils::slot::texture::TextFont, _texture);
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
// Render string to batch
|
// Render string to batch
|
||||||
void drawString(gpu::Batch& batch, DrawInfo& drawInfo, const QString& str,
|
void drawString(gpu::Batch& batch, DrawInfo& drawInfo, const QString& str,
|
||||||
const glm::vec4& color, EffectType effectType,
|
const glm::vec4& color, EffectType effectType,
|
||||||
const glm::vec2& origin, const glm::vec2& bound, bool forwardRendered);
|
const glm::vec2& origin, const glm::vec2& bound, bool layered);
|
||||||
|
|
||||||
static Pointer load(const QString& family);
|
static Pointer load(const QString& family);
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ private:
|
||||||
|
|
||||||
// gpu structures
|
// gpu structures
|
||||||
gpu::PipelinePointer _pipeline;
|
gpu::PipelinePointer _pipeline;
|
||||||
|
gpu::PipelinePointer _layeredPipeline;
|
||||||
gpu::PipelinePointer _transparentPipeline;
|
gpu::PipelinePointer _transparentPipeline;
|
||||||
gpu::TexturePointer _texture;
|
gpu::TexturePointer _texture;
|
||||||
gpu::Stream::FormatPointer _format;
|
gpu::Stream::FormatPointer _format;
|
||||||
|
|
Loading…
Reference in a new issue