grid.fragment.fx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #extension GL_OES_standard_derivatives : enable
  2. #define SQRT2 1.41421356
  3. #define PI 3.14159
  4. precision highp float;
  5. uniform vec3 mainColor;
  6. uniform vec3 lineColor;
  7. uniform vec4 gridControl;
  8. uniform vec3 gridOffset;
  9. // Varying
  10. #ifdef TRANSPARENT
  11. varying vec4 vCameraSpacePosition;
  12. #endif
  13. varying vec3 vPosition;
  14. varying vec3 vNormal;
  15. #include<fogFragmentDeclaration>
  16. float getVisibility(float position) {
  17. // Major grid line every Frequency defined in material.
  18. float majorGridFrequency = gridControl.y;
  19. if (floor(position + 0.5) == floor(position / majorGridFrequency + 0.5) * majorGridFrequency)
  20. {
  21. return 1.0;
  22. }
  23. return gridControl.z;
  24. }
  25. float getAnisotropicAttenuation(float differentialLength) {
  26. const float maxNumberOfLines = 10.0;
  27. return clamp(1.0 / (differentialLength + 1.0) - 1.0 / maxNumberOfLines, 0.0, 1.0);
  28. }
  29. float isPointOnLine(float position, float differentialLength) {
  30. float fractionPartOfPosition = position - floor(position + 0.5); // fract part around unit [-0.5; 0.5]
  31. fractionPartOfPosition /= differentialLength; // adapt to the screen space size it takes
  32. fractionPartOfPosition = clamp(fractionPartOfPosition, -1., 1.);
  33. float result = 0.5 + 0.5 * cos(fractionPartOfPosition * PI); // Convert to 0-1 for antialiasing.
  34. return result;
  35. }
  36. float contributionOnAxis(float position) {
  37. float differentialLength = length(vec2(dFdx(position), dFdy(position)));
  38. differentialLength *= SQRT2; // Multiply by SQRT2 for diagonal length
  39. // Is the point on the line.
  40. float result = isPointOnLine(position, differentialLength);
  41. // Add dynamic visibility.
  42. float visibility = getVisibility(position);
  43. result *= visibility;
  44. // Anisotropic filtering.
  45. float anisotropicAttenuation = getAnisotropicAttenuation(differentialLength);
  46. result *= anisotropicAttenuation;
  47. return result;
  48. }
  49. float normalImpactOnAxis(float x) {
  50. float normalImpact = clamp(1.0 - 3.0 * abs(x * x * x), 0.0, 1.0);
  51. return normalImpact;
  52. }
  53. void main(void) {
  54. // Scale position to the requested ratio.
  55. float gridRatio = gridControl.x;
  56. vec3 gridPos = (vPosition + gridOffset) / gridRatio;
  57. // Find the contribution of each coords.
  58. float x = contributionOnAxis(gridPos.x);
  59. float y = contributionOnAxis(gridPos.y);
  60. float z = contributionOnAxis(gridPos.z);
  61. // Find the normal contribution.
  62. vec3 normal = normalize(vNormal);
  63. x *= normalImpactOnAxis(normal.x);
  64. y *= normalImpactOnAxis(normal.y);
  65. z *= normalImpactOnAxis(normal.z);
  66. // Create the grid value by combining axis.
  67. float grid = clamp(x + y + z, 0., 1.);
  68. // Create the color.
  69. vec3 color = mix(mainColor, lineColor, grid);
  70. #ifdef FOG
  71. #include<fogFragment>
  72. #endif
  73. #ifdef TRANSPARENT
  74. float distanceToFragment = length(vCameraSpacePosition.xyz);
  75. float cameraPassThrough = clamp(distanceToFragment - 0.25, 0.0, 1.0);
  76. float opacity = clamp(grid, 0.08, cameraPassThrough * gridControl.w * grid);
  77. gl_FragColor = vec4(color.rgb, opacity);
  78. #ifdef PREMULTIPLYALPHA
  79. gl_FragColor.rgb *= opacity;
  80. #endif
  81. #else
  82. // Apply the color.
  83. gl_FragColor = vec4(color.rgb, 1.0);
  84. #endif
  85. }