| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- import { Fn, Loop, dot, float, fract, int, min, sin, vec2, vec3, TWO_PI } from 'three/tsl';
- /**
- * @module VoronoiNoise
- * @three_import import { voronoi2d, voronoi3d } from 'three/addons/tsl/math/voronoiNoise.js';
- */
- /**
- * Generates a pseudo-random vec2 from the given coordinate.
- *
- * Reference: {@link https://www.shadertoy.com/view/MslGD8}.
- *
- * @tsl
- * @function
- * @param {Node<vec2>} p - The input coordinate.
- * @return {Node<vec2>} A pseudo-random value in the range `[0, 1]`.
- */
- export const hash2d = /*@__PURE__*/ Fn( ( [ p ] ) => {
- return fract( sin( vec2( dot( p, vec2( 127.1, 311.7 ) ), dot( p, vec2( 269.5, 183.3 ) ) ) ).mul( 18.5453 ) );
- }, { p: 'vec2', return: 'vec2' } );
- /**
- * Animated 2D Voronoi noise. The feature points orbit inside their cells so the
- * resulting pattern morphs over time.
- *
- * Reference: {@link https://www.shadertoy.com/view/MslGD8}.
- *
- * @tsl
- * @function
- * @param {Node<vec2>} p - The input coordinate.
- * @param {Node<float>} time - The animation time.
- * @return {Node<float>} The squared distance to the closest feature point, roughly in the range `[0, 1]`.
- */
- export const voronoi2d = /*@__PURE__*/ Fn( ( [ p, time ] ) => {
- const n = p.floor().toConst();
- const f = p.fract().toConst();
- const minDist = float( 8 ).toVar();
- Loop( { start: int( - 1 ), end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => {
- Loop( { start: int( - 1 ), end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => {
- const g = vec2( float( x ), float( y ) ).toConst();
- const o = hash2d( n.add( g ) ).toConst();
- const r = g.sub( f ).add( sin( time.add( o.mul( TWO_PI ) ) ).mul( 0.5 ).add( 0.5 ) );
- minDist.assign( min( minDist, dot( r, r ) ) );
- } );
- } );
- return minDist;
- }, { p: 'vec2', time: 'float', return: 'float' } );
- /**
- * Generates a pseudo-random vec3 from the given coordinate.
- *
- * @tsl
- * @function
- * @param {Node<vec3>} p - The input coordinate.
- * @return {Node<vec3>} A pseudo-random value in the range `[0, 1]`.
- */
- export const hash3d = /*@__PURE__*/ Fn( ( [ p ] ) => {
- 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 ) );
- }, { p: 'vec3', return: 'vec3' } );
- /**
- * Animated 3D Voronoi noise. Like {@link voronoi2d} but with a volumetric input
- * coordinate so the pattern can be applied to arbitrary surfaces without
- * projection artifacts. Evaluates 27 cells instead of 9 and is therefore
- * considerably more expensive than the 2D version.
- *
- * @tsl
- * @function
- * @param {Node<vec3>} p - The input coordinate.
- * @param {Node<float>} time - The animation time.
- * @return {Node<float>} The squared distance to the closest feature point, roughly in the range `[0, 1]`.
- */
- export const voronoi3d = /*@__PURE__*/ Fn( ( [ p, time ] ) => {
- const n = p.floor().toConst();
- const f = p.fract().toConst();
- const minDist = float( 8 ).toVar();
- Loop( { start: int( - 1 ), end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => {
- Loop( { start: int( - 1 ), end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => {
- Loop( { start: int( - 1 ), end: int( 1 ), name: 'z', condition: '<=' }, ( { z } ) => {
- const g = vec3( float( x ), float( y ), float( z ) ).toConst();
- const o = hash3d( n.add( g ) ).toConst();
- const r = g.sub( f ).add( sin( time.add( o.mul( TWO_PI ) ) ).mul( 0.5 ).add( 0.5 ) );
- minDist.assign( min( minDist, dot( r, r ) ) );
- } );
- } );
- } );
- return minDist;
- }, { p: 'vec3', time: 'float', return: 'float' } );
|