From d7bbf9d82e9f129877e6d304b527071155348c59 Mon Sep 17 00:00:00 2001 From: Jere Tuliniemi Date: Mon, 20 May 2019 13:12:37 +0300 Subject: Copy distance field shader changes to OpenGL runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fixes the OpenGL runtime to use alpha channel for the glyph texture when using ES2. Task-number: QT3DS-3343 Change-Id: Ia37c341802e504da21ebeaff6f3f1f5b50bd1bfe Reviewed-by: Mahmoud Badri Reviewed-by: Miikka Heikkinen Reviewed-by: Antti Määttä --- .../runtimerender/Qt3DSDistanceFieldGlyphCache.cpp | 36 ++++++++--------- .../runtimerender/Qt3DSDistanceFieldGlyphCache_p.h | 1 + src/Runtime/res/effectlib/distancefieldtext.frag | 24 +++++++++-- src/Runtime/res/effectlib/distancefieldtext.vert | 16 +++++++- .../res/effectlib/distancefieldtext_core.frag | 7 ++-- .../res/effectlib/distancefieldtext_core.vert | 32 +-------------- .../effectlib/distancefieldtext_dropshadow.frag | 46 +++++++++++++++------- .../effectlib/distancefieldtext_dropshadow.vert | 15 ++++++- .../distancefieldtext_dropshadow_core.frag | 26 ++++++------ .../distancefieldtext_dropshadow_core.vert | 28 ------------- 10 files changed, 114 insertions(+), 117 deletions(-) (limited to 'src/Runtime') diff --git a/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp b/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp index c6941860..3779aa56 100644 --- a/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp +++ b/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp @@ -92,6 +92,17 @@ void Q3DSDistanceFieldGlyphCache::releaseGlyphs(const QSet &glyphs) m_unusedGlyphs += glyphs; } +void Q3DSDistanceFieldGlyphCache::setTextureData(qt3ds::render::NVRenderTexture2D *texture, + QImage &image) +{ + bool isGLES2 = m_context.GetRenderContext().GetRenderContextType() + == qt3ds::render::NVRenderContextValues::GLES2; + texture->SetTextureData(qt3ds::render::toU8DataRef(image.bits(), image.byteCount()), + 0, image.width(), image.height(), + isGLES2 ? qt3ds::render::NVRenderTextureFormats::Alpha8 + : qt3ds::render::NVRenderTextureFormats::R8); +} + void Q3DSDistanceFieldGlyphCache::resizeTexture(TextureInfo *info, int width, int height) { QImage &image = info->copy; @@ -99,17 +110,12 @@ void Q3DSDistanceFieldGlyphCache::resizeTexture(TextureInfo *info, int width, in info->texture = m_context.GetRenderContext().CreateTexture2D(); info->texture->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Enum::Linear); info->texture->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Enum::Linear); - info->texture->SetTextureData(qt3ds::render::toU8DataRef(image.bits(), image.byteCount()), - 0, image.width(), image.height(), - qt3ds::render::NVRenderTextureFormats::R8); + setTextureData(info->texture, image); } qt3ds::render::STextureDetails textureDetails = info->texture->GetTextureDetails(); - if (int(textureDetails.m_Width) != width || int(textureDetails.m_Height) != height) { - info->texture->SetTextureData(qt3ds::render::toU8DataRef(image.bits(), image.byteCount()), - 0, image.width(), image.height(), - qt3ds::render::NVRenderTextureFormats::R8); - } + if (int(textureDetails.m_Width) != width || int(textureDetails.m_Height) != height) + setTextureData(info->texture, image); if (info->copy.width() != width || info->copy.height() != height) { QImage newImage(width, height, QImage::Format_Alpha8); @@ -122,9 +128,7 @@ void Q3DSDistanceFieldGlyphCache::resizeTexture(TextureInfo *info, int width, in info->copy = newImage; - info->texture->SetTextureData(qt3ds::render::toU8DataRef(image.bits(), image.byteCount()), - 0, image.width(), image.height(), - qt3ds::render::NVRenderTextureFormats::R8); + setTextureData(info->texture, image); } } @@ -168,10 +172,7 @@ void Q3DSDistanceFieldGlyphCache::storeGlyphs(const QList &glyph QImage &image = i.key()->copy; - i.key()->texture->SetTextureData(qt3ds::render::toU8DataRef(image.bits(), - image.byteCount()), - 0, image.width(), image.height(), - qt3ds::render::NVRenderTextureFormats::R8); + setTextureData(i.key()->texture, image); } } @@ -496,10 +497,7 @@ bool Q3DSDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) textureData += size; QImage &image = texInfo->copy; - texInfo->texture->SetTextureData(qt3ds::render::toU8DataRef(image.bits(), - image.byteCount()), - 0, image.width(), image.height(), - qt3ds::render::NVRenderTextureFormats::R8); + setTextureData(texInfo->texture, image); QVector glyphs = glyphTextures.value(texInfo); diff --git a/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldGlyphCache_p.h b/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldGlyphCache_p.h index e3ec204a..679d3ad7 100644 --- a/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldGlyphCache_p.h +++ b/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldGlyphCache_p.h @@ -82,6 +82,7 @@ private: int maxTextureSize() const; void resizeTexture(TextureInfo *info, int width, int height); + void setTextureData(qt3ds::render::NVRenderTexture2D *texture, QImage &image); QSGAreaAllocator *m_areaAllocator = nullptr; int m_maxTextureSize = 0; diff --git a/src/Runtime/res/effectlib/distancefieldtext.frag b/src/Runtime/res/effectlib/distancefieldtext.frag index efcf89e4..1d834902 100644 --- a/src/Runtime/res/effectlib/distancefieldtext.frag +++ b/src/Runtime/res/effectlib/distancefieldtext.frag @@ -1,12 +1,28 @@ +#ifdef GL_OES_standard_derivatives +# extension GL_OES_standard_derivatives : enable +#else +# define use_fallback +#endif + varying highp vec2 sampleCoord; -varying highp vec2 alphas; uniform sampler2D _qt_texture; uniform highp vec4 color; +#ifdef use_fallback +varying highp vec2 alphas; +#endif + void main() { - gl_FragColor = color * smoothstep(alphas.x, - alphas.y, - texture2D(_qt_texture, sampleCoord).a); + highp float distance = texture2D(_qt_texture, sampleCoord).a; + +#ifdef use_fallback + highp float alpha = smoothstep(alphas.x, alphas.y, distance); +#else + highp float f = fwidth(distance); + highp float alpha = smoothstep(0.5 - f, 0.5, distance); +#endif + + gl_FragColor = color * alpha; } diff --git a/src/Runtime/res/effectlib/distancefieldtext.vert b/src/Runtime/res/effectlib/distancefieldtext.vert index 01024c6b..f6b2de41 100644 --- a/src/Runtime/res/effectlib/distancefieldtext.vert +++ b/src/Runtime/res/effectlib/distancefieldtext.vert @@ -1,3 +1,9 @@ +#ifdef GL_OES_standard_derivatives +# extension GL_OES_standard_derivatives : enable +#else +# define use_fallback +#endif + uniform highp mat4 mvp; uniform highp float fontScale; uniform int textureWidth; @@ -7,6 +13,8 @@ attribute highp vec3 vCoord; attribute highp vec2 tCoord; varying highp vec2 sampleCoord; + +#ifdef use_fallback varying highp vec2 alphas; highp float thresholdFunc(highp float scale) @@ -55,11 +63,15 @@ highp float determinant(highp mat4 m) det -= m[3][0] * determinantOfSubmatrix(m, 0, 1, 2, 1, 2, 3); return det; } +#endif void main() { - highp float scale = fontScale * sqrt(abs(determinant(mvp))); +#ifdef use_fallback + highp float scale = fontScale * pow(abs(determinant(mvp)), 1.0 / 3.0); alphas = alphaRange(scale); - sampleCoord = tCoord * vec2(1.0 / highp float(textureWidth), 1.0 / highp float(textureHeight)); +#endif + + sampleCoord = tCoord * vec2(1.0 / float(textureWidth), 1.0 / float(textureHeight)); gl_Position = mvp * vec4(vCoord, 1.0); } diff --git a/src/Runtime/res/effectlib/distancefieldtext_core.frag b/src/Runtime/res/effectlib/distancefieldtext_core.frag index 0f848bc1..bf60f874 100644 --- a/src/Runtime/res/effectlib/distancefieldtext_core.frag +++ b/src/Runtime/res/effectlib/distancefieldtext_core.frag @@ -5,10 +5,9 @@ out vec4 fragColor; uniform sampler2D _qt_texture; uniform vec4 color; -in vec2 alphas; - void main() { - fragColor = color * smoothstep(alphas.x, alphas.y, - texture(_qt_texture, sampleCoord).r); + float distance = texture(_qt_texture, sampleCoord).r; + float f = fwidth(distance); + fragColor = color * smoothstep(0.5 - f, 0.5, distance); } diff --git a/src/Runtime/res/effectlib/distancefieldtext_core.vert b/src/Runtime/res/effectlib/distancefieldtext_core.vert index ce6a165c..2dc198f4 100644 --- a/src/Runtime/res/effectlib/distancefieldtext_core.vert +++ b/src/Runtime/res/effectlib/distancefieldtext_core.vert @@ -3,41 +3,13 @@ in vec2 tCoord; out vec2 sampleCoord; -out vec2 alphas; - uniform mat4 mvp; uniform int textureWidth; uniform int textureHeight; uniform float fontScale; -float thresholdFunc(float scale) -{ - float base = 0.5; - float baseDev = 0.065; - float devScaleMin = 0.15; - float devScaleMax = 0.3; - return base - ((clamp(scale, devScaleMin, devScaleMax) - devScaleMin) - / (devScaleMax - devScaleMin) * -baseDev + baseDev); -} - -float spreadFunc(float scale) -{ - return 0.06 / scale; -} - -vec2 alphaRange(float scale) -{ - float base = thresholdFunc(scale); - float range = spreadFunc(scale); - float alphaMin = max(0.0, base - range); - float alphaMax = min(base + range, 1.0); - return vec2(alphaMin, alphaMax); -} - void main() { - float scale = fontScale * sqrt(abs(determinant(mvp))); - alphas = alphaRange(scale); - sampleCoord = tCoord * vec2(1.0 / float(textureWidth), 1.0 / float(textureHeight)); - gl_Position = mvp * vec4(vCoord, 1.0); + sampleCoord = tCoord * vec2(1.0 / float(textureWidth), 1.0 / float(textureHeight)); + gl_Position = mvp * vec4(vCoord, 1.0); } diff --git a/src/Runtime/res/effectlib/distancefieldtext_dropshadow.frag b/src/Runtime/res/effectlib/distancefieldtext_dropshadow.frag index 94b277cd..fdb68bac 100644 --- a/src/Runtime/res/effectlib/distancefieldtext_dropshadow.frag +++ b/src/Runtime/res/effectlib/distancefieldtext_dropshadow.frag @@ -1,29 +1,47 @@ +#ifdef GL_OES_standard_derivatives +# extension GL_OES_standard_derivatives : enable +#else +# define use_fallback +#endif + varying highp vec2 sampleCoord; -varying highp vec2 alphas; varying highp vec2 shadowSampleCoord; varying highp vec4 normalizedTextureBounds; +#ifdef use_fallback +varying highp vec2 alphas; +#endif + uniform sampler2D _qt_texture; uniform highp vec4 color; uniform highp vec4 shadowColor; void main() { - highp float shadowAlpha = smoothstep(alphas.x, - alphas.y, - texture2D(_qt_texture, - clamp(shadowSampleCoord, - normalizedTextureBounds.xy, - normalizedTextureBounds.zw)).a); + highp float shadowDistance = texture2D(_qt_texture, + clamp(shadowSampleCoord, + normalizedTextureBounds.xy, + normalizedTextureBounds.zw)).a; +#ifdef use_fallback + highp float shadowAlpha = smoothstep(alphas.x, alphas.y, shadowDistance); +#else + highp float shadowDistanceD = fwidth(shadowDistance); + highp float shadowAlpha = smoothstep(0.5 - shadowDistanceD, 0.5, shadowDistance); +#endif + highp vec4 shadowPixel = color * shadowColor * shadowAlpha; - highp float textAlpha = smoothstep(alphas.x, - alphas.y, - texture2D(_qt_texture, - clamp(sampleCoord, - normalizedTextureBounds.xy, - normalizedTextureBounds.zw)).a); - highp vec4 textPixel = color * textAlpha; + highp float textDistance = texture2D(_qt_texture, + clamp(sampleCoord, + normalizedTextureBounds.xy, + normalizedTextureBounds.zw)).a; +#ifdef use_fallback + highp float textAlpha = smoothstep(alphas.x, alphas.y, textDistance); +#else + highp float textDistanceD = fwidth(textDistance); + highp float textAlpha = smoothstep(0.5 - textDistanceD, 0.5, textDistance); +#endif + highp vec4 textPixel = color * textAlpha; gl_FragColor = mix(shadowPixel, textPixel, textPixel.a); } diff --git a/src/Runtime/res/effectlib/distancefieldtext_dropshadow.vert b/src/Runtime/res/effectlib/distancefieldtext_dropshadow.vert index f633aaa5..835d34dd 100644 --- a/src/Runtime/res/effectlib/distancefieldtext_dropshadow.vert +++ b/src/Runtime/res/effectlib/distancefieldtext_dropshadow.vert @@ -1,3 +1,9 @@ +#ifdef GL_OES_standard_derivatives +# extension GL_OES_standard_derivatives : enable +#else +# define use_fallback +#endif + uniform highp mat4 mvp; uniform highp float fontScale; uniform int textureWidth; @@ -10,9 +16,11 @@ attribute highp vec4 textureBounds; varying highp vec2 sampleCoord; varying highp vec2 shadowSampleCoord; -varying highp vec2 alphas; varying highp vec4 normalizedTextureBounds; +#ifdef use_fallback +varying highp vec2 alphas; + highp float thresholdFunc(highp float scale) { highp float base = 0.5; @@ -59,11 +67,14 @@ highp float determinant(highp mat4 m) det -= m[3][0] * determinantOfSubmatrix(m, 0, 1, 2, 1, 2, 3); return det; } +#endif void main() { - highp float scale = fontScale * sqrt(abs(determinant(mvp))); +#ifdef use_fallback + highp float scale = fontScale * pow(abs(determinant(mvp)), 1.0 / 3.0); alphas = alphaRange(scale); +#endif highp vec2 textureSizeMultiplier = vec2(1.0 / highp float(textureWidth), 1.0 / float(textureHeight)); diff --git a/src/Runtime/res/effectlib/distancefieldtext_dropshadow_core.frag b/src/Runtime/res/effectlib/distancefieldtext_dropshadow_core.frag index 4e46bd5f..51aae5a7 100644 --- a/src/Runtime/res/effectlib/distancefieldtext_dropshadow_core.frag +++ b/src/Runtime/res/effectlib/distancefieldtext_dropshadow_core.frag @@ -8,24 +8,22 @@ uniform sampler2D _qt_texture; uniform vec4 color; uniform vec4 shadowColor; -in vec2 alphas; - void main() { - float shadowAlpha = smoothstep(alphas.x, - alphas.y, - texture(_qt_texture, - clamp(shadowSampleCoord, - normalizedTextureBounds.xy, - normalizedTextureBounds.zw)).r); + float shadowDistance = texture(_qt_texture, + clamp(shadowSampleCoord, + normalizedTextureBounds.xy, + normalizedTextureBounds.zw)).r; + float shadowDistanceD = fwidth(shadowDistance); + float shadowAlpha = smoothstep(0.5 - shadowDistanceD, 0.5, shadowDistance); vec4 shadowPixel = color * shadowColor * shadowAlpha; - float textAlpha = smoothstep(alphas.x, - alphas.y, - texture(_qt_texture, - clamp(sampleCoord, - normalizedTextureBounds.xy, - normalizedTextureBounds.zw)).r); + float textDistance = texture(_qt_texture, + clamp(sampleCoord, + normalizedTextureBounds.xy, + normalizedTextureBounds.zw)).r; + float textDistanceD = fwidth(textDistance); + float textAlpha = smoothstep(0.5 - textDistanceD, 0.5, textDistance); vec4 textPixel = color * textAlpha; fragColor = mix(shadowPixel, textPixel, textPixel.a); diff --git a/src/Runtime/res/effectlib/distancefieldtext_dropshadow_core.vert b/src/Runtime/res/effectlib/distancefieldtext_dropshadow_core.vert index 9be245b8..7d9736e5 100644 --- a/src/Runtime/res/effectlib/distancefieldtext_dropshadow_core.vert +++ b/src/Runtime/res/effectlib/distancefieldtext_dropshadow_core.vert @@ -5,7 +5,6 @@ in vec4 textureBounds; out vec2 sampleCoord; out vec2 shadowSampleCoord; -out vec2 alphas; out vec4 normalizedTextureBounds; uniform mat4 mvp; @@ -14,35 +13,8 @@ uniform int textureHeight; uniform float fontScale; uniform vec2 shadowOffset; -float thresholdFunc(float scale) -{ - float base = 0.5; - float baseDev = 0.065; - float devScaleMin = 0.15; - float devScaleMax = 0.3; - return base - ((clamp(scale, devScaleMin, devScaleMax) - devScaleMin) - / (devScaleMax - devScaleMin) * -baseDev + baseDev); -} - -float spreadFunc(float scale) -{ - return 0.06 / scale; -} - -vec2 alphaRange(float scale) -{ - float base = thresholdFunc(scale); - float range = spreadFunc(scale); - float alphaMin = max(0.0, base - range); - float alphaMax = min(base + range, 1.0); - return vec2(alphaMin, alphaMax); -} - void main() { - float scale = fontScale * sqrt(abs(determinant(mvp))); - alphas = alphaRange(scale); - vec2 textureSizeMultiplier = vec2(1.0 / float(textureWidth), 1.0 / float(textureHeight)); sampleCoord = tCoord * textureSizeMultiplier; -- cgit v1.2.3