forked from organicmaps/organicmaps
[drape] improve text rendering
This commit is contained in:
parent
f642dd2c6b
commit
e45757ac50
6 changed files with 73 additions and 80 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,10 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
if (!IsUserMarkLayer(key))
|
||||
m_tileTree->ProcessTile(key, GetCurrentZoomLevel(), state, move(bucket));
|
||||
else
|
||||
{
|
||||
m_userMarkRenderGroups.emplace_back(make_unique_dp<UserMarkRenderGroup>(state, key, move(bucket)));
|
||||
m_userMarkRenderGroups.back()->SetRenderParams(program, make_ref(&m_generalUniforms));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -411,6 +414,8 @@ void FrontendRenderer::AddToRenderGroup(vector<drape_ptr<RenderGroup>> & groups,
|
|||
TileKey const & newTile)
|
||||
{
|
||||
drape_ptr<RenderGroup> group = make_unique_dp<RenderGroup>(state, newTile);
|
||||
ref_ptr<dp::GpuProgram> 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<BaseRenderGroup> group)
|
||||
{
|
||||
group->UpdateAnimation();
|
||||
|
||||
dp::GLState const & state = group->GetState();
|
||||
ref_ptr<dp::GpuProgram> program = m_gpuProgramManager->GetProgram(state.GetProgramIndex());
|
||||
program->Bind();
|
||||
|
||||
ApplyState(state, program);
|
||||
ApplyUniforms(m_generalUniforms, program);
|
||||
ApplyUniforms(group->GetUniforms(), program);
|
||||
|
||||
group->Render(modelView);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,12 @@
|
|||
namespace df
|
||||
{
|
||||
|
||||
void BaseRenderGroup::SetRenderParams(ref_ptr<dp::GpuProgram> shader, ref_ptr<dp::UniformValuesStorage> 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<dp::RenderBucket> & renderBucket : m_renderBuckets)
|
||||
renderBucket->Update(modelView);
|
||||
}
|
||||
|
@ -48,14 +47,44 @@ void RenderGroup::CollectOverlay(ref_ptr<dp::OverlayTree> tree)
|
|||
if (m_pendingOnDelete)
|
||||
return;
|
||||
|
||||
ASSERT(m_shader != nullptr, ());
|
||||
ASSERT(m_generalUniforms != nullptr, ());
|
||||
for(drape_ptr<dp::RenderBucket> & renderBucket : m_renderBuckets)
|
||||
renderBucket->CollectOverlayHandles(tree, GetOpacity() < 1.0);
|
||||
}
|
||||
|
||||
void RenderGroup::Render(ScreenBase const & screen)
|
||||
{
|
||||
for(drape_ptr<dp::RenderBucket> & 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<dp::RenderBucket> & 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<dp::RenderBucket> & renderBucket : m_renderBuckets)
|
||||
renderBucket->Render(screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
dp::ApplyUniforms(m_uniforms, m_shader);
|
||||
|
||||
for(drape_ptr<dp::RenderBucket> & renderBucket : m_renderBuckets)
|
||||
renderBucket->Render(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderGroup::AddBucket(drape_ptr<dp::RenderBucket> && bucket)
|
||||
|
|
|
@ -25,6 +25,8 @@ public:
|
|||
: m_state(state)
|
||||
, m_tileKey(tileKey) {}
|
||||
|
||||
void SetRenderParams(ref_ptr<dp::GpuProgram> shader, ref_ptr<dp::UniformValuesStorage> 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<dp::GpuProgram> m_shader;
|
||||
dp::UniformValuesStorage m_uniforms;
|
||||
ref_ptr<dp::UniformValuesStorage> m_generalUniforms;
|
||||
|
||||
private:
|
||||
TileKey m_tileKey;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue