@voluma/vlam 0.2.2 → 0.2.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.
- package/README.md +1 -3
- package/dist/effects.d.ts +99 -5
- package/dist/effects.js +214 -111
- package/dist/effects.js.map +1 -1
- package/dist/index.js +281 -219
- package/dist/index.js.map +1 -1
- package/dist/relighting-pass.d.ts +49 -0
- package/dist/streamed-splat-mesh-utils.d.ts +1 -1
- package/dist/streamed-splat-mesh.d.ts +14 -3
- package/dist/worker-sorter.d.ts +13 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,9 +16,7 @@ Local site and generated API: `npm run dev` (http://localhost:5170, viewer at `/
|
|
|
16
16
|
> Package `@voluma/vlam`, public **0.2.0**. APIs may still move before 1.0.
|
|
17
17
|
|
|
18
18
|
## Important notice!
|
|
19
|
-
This is a pre-release. The API can still change in breaking ways before v1.0.
|
|
20
|
-
|
|
21
|
-
Phones and Intel/AMD integrated GPUs still need more device runs. A Galaxy S24 Ultra holds WebGPU; goose.sog is locked 60 rAF in SD and ~58 in HD, streamed million-splat views are fill-bound. On a MacBook Air M3 the demo keeps the fill-constrained (SD) preset; HD is a toggle, not the default.
|
|
19
|
+
This is a pre-release not yet recommended for production. The API can still change in breaking ways before v1.0.
|
|
22
20
|
|
|
23
21
|
|
|
24
22
|
## Install
|
package/dist/effects.d.ts
CHANGED
|
@@ -15,6 +15,12 @@
|
|
|
15
15
|
* tiles (or raw geometries) for PlayCanvas-style {@link SplatMesh.setRelighting}.
|
|
16
16
|
* - {@link createRelightingShadowFactorMaterial}: writes a shadow **multiplier**
|
|
17
17
|
* (1 = lit, <1 = umbra) so coverage does not statically tint splats.
|
|
18
|
+
* Accepts one light or {@link RelightingLightContribution}[] with intensity
|
|
19
|
+
* weights. Optional `color` / `diffuse` / `direction` add a Lambert boost on
|
|
20
|
+
* top of that identity (RGB may exceed 1 on a HalfFloat lighting RT).
|
|
21
|
+
* - {@link renderRelightingFactorMap}: host-safe lighting pass. Isolates
|
|
22
|
+
* `autoClear`, shadow maps, and swaps a passthrough `contextNode` so the
|
|
23
|
+
* example works on an existing `WebGPURenderer`, not only `createSplatRenderer`.
|
|
18
24
|
* - {@link worldWarpPreset}: camera-centered sphere wrap (planet / bowl).
|
|
19
25
|
* - {@link depthOfFieldPreset}: stylized modifier-based depth-of-field (M13).
|
|
20
26
|
* For physically-modeled camera DoF prefer the core
|
|
@@ -262,6 +268,7 @@ export declare function worldWarpPreset(options?: {
|
|
|
262
268
|
intensity?: number;
|
|
263
269
|
radius?: number;
|
|
264
270
|
}): WorldWarpPreset;
|
|
271
|
+
export { renderRelightingFactorMap, type RelightingFactorRenderer } from './relighting-pass';
|
|
265
272
|
/** Handle returned by {@link createRelightingProxy}. */
|
|
266
273
|
export interface RelightingProxy {
|
|
267
274
|
/** World-space group of lit proxy meshes (hide from the main splat scene). */
|
|
@@ -274,14 +281,77 @@ export interface RelightingProxy {
|
|
|
274
281
|
/** Disposes geometries and the default material owned by this helper. */
|
|
275
282
|
dispose(): void;
|
|
276
283
|
}
|
|
284
|
+
/** One independent shadow-casting light for {@link createRelightingShadowFactorMaterial}. */
|
|
285
|
+
export type RelightingLightContribution = {
|
|
286
|
+
light: THREE.Light;
|
|
287
|
+
/** Relative umbra weight. Default `1`. Values `<= 0` are skipped unless `fill` is set. */
|
|
288
|
+
intensity?: number;
|
|
289
|
+
/**
|
|
290
|
+
* Additive Lambert fill on top of the umbra factor (RGB may exceed 1).
|
|
291
|
+
* Gated by `shadow()`, facing, and for spot/point lights the Frostbite
|
|
292
|
+
* `distance` window (and the spot cone). `0` / omitted = umbra only.
|
|
293
|
+
*/
|
|
294
|
+
fill?: number;
|
|
295
|
+
};
|
|
296
|
+
/** Options for {@link createRelightingShadowFactorMaterial}. */
|
|
297
|
+
export type RelightingShadowFactorOptions = {
|
|
298
|
+
umbra?: number;
|
|
299
|
+
receiveUpMin?: number;
|
|
300
|
+
color?: THREE.Color;
|
|
301
|
+
diffuse?: number;
|
|
302
|
+
direction?: THREE.Vector3;
|
|
303
|
+
/**
|
|
304
|
+
* How independent contributions combine into one multiplier.
|
|
305
|
+
* - `average` (default): intensity-weighted mean of shadows (fill lights).
|
|
306
|
+
* - `min`: union of umbras — each caster keeps its own silhouette. Contribution
|
|
307
|
+
* `intensity` scales umbra depth: `0` → none, `1` → default `umbra`,
|
|
308
|
+
* `>1` → darker than default (`umbra_i = clamp(1 - I*(1-umbra), 0, 1)`).
|
|
309
|
+
*/
|
|
310
|
+
combine?: 'average' | 'min';
|
|
311
|
+
midLight?: THREE.Light;
|
|
312
|
+
midRadius?: number;
|
|
313
|
+
outerLight?: THREE.Light;
|
|
314
|
+
outerRadius?: number;
|
|
315
|
+
farLight?: THREE.Light;
|
|
316
|
+
nearRadius?: number;
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* Cap on independent shadow lights (cascades of the first directional do not
|
|
320
|
+
* count). Extra contributions are ignored. The compiled graph unrolls only
|
|
321
|
+
* the live contribution count, not a padded 32-wide loop.
|
|
322
|
+
*/
|
|
323
|
+
export declare const MAX_RELIGHTING_SHADOW_LIGHTS = 32;
|
|
277
324
|
/**
|
|
278
325
|
* Node material for a **shadow-factor** lighting RT used with
|
|
279
326
|
* {@link SplatMesh.setRelighting}.
|
|
280
327
|
*
|
|
281
|
-
* Fragment output is `vec4(vec3(mix(umbra, 1, shadow
|
|
328
|
+
* Fragment output is `vec4(vec3(mix(umbra, 1, shadow)) + boost, 1)`:
|
|
282
329
|
* - covered + lit → RGB ≈ 1 (identity modulate when brightness/background are 1)
|
|
283
330
|
* - covered + umbra → RGB ≈ `umbra` (soft darken; never pure black)
|
|
284
331
|
* - uncovered stays clear-alpha 0 from the RT clear
|
|
332
|
+
* - with `diffuse` > 0, facing surfaces add `color * NdotL * diffuse`
|
|
333
|
+
* (RGB may exceed 1; use a HalfFloat lighting RT)
|
|
334
|
+
*
|
|
335
|
+
* Pass one {@link THREE.Light} (demo / single-sun) or an array of
|
|
336
|
+
* {@link RelightingLightContribution} so independent lights share one
|
|
337
|
+
* multiplier. Default combine is intensity-weighted average
|
|
338
|
+
* (`illum = sum(I_i * shadow_i) / sum(I_i)`); pass `combine: 'min'` for a
|
|
339
|
+
* union of umbras so each caster keeps its silhouette. Spot / point lights
|
|
340
|
+
* with `distance > 0` fade their umbra to lit via a Frostbite cutoff window
|
|
341
|
+
* (steepened by `decay`) so the shadow map far plane is not a hard cliff.
|
|
342
|
+
* Contribution `fill` adds occluded Lambert (range + cone for punctual lights)
|
|
343
|
+
* on top of that identity so marker lamps can light splats without wrapping
|
|
344
|
+
* through collision. Cascades (`midLight` / `outerLight` / `farLight`) still
|
|
345
|
+
* attach to the **first** directional only. At most
|
|
346
|
+
* {@link MAX_RELIGHTING_SHADOW_LIGHTS} independent lights are used; extras
|
|
347
|
+
* are ignored. Graph size follows the live contribution count (not a padded
|
|
348
|
+
* loop of that width).
|
|
349
|
+
*
|
|
350
|
+
* By default, only **upward** proxy faces receive (`receiveUpMin`). Vertical
|
|
351
|
+
* and noisy foliage triangles still **cast**, but they do not self-shadow —
|
|
352
|
+
* that PCF acne reads as per-frame sparkle in trees. Pass `receiveUpMin: 0`
|
|
353
|
+
* to receive on every face. Contribution `fill` does **not** use that slope
|
|
354
|
+
* gate (stems would otherwise stay unlit in the factor map).
|
|
285
355
|
*
|
|
286
356
|
* Clear the lighting RT to **RGB 1, A 0** (not black). Softness / bilinear
|
|
287
357
|
* samples at coverage edges otherwise pull in black and draw a dark outline
|
|
@@ -292,12 +362,36 @@ export interface RelightingProxy {
|
|
|
292
362
|
* Assign to proxy meshes with `castShadow` and `receiveShadow` both true; the
|
|
293
363
|
* umbra shape follows those triangles (splat foliage cannot cast).
|
|
294
364
|
*
|
|
295
|
-
* @param
|
|
365
|
+
* @param lights - Shadow-casting light, or intensity-weighted contributions.
|
|
366
|
+
* The first entry is the innermost cascade when `midLight` / `outerLight` /
|
|
367
|
+
* `farLight` are set.
|
|
296
368
|
* @param options.umbra - Multiplier in full shadow, in `[0, 1]`. Default `0.45`.
|
|
369
|
+
* @param options.receiveUpMin - World-up `normal.y` below which the face does
|
|
370
|
+
* not receive. Default `0.25`. `0` disables the slope gate.
|
|
371
|
+
* @param options.color - Light tint for the optional Lambert boost. Mutate
|
|
372
|
+
* in place; the material holds this object. Default white.
|
|
373
|
+
* @param options.diffuse - Lambert boost on top of identity. Default `0`
|
|
374
|
+
* (shadow multiplier only). Facing, unshadowed coverage becomes
|
|
375
|
+
* `1 + color * NdotL * diffuse`.
|
|
376
|
+
* @param options.direction - World-space direction **toward** the light.
|
|
377
|
+
* Mutate in place each frame as the sun moves. Default `(0, 1, 0)`.
|
|
378
|
+
* @param options.midLight - Optional mid cascade (demo: ~50 m). Blend from
|
|
379
|
+
* the first light over `nearRadius`.
|
|
380
|
+
* @param options.midRadius - World metres where the mid cascade yields to
|
|
381
|
+
* `outerLight` (or `farLight`). Default `50`.
|
|
382
|
+
* @param options.outerLight - Optional outer cascade (demo: ~160 m) between
|
|
383
|
+
* mid and scene-sized far. Blend from mid over `midRadius`, then to
|
|
384
|
+
* `farLight` over `outerRadius`.
|
|
385
|
+
* @param options.outerRadius - World metres where the outer cascade yields to
|
|
386
|
+
* `farLight`. Default `160`. Ignored without `outerLight` and `farLight`.
|
|
387
|
+
* @param options.farLight - Optional scene-sized cascade. Out-of-frustum
|
|
388
|
+
* `shadow()` is 1 (lit), so inner maps can stay tight without clipping
|
|
389
|
+
* distant umbras. Blend by camera distance.
|
|
390
|
+
* @param options.nearRadius - World metres where the inner cascade yields to
|
|
391
|
+
* `midLight` (or to `farLight` if there is no mid). Default `20` with
|
|
392
|
+
* `midLight`, else `100`.
|
|
297
393
|
*/
|
|
298
|
-
export declare function createRelightingShadowFactorMaterial(
|
|
299
|
-
umbra?: number;
|
|
300
|
-
}): THREE.MeshStandardNodeMaterial;
|
|
394
|
+
export declare function createRelightingShadowFactorMaterial(lights: THREE.Light | RelightingLightContribution[], options?: RelightingShadowFactorOptions): THREE.MeshStandardNodeMaterial;
|
|
301
395
|
/**
|
|
302
396
|
* Builds a PlayCanvas-style relighting **proxy** from collision tiles or raw
|
|
303
397
|
* geometries. The host places {@link RelightingProxy.group} on a dedicated
|
package/dist/effects.js
CHANGED
|
@@ -1,87 +1,100 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import {
|
|
3
|
-
import { w as
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import * as w from "three/webgpu";
|
|
2
|
+
import { context as mt, positionWorld as ot, cameraPosition as ft, smoothstep as F, float as a, normalWorld as Q, mix as p, min as ht, vec3 as v, uniform as R, vec4 as U, wgslFn as gt, uniformArray as xt, shadow as L, objectPosition as O, cos as nt, int as bt, mat3 as pt, modelViewMatrix as wt, reference as Mt, frameGroup as vt, vec2 as yt } from "three/tsl";
|
|
3
|
+
import { w as Ct } from "./logging-BfPdd7NJ.js";
|
|
4
|
+
const Z = new w.Vector2(), st = new w.Color(), Tt = mt({
|
|
5
|
+
getOutput: (t) => t
|
|
6
|
+
});
|
|
7
|
+
function Gt(t, e, c, o) {
|
|
8
|
+
t.getDrawingBufferSize(Z), o.setSize(Math.max(1, Z.x), Math.max(1, Z.y));
|
|
9
|
+
const m = t.getRenderTarget(), l = t.getActiveCubeFace(), d = t.getActiveMipmapLevel(), i = t.getMRT(), b = t.getClearAlpha(), n = t.autoClear, x = t.shadowMap.enabled, u = t.shadowMap.autoUpdate, s = t.contextNode;
|
|
10
|
+
t.getClearColor(st);
|
|
11
|
+
try {
|
|
12
|
+
t.contextNode = Tt, t.autoClear = !0, t.shadowMap.enabled = !0, u === !1 && (t.shadowMap.autoUpdate = !0), t.setMRT(null), t.setRenderTarget(o), t.setClearColor(16777215, 0), t.clear(), t.render(e, c);
|
|
13
|
+
} finally {
|
|
14
|
+
t.setRenderTarget(m, l, d), t.setMRT(i), t.setClearColor(st, b), t.autoClear = n, t.shadowMap.enabled = x, u !== void 0 && (t.shadowMap.autoUpdate = u), t.contextNode = s;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const tt = 5, Rt = { tint: 0, desaturate: 1, hide: 2, rim: 3 }, St = [0, 0, 0], kt = [1, 1, 1], Lt = [0, 0, 0, 1];
|
|
18
|
+
function Vt(t = [], e = {}) {
|
|
19
|
+
const c = Math.max(1, Math.floor(e.maxShapes ?? 32)), o = [];
|
|
20
|
+
for (let n = 0; n < c * tt; n++) o.push(new w.Vector4());
|
|
21
|
+
const m = xt(o, "vec4"), l = R(0, "int");
|
|
22
|
+
let d = !1;
|
|
23
|
+
const i = (n) => {
|
|
24
|
+
const x = Math.min(n.length, c);
|
|
25
|
+
n.length > c && !d && (d = !0, Ct(
|
|
26
|
+
`sdfEffects: ${n.length} shapes exceeds maxShapes=${c}; extra shapes are ignored. Raise maxShapes if you need more.`
|
|
14
27
|
));
|
|
15
|
-
for (let
|
|
16
|
-
const s =
|
|
28
|
+
for (let u = 0; u < x; u++) {
|
|
29
|
+
const s = n[u];
|
|
17
30
|
if (s.kind === "box") {
|
|
18
|
-
const
|
|
19
|
-
if (!
|
|
31
|
+
const f = s.halfExtents;
|
|
32
|
+
if (!f || !(f[0] > 0) || !(f[1] > 0) || !(f[2] > 0))
|
|
20
33
|
throw new Error(
|
|
21
|
-
`sdfEffects.setShapes: shape ${
|
|
34
|
+
`sdfEffects.setShapes: shape ${u} is a box and requires halfExtents with three positive components (got ${f ? `[${f.join(", ")}]` : "undefined"}).`
|
|
22
35
|
);
|
|
23
36
|
} else if (typeof s.radius == "number" && s.radius > 0) {
|
|
24
37
|
if (s.kind === "cylinder" && !(typeof s.height == "number" && s.height > 0))
|
|
25
38
|
throw new Error(
|
|
26
|
-
`sdfEffects.setShapes: shape ${
|
|
39
|
+
`sdfEffects.setShapes: shape ${u} is a cylinder and requires a positive height (got ${String(s.height)}).`
|
|
27
40
|
);
|
|
28
41
|
} else throw new Error(
|
|
29
|
-
`sdfEffects.setShapes: shape ${
|
|
42
|
+
`sdfEffects.setShapes: shape ${u} is a ${s.kind} and requires a positive radius (got ${String(s.radius)}).`
|
|
30
43
|
);
|
|
31
44
|
}
|
|
32
|
-
for (let
|
|
33
|
-
const s =
|
|
34
|
-
if (
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
} else s.kind === "cylinder" ?
|
|
45
|
+
for (let u = 0; u < x; u++) {
|
|
46
|
+
const s = n[u], f = u * tt, h = s.center ?? St, r = s.color ?? kt, g = s.rotation ?? Lt, y = s.kind === "box" ? 1 : s.kind === "cylinder" ? 2 : 0;
|
|
47
|
+
if (o[f + 0].set(h[0], h[1], h[2], y), s.kind === "box") {
|
|
48
|
+
const M = s.halfExtents;
|
|
49
|
+
o[f + 1].set(M[0], M[1], M[2], s.falloff ?? 0);
|
|
50
|
+
} else s.kind === "cylinder" ? o[f + 1].set(
|
|
38
51
|
s.radius,
|
|
39
52
|
s.height / 2,
|
|
40
53
|
0,
|
|
41
54
|
s.falloff ?? 0
|
|
42
|
-
) :
|
|
43
|
-
|
|
55
|
+
) : o[f + 1].set(s.radius, 0, 0, s.falloff ?? 0);
|
|
56
|
+
o[f + 2].set(r[0], r[1], r[2], Rt[s.mode]), o[f + 3].set(g[0], g[1], g[2], g[3]), o[f + 4].set(s.invert ? 1 : 0, s.strength ?? 1, 0, 0);
|
|
44
57
|
}
|
|
45
|
-
|
|
58
|
+
l.value = x;
|
|
46
59
|
};
|
|
47
|
-
return
|
|
48
|
-
const
|
|
49
|
-
let
|
|
50
|
-
for (let
|
|
51
|
-
const
|
|
52
|
-
|
|
60
|
+
return i(t), { modifier: (n) => {
|
|
61
|
+
const x = n.localCenter;
|
|
62
|
+
let u = n.color.rgb, s = a(1);
|
|
63
|
+
for (let f = 0; f < c; f++) {
|
|
64
|
+
const h = f * tt, r = (dt) => m.element(h + dt), g = r(0), y = r(1), M = r(2), C = r(3), T = r(4), J = g.xyz, N = g.w, z = y.xyz, _ = y.w.max(1e-4), G = M.xyz, S = M.w, K = T.x, V = T.y, B = bt(f).lessThan(l).select(a(1), a(0)), W = x.sub(J), E = At(C, W), P = E.length().sub(z.x), k = zt(E, z), $ = Et(E, z.x, z.y), D = N.greaterThan(0.5).and(N.lessThan(1.5)).select(a(1), a(0)), j = N.greaterThan(1.5).select(a(1), a(0)), q = p(p(P, k, D), $, j), H = p(q, q.negate(), K), A = a(1).sub(F(0, _, H)).mul(V).mul(B), X = a(1).sub(F(0, _, H.abs())).mul(V).mul(B), Y = S.lessThan(0.5).select(a(1), a(0)), ct = S.greaterThan(0.5).and(S.lessThan(1.5)).select(a(1), a(0)), rt = S.greaterThan(1.5).and(S.lessThan(2.5)).select(a(1), a(0)), lt = S.greaterThan(2.5).select(a(1), a(0)), ut = u.dot(v(0.2126, 0.7152, 0.0722));
|
|
65
|
+
u = p(u, G, A.mul(Y)), u = p(u, v(ut), A.mul(ct)), u = p(u, G, X.mul(lt)), s = s.mul(a(1).sub(A.mul(rt)));
|
|
53
66
|
}
|
|
54
|
-
return { color:
|
|
55
|
-
}, setShapes:
|
|
67
|
+
return { color: U(u, n.color.a.mul(s)) };
|
|
68
|
+
}, setShapes: i, maxShapes: c, _uniforms: { slots: o, count: l } };
|
|
56
69
|
}
|
|
57
|
-
function
|
|
58
|
-
const
|
|
59
|
-
return
|
|
70
|
+
function zt(t, e) {
|
|
71
|
+
const c = t.abs().sub(e), o = c.max(v(0, 0, 0)).length(), m = c.x.max(c.y.max(c.z)).min(0);
|
|
72
|
+
return o.add(m);
|
|
60
73
|
}
|
|
61
|
-
function
|
|
62
|
-
const
|
|
63
|
-
return
|
|
74
|
+
function Et(t, e, c) {
|
|
75
|
+
const o = t.xz.length().sub(e), m = t.y.abs().sub(c), l = yt(o.max(0), m.max(0)).length(), d = o.max(m).min(0);
|
|
76
|
+
return l.add(d);
|
|
64
77
|
}
|
|
65
|
-
function
|
|
66
|
-
const
|
|
67
|
-
return
|
|
78
|
+
function At(t, e) {
|
|
79
|
+
const c = t.xyz, o = t.w, m = c.cross(e).mul(2);
|
|
80
|
+
return e.sub(m.mul(o)).add(c.cross(m));
|
|
68
81
|
}
|
|
69
|
-
function
|
|
70
|
-
const
|
|
71
|
-
return { modifier: (
|
|
72
|
-
const
|
|
73
|
-
return { color:
|
|
74
|
-
}, direction:
|
|
82
|
+
function Bt(t = {}) {
|
|
83
|
+
const e = new w.Vector3(...t.direction ?? [0.3, 1, 0.6]).normalize(), c = R(e), o = a(t.ambient ?? 0.35), m = a(t.diffuse ?? 0.75);
|
|
84
|
+
return { modifier: (d) => {
|
|
85
|
+
const i = d.normal.dot(c.normalize()).max(0), b = o.add(i.mul(m));
|
|
86
|
+
return { color: U(d.color.rgb.mul(b), d.color.a) };
|
|
87
|
+
}, direction: c };
|
|
75
88
|
}
|
|
76
|
-
function
|
|
77
|
-
const
|
|
78
|
-
return { modifier: (
|
|
79
|
-
const
|
|
80
|
-
return { scale:
|
|
81
|
-
}, focusDistance:
|
|
89
|
+
function Wt(t = {}) {
|
|
90
|
+
const e = R(Math.max(1e-4, t.focusDistance ?? 10)), c = R(Math.max(0, t.aperture ?? 0.5)), o = a(Math.max(0, t.maxBlur ?? 6));
|
|
91
|
+
return { modifier: (l) => {
|
|
92
|
+
const d = l.viewCenter.z.negate().max(1e-4), i = e.max(1e-4), b = d.sub(i).abs().div(i).mul(c).min(o), n = a(1).add(b), x = l.color.a.div(n.mul(n));
|
|
93
|
+
return { scale: l.scale.mul(n), color: U(l.color.rgb, x) };
|
|
94
|
+
}, focusDistance: e, aperture: c };
|
|
82
95
|
}
|
|
83
|
-
function
|
|
84
|
-
const
|
|
96
|
+
function $t(t = {}) {
|
|
97
|
+
const e = R(0), c = t.frequency ?? 3, o = Math.min(Math.max(t.edge ?? 0.08, 0), 0.5), m = gt(
|
|
85
98
|
/* wgsl */
|
|
86
99
|
`
|
|
87
100
|
fn vnoise( x: vec3<f32> ) -> f32 {
|
|
@@ -108,73 +121,163 @@ function Me(o = {}) {
|
|
|
108
121
|
}
|
|
109
122
|
`
|
|
110
123
|
);
|
|
111
|
-
return { modifier: (u) => {
|
|
112
|
-
const l = d({ x: u.localCenter.mul(r) }), b = l.mul(1 - 2 * t).add(t), e = X(b.sub(t), b.add(t), n), m = n.greaterThan(b.sub(t));
|
|
113
|
-
return { color: O(u.color.rgb, u.color.a.mul(e)), visible: m };
|
|
114
|
-
}, progress: n };
|
|
115
|
-
}
|
|
116
|
-
function ke(o = {}) {
|
|
117
|
-
const n = C(Math.min(1, Math.max(-1, o.intensity ?? 0))), r = C(Math.max(1e-4, o.radius ?? 1));
|
|
118
124
|
return { modifier: (d) => {
|
|
119
|
-
const
|
|
125
|
+
const i = m({ x: d.localCenter.mul(c) }), b = i.mul(1 - 2 * o).add(o), n = F(b.sub(o), b.add(o), e), x = e.greaterThan(b.sub(o));
|
|
126
|
+
return { color: U(d.color.rgb, d.color.a.mul(n)), visible: x };
|
|
127
|
+
}, progress: e };
|
|
128
|
+
}
|
|
129
|
+
function jt(t = {}) {
|
|
130
|
+
const e = R(Math.min(1, Math.max(-1, t.intensity ?? 0))), c = R(Math.max(1e-4, t.radius ?? 1));
|
|
131
|
+
return { modifier: (m) => {
|
|
132
|
+
const l = e.clamp(-1, 1), d = c.max(1e-4), i = m.viewCenter, b = l.max(0), n = l.negate().max(0), x = i.z.negate().max(0), u = x.div(d).atan().mul(a(Math.PI * 0.5)), s = u.cos(), f = u.sin(), h = f.negate(), r = v(i.x, i.y.mul(s).sub(i.z.mul(f)), i.y.mul(f).add(i.z.mul(s))), g = v(i.x, i.y.mul(s).sub(i.z.mul(h)), i.y.mul(h).add(i.z.mul(s))), y = p(p(i, r, n), g, b), M = a(Math.PI * 0.5).mul(d), C = i.z.lessThan(0).select(M.negate().div(x.mul(x).add(d.mul(d))), a(0)), T = C.negate(), J = v(1, 0, 0), N = v(0, s, f), z = v(0, f.negate().sub(r.z.mul(C)), s.add(r.y.mul(C))), _ = v(1, 0, 0), G = v(0, s, h), S = v(
|
|
120
133
|
0,
|
|
121
|
-
|
|
122
|
-
s.add(
|
|
123
|
-
),
|
|
134
|
+
h.negate().sub(g.z.mul(T)),
|
|
135
|
+
s.add(g.y.mul(T))
|
|
136
|
+
), K = v(1, 0, 0), V = v(0, 1, 0), B = v(0, 0, 1), W = p(p(K, J, n), _, b), E = p(p(V, N, n), G, b), P = p(p(B, z, n), S, b), k = W.div(W.length().max(1e-6)), $ = E.sub(k.mul(k.dot(E))), D = $.div($.length().max(1e-6)), j = P.sub(k.mul(k.dot(P))).sub(D.mul(D.dot(P))), q = j.div(j.length().max(1e-6)), H = pt(k, D, q), A = wt.toMat3(), X = A.transpose(), Y = X.mul(H).mul(A);
|
|
124
137
|
return {
|
|
125
|
-
offset:
|
|
126
|
-
rotation:
|
|
138
|
+
offset: m.offset.add(X.mul(y.sub(i))),
|
|
139
|
+
rotation: Y.mul(m.rotation)
|
|
127
140
|
};
|
|
128
|
-
}, intensity:
|
|
141
|
+
}, intensity: e, radius: c };
|
|
129
142
|
}
|
|
130
|
-
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
143
|
+
const Ft = 32, et = (t) => {
|
|
144
|
+
const e = t.intensity;
|
|
145
|
+
return Number.isFinite(e) ? Math.max(0, e) : 1;
|
|
146
|
+
}, it = (t) => {
|
|
147
|
+
const e = t.fill;
|
|
148
|
+
return Number.isFinite(e) ? Math.max(0, e) : 0;
|
|
149
|
+
}, I = (t, e, c) => {
|
|
150
|
+
const o = Mt(t, e, c);
|
|
151
|
+
return o.setGroup(vt), o;
|
|
152
|
+
}, at = (t) => {
|
|
153
|
+
const e = t;
|
|
154
|
+
if (!(e.isSpotLight === !0 || e.isPointLight === !0)) return a(1);
|
|
155
|
+
if (!(Number(e.distance) > 0)) return a(1);
|
|
156
|
+
const m = Math.max(Number(e.decay) || 1, 0.01), l = ot.distance(O(e)), d = I("distance", "float", e).max(1e-4), i = l.div(d).pow4().oneMinus().clamp().pow2();
|
|
157
|
+
return i.pow(a(m));
|
|
158
|
+
}, Nt = (t, e, c) => {
|
|
159
|
+
const o = t, m = o.isSpotLight === !0, l = o.isPointLight === !0;
|
|
160
|
+
if (!m && !l) return v(0, 0, 0);
|
|
161
|
+
const d = O(o), i = d.sub(ot), b = i.length().max(1e-4), n = i.div(b), x = Q.dot(n).max(0), u = at(t);
|
|
162
|
+
let s = u.mul(x).mul(c);
|
|
163
|
+
if (m) {
|
|
164
|
+
const h = t, r = O(h.target).sub(d).normalize(), g = I("angle", "float", h).max(1e-3), y = I("penumbra", "float", h).clamp(0, 0.95), M = g.mul(a(1).sub(y)).max(1e-3), C = F(nt(g), nt(M), n.negate().dot(r));
|
|
165
|
+
s = s.mul(C);
|
|
166
|
+
}
|
|
167
|
+
const f = I("color", "color", t);
|
|
168
|
+
return f.mul(a(e)).mul(s);
|
|
169
|
+
}, Pt = (t, e, c) => {
|
|
170
|
+
const o = t;
|
|
171
|
+
if (o.isDirectionalLight !== !0) return v(0, 0, 0);
|
|
172
|
+
const m = O(o.target).sub(O(o)).normalize(), l = Q.dot(m.negate()).max(0), d = I("color", "color", t);
|
|
173
|
+
return d.mul(a(e)).mul(l).mul(c);
|
|
174
|
+
}, Dt = (t) => {
|
|
175
|
+
const e = Array.isArray(t) ? t : [{ light: t, intensity: 1 }], c = [];
|
|
176
|
+
for (const o of e) {
|
|
177
|
+
if (c.length >= Ft) break;
|
|
178
|
+
et(o) <= 0 && it(o) <= 0 || c.push(o);
|
|
179
|
+
}
|
|
180
|
+
return c;
|
|
181
|
+
}, It = (t, e, c) => {
|
|
182
|
+
const o = Number.isFinite(e.nearRadius) ? Math.max(1, e.nearRadius) : e.midLight ? 20 : 100, m = Number.isFinite(e.midRadius) ? Math.max(o, e.midRadius) : 50, l = Number.isFinite(e.outerRadius) ? Math.max(m, e.outerRadius) : 160, d = (b, n, x) => p(b, n, F(a(x * 0.7), a(x * 0.95), c));
|
|
183
|
+
let i = L(t);
|
|
184
|
+
return e.midLight ? (i = d(i, L(e.midLight), o), e.outerLight ? (i = d(i, L(e.outerLight), m), e.farLight && (i = d(i, L(e.farLight), l))) : e.farLight && (i = d(i, L(e.farLight), m))) : e.farLight && (i = d(i, L(e.farLight), o)), i;
|
|
185
|
+
};
|
|
186
|
+
function qt(t, e = {}) {
|
|
187
|
+
const c = Number.isFinite(e.umbra) ? Math.min(1, Math.max(0, e.umbra)) : 0.45, o = Number.isFinite(e.receiveUpMin) ? Math.min(0.95, Math.max(0, e.receiveUpMin)) : 0.25, m = Number.isFinite(e.diffuse) ? Math.max(0, e.diffuse) : 0, l = new w.MeshStandardNodeMaterial();
|
|
188
|
+
l.side = w.DoubleSide, l.color = new w.Color(1, 1, 1), l.roughness = 1, l.metalness = 0, l.transparent = !1, l.depthWrite = !0, l.polygonOffset = !0, l.polygonOffsetFactor = 2, l.polygonOffsetUnits = 2;
|
|
189
|
+
const d = ot.distance(ft), i = Dt(t), b = o > 0 ? F(a(o), a(o + 0.3), Q.y) : a(1), n = (h, r) => {
|
|
190
|
+
const g = h === 0 ? It(r, e, d) : L(r);
|
|
191
|
+
return p(a(1), g, at(r));
|
|
192
|
+
}, x = i.map(
|
|
193
|
+
(h, r) => n(r, h.light)
|
|
194
|
+
);
|
|
195
|
+
let u, s = a(1);
|
|
196
|
+
if (e.combine === "min" && i.length > 0) {
|
|
197
|
+
let h = a(1);
|
|
198
|
+
for (let r = 0; r < i.length; r++) {
|
|
199
|
+
const g = i[r], y = et(g);
|
|
200
|
+
if (y <= 0) continue;
|
|
201
|
+
const M = Math.min(1, Math.max(0, 1 - y * (1 - c))), C = x[r], T = p(a(M), a(1), C);
|
|
202
|
+
h = ht(h, T);
|
|
203
|
+
}
|
|
204
|
+
s = h, u = p(a(1), h, b);
|
|
205
|
+
} else {
|
|
206
|
+
const h = i.map((r, g) => ({ index: g, intensity: et(r) })).filter(({ intensity: r }) => r > 0);
|
|
207
|
+
if (h.length === 1)
|
|
208
|
+
s = x[h[0].index];
|
|
209
|
+
else if (h.length > 1) {
|
|
210
|
+
let r = a(0), g = 0;
|
|
211
|
+
for (const { index: y, intensity: M } of h) {
|
|
212
|
+
g += M;
|
|
213
|
+
const C = x[y];
|
|
214
|
+
r = r.add(a(M).mul(C));
|
|
215
|
+
}
|
|
216
|
+
s = r.div(a(g));
|
|
217
|
+
}
|
|
218
|
+
if (h.length > 0) {
|
|
219
|
+
const r = p(a(1), s, b);
|
|
220
|
+
u = p(a(c), a(1), r);
|
|
221
|
+
} else
|
|
222
|
+
u = a(1);
|
|
223
|
+
}
|
|
224
|
+
let f = v(0, 0, 0);
|
|
225
|
+
if (m > 0) {
|
|
226
|
+
const h = R(e.color ?? new w.Color(1, 1, 1)), r = R(e.direction ?? new w.Vector3(0, 1, 0)), g = Q.dot(r.normalize()).max(0);
|
|
227
|
+
f = h.mul(g).mul(a(m)).mul(b).mul(s);
|
|
228
|
+
}
|
|
229
|
+
for (let h = 0; h < i.length; h++) {
|
|
230
|
+
const r = i[h], g = it(r);
|
|
231
|
+
if (g <= 0) continue;
|
|
232
|
+
const y = r.light, M = x[h], C = Nt(y, g, M), T = Pt(y, g, M);
|
|
233
|
+
f = f.add(C).add(T);
|
|
234
|
+
}
|
|
235
|
+
return l.outputNode = U(v(u).add(f), a(1)), l;
|
|
135
236
|
}
|
|
136
|
-
function
|
|
137
|
-
const
|
|
138
|
-
return
|
|
237
|
+
function Ot(t) {
|
|
238
|
+
const e = new w.BufferGeometry();
|
|
239
|
+
return e.setAttribute("position", new w.BufferAttribute(t.positions.slice(), 3)), e.setIndex(new w.BufferAttribute(t.indices.slice(), 1)), e;
|
|
139
240
|
}
|
|
140
|
-
function
|
|
141
|
-
const
|
|
142
|
-
color: new
|
|
241
|
+
function Ht(t = {}) {
|
|
242
|
+
const e = t.albedo ?? 0.5, c = new w.Group(), o = t.matrixWorld ?? null, m = [], l = new w.MeshStandardMaterial({
|
|
243
|
+
color: new w.Color(e, e, e),
|
|
143
244
|
roughness: 1,
|
|
144
245
|
metalness: 0,
|
|
145
|
-
side:
|
|
146
|
-
}),
|
|
147
|
-
|
|
148
|
-
},
|
|
149
|
-
let
|
|
150
|
-
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
},
|
|
246
|
+
side: w.DoubleSide
|
|
247
|
+
}), d = (n) => {
|
|
248
|
+
o && n.applyMatrix4(o);
|
|
249
|
+
}, i = (n, x) => {
|
|
250
|
+
let u = n, s = x;
|
|
251
|
+
o && !x && (u = n.clone(), s = !0), d(u), u.computeVertexNormals(), s && m.push(u);
|
|
252
|
+
const f = new w.Mesh(u, l);
|
|
253
|
+
f.castShadow = !0, f.receiveShadow = !0, f.raycast = () => {
|
|
254
|
+
}, c.add(f);
|
|
154
255
|
};
|
|
155
|
-
for (const
|
|
156
|
-
|
|
157
|
-
for (const
|
|
158
|
-
|
|
256
|
+
for (const n of t.tiles ?? [])
|
|
257
|
+
i(Ot(n.data), !0);
|
|
258
|
+
for (const n of t.geometries ?? [])
|
|
259
|
+
i(n, !1);
|
|
159
260
|
return {
|
|
160
|
-
group:
|
|
161
|
-
configureMaterial: (
|
|
162
|
-
|
|
261
|
+
group: c,
|
|
262
|
+
configureMaterial: (n) => {
|
|
263
|
+
n.side = w.DoubleSide, n.transparent = !1, n.opacity = 1, "color" in n && n.color instanceof w.Color && n.color.setRGB(e, e, e), "roughness" in n && typeof n.roughness == "number" && (n.roughness = 1), "metalness" in n && typeof n.metalness == "number" && (n.metalness = 0);
|
|
163
264
|
},
|
|
164
265
|
dispose: () => {
|
|
165
|
-
|
|
166
|
-
for (const
|
|
167
|
-
|
|
266
|
+
l.dispose();
|
|
267
|
+
for (const n of m) n.dispose();
|
|
268
|
+
c.clear();
|
|
168
269
|
}
|
|
169
270
|
};
|
|
170
271
|
}
|
|
171
272
|
export {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
273
|
+
Ft as MAX_RELIGHTING_SHADOW_LIGHTS,
|
|
274
|
+
Ht as createRelightingProxy,
|
|
275
|
+
qt as createRelightingShadowFactorMaterial,
|
|
276
|
+
Wt as depthOfFieldPreset,
|
|
277
|
+
Bt as lightingPreset,
|
|
278
|
+
Gt as renderRelightingFactorMap,
|
|
279
|
+
$t as revealPreset,
|
|
280
|
+
Vt as sdfEffects,
|
|
281
|
+
jt as worldWarpPreset
|
|
179
282
|
};
|
|
180
283
|
//# sourceMappingURL=effects.js.map
|