Przeglądaj źródła

Merge remote-tracking branch '1vanK/master'

Lasse Öörni 9 lat temu
rodzic
commit
09762ae735
2 zmienionych plików z 107 dodań i 38 usunięć
  1. 64 19
      bin/CoreData/Shaders/GLSL/Text.glsl
  2. 43 19
      bin/CoreData/Shaders/HLSL/Text.hlsl

+ 64 - 19
bin/CoreData/Shaders/GLSL/Text.glsl

@@ -19,40 +19,85 @@ void VS()
     mat4 modelMatrix = iModelMatrix;
     vec3 worldPos = GetWorldPos(modelMatrix);
     gl_Position = GetClipPos(worldPos);
-    
+
     vTexCoord = iTexCoord;
     vColor = iColor;
 }
 
+/*
+    1) Simplest SDF shader:
+
+    float distance = texture2D(sDiffMap, vTexCoord).a;
+    if (distance >= 0.5)
+        gl_FragColor.a = vColor.a; // This is glyph
+    else
+        gl_FragColor.a = 0.0; // Outside glyph
+
+    2) Glyph with antialiazed border:
+
+    float distance = texture2D(sDiffMap, vTexCoord).a;
+    gl_FragColor.a = vColor.a * smoothstep(0.495, 0.505, distance);
+
+    3) Quality improvement for far and small text:
+
+    float distance = texture2D(sDiffMap, vTexCoord).a;
+    // How much "distance" is changed for neighboring pixels.
+    // If text is far then width is big. Far text will be blurred.
+    float width = fwidth(distance);
+    gl_FragColor.a = vColor.a * smoothstep(0.5 - width, 0.5 + width, distance);
+*/
+
+#if defined(COMPILEPS) && defined(SIGNED_DISTANCE_FIELD)
+    float GetAlpha(float distance, float width)
+    {
+        return smoothstep(0.5 - width, 0.5 + width, distance);
+    }
+
+    // Comment for turn off supersampling
+    #define SUPERSAMPLING
+#endif
+
 void PS()
 {
 #ifdef SIGNED_DISTANCE_FIELD
     gl_FragColor.rgb = vColor.rgb;
-
     float distance = texture2D(sDiffMap, vTexCoord).a;
-    if (distance < 0.5)
-    {
-    #ifdef TEXT_EFFECT_SHADOW
-        if (texture2D(sDiffMap, vTexCoord - cShadowOffset).a > 0.5)
-            gl_FragColor = cShadowColor;
-        else
-    #endif
-        gl_FragColor.a = 0.0;
-    }
-    else
-    {
+
     #ifdef TEXT_EFFECT_STROKE
-        if (distance < 0.525)
-            gl_FragColor.rgb = cStrokeColor.rgb;
+        float outlineFactor = smoothstep(0.5, 0.52, distance); // Border of glyph
+        gl_FragColor.rgb = mix(cStrokeColor.rgb, vColor.rgb, outlineFactor);
     #endif
 
     #ifdef TEXT_EFFECT_SHADOW
-        if (texture2D(sDiffMap, vTexCoord + cShadowOffset).a < 0.5)
-            gl_FragColor.a = vColor.a;
+        if (texture2D(sDiffMap, vTexCoord - cShadowOffset).a > 0.5 && distance <= 0.5)
+            gl_FragColor = cShadowColor;
         else
     #endif
-        gl_FragColor.a = vColor.a * smoothstep(0.5, 0.505, distance);
-    }
+        {
+            float width = fwidth(distance);
+            float alpha = GetAlpha(distance, width);
+
+            #ifdef SUPERSAMPLING
+                vec2 deltaUV = 0.354 * fwidth(vTexCoord); // (1.0 / sqrt(2.0)) / 2.0 = 0.354
+                vec4 square = vec4(vTexCoord - deltaUV, vTexCoord + deltaUV);
+
+                float distance2 = texture2D(sDiffMap, square.xy).a;
+                float distance3 = texture2D(sDiffMap, square.zw).a;
+                float distance4 = texture2D(sDiffMap, square.xw).a;
+                float distance5 = texture2D(sDiffMap, square.zy).a;
+
+                alpha += GetAlpha(distance2, width)
+                       + GetAlpha(distance3, width)
+                       + GetAlpha(distance4, width)
+                       + GetAlpha(distance5, width);
+
+                // For calculating of average correct would be dividing by 5.
+                // But when text is blurred, its brightness is lost. Therefore divide by 4.
+                alpha = alpha * 0.25;
+            #endif
+
+            gl_FragColor.a = alpha;
+        }
 #else
     #ifdef ALPHAMAP
         gl_FragColor.rgb = vColor.rgb;

+ 43 - 19
bin/CoreData/Shaders/HLSL/Text.hlsl

@@ -37,37 +37,61 @@ void VS(float4 iPos : POSITION,
     oTexCoord = iTexCoord;
 }
 
+// See notes in GLSL shader
+#if defined(COMPILEPS) && defined(SIGNED_DISTANCE_FIELD)
+    float GetAlpha(float distance, float width)
+    {
+        return smoothstep(0.5 - width, 0.5 + width, distance);
+    }
+
+    // Comment for turn off supersampling
+    #define SUPERSAMPLING
+#endif
+
+
 void PS(float2 iTexCoord : TEXCOORD0,
     float4 iColor : COLOR0,
     out float4 oColor : OUTCOLOR0)
 {
 #ifdef SIGNED_DISTANCE_FIELD
     oColor.rgb = iColor.rgb;
-    
     float distance = Sample2D(DiffMap, iTexCoord).a;
-    if (distance < 0.5f)
-    {
-    #ifdef TEXT_EFFECT_SHADOW
-        if (Sample2D(DiffMap, iTexCoord - cShadowOffset).a > 0.5f)
-            oColor = cShadowColor;
-        else
-    #endif
-        oColor.a = 0.0f;
-    }
-    else
-    {
+
     #ifdef TEXT_EFFECT_STROKE
-        if (distance < 0.525f)
-            oColor.rgb = cStrokeColor.rgb;
+        float outlineFactor = smoothstep(0.5, 0.52, distance); // Border of glyph
+        oColor.rgb = lerp(cStrokeColor.rgb, iColor.rgb, outlineFactor);
     #endif
 
     #ifdef TEXT_EFFECT_SHADOW
-        if (Sample2D(DiffMap, iTexCoord + cShadowOffset).a < 0.5f)
-            oColor.a = iColor.a;
+        if (Sample2D(DiffMap, iTexCoord - cShadowOffset).a > 0.5 && distance <= 0.5)
+            oColor = cShadowColor;
         else
     #endif
-        oColor.a = iColor.a * smoothstep(0.5f, 0.505f, distance);
-    }
+        {
+            float width = fwidth(distance);
+            float alpha = GetAlpha(distance, width);
+
+            #ifdef SUPERSAMPLING  
+                float2 deltaUV = 0.354 * fwidth(iTexCoord); // (1.0 / sqrt(2.0)) / 2.0 = 0.354
+                float4 square = float4(iTexCoord - deltaUV, iTexCoord + deltaUV);
+
+                float distance2 = Sample2D(DiffMap, square.xy).a;
+                float distance3 = Sample2D(DiffMap, square.zw).a;
+                float distance4 = Sample2D(DiffMap, square.xw).a;
+                float distance5 = Sample2D(DiffMap, square.zy).a;
+
+                alpha += GetAlpha(distance2, width)
+                       + GetAlpha(distance3, width)
+                       + GetAlpha(distance4, width)
+                       + GetAlpha(distance5, width);
+            
+                // For calculating of average correct would be dividing by 5.
+                // But when text is blurred, its brightness is lost. Therefore divide by 4.
+                alpha = alpha * 0.25;
+            #endif
+
+            oColor.a = alpha;
+        }
 #else
     #ifdef ALPHAMAP
         oColor.rgb = iColor.rgb;
@@ -76,4 +100,4 @@ void PS(float2 iTexCoord : TEXCOORD0,
         oColor = iColor* Sample2D(DiffMap, iTexCoord);
     #endif
 #endif
-}
+}