From e45757ac50177f1d80579a0cc20daa517c3d52c4 Mon Sep 17 00:00:00 2001 From: ExMix Date: Sun, 15 Nov 2015 18:33:52 +0300 Subject: [PATCH] [drape] improve text rendering --- drape/shaders/text_fragment_shader.fsh | 53 ++++---------------------- drape/shaders/text_vertex_shader.vsh | 17 ++++++--- drape_frontend/frontend_renderer.cpp | 14 +++---- drape_frontend/render_group.cpp | 51 +++++++++++++++++++------ drape_frontend/render_group.hpp | 4 ++ drape_frontend/text_layout.cpp | 14 +++---- 6 files changed, 73 insertions(+), 80 deletions(-) diff --git a/drape/shaders/text_fragment_shader.fsh b/drape/shaders/text_fragment_shader.fsh index 2434e5d8b8..c5911d8704 100755 --- a/drape/shaders/text_fragment_shader.fsh +++ b/drape/shaders/text_fragment_shader.fsh @@ -1,56 +1,17 @@ varying vec2 v_colorTexCoord; -varying vec2 v_outlineColorTexCoord; varying vec2 v_maskTexCoord; uniform sampler2D u_colorTex; uniform sampler2D u_maskTex; uniform float u_opacity; -uniform vec4 u_outlineGlyphParams; -uniform vec2 u_glyphParams; - -vec4 colorize(vec4 base, vec4 outline, float alpha) -{ - if (alpha > u_outlineGlyphParams.w) - return vec4(outline.rgb, 0); - if (alpha > u_outlineGlyphParams.z) - { - float oFactor = smoothstep(u_outlineGlyphParams.w, u_outlineGlyphParams.z, alpha); - return vec4(outline.rgb, mix(0.0, outline.a, oFactor)); - } - if (alpha > u_outlineGlyphParams.y) - { - return outline; - } - if (alpha > u_outlineGlyphParams.x) - { - float oFactor = smoothstep(u_outlineGlyphParams.x, u_outlineGlyphParams.y, alpha); - return mix(base, outline, oFactor); - } - return base; -} - -vec4 without_outline(vec4 base, float alpha) -{ - if (alpha > u_glyphParams.x) - { - float oFactor = smoothstep(u_glyphParams.x, u_glyphParams.y, alpha); - return vec4(base.rgb, mix(base.a, 0.0, oFactor)); - } - return base; -} +uniform float u_contrast; +uniform float u_gamma; void main (void) { - vec4 base = texture2D(u_colorTex, v_colorTexCoord); - vec4 outline = texture2D(u_colorTex, v_outlineColorTexCoord); - float alpha = texture2D(u_maskTex, v_maskTexCoord).a; - - vec4 finalColor; - if (outline.a > 0.1) - finalColor = colorize(base, outline, 1.0 - alpha); - else - finalColor = without_outline(base, 1.0 - alpha); - - finalColor.a *= u_opacity; - gl_FragColor = finalColor; + vec4 glyphColor = texture2D(u_colorTex, v_colorTexCoord); + float dist = texture2D(u_maskTex, v_maskTexCoord).a; + float alpha = smoothstep(u_contrast - u_gamma, u_contrast + u_gamma, dist) * u_opacity; + glyphColor.a *= alpha; + gl_FragColor = glyphColor; } diff --git a/drape/shaders/text_vertex_shader.vsh b/drape/shaders/text_vertex_shader.vsh index 84ac98b129..4592b4f9d7 100755 --- a/drape/shaders/text_vertex_shader.vsh +++ b/drape/shaders/text_vertex_shader.vsh @@ -6,19 +6,26 @@ attribute vec2 a_maskTexCoord; uniform mat4 modelView; uniform mat4 projection; +uniform float u_isOutlinePass; varying vec2 v_colorTexCoord; varying vec2 v_maskTexCoord; -varying vec2 v_outlineColorTexCoord; + +const float Zero = 0.0; +const float One = 1.0; +const float BaseDepthShoft = -10.0; void main() { + float isOutline = step(0.5, u_isOutlinePass); + float notOutline = One - isOutline; + float depthShift = BaseDepthShoft * isOutline; + // Here we intentionally decrease precision of 'pos' calculation // to eliminate jittering effect in process of billboard reconstruction. - lowp vec4 pos = a_position * modelView; - highp vec4 shiftedPos = vec4(a_normal, 0, 0) + pos; + lowp vec4 pos = (a_position + vec4(Zero, Zero, depthShift, Zero)) * modelView; + highp vec4 shiftedPos = vec4(a_normal, Zero, Zero) + pos; gl_Position = shiftedPos * projection; - v_colorTexCoord = a_colorTexCoord; + v_colorTexCoord = a_colorTexCoord * notOutline + a_outlineColorTexCoord * isOutline; v_maskTexCoord = a_maskTexCoord; - v_outlineColorTexCoord = a_outlineColorTexCoord; } diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index d2f814c2cf..8768e94a85 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -120,7 +120,10 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) if (!IsUserMarkLayer(key)) m_tileTree->ProcessTile(key, GetCurrentZoomLevel(), state, move(bucket)); else + { m_userMarkRenderGroups.emplace_back(make_unique_dp(state, key, move(bucket))); + m_userMarkRenderGroups.back()->SetRenderParams(program, make_ref(&m_generalUniforms)); + } break; } @@ -411,6 +414,8 @@ void FrontendRenderer::AddToRenderGroup(vector> & groups, TileKey const & newTile) { drape_ptr group = make_unique_dp(state, newTile); + ref_ptr program = m_gpuProgramManager->GetProgram(state.GetProgramIndex()); + group->SetRenderParams(program, make_ref(&m_generalUniforms)); group->AddBucket(move(renderBucket)); groups.push_back(move(group)); } @@ -639,15 +644,6 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) void FrontendRenderer::RenderSingleGroup(ScreenBase const & modelView, ref_ptr group) { group->UpdateAnimation(); - - dp::GLState const & state = group->GetState(); - ref_ptr program = m_gpuProgramManager->GetProgram(state.GetProgramIndex()); - program->Bind(); - - ApplyState(state, program); - ApplyUniforms(m_generalUniforms, program); - ApplyUniforms(group->GetUniforms(), program); - group->Render(modelView); } diff --git a/drape_frontend/render_group.cpp b/drape_frontend/render_group.cpp index 48cd16d2e9..17eab003d2 100755 --- a/drape_frontend/render_group.cpp +++ b/drape_frontend/render_group.cpp @@ -12,6 +12,12 @@ namespace df { +void BaseRenderGroup::SetRenderParams(ref_ptr shader, ref_ptr generalUniforms) +{ + m_shader = shader; + m_generalUniforms = generalUniforms; +} + void BaseRenderGroup::UpdateAnimation() { m_uniforms.SetFloatValue("u_opacity", 1.0); @@ -21,15 +27,6 @@ RenderGroup::RenderGroup(dp::GLState const & state, df::TileKey const & tileKey) : TBase(state, tileKey) , m_pendingOnDelete(false) { - if (state.GetProgramIndex() == gpu::TEXT_PROGRAM) - { - auto const & params = VisualParams::Instance().GetGlyphVisualParams(); - m_uniforms.SetFloatValue("u_outlineGlyphParams", - params.m_outlineMinStart, params.m_outlineMinEnd, - params.m_outlineMaxStart, params.m_outlineMaxEnd); - m_uniforms.SetFloatValue("u_glyphParams", - params.m_alphaGlyphMin, params.m_alphaGlyphMax); - } } RenderGroup::~RenderGroup() @@ -39,6 +36,8 @@ RenderGroup::~RenderGroup() void RenderGroup::Update(ScreenBase const & modelView) { + ASSERT(m_shader != nullptr, ()); + ASSERT(m_generalUniforms != nullptr, ()); for(drape_ptr & renderBucket : m_renderBuckets) renderBucket->Update(modelView); } @@ -48,14 +47,44 @@ void RenderGroup::CollectOverlay(ref_ptr tree) if (m_pendingOnDelete) return; + ASSERT(m_shader != nullptr, ()); + ASSERT(m_generalUniforms != nullptr, ()); for(drape_ptr & renderBucket : m_renderBuckets) renderBucket->CollectOverlayHandles(tree, GetOpacity() < 1.0); } void RenderGroup::Render(ScreenBase const & screen) { - for(drape_ptr & renderBucket : m_renderBuckets) - renderBucket->Render(screen); + ASSERT(m_shader != nullptr, ()); + ASSERT(m_generalUniforms != nullptr, ()); + + m_shader->Bind(); + dp::ApplyState(m_state, m_shader); + dp::ApplyUniforms(*(m_generalUniforms.get()), m_shader); + if (m_state.GetProgramIndex() == gpu::TEXT_PROGRAM) + { + m_uniforms.SetFloatValue("u_contrast", 0.05f); + m_uniforms.SetFloatValue("u_gamma", 0.01f); + m_uniforms.SetFloatValue("u_isOutlinePass", 1.0f); + dp::ApplyUniforms(m_uniforms, m_shader); + + for(drape_ptr & renderBucket : m_renderBuckets) + renderBucket->Render(screen); + + m_uniforms.SetFloatValue("u_contrast", 0.45f); + m_uniforms.SetFloatValue("u_gamma", 0.05f); + m_uniforms.SetFloatValue("u_isOutlinePass", 0.0f); + dp::ApplyUniforms(m_uniforms, m_shader); + for(drape_ptr & renderBucket : m_renderBuckets) + renderBucket->Render(screen); + } + else + { + dp::ApplyUniforms(m_uniforms, m_shader); + + for(drape_ptr & renderBucket : m_renderBuckets) + renderBucket->Render(screen); + } } void RenderGroup::AddBucket(drape_ptr && bucket) diff --git a/drape_frontend/render_group.hpp b/drape_frontend/render_group.hpp index f20616b0cb..c9cc7ebc83 100755 --- a/drape_frontend/render_group.hpp +++ b/drape_frontend/render_group.hpp @@ -25,6 +25,8 @@ public: : m_state(state) , m_tileKey(tileKey) {} + void SetRenderParams(ref_ptr shader, ref_ptr generalUniforms); + dp::GLState const & GetState() const { return m_state; } TileKey const & GetTileKey() const { return m_tileKey; } dp::UniformValuesStorage const & GetUniforms() const { return m_uniforms; } @@ -34,7 +36,9 @@ public: protected: dp::GLState m_state; + ref_ptr m_shader; dp::UniformValuesStorage m_uniforms; + ref_ptr m_generalUniforms; private: TileKey m_tileKey; diff --git a/drape_frontend/text_layout.cpp b/drape_frontend/text_layout.cpp index 0d399d7ecc..ec5f6da827 100644 --- a/drape_frontend/text_layout.cpp +++ b/drape_frontend/text_layout.cpp @@ -24,8 +24,7 @@ public: dp::TextureManager::ColorRegion const & color, dp::TextureManager::ColorRegion const & outline, gpu::TTextStaticVertexBuffer & buffer) - : m_depthShift(0.0f, 0.0f, 0.0f) - , m_pivot(pivot) + : m_pivot(pivot) , m_colorCoord(glsl::ToVec2(color.GetTexRect().Center())) , m_outlineCoord(glsl::ToVec2(outline.GetTexRect().Center())) , m_buffer(buffer) @@ -35,16 +34,13 @@ public: void operator() (dp::TextureManager::GlyphRegion const & glyph) { m2::RectF const & mask = glyph.GetTexRect(); - glsl::vec3 pivot = m_pivot + m_depthShift; - m_buffer.push_back(gpu::TextStaticVertex(pivot, m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.LeftTop()))); - m_buffer.push_back(gpu::TextStaticVertex(pivot, m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.LeftBottom()))); - m_buffer.push_back(gpu::TextStaticVertex(pivot, m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.RightTop()))); - m_buffer.push_back(gpu::TextStaticVertex(pivot, m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.RightBottom()))); - m_depthShift += glsl::vec3(0.0f, 0.0f, 1.0f); + m_buffer.push_back(gpu::TextStaticVertex(m_pivot, m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.LeftTop()))); + m_buffer.push_back(gpu::TextStaticVertex(m_pivot, m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.LeftBottom()))); + m_buffer.push_back(gpu::TextStaticVertex(m_pivot, m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.RightTop()))); + m_buffer.push_back(gpu::TextStaticVertex(m_pivot, m_colorCoord, m_outlineCoord, glsl::ToVec2(mask.RightBottom()))); } protected: - glsl::vec3 m_depthShift; glsl::vec3 const & m_pivot; glsl::vec2 m_colorCoord; glsl::vec2 m_outlineCoord;