Setting the file. One moment.
Shared Surface · Frost Sequence Camera Orbit · heygen-com/hyperframes · Skills Docs
ContentsBack to the top of the page Three Mesh BVH LICENSE
source/src/ice/ SharedSurface.ts
TypeScript · 146 lines · 5 KB
"../tsl/noise"
;
8 const { Fn , If , vec3 , vec4 , float , dot , smoothstep , normalize , clamp , dFdx , dFdy , length , max } =
9 tsl;
10 type N = any ;
11 export function iceSmudgeDirections ( seed : number ) {
12 const rand = rng (seed + 11 );
13 return [ 0 , 1 , 2 ]. map (() => {
14 const v = new THREE . Vector3 ( rand () * 2 - 1 , rand () * 2 - 1 , rand () * 2 - 1 ). normalize ();
15 return vec3 (v.x, v.y, v.z);
16 });
17 }
18 export function iceSurface (
19 p : N ,
20 nBase : N ,
21 seedV : N ,
22 smudgeDirs : N [],
23 erosion : any ,
24 u : any ,
25 f : any ,
26 filter = false ,
27 ) {
28 const band = ( scale : N ) =>
29 filter
30 ? float ( 1 ). sub (
31 smoothstep ( 0.35 , 1.25 , max ( length ( dFdx (p. mul (scale))), length ( dFdy (p. mul (scale))))),
32 )
33 : float ( 1 );
34 // frost
35 // Sample at the visible solid hit, consistently before and during breakup.
36 const frost0 = iceFrost (p, seedV, u.frostScale, u.frostThreshold, u.frostSoftness);
37 const frost = saturate (frost0. add (u.interiorFrost)). mul (f.frost);
38
39 // smudges: anisotropic streaks in 3 directions + blotchy prints (evaluated at the solid hit)
40 const stretch = ( q : N , d : N ) =>
41 q. sub (d. mul ( dot (q, d)). mul ( float ( 1 ). sub ( float ( 1 ). div (u.smudgeAniso))));
42 const smudgeNoise = vec4 (
43 gnoise ( stretch (p. mul (u.smudgeScale), smudgeDirs[ 0 ]). add (seedV. mul ( 3 ))),
44 gnoise ( stretch (p. mul (u.smudgeScale), smudgeDirs[ 1 ]). add (seedV. mul ( 4 ))),
45 gnoise ( stretch (p. mul (u.smudgeScale), smudgeDirs[ 2 ]). add (seedV. mul ( 5 ))),
46 gnoise (p. mul (u.smudgeScale. mul ( 1.7 )). add (seedV. mul ( 7.0 ))),
47 );
48 const streaks = smoothstep ( 0.45 , 0.85 , smudgeNoise.x. mul ( 0.5 ). add ( 0.5 ))
49 . add ( smoothstep ( 0.45 , 0.85 , smudgeNoise.y. mul ( 0.5 ). add ( 0.5 )))
50 . add ( smoothstep ( 0.45 , 0.85 , smudgeNoise.z. mul ( 0.5 ). add ( 0.5 )));
51 const blotch = smoothstep ( 0.6 , 0.72 , smudgeNoise.w. mul ( 0.5 ). add ( 0.5 ));
52 // noise masks: where smudges / micro bumps / cracks apply (low frequency)
53 const maskNoise = vec3 (
54 fbm (p. mul (u.smudgeMaskScale). add (seedV. mul ( 21.0 )), 2 )
55 . mul ( 0.5 )
56 . add ( 0.5 ),
57 fbm (p. mul (u.bumpMaskScale). add (seedV. mul ( 27.0 )), 2 )
58 . mul ( 0.5 )
59 . add ( 0.5 ),
60 fbm (p. mul (u.regionScale). add (seedV. mul ( 33.0 )), 2 )
61 . mul ( 0.5 )
62 . add ( 0.5 ),
63 );
64 const smudgeMask = softThreshold (maskNoise.x, float ( 1 ). sub (u.smudgeCoverage), 0.35 );
65 const microMask = softThreshold (maskNoise.y, float ( 1 ). sub (u.microCoverage), 0.35 );
66 const regionMask = softThreshold (maskNoise.z, float ( 1 ). sub (u.regionCoverage), 0.45 );
67 const smudge = saturate (
68 streaks. div ( 3 ). add (blotch. mul ( 0.6 )). mul (u.smudgeAmount). mul (smudgeMask),
69 ). mul (f.smudges);
70
71 // surface cracks (distance to the nearest Voronoi boundary at the surface)
72 const crackHelper = erosion. sampleCrack (p);
73 const warpedP = ErosionField. warpDomain (p, crackHelper.xyz, u.crackLarge, u.crackWarp). add (
74 seedV. mul ( 0.37 ),
75 );
76 const ve = Fn (() => {
77 const edge = vec4 ( 0 , 0 , 1 , 1 ). toVar ();
78 If (f.cracks. greaterThan ( 0.5 ), () => {
79 edge. assign (
80 erosion.materialPlanes
81 ? erosion.materialPlanes. sample (warpedP)
82 : voronoiEdge (warpedP, u.seed, u.crackCoverage),
83 );
84 });
85 return edge;
86 })();
87 const dEdge = ve.w. div (u.crackLarge);
88 const veinSurf = float ( 1 ). sub (
89 u.veinContrast. mul (
90 fbm (p. mul (u.veinScale). add (seedV. mul ( 41.0 )), 2 )
91 . mul ( 0.5 )
92 . add ( 0.5 ),
93 ),
94 );
95 const surfCrack = smoothstep (u.crackWidth. mul ( 5.0 ), 0.0 , dEdge)
96 . mul (u.surfaceCrack)
97 . mul (regionMask)
98 . mul (veinSurf)
99 . mul (f.cracks);
100
101 // Independent normal layers; none is activated by the breakup field.
102 const topness = saturate (nBase.y. mul ( 0.5 ). add ( 0.5 ));
103 const crystals = vnoise3 (p. mul (u.crystalScale). add (seedV))
104 . mul (u.crystalBump)
105 . mul ( 0.6 )
106 . mul (f.crystals)
107 . mul ( band (u.crystalScale));
108 const grain = vnoise3 (p. mul (u.edgeBumpScale). add (seedV. mul ( 13.0 )))
109 . mul (u.edgeBump)
110 . mul ( 0.5 )
111 . mul (f.grain)
112 . mul ( band (u.edgeBumpScale));
113 const micro = vnoise3 (p. mul (u.microScale). add (seedV. mul ( 5.0 )))
114 . mul (u.microBump)
115 . mul (microMask)
116 . mul (f.micro)
117 . mul ( band (u.microScale));
118 const ripple = vnoise3 (p. mul (u.rippleScale). add (seedV. mul ( 9.0 )))
119 . mul (u.rippleBump)
120 . mul (topness)
121 . mul (f.ripples)
122 . mul ( band (u.rippleScale));
123 // The master switch removes normal perturbations without discarding their saved
124 // strengths, crack colour, frost coverage or genuine fracture-face normals.
125 const detailNormal = crystals
126 . add (grain)
127 . sub (micro)
128 . sub (ripple)
129 . sub (ve.xyz. mul (surfCrack). mul ( 0.6 ));
130 const nSurface = normalize (nBase. add (detailNormal. mul (f.surfaceBumps)));
131 return {
132 frost,
133 smudge,
134 surfCrack,
135 nSurface,
136 regionMask,
137 roughness: clamp (
138 u.baseRough
139 . add (frost. mul (u.frostRough))
140 . add (smudge. mul (u.smudgeRough))
141 . add (surfCrack. mul ( 0.12 )),
142 0.015 ,
143 0.8 ,
144 ),
145 };
146 }