@dailies-studio/tsl-textures 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +142 -0
  3. package/dist/cjs/tsl-textures.cjs +4749 -0
  4. package/dist/cjs/tsl-textures.min.cjs +2 -0
  5. package/dist/tsl-textures.js +4659 -0
  6. package/dist/tsl-textures.min.js +2 -0
  7. package/package.json +36 -0
  8. package/src/brain.js +116 -0
  9. package/src/bricks.js +116 -0
  10. package/src/camouflage.js +85 -0
  11. package/src/caustics.js +75 -0
  12. package/src/cave-art.js +83 -0
  13. package/src/circle-decor.js +76 -0
  14. package/src/circles.js +83 -0
  15. package/src/clouds.js +114 -0
  16. package/src/concrete.js +95 -0
  17. package/src/cork.js +104 -0
  18. package/src/crumpled-fabric.js +81 -0
  19. package/src/dalmatian-spots.js +80 -0
  20. package/src/darth-maul.js +84 -0
  21. package/src/dyson-sphere.js +144 -0
  22. package/src/entangled.js +75 -0
  23. package/src/fordite.js +69 -0
  24. package/src/gas-giant.js +94 -0
  25. package/src/grid.js +84 -0
  26. package/src/halftone.js +252 -0
  27. package/src/isolayers.js +79 -0
  28. package/src/isolines.js +72 -0
  29. package/src/karst-rock.js +67 -0
  30. package/src/marble.js +96 -0
  31. package/src/melter.js +76 -0
  32. package/src/neon-lights.js +107 -0
  33. package/src/perlin-noise.js +66 -0
  34. package/src/photosphere.js +73 -0
  35. package/src/planet.js +168 -0
  36. package/src/polka-dots.js +106 -0
  37. package/src/processed-wood.js +80 -0
  38. package/src/protozoa.js +110 -0
  39. package/src/reticular-veins.js +72 -0
  40. package/src/roman-paving.js +58 -0
  41. package/src/rotator.js +120 -0
  42. package/src/rough-clay.js +90 -0
  43. package/src/runny-eggs.js +180 -0
  44. package/src/rust.js +144 -0
  45. package/src/satin.js +69 -0
  46. package/src/scaler.js +111 -0
  47. package/src/scepter-head.js +94 -0
  48. package/src/scream.js +72 -0
  49. package/src/stars.js +72 -0
  50. package/src/static-noise.js +73 -0
  51. package/src/supersphere.js +108 -0
  52. package/src/tiger-fur.js +77 -0
  53. package/src/translator.js +116 -0
  54. package/src/tsl-textures.js +63 -0
  55. package/src/tsl-utils.js +344 -0
  56. package/src/turbulent-smoke.js +73 -0
  57. package/src/voronoi-cells.js +99 -0
  58. package/src/water-drops.js +96 -0
  59. package/src/watermelon.js +87 -0
  60. package/src/waves.js +150 -0
  61. package/src/wood.js +99 -0
  62. package/src/zebra-lines.js +77 -0
package/src/satin.js ADDED
@@ -0,0 +1,69 @@
1
+ 
2
+ // TSL-Textures: Satin
3
+
4
+
5
+
6
+ import { Color } from "three";
7
+ import { Fn, mix, positionGeometry, vec3 } from 'three/tsl';
8
+ import { noise } from './tsl-utils.js';
9
+
10
+
11
+
12
+ var defaults = {
13
+ $name: 'Satin',
14
+
15
+ position: positionGeometry,
16
+ scale: 2,
17
+
18
+ color: new Color( 0x7080FF ),
19
+ background: new Color( 0x000050 ),
20
+
21
+ seed: 0,
22
+ };
23
+
24
+
25
+
26
+ var satinRaw = Fn( ([ position, scale, color, background, seed ]) => {
27
+
28
+ var pos = position.toVar( 'pos' ),
29
+ scale = scale.div( 3 ).exp( ).toVar( 'xscale' );
30
+
31
+ var k = noise(
32
+ vec3(
33
+ noise( vec3( pos.x.mul( 2 ), pos.y, pos.z ).mul( scale ) ),
34
+ noise( vec3( pos.x, pos.y.mul( 2 ), pos.z ).mul( scale ) ),
35
+ noise( vec3( pos.x, pos.y, pos.z.mul( 2 ) ).mul( scale ) ),
36
+ ).mul( scale ).add( seed )
37
+ ).abs().pow( 3 ).mul( 20 ).toVar( 'k' );
38
+
39
+ return mix( background, color, k );
40
+
41
+ } ).setLayout( {
42
+ name: 'satinRaw',
43
+ type: 'vec3',
44
+ inputs: [
45
+ { name: 'position', type: 'vec3' },
46
+ { name: 'scale', type: 'float' },
47
+ { name: 'color', type: 'vec3' },
48
+ { name: 'background', type: 'vec3' },
49
+ { name: 'seed', type: 'float' },
50
+ ] }
51
+ );
52
+
53
+
54
+
55
+ function satin( params={} ) {
56
+
57
+ var { position, scale, color, background, seed } = { ...defaults, ...params };
58
+
59
+ return satinRaw( position, scale, color, background, seed );
60
+
61
+ }
62
+
63
+
64
+
65
+ satin.defaults = defaults;
66
+
67
+
68
+
69
+ export { satin };
package/src/scaler.js ADDED
@@ -0,0 +1,111 @@
1
+ 
2
+ // TSL-Textures: Scaler
3
+
4
+
5
+
6
+ import { Vector2, Vector3 } from "three";
7
+ import { cross, Fn, mix, normalLocal, positionGeometry, tangentLocal, vec3 } from 'three/tsl';
8
+ import { approximateNormal, selectPlanar } from './tsl-utils.js';
9
+
10
+
11
+
12
+ var defaults = {
13
+ $name: 'Scaler',
14
+ $positionNode: true,
15
+ $selectorPlanar: true,
16
+
17
+ scales: new Vector3( 0.01, 0.9, 1.7 ),
18
+ center: new Vector3( 0, 0, 0 ),
19
+
20
+ selectorCenter: new Vector3( 0, 0, 0 ),
21
+ selectorAngles: new Vector2( 0, 0 ),
22
+ selectorWidth: 2,
23
+
24
+ };
25
+
26
+
27
+
28
+ var surfacePos = Fn( ([ pos, scales, center, selectorAngles, selectorCenter, selectorWidth ])=>{
29
+
30
+ var zone = selectPlanar( pos, selectorAngles, selectorCenter, selectorWidth );
31
+
32
+ var S = mix( vec3( 1, 1, 1 ), scales, zone );
33
+
34
+ return pos.sub( center ).mul( S ).add( center );
35
+
36
+ } );
37
+
38
+
39
+
40
+ var scalerRaw = Fn( ([ scales, center, selectorAngles, selectorCenter, selectorWidth ])=>{
41
+
42
+ return surfacePos( positionGeometry, scales, center, selectorAngles, selectorCenter, selectorWidth );
43
+
44
+ } ).setLayout( {
45
+ name: 'scalerRaw',
46
+ type: 'vec3',
47
+ inputs: [
48
+ { name: 'scales', type: 'vec3' },
49
+ { name: 'center', type: 'vec3' },
50
+ { name: 'selectorAngles', type: 'vec2' },
51
+ { name: 'selectorCenter', type: 'vec3' },
52
+ { name: 'selectorWidth', type: 'float' },
53
+ ]
54
+ } );
55
+
56
+
57
+
58
+ var scalerNormalRaw = Fn( ([ scales, center, selectorAngles, selectorCenter, selectorWidth ]) => {
59
+
60
+ var EPS = 0.01;
61
+
62
+ var position = positionGeometry,
63
+ normal = normalLocal.normalize().toVar(),
64
+ tangent = tangentLocal.normalize().mul( EPS ).toVar(),
65
+ bitangent = cross( normal, tangent ).normalize().mul( EPS ).toVar();
66
+
67
+ var pos = surfacePos( position, scales, center, selectorAngles, selectorCenter, selectorWidth );
68
+ var posU = surfacePos( position.add( tangent ), scales, center, selectorAngles, selectorCenter, selectorWidth );
69
+ var posV = surfacePos( position.add( bitangent ), scales, center, selectorAngles, selectorCenter, selectorWidth );
70
+
71
+ return approximateNormal( pos, posU, posV );
72
+
73
+ } ).setLayout( {
74
+ name: 'scalerNormalRaw',
75
+ type: 'vec3',
76
+ inputs: [
77
+ { name: 'scales', type: 'vec3' },
78
+ { name: 'center', type: 'vec3' },
79
+ { name: 'selectorAngles', type: 'vec2' },
80
+ { name: 'selectorCenter', type: 'vec3' },
81
+ { name: 'selectorWidth', type: 'float' },
82
+ ]
83
+ } );
84
+
85
+
86
+
87
+ function scaler( params={} ) {
88
+
89
+ var { scales, center, selectorAngles, selectorCenter, selectorWidth } = { ...defaults, ...params };
90
+
91
+ return scalerRaw( scales, center, selectorAngles, selectorCenter, selectorWidth );
92
+
93
+ }
94
+
95
+
96
+
97
+ scaler.normal = function ( params={} ) {
98
+
99
+ var { scales, center, selectorAngles, selectorCenter, selectorWidth } = { ...defaults, ...params };
100
+
101
+ return scalerNormalRaw( scales, center, selectorAngles, selectorCenter, selectorWidth );
102
+
103
+ };
104
+
105
+
106
+
107
+ scaler.defaults = defaults;
108
+
109
+
110
+
111
+ export { scaler };
@@ -0,0 +1,94 @@
1
+ 
2
+ // TSL-Textures: Scepter Head
3
+
4
+
5
+
6
+ import { Color } from "three";
7
+ import { abs, add, cos, floor, Fn, max, mix, mod, mul, positionGeometry, remapClamp, sign, tan, vec3 } from 'three/tsl';
8
+ import { hsl, noise, remapExp, toHsl } from './tsl-utils.js';
9
+
10
+
11
+
12
+ var defaults = {
13
+ $name: 'Scepter head',
14
+
15
+ position: positionGeometry,
16
+
17
+ xFactor: 10,
18
+ yFactor: 22,
19
+ zFactor: 10,
20
+
21
+ colorRim: new Color( 0xFFFFFF ),
22
+ colorA: new Color( 0x70E0FF ),
23
+ colorB: new Color( 0x3000FF ),
24
+ };
25
+
26
+
27
+
28
+ var scepterHeadRaw = Fn( ([ position, xFactor, yFactor, zFactor, colorRim, colorA, colorB ]) => {
29
+
30
+ var pos = position.toVar( 'pos' );
31
+
32
+ var fx = pos.x.mul( remapExp( xFactor, 0, 100, 1.35, 30 ) ).toVar( 'fx' ),
33
+ fy = pos.y.mul( remapExp( yFactor, 0, 100, 1.35, 30 ) ).toVar( 'fy' ),
34
+ fz = pos.z.mul( remapExp( zFactor, 0, 100, 1.35, 30 ) ).toVar( 'fz' );
35
+
36
+ var cosX = cos( fx ),
37
+ cosY = cos( fy ),
38
+ cosZ = cos( fz );
39
+
40
+ var k = noise( vec3( pos.x.div( cosX ), pos.y.div( cosY ), pos.z.div( cosZ ) ) );
41
+
42
+ k = sign( k ).mul( abs( k ).pow( 0.75 ) );
43
+
44
+ var dx = abs( mul( fx, tan( fx ) ).add( 1 ).div( cosX ) ),
45
+ dy = abs( mul( fy, tan( fy ) ).add( 1 ).div( cosY ) ),
46
+ dz = abs( mul( fz, tan( fz ) ).add( 1 ).div( cosZ ) );
47
+
48
+ var HSL = vec3().toVar();
49
+
50
+ var indexX = ( abs( floor( ( fx.mul( 2/Math.PI ).add( 1 ) ).div( 2 ) ) ) ),
51
+ indexY = ( abs( floor( ( fy.mul( 2/Math.PI ).add( 1 ) ).div( 2 ) ) ) ),
52
+ indexZ = ( abs( floor( ( fz.mul( 2/Math.PI ).add( 1 ) ).div( 2 ) ) ) );
53
+
54
+ var index = mod( ( add( indexX, indexY, indexZ ) ), 2 );
55
+
56
+ HSL.assign( toHsl( mix( colorA, colorB, index ) ) );
57
+ var color1 = hsl( vec3( HSL.xy, HSL.z.mul( k ) ) ).toVar( 'color1' );
58
+
59
+ HSL.assign( toHsl( colorRim ) );
60
+ var color2 = hsl( vec3( HSL.xy, mul( 2, k, HSL.z ) ) ).toVar( 'color2' );
61
+
62
+ return mix( color1, color2, remapClamp( max( dx, max( dy, dz ) ), 55-10, 55+10 ) );
63
+
64
+ } ).setLayout( {
65
+ name: 'scepterHeadRaw',
66
+ type: 'vec3',
67
+ inputs: [
68
+ { name: 'position', type: 'vec3' },
69
+ { name: 'xFactor', type: 'float' },
70
+ { name: 'yFactor', type: 'float' },
71
+ { name: 'zFactor', type: 'float' },
72
+ { name: 'colorRim', type: 'vec3' },
73
+ { name: 'colorA', type: 'vec3' },
74
+ { name: 'colorB', type: 'vec3' },
75
+ ] }
76
+ );
77
+
78
+
79
+
80
+ function scepterHead( params={} ) {
81
+
82
+ var { position, xFactor, yFactor, zFactor, colorRim, colorA, colorB } = { ...defaults, ...params };
83
+
84
+ return scepterHeadRaw( position, xFactor, yFactor, zFactor, colorRim, colorA, colorB );
85
+
86
+ }
87
+
88
+
89
+
90
+ scepterHead.defaults = defaults;
91
+
92
+
93
+
94
+ export { scepterHead };
package/src/scream.js ADDED
@@ -0,0 +1,72 @@
1
+ 
2
+ // TSL-Textures: Scream
3
+
4
+
5
+
6
+ import { Color } from "three";
7
+ import { add, cos, exp, Fn, mix, positionGeometry, sin, vec3 } from 'three/tsl';
8
+ import { hsl, noise, toHsl } from './tsl-utils.js';
9
+
10
+
11
+
12
+ var defaults = {
13
+ $name: 'Scream',
14
+
15
+ position: positionGeometry,
16
+ scale: 2,
17
+ variety: 1,
18
+
19
+ color: new Color( 0xF0F060 ),
20
+ background: new Color( 0xD09090 ),
21
+
22
+ seed: 0,
23
+ };
24
+
25
+
26
+
27
+ var screamRaw = Fn( ([ position, scale, variety, color, background, seed ]) => {
28
+
29
+ var pos = position.mul( exp( scale ) ).add( seed ).toVar( 'pos' );
30
+
31
+ var k = noise( add( sin( pos.xyz ), cos( pos.yzx ) ) );
32
+
33
+ pos.assign( position.mul( exp( scale ).mul( k ) ).add( seed ) );
34
+
35
+ var k = noise( add( sin( pos.xyz ), cos( pos.yzx ) ).mul( 2 ) );
36
+
37
+ var col = mix( background, color, k ).toVar( 'col' );
38
+
39
+ var HSL = toHsl( col ).toVar( 'HSL' );
40
+
41
+ return hsl( vec3( add( HSL.x, variety.mul( sin( k.mul( Math.PI ) ) ).mul( 0.5 ) ), HSL.yz ) );
42
+
43
+ } ).setLayout( {
44
+ name: 'satinRaw',
45
+ type: 'vec3',
46
+ inputs: [
47
+ { name: 'position', type: 'vec3' },
48
+ { name: 'scale', type: 'float' },
49
+ { name: 'variety', type: 'float' },
50
+ { name: 'color', type: 'vec3' },
51
+ { name: 'background', type: 'vec3' },
52
+ { name: 'seed', type: 'float' },
53
+ ] }
54
+ );
55
+
56
+
57
+
58
+ function scream( params={} ) {
59
+
60
+ var { position, scale, variety, color, background, seed } = { ...defaults, ...params };
61
+
62
+ return screamRaw( position, scale, variety, color, background, seed );
63
+
64
+ }
65
+
66
+
67
+
68
+ scream.defaults = defaults;
69
+
70
+
71
+
72
+ export { scream };
package/src/stars.js ADDED
@@ -0,0 +1,72 @@
1
+ 
2
+ // TSL-Textures: Stars
3
+
4
+
5
+
6
+ import { Color } from "three";
7
+ import { abs, add, exp, Fn, mix, positionGeometry, select, vec3 } from 'three/tsl';
8
+ import { hsl, noise, toHsl } from './tsl-utils.js';
9
+
10
+
11
+
12
+ var defaults = {
13
+ $name: 'Stars',
14
+
15
+ position: positionGeometry,
16
+ scale: 2,
17
+ density: 2,
18
+ variation: 0,
19
+
20
+ color: new Color( 0xfff5f0 ),
21
+ background: new Color( 0x000060 ),
22
+
23
+ seed: 0,
24
+ };
25
+
26
+
27
+
28
+ var starsRaw = Fn( ([ position, scale, density, variation, color, background, seed ]) => {
29
+
30
+ var pos = position.mul( exp( scale.div( 2 ).add( 3 ) ) ).add( seed ).toVar( );
31
+
32
+ var k = abs( noise( pos ) ).pow( 10 ).mul( 10 );
33
+
34
+ k = k.mul( exp( density.sub( 2 ) ) );
35
+
36
+ var dS = select( k.greaterThan( 0.1 ), variation.mul( noise( pos ) ), 0 );
37
+
38
+ var col = toHsl( mix( background, color, k ) );
39
+
40
+ return hsl( vec3( add( col.x, dS ), col.yz ) );
41
+
42
+ } ).setLayout( {
43
+ name: 'starsRaw',
44
+ type: 'vec3',
45
+ inputs: [
46
+ { name: 'position', type: 'vec3' },
47
+ { name: 'scale', type: 'float' },
48
+ { name: 'density', type: 'float' },
49
+ { name: 'variation', type: 'float' },
50
+ { name: 'color', type: 'vec3' },
51
+ { name: 'background', type: 'vec3' },
52
+ { name: 'seed', type: 'float' },
53
+ ] }
54
+ );
55
+
56
+
57
+
58
+ function stars( params={} ) {
59
+
60
+ var { position, scale, density, variation, color, background, seed } = { ...defaults, ...params };
61
+
62
+ return starsRaw( position, scale, density, variation, color, background, seed );
63
+
64
+ }
65
+
66
+
67
+
68
+ stars.defaults = defaults;
69
+
70
+
71
+
72
+ export { stars };
@@ -0,0 +1,73 @@
1
+ 
2
+ // TSL-Textures: Noise Pattern
3
+
4
+
5
+
6
+ import { clamp, exp, Fn, screenCoordinate, time, vec3 } from 'three/tsl';
7
+ import { noise, vnoise } from './tsl-utils.js';
8
+
9
+
10
+
11
+ var defaults = {
12
+ $name: 'Static noise',
13
+
14
+ position: screenCoordinate,
15
+ time: time,
16
+
17
+ scale: 2,
18
+ balance: 0,
19
+ contrast: 0,
20
+
21
+ delay: 0,
22
+
23
+ seed: 0,
24
+ };
25
+
26
+
27
+
28
+ var staticNoiseRaw = Fn( ([ position, time, scale, balance, contrast, delay, seed ]) => {
29
+
30
+ var pos = position.div( exp( scale ) ).add( seed );
31
+
32
+ var speed = delay.sub( 1 ).mul( 5 ).exp(),
33
+ t = time.div( speed ).round().mul( speed );
34
+
35
+ var offset = vnoise( t.sin() ).mul( 1000 );
36
+
37
+ var k = noise( pos.add( offset ) ).min( 1 );
38
+
39
+ k = k.mul( 0.5, exp( contrast ) ).add( 0.5, balance );
40
+
41
+ return vec3( k );
42
+
43
+ } ).setLayout( {
44
+ name: 'staticNoiseRaw',
45
+ type: 'vec3',
46
+ inputs: [
47
+ { name: 'position', type: 'vec2' },
48
+ { name: 'time', type: 'float' },
49
+ { name: 'scale', type: 'float' },
50
+ { name: 'balance', type: 'float' },
51
+ { name: 'contrast', type: 'float' },
52
+ { name: 'delay', type: 'float' },
53
+ { name: 'seed', type: 'float' },
54
+ ] }
55
+ );
56
+
57
+
58
+
59
+ function staticNoise( params={} ) {
60
+
61
+ var { position, time, scale, balance, contrast, delay, seed } = { ...defaults, ...params };
62
+
63
+ return staticNoiseRaw( position, time, scale, balance, contrast, delay, seed );
64
+
65
+ }
66
+
67
+
68
+
69
+ staticNoise.defaults = defaults;
70
+
71
+
72
+
73
+ export { staticNoise };
@@ -0,0 +1,108 @@
1
+ 
2
+ // TSL-Textures: Supersphere
3
+
4
+
5
+
6
+ import { cross, float, Fn, normalLocal, positionGeometry, tangentLocal } from 'three/tsl';
7
+ import { approximateNormal } from './tsl-utils.js';
8
+
9
+
10
+
11
+ var defaults = {
12
+ $name: 'Supersphere',
13
+ $positionNode: true,
14
+
15
+ exponent: 3,
16
+
17
+ };
18
+
19
+
20
+
21
+ var surfacePos = Fn( ([ pos, exponent ])=>{
22
+
23
+ var xexponent = float( 2 ).pow( exponent );
24
+ var equPos = pos.div( pos.length() ).toVar();
25
+ var equPos2 = equPos.abs().pow( xexponent ).toVar();
26
+
27
+ var p = equPos2.x
28
+ .add( equPos2.y )
29
+ .add( equPos2.z )
30
+ .pow( xexponent.reciprocal( ) );
31
+
32
+ return equPos.div( p );
33
+
34
+ } ).setLayout( {
35
+ name: 'surfacePos',
36
+ type: 'vec3',
37
+ inputs: [
38
+ { name: 'pos', type: 'vec3' },
39
+ { name: 'exponent', type: 'float' },
40
+ ]
41
+ } );
42
+
43
+
44
+
45
+ var supersphereRaw = Fn( ([ exponent ])=>{
46
+
47
+ return surfacePos( positionGeometry, exponent );
48
+
49
+ } ).setLayout( {
50
+ name: 'supersphereRaw',
51
+ type: 'vec3',
52
+ inputs: [
53
+ { name: 'exponent', type: 'float' },
54
+ ]
55
+ } );
56
+
57
+
58
+
59
+ var supersphereNormalRaw = Fn( ([ exponent ]) => {
60
+
61
+ const EPS = 0.01;
62
+
63
+ var position = positionGeometry,
64
+ normal = normalLocal.normalize().toVar(),
65
+ tangent = tangentLocal.normalize().mul( EPS ).toVar(),
66
+ bitangent = cross( normal, tangent ).normalize().mul( EPS ).toVar();
67
+
68
+ var pos = surfacePos( position, exponent );
69
+ var posU = surfacePos( position.add( tangent ), exponent );
70
+ var posV = surfacePos( position.add( bitangent ), exponent );
71
+
72
+ return approximateNormal( pos, posU, posV );
73
+
74
+ } ).setLayout( {
75
+ name: 'supersphereRaw',
76
+ type: 'vec3',
77
+ inputs: [
78
+ { name: 'exponent', type: 'float' },
79
+ ]
80
+ } );
81
+
82
+
83
+
84
+ function supersphere( params={} ) {
85
+
86
+ var { exponent } = { ...defaults, ...params };
87
+
88
+ return supersphereRaw( exponent );
89
+
90
+ }
91
+
92
+
93
+
94
+ supersphere.normal = function ( params={} ) {
95
+
96
+ var { exponent } = { ...defaults, ...params };
97
+
98
+ return supersphereNormalRaw( exponent );
99
+
100
+ };
101
+
102
+
103
+
104
+ supersphere.defaults = defaults;
105
+
106
+
107
+
108
+ export { supersphere };
@@ -0,0 +1,77 @@
1
+ 
2
+ // TSL-Textures: Tiger fur
3
+
4
+
5
+
6
+ import { Color } from "three";
7
+ import { exp, Fn, mix, positionGeometry, vec3 } from 'three/tsl';
8
+ import { noise } from './tsl-utils.js';
9
+
10
+
11
+
12
+ var defaults = {
13
+ $name: 'Tiger fur',
14
+
15
+ position: positionGeometry,
16
+ scale: 2,
17
+ lengths: 4,
18
+ blur: 0.3,
19
+ strength: 0.3,
20
+ hairs: 0.5,
21
+
22
+ color: new Color( 0xFFAA00 ),
23
+ bottomColor: new Color( 0xFFFFEE ),
24
+
25
+ seed: 0,
26
+ };
27
+
28
+
29
+
30
+ var tigerFurRaw = Fn( ([ position, scale, lengths, blur, strength, hairs, color, bottomColor, seed ])=>{
31
+
32
+ var xscale = scale.div( 2 ).add( 1 ).toVar();
33
+ var pos = position.mul( exp( xscale ) ).add( seed ).toVar( );
34
+
35
+ var len = lengths.add( 5 ).reciprocal().toVar();
36
+ var hairs = hairs.mul( 0.3 ).toVar();
37
+ var k = noise( pos.mul( xscale, vec3( 1, len, len ) ) );
38
+ k = k.add( noise( pos.mul( vec3( 25, 1, 1 ) ) ).add( 1 ).mul( hairs ) );
39
+ k = k.add( strength.sub( 0.5 ) ).smoothstep( blur.negate(), blur ).oneMinus();
40
+
41
+ var n = position.y.add( hairs.sub( 0.5 ) ).smoothstep( -1, 0.5 );
42
+
43
+ return mix( bottomColor, color, n ).mul( k );
44
+
45
+ } ).setLayout( {
46
+ name: 'tigerFurRaw',
47
+ type: 'vec3',
48
+ inputs: [
49
+ { name: 'position', type: 'vec3' },
50
+ { name: 'scale', type: 'float' },
51
+ { name: 'lengths', type: 'float' },
52
+ { name: 'blur', type: 'float' },
53
+ { name: 'strength', type: 'float' },
54
+ { name: 'hairs', type: 'float' },
55
+ { name: 'color', type: 'vec3' },
56
+ { name: 'bottomColor', type: 'vec3' },
57
+ { name: 'seed', type: 'float' },
58
+ ] }
59
+ );
60
+
61
+
62
+
63
+ function tigerFur( params={} ) {
64
+
65
+ var { position, scale, lengths, blur, strength, hairs, color, bottomColor, seed } = { ...defaults, ...params };
66
+
67
+ return tigerFurRaw( position, scale, lengths, blur, strength, hairs, color, bottomColor, seed );
68
+
69
+ }
70
+
71
+
72
+
73
+ tigerFur.defaults = defaults;
74
+
75
+
76
+
77
+ export { tigerFur };