InfiniteGridHelper.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // Author: Fyrestar https://mevedia.com (https://github.com/Fyrestar/THREE.InfiniteGridHelper)
  2. THREE.InfiniteGridHelper = function InfiniteGridHelper( size1, size2, color, distance, axes = 'xzy' ) {
  3. color = color || new THREE.Color( 'white' );
  4. size1 = size1 || 10;
  5. size2 = size2 || 100;
  6. distance = distance || 8000;
  7. const planeAxes = axes.substr( 0, 2 );
  8. const geometry = new THREE.PlaneBufferGeometry( 2, 2, 1, 1 );
  9. const material = new THREE.ShaderMaterial( {
  10. side: THREE.DoubleSide,
  11. uniforms: {
  12. uSize1: {
  13. value: size1
  14. },
  15. uSize2: {
  16. value: size2
  17. },
  18. uColor: {
  19. value: color
  20. },
  21. uDistance: {
  22. value: distance
  23. }
  24. },
  25. transparent: true,
  26. vertexShader: `
  27. varying vec3 worldPosition;
  28. uniform float uDistance;
  29. void main() {
  30. vec3 pos = position.${axes} * uDistance;
  31. pos.${planeAxes} += cameraPosition.${planeAxes};
  32. worldPosition = pos;
  33. gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
  34. }
  35. `,
  36. fragmentShader: `
  37. varying vec3 worldPosition;
  38. uniform float uSize1;
  39. uniform float uSize2;
  40. uniform vec3 uColor;
  41. uniform float uDistance;
  42. float getGrid(float size) {
  43. vec2 r = worldPosition.${planeAxes} / size;
  44. vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r);
  45. float line = min(grid.x, grid.y);
  46. return 1.0 - min(line, 1.0);
  47. }
  48. void main() {
  49. float d = 1.0 - min(distance(cameraPosition.${planeAxes}, worldPosition.${planeAxes}) / uDistance, 1.0);
  50. float g1 = getGrid(uSize1);
  51. float g2 = getGrid(uSize2);
  52. gl_FragColor = vec4(uColor.rgb, mix(g2, g1, g1) * pow(d, 3.0));
  53. gl_FragColor.a = mix(0.5 * gl_FragColor.a, gl_FragColor.a, g2);
  54. if ( gl_FragColor.a <= 0.0 ) discard;
  55. }
  56. `,
  57. extensions: {
  58. derivatives: true
  59. }
  60. } );
  61. THREE.Mesh.call( this, geometry, material );
  62. this.frustumCulled = false;
  63. };
  64. THREE.InfiniteGridHelper.prototype = {
  65. ...THREE.Mesh.prototype,
  66. ...THREE.Object3D.prototype,
  67. ...THREE.EventDispatcher.prototype
  68. };
  69. if ( parseInt( THREE.REVISION ) > 126 ) {
  70. class InfiniteGridHelper extends THREE.Mesh {
  71. constructor ( size1, size2, color, distance, axes = 'xzy' ) {
  72. color = color || new THREE.Color( 'white' );
  73. size1 = size1 || 10;
  74. size2 = size2 || 100;
  75. distance = distance || 8000;
  76. const planeAxes = axes.substr( 0, 2 );
  77. const geometry = new THREE.PlaneBufferGeometry( 2, 2, 1, 1 );
  78. const material = new THREE.ShaderMaterial( {
  79. side: THREE.DoubleSide,
  80. uniforms: {
  81. uSize1: {
  82. value: size1
  83. },
  84. uSize2: {
  85. value: size2
  86. },
  87. uColor: {
  88. value: color
  89. },
  90. uDistance: {
  91. value: distance
  92. }
  93. },
  94. transparent: true,
  95. vertexShader: `
  96. varying vec3 worldPosition;
  97. uniform float uDistance;
  98. void main() {
  99. vec3 pos = position.${axes} * uDistance;
  100. pos.${planeAxes} += cameraPosition.${planeAxes};
  101. worldPosition = pos;
  102. gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
  103. }
  104. `,
  105. fragmentShader: `
  106. varying vec3 worldPosition;
  107. uniform float uSize1;
  108. uniform float uSize2;
  109. uniform vec3 uColor;
  110. uniform float uDistance;
  111. float getGrid(float size) {
  112. vec2 r = worldPosition.${planeAxes} / size;
  113. vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r);
  114. float line = min(grid.x, grid.y);
  115. return 1.0 - min(line, 1.0);
  116. }
  117. void main() {
  118. float d = 1.0 - min(distance(cameraPosition.${planeAxes}, worldPosition.${planeAxes}) / uDistance, 1.0);
  119. float g1 = getGrid(uSize1);
  120. float g2 = getGrid(uSize2);
  121. gl_FragColor = vec4(uColor.rgb, mix(g2, g1, g1) * pow(d, 3.0));
  122. gl_FragColor.a = mix(0.5 * gl_FragColor.a, gl_FragColor.a, g2);
  123. if ( gl_FragColor.a <= 0.0 ) discard;
  124. }
  125. `,
  126. extensions: {
  127. derivatives: true
  128. }
  129. } );
  130. super( geometry, material );
  131. this.frustumCulled = false;
  132. }
  133. }
  134. Object.assign( InfiniteGridHelper.prototype, THREE.InfiniteGridHelper.prototype );
  135. THREE.InfiniteGridHelper = InfiniteGridHelper;
  136. }
  137. module.exports.InfiniteGridHelper = THREE.InfiniteGridHelper
  138. // module.exports.InfiniteGridHelper =THREE.InfiniteGridHelper;