Text.glsl 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include "Uniforms.glsl"
  2. #include "Samplers.glsl"
  3. #include "Transform.glsl"
  4. varying vec2 vTexCoord;
  5. varying vec4 vColor;
  6. #ifdef TEXT_EFFECT_SHADOW
  7. uniform vec2 cShadowOffset;
  8. uniform vec4 cShadowColor;
  9. #endif
  10. #ifdef TEXT_EFFECT_STROKE
  11. uniform vec4 cStrokeColor;
  12. #endif
  13. void VS()
  14. {
  15. mat4 modelMatrix = iModelMatrix;
  16. vec3 worldPos = GetWorldPos(modelMatrix);
  17. gl_Position = GetClipPos(worldPos);
  18. vTexCoord = iTexCoord;
  19. vColor = iColor;
  20. }
  21. /*
  22. 1) Simplest SDF shader:
  23. float distance = texture2D(sDiffMap, vTexCoord).a;
  24. if (distance >= 0.5)
  25. gl_FragColor.a = vColor.a; // This is glyph
  26. else
  27. gl_FragColor.a = 0.0; // Outside glyph
  28. 2) Glyph with antialiazed border:
  29. float distance = texture2D(sDiffMap, vTexCoord).a;
  30. gl_FragColor.a = vColor.a * smoothstep(0.495, 0.505, distance);
  31. 3) Quality improvement for far and small text:
  32. float distance = texture2D(sDiffMap, vTexCoord).a;
  33. // How much "distance" is changed for neighboring pixels.
  34. // If text is far then width is big. Far text will be blurred.
  35. float width = fwidth(distance);
  36. gl_FragColor.a = vColor.a * smoothstep(0.5 - width, 0.5 + width, distance);
  37. */
  38. #if defined(COMPILEPS) && defined(SIGNED_DISTANCE_FIELD)
  39. float GetAlpha(float distance, float width)
  40. {
  41. return smoothstep(0.5 - width, 0.5 + width, distance);
  42. }
  43. // Comment this define to turn off supersampling
  44. #define SUPERSAMPLING
  45. #endif
  46. void PS()
  47. {
  48. #ifdef SIGNED_DISTANCE_FIELD
  49. gl_FragColor.rgb = vColor.rgb;
  50. float distance = texture2D(sDiffMap, vTexCoord).a;
  51. #ifdef TEXT_EFFECT_STROKE
  52. #ifdef SUPERSAMPLING
  53. float outlineFactor = smoothstep(0.5, 0.525, distance); // Border of glyph
  54. gl_FragColor.rgb = mix(cStrokeColor.rgb, vColor.rgb, outlineFactor);
  55. #else
  56. if (distance < 0.525)
  57. gl_FragColor.rgb = cStrokeColor.rgb;
  58. #endif
  59. #endif
  60. #ifdef TEXT_EFFECT_SHADOW
  61. if (texture2D(sDiffMap, vTexCoord - cShadowOffset).a > 0.5 && distance <= 0.5)
  62. gl_FragColor = cShadowColor;
  63. #ifndef SUPERSAMPLING
  64. else if (distance <= 0.5)
  65. gl_FragColor.a = 0;
  66. #endif
  67. else
  68. #endif
  69. {
  70. float width = fwidth(distance);
  71. float alpha = GetAlpha(distance, width);
  72. #ifdef SUPERSAMPLING
  73. vec2 deltaUV = 0.354 * fwidth(vTexCoord); // (1.0 / sqrt(2.0)) / 2.0 = 0.354
  74. vec4 square = vec4(vTexCoord - deltaUV, vTexCoord + deltaUV);
  75. float distance2 = texture2D(sDiffMap, square.xy).a;
  76. float distance3 = texture2D(sDiffMap, square.zw).a;
  77. float distance4 = texture2D(sDiffMap, square.xw).a;
  78. float distance5 = texture2D(sDiffMap, square.zy).a;
  79. alpha += GetAlpha(distance2, width)
  80. + GetAlpha(distance3, width)
  81. + GetAlpha(distance4, width)
  82. + GetAlpha(distance5, width);
  83. // For calculating of average correct would be dividing by 5.
  84. // But when text is blurred, its brightness is lost. Therefore divide by 4.
  85. alpha = alpha * 0.25;
  86. #endif
  87. gl_FragColor.a = alpha;
  88. }
  89. #else
  90. #ifdef ALPHAMAP
  91. gl_FragColor.rgb = vColor.rgb;
  92. #ifdef GL3
  93. gl_FragColor.a = vColor.a * texture2D(sDiffMap, vTexCoord).r;
  94. #else
  95. gl_FragColor.a = vColor.a * texture2D(sDiffMap, vTexCoord).a;
  96. #endif
  97. #else
  98. gl_FragColor = vColor * texture2D(sDiffMap, vTexCoord);
  99. #endif
  100. #endif
  101. }