voronoiNoise.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import { Fn, Loop, dot, float, fract, int, min, sin, vec2, vec3, TWO_PI } from 'three/tsl';
  2. /**
  3. * @module VoronoiNoise
  4. * @three_import import { voronoi2d, voronoi3d } from 'three/addons/tsl/math/voronoiNoise.js';
  5. */
  6. /**
  7. * Generates a pseudo-random vec2 from the given coordinate.
  8. *
  9. * Reference: {@link https://www.shadertoy.com/view/MslGD8}.
  10. *
  11. * @tsl
  12. * @function
  13. * @param {Node<vec2>} p - The input coordinate.
  14. * @return {Node<vec2>} A pseudo-random value in the range `[0, 1]`.
  15. */
  16. export const hash2d = /*@__PURE__*/ Fn( ( [ p ] ) => {
  17. return fract( sin( vec2( dot( p, vec2( 127.1, 311.7 ) ), dot( p, vec2( 269.5, 183.3 ) ) ) ).mul( 18.5453 ) );
  18. }, { p: 'vec2', return: 'vec2' } );
  19. /**
  20. * Animated 2D Voronoi noise. The feature points orbit inside their cells so the
  21. * resulting pattern morphs over time.
  22. *
  23. * Reference: {@link https://www.shadertoy.com/view/MslGD8}.
  24. *
  25. * @tsl
  26. * @function
  27. * @param {Node<vec2>} p - The input coordinate.
  28. * @param {Node<float>} time - The animation time.
  29. * @return {Node<float>} The squared distance to the closest feature point, roughly in the range `[0, 1]`.
  30. */
  31. export const voronoi2d = /*@__PURE__*/ Fn( ( [ p, time ] ) => {
  32. const n = p.floor().toConst();
  33. const f = p.fract().toConst();
  34. const minDist = float( 8 ).toVar();
  35. Loop( { start: int( - 1 ), end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => {
  36. Loop( { start: int( - 1 ), end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => {
  37. const g = vec2( float( x ), float( y ) ).toConst();
  38. const o = hash2d( n.add( g ) ).toConst();
  39. const r = g.sub( f ).add( sin( time.add( o.mul( TWO_PI ) ) ).mul( 0.5 ).add( 0.5 ) );
  40. minDist.assign( min( minDist, dot( r, r ) ) );
  41. } );
  42. } );
  43. return minDist;
  44. }, { p: 'vec2', time: 'float', return: 'float' } );
  45. /**
  46. * Generates a pseudo-random vec3 from the given coordinate.
  47. *
  48. * @tsl
  49. * @function
  50. * @param {Node<vec3>} p - The input coordinate.
  51. * @return {Node<vec3>} A pseudo-random value in the range `[0, 1]`.
  52. */
  53. export const hash3d = /*@__PURE__*/ Fn( ( [ p ] ) => {
  54. return fract( sin( vec3( dot( p, vec3( 127.1, 311.7, 74.7 ) ), dot( p, vec3( 269.5, 183.3, 246.1 ) ), dot( p, vec3( 113.5, 271.9, 124.6 ) ) ) ).mul( 18.5453 ) );
  55. }, { p: 'vec3', return: 'vec3' } );
  56. /**
  57. * Animated 3D Voronoi noise. Like {@link voronoi2d} but with a volumetric input
  58. * coordinate so the pattern can be applied to arbitrary surfaces without
  59. * projection artifacts. Evaluates 27 cells instead of 9 and is therefore
  60. * considerably more expensive than the 2D version.
  61. *
  62. * @tsl
  63. * @function
  64. * @param {Node<vec3>} p - The input coordinate.
  65. * @param {Node<float>} time - The animation time.
  66. * @return {Node<float>} The squared distance to the closest feature point, roughly in the range `[0, 1]`.
  67. */
  68. export const voronoi3d = /*@__PURE__*/ Fn( ( [ p, time ] ) => {
  69. const n = p.floor().toConst();
  70. const f = p.fract().toConst();
  71. const minDist = float( 8 ).toVar();
  72. Loop( { start: int( - 1 ), end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => {
  73. Loop( { start: int( - 1 ), end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => {
  74. Loop( { start: int( - 1 ), end: int( 1 ), name: 'z', condition: '<=' }, ( { z } ) => {
  75. const g = vec3( float( x ), float( y ), float( z ) ).toConst();
  76. const o = hash3d( n.add( g ) ).toConst();
  77. const r = g.sub( f ).add( sin( time.add( o.mul( TWO_PI ) ) ).mul( 0.5 ).add( 0.5 ) );
  78. minDist.assign( min( minDist, dot( r, r ) ) );
  79. } );
  80. } );
  81. } );
  82. return minDist;
  83. }, { p: 'vec3', time: 'float', return: 'float' } );
粤ICP备19079148号