diff --git a/libraries/render-utils/src/sdf_text3D_overlay.slf b/libraries/render-utils/src/sdf_text3D_overlay.slf new file mode 100644 index 0000000000..d357b05e14 --- /dev/null +++ b/libraries/render-utils/src/sdf_text3D_overlay.slf @@ -0,0 +1,52 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// sdf_text.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 + +uniform sampler2D Font; +uniform bool Outline; +uniform vec4 Color; + +// the interpolated normal +in vec3 _normal; +in vec2 _texCoord0; + +layout(location = 0) out vec4 _fragColor0; + +const float gamma = 2.2; +const float smoothing = 32.0; +const float interiorCutoff = 0.8; +const float outlineExpansion = 0.2; + +void main() { + // retrieve signed distance + float sdf = texture(Font, _texCoord0).g; + if (Outline) { + if (sdf > interiorCutoff) { + sdf = 1.0 - sdf; + } else { + sdf += outlineExpansion; + } + } + // perform adaptive anti-aliasing of the edges + // The larger we're rendering, the less anti-aliasing we need + float s = smoothing * length(fwidth(_texCoord0)); + float w = clamp( s, 0.0, 0.5); + float a = smoothstep(0.5 - w, 0.5 + w, sdf); + + // gamma correction for linear attenuation + a = pow(a, 1.0 / gamma); + + // discard if unvisible + if (a < 0.01) { + discard; + } + _fragColor0 = vec4(Color.rgb, a); +} \ No newline at end of file diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index 762a7fb723..3c460fdd99 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -9,6 +9,7 @@ #include "sdf_text3D_vert.h" #include "sdf_text3D_frag.h" +#include "sdf_text3D_overlay_frag.h" #include "../RenderUtilsLogging.h" #include "FontFamilies.h" @@ -220,10 +221,13 @@ void Font::setupGPU() { { auto vertexShader = gpu::Shader::createVertex(std::string(sdf_text3D_vert)); auto pixelShader = gpu::Shader::createPixel(std::string(sdf_text3D_frag)); + auto pixelShaderOverlay = gpu::Shader::createPixel(std::string(sdf_text3D_overlay_frag)); gpu::ShaderPointer program = gpu::Shader::createProgram(vertexShader, pixelShader); + gpu::ShaderPointer programOverlay = gpu::Shader::createProgram(vertexShader, pixelShaderOverlay); gpu::Shader::BindingSet slotBindings; gpu::Shader::makeProgram(*program, slotBindings); + gpu::Shader::makeProgram(*programOverlay, slotBindings); _fontLoc = program->getTextures().findLocation("Font"); _outlineLoc = program->getUniforms().findLocation("Outline"); @@ -237,9 +241,10 @@ void Font::setupGPU() { gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); _pipeline = gpu::Pipeline::create(program, state); - auto layeredState = std::make_shared(state->getValues()); - layeredState->setDepthTest(false); - _layeredPipeline = gpu::Pipeline::create(program, layeredState); + auto layeredState = std::make_shared(); + layeredState->setCullMode(gpu::State::CULL_BACK); + layeredState->setDepthTest(true, true, gpu::LESS_EQUAL); + _layeredPipeline = gpu::Pipeline::create(programOverlay, layeredState); } // Sanity checks