summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2019-05-07 12:25:01 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2019-05-15 05:11:52 +0000
commit1bfdb226001d7a323ef9f7ec8017bc2eede5f67b (patch)
tree936b51d90b2af569345f443c903da0043a8a538f
parent61c2aba1dbda677e6379750bc1a42c60e6db10cd (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.frag24
-rw-r--r--src/runtime/shaders/distancefieldtext.vert14
-rw-r--r--src/runtime/shaders/distancefieldtext_core.frag7
-rw-r--r--src/runtime/shaders/distancefieldtext_core.vert31
-rw-r--r--src/runtime/shaders/distancefieldtext_dropshadow.frag46
-rw-r--r--src/runtime/shaders/distancefieldtext_dropshadow.vert15
-rw-r--r--src/runtime/shaders/distancefieldtext_dropshadow_core.frag26
-rw-r--r--src/runtime/shaders/distancefieldtext_dropshadow_core.vert27
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;