Text.glsl 3.7 KB

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