diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2019-05-07 12:25:01 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2019-05-15 05:11:52 +0000 |
commit | 1bfdb226001d7a323ef9f7ec8017bc2eede5f67b (patch) | |
tree | 936b51d90b2af569345f443c903da0043a8a538f | |
parent | 61c2aba1dbda677e6379750bc1a42c60e6db10cd (diff) |
Improve antialiasing on distance field text
The current approach of trying to calculate the scale
factor based on the determinant of the matrix breaks
down when the text is very close to the camera or
when the determinant is too low for single precision
floats.
On a lot of hardware (core GL, GLES3+, and GLES2 with the
standard derivation extension), we can get the positive
derivation of the distance field using fwidth() and
do the antialiasing based on this.
So this will improve the appearance and consistency of
the antialiasing on all devices that support the
derivation extension.
In addition, this fixes the sqrt() in the fall back to
be a cubic root instead, since there are three scale
factors in 3D rather than two.
Task-number: QT3DS-3343
Change-Id: I64483ee1a30e42f955597944f45e6fdead8063bd
Reviewed-by: Jere Tuliniemi <jere.tuliniemi@qt.io>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
-rw-r--r-- | src/runtime/shaders/distancefieldtext.frag | 24 | ||||
-rw-r--r-- | src/runtime/shaders/distancefieldtext.vert | 14 | ||||
-rw-r--r-- | src/runtime/shaders/distancefieldtext_core.frag | 7 | ||||
-rw-r--r-- | src/runtime/shaders/distancefieldtext_core.vert | 31 | ||||
-rw-r--r-- | src/runtime/shaders/distancefieldtext_dropshadow.frag | 46 | ||||
-rw-r--r-- | src/runtime/shaders/distancefieldtext_dropshadow.vert | 15 | ||||
-rw-r--r-- | src/runtime/shaders/distancefieldtext_dropshadow_core.frag | 26 | ||||
-rw-r--r-- | src/runtime/shaders/distancefieldtext_dropshadow_core.vert | 27 |
8 files changed, 95 insertions, 95 deletions
diff --git a/src/runtime/shaders/distancefieldtext.frag b/src/runtime/shaders/distancefieldtext.frag index efcf89e..1d83490 100644 --- a/src/runtime/shaders/distancefieldtext.frag +++ b/src/runtime/shaders/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/shaders/distancefieldtext.vert b/src/runtime/shaders/distancefieldtext.vert index fa96ff7..306d109 100644 --- a/src/runtime/shaders/distancefieldtext.vert +++ b/src/runtime/shaders/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 vec4 vCoord; attribute highp vec2 tCoord; varying highp vec2 sampleCoord; + +#ifdef use_fallback varying highp vec2 alphas; highp float thresholdFunc(highp float scale) @@ -53,11 +61,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); +#endif + sampleCoord = tCoord * vec2(1.0 / float(textureWidth), 1.0 / float(textureHeight)); gl_Position = mvp * vCoord; } diff --git a/src/runtime/shaders/distancefieldtext_core.frag b/src/runtime/shaders/distancefieldtext_core.frag index bac8ca6..e7c18ab 100644 --- a/src/runtime/shaders/distancefieldtext_core.frag +++ b/src/runtime/shaders/distancefieldtext_core.frag @@ -7,10 +7,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/shaders/distancefieldtext_core.vert b/src/runtime/shaders/distancefieldtext_core.vert index a64062c..8f18c66 100644 --- a/src/runtime/shaders/distancefieldtext_core.vert +++ b/src/runtime/shaders/distancefieldtext_core.vert @@ -5,40 +5,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 * vCoord; + sampleCoord = tCoord * vec2(1.0 / float(textureWidth), 1.0 / float(textureHeight)); + gl_Position = mvp * vCoord; } diff --git a/src/runtime/shaders/distancefieldtext_dropshadow.frag b/src/runtime/shaders/distancefieldtext_dropshadow.frag index 94b277c..fdb68ba 100644 --- a/src/runtime/shaders/distancefieldtext_dropshadow.frag +++ b/src/runtime/shaders/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/shaders/distancefieldtext_dropshadow.vert b/src/runtime/shaders/distancefieldtext_dropshadow.vert index e44e880..b176cc7 100644 --- a/src/runtime/shaders/distancefieldtext_dropshadow.vert +++ b/src/runtime/shaders/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; @@ -57,11 +65,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/shaders/distancefieldtext_dropshadow_core.frag b/src/runtime/shaders/distancefieldtext_dropshadow_core.frag index 8daa915..af7be60 100644 --- a/src/runtime/shaders/distancefieldtext_dropshadow_core.frag +++ b/src/runtime/shaders/distancefieldtext_dropshadow_core.frag @@ -10,24 +10,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/shaders/distancefieldtext_dropshadow_core.vert b/src/runtime/shaders/distancefieldtext_dropshadow_core.vert index f01e01b..df76463 100644 --- a/src/runtime/shaders/distancefieldtext_dropshadow_core.vert +++ b/src/runtime/shaders/distancefieldtext_dropshadow_core.vert @@ -7,7 +7,6 @@ in vec4 textureBounds; out vec2 sampleCoord; out vec2 shadowSampleCoord; -out vec2 alphas; out vec4 normalizedTextureBounds; uniform mat4 mvp; @@ -16,34 +15,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; |