InfiniteGridHelper.js 5.4 KB

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