Setting the file. One moment.
Optical Transport · Frost Sequence Camera Orbit · heygen-com/hyperframes · Skills Docs
ContentsBack to the top of the page Three Mesh BVH LICENSE
Next
Bundled file Optics
source/src/ice/ OpticalTransport.ts
TypeScript · 153 lines · 5 KB
,
11 vec4 ,
12 float ,
13 int ,
14 Loop ,
15 If ,
16 Break ,
17 normalize ,
18 length ,
19 max ,
20 min ,
21 abs ,
22 dot ,
23 pow ,
24 exp ,
25 log ,
26 mix ,
27 clamp ,
28 refract ,
29 reflect ,
30 select ,
31 mat3 ,
32 texture ,
33 equirectUV ,
34 cameraViewMatrix ,
35 cameraProjectionMatrix ,
36 cross ,
37 } = tsl;
38 type N = any ;
39 export function opticalTransport ( o : any ) {
40 const { shape , erosion , p , ray , normal , environment , backdrop , u , f , roughness } = o;
41 const B = shape.bound,
42 epsilon = Math. max ( 0.001 , B / 1500 );
43 const worldDir = ( d : N ) => normalize ( mat3 (u.model). mul (d));
44 const env = ( direction : N , rough : N ) =>
45 iceEnvironment (environment, u.envStrength, direction, rough);
46 const gradient = ( q : N ) => {
47 const e = shape.voxelSize ? shape.voxelSize. mul ( 0.75 ) : float ( B / 240 );
48 const g = vec3 (
49 shape. sdfNode (q. add ( vec3 (e, 0 , 0 ))). sub (shape. sdfNode (q. sub ( vec3 (e, 0 , 0 )))),
50 shape. sdfNode (q. add ( vec3 ( 0 , e, 0 ))). sub (shape. sdfNode (q. sub ( vec3 ( 0 , e, 0 )))),
51 shape. sdfNode (q. add ( vec3 ( 0 , 0 , e))). sub (shape. sdfNode (q. sub ( vec3 ( 0 , 0 , e)))),
52 );
53 return g. div ( max ( length (g), 1e-5 ));
54 };
55 const ior = max (u.ior, 1.001 );
56 const n = select ( dot (normal, ray). greaterThan ( 0 ), normal. negate (), normal);
57 const inside = normalize ( refract (ray, n, float ( 1 ). div (ior)));
58 const exit = Fn (() => {
59 const distance = float (epsilon * 2 ). toVar ();
60 const last = float ( 0 ). toVar ();
61 Loop ( 64 , () => {
62 const q = p. add (inside. mul (distance));
63 const sdf = shape. sdfNode (q);
64 const er = erosion. sample (q).r;
65 If (
66 distance
67 . greaterThan (epsilon * 4 )
68 . and (sdf. greaterThan ( 0 ). or (er. greaterThan (u.cutThreshold))),
69 () => {
70 Break ();
71 },
72 );
73 last. assign (distance);
74 distance. addAssign ( clamp ( abs (sdf). mul ( 0.7 ), epsilon, B / 12 ));
75 If (distance. greaterThan ( B * 2 ), () => {
76 Break ();
77 });
78 });
79 // Refine the boundary so thickness does not jump in visible steps.
80 Loop ( 5 , () => {
81 const mid = last. add (distance). mul ( 0.5 );
82 const q = p. add (inside. mul (mid));
83 If (shape. sdfNode (q). lessThan ( 0 ). and (erosion. sample (q).r. lessThan (u.cutThreshold)), () => {
84 last. assign (mid);
85 }). Else (() => {
86 distance. assign (mid);
87 });
88 });
89 return vec4 (p. add (inside. mul (distance)), distance);
90 })();
91 const exitNormal = gradient (exit.xyz);
92 const exitN = select ( dot (exitNormal, inside). lessThan ( 0 ), exitNormal. negate (), exitNormal);
93 const outward = refract (inside, exitN. negate (), ior);
94 const tir = length (outward). lessThan ( 0.0001 );
95 const outgoing = select (tir, reflect (inside, exitN), outward);
96 const exitWorld = u.model. mul ( vec4 (exit.xyz, 1 )).xyz;
97 const transmittedPlate = ( direction : N ) => {
98 const dirW = worldDir (direction);
99 const posV = cameraViewMatrix. mul ( vec4 (exitWorld, 1 )).xyz;
100 const dirV = mat3 (cameraViewMatrix). mul (dirW);
101 const t = float ( - 35 ). sub (posV.z). div ( min (dirV.z, - 0.001 ));
102 const q = posV. add (dirV. mul ( clamp (t, 0 , 150 )));
103 const clip = cameraProjectionMatrix. mul ( vec4 (q, 1 ));
104 const uv = vec2 (
105 clip.x. div ( max (clip.w, 0.001 )). mul ( 0.5 ). add ( 0.5 ),
106 clip.y. div ( max (clip.w, 0.001 )). mul ( - 0.5 ). add ( 0.5 ),
107 );
108 const background = backdropColorAt (backdrop, clamp (uv, 0 , 1 ));
109 // Backlighting is an authored studio source behind the translucent volume.
110 return background. add ( env (dirW, roughness). mul (u.backlight));
111 };
112 const dispersion = u.dispersion. mul (f.dispersion). mul ( 0.025 );
113 const spreadDir = normalize ( cross (inside, exitN). add ( vec3 ( 0.00001 , 0 , 0 )));
114 const transmitted = vec3 (
115 transmittedPlate ( normalize (outgoing. add (spreadDir. mul (dispersion)))).r,
116 transmittedPlate (outgoing).g,
117 transmittedPlate ( normalize (outgoing. sub (spreadDir. mul (dispersion)))).b,
118 );
119 const f0 = pow (ior. sub ( 1 ). div (ior. add ( 1 )), 2 );
120 const fresnel = f0
121 . add (
122 float ( 1 )
123 . sub (f0)
124 . mul ( pow ( float ( 1 ). sub ( clamp ( dot (n, ray. negate ()), 0 , 1 )), 5 )),
125 )
126 . mul (f.reflections);
127 const exitFresnel = select (
128 tir,
129 float ( 1 ),
130 f0. add (
131 float ( 1 )
132 . sub (f0)
133 . mul ( pow ( float ( 1 ). sub ( abs ( dot (exitN, inside))), 5 )),
134 ),
135 );
136 const distance = exit.w. mul (u.thicknessScale);
137 const attenuation = exp (
138 log ( max (u.attColor, vec3 ( 0.001 )))
139 . mul (distance. div ( max (u.attDist, 0.01 )))
140 . mul (f.absorption),
141 );
142 const reflected = env ( worldDir ( reflect (ray, n)), roughness);
143 const innerReflection = env ( worldDir ( reflect (inside, exitN)), roughness);
144 const through = transmitted
145 . mul ( float ( 1 ). sub (exitFresnel))
146 . add (innerReflection. mul (exitFresnel))
147 . mul (attenuation);
148 return {
149 reflected: reflected. mul (fresnel),
150 transmitted: through. mul ( float ( 1 ). sub (fresnel)),
151 distance,
152 };
153 }