@driftengine/core 4.13.6 → 4.14.0
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/CHANGELOG.json +51 -0
- package/README.md +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/render/backend/api.d.ts +19 -3
- package/dist/render/backend/webgl2/motionTarget.d.ts +39 -0
- package/dist/render/backend/webgl2/motionTarget.js +254 -0
- package/dist/render/backend/webgl2/pointSkinFeedback.d.ts +13 -3
- package/dist/render/backend/webgl2/pointSkinFeedback.js +45 -12
- package/dist/render/backend/webgl2/renderer.d.ts +101 -7
- package/dist/render/backend/webgl2/renderer.js +337 -9
- package/dist/render/backend/webgpu/pointSkinPass.d.ts +16 -3
- package/dist/render/backend/webgpu/pointSkinPass.js +79 -21
- package/dist/render/backend/webgpu/postPass.d.ts +6 -1
- package/dist/render/backend/webgpu/renderer.d.ts +41 -0
- package/dist/render/backend/webgpu/renderer.js +143 -5
- package/dist/render/baseDecals.d.ts +48 -0
- package/dist/render/baseDecals.js +71 -0
- package/dist/render/emissiveFlow.d.ts +40 -0
- package/dist/render/emissiveFlow.js +51 -0
- package/dist/render/fixtureAtlas.d.ts +8 -3
- package/dist/render/fixtureAtlas.js +17 -6
- package/dist/render/globalMedium.d.ts +17 -0
- package/dist/render/globalMedium.js +14 -0
- package/dist/render/globalMediumPass.js +3 -2
- package/dist/render/iridescentOverlay.d.ts +78 -0
- package/dist/render/iridescentOverlay.js +102 -0
- package/dist/render/mesh.d.ts +24 -0
- package/dist/render/mesh.js +79 -0
- package/dist/render/pointSkin.d.ts +18 -0
- package/dist/render/pointSkin.js +50 -5
- package/dist/render/recon/mover.d.ts +3 -2
- package/dist/render/recon/mover.js +3 -2
- package/dist/render/sceneTarget.d.ts +2 -0
- package/dist/render/sceneTarget.js +1 -1
- package/dist/render/shaders/flat/baseDecals.d.ts +17 -0
- package/dist/render/shaders/flat/baseDecals.js +71 -0
- package/dist/render/shaders/flat/emissiveFlow.d.ts +15 -0
- package/dist/render/shaders/flat/emissiveFlow.js +45 -0
- package/dist/render/shaders/flat/glassTint.d.ts +1 -1
- package/dist/render/shaders/flat/glassTint.js +3 -0
- package/dist/render/shaders/flat/index.d.ts +16 -0
- package/dist/render/shaders/flat/index.js +9 -0
- package/dist/render/shaders/flat/iridescentOverlay.d.ts +15 -0
- package/dist/render/shaders/flat/iridescentOverlay.js +65 -0
- package/dist/render/shaders/flat/layered.js +4 -4
- package/dist/render/shaders/flat/main.d.ts +1 -1
- package/dist/render/shaders/flat/main.js +12 -1
- package/dist/render/shaders/flat/mapReads.d.ts +1 -1
- package/dist/render/shaders/flat/mapReads.js +7 -3
- package/dist/render/shaders/flat/worldUv.js +6 -5
- package/dist/render/shaders/generated/flat.wgsl.d.ts +480 -16
- package/dist/render/shaders/generated/flat.wgsl.js +519 -55
- package/dist/render/shaders/generated/temporalResolve.wgsl.d.ts +15 -5
- package/dist/render/shaders/generated/temporalResolve.wgsl.js +15 -5
- package/dist/render/shaders/temporalResolve.js +25 -9
- package/dist/render/surfaceTexture.d.ts +32 -0
- package/dist/render/temporalPass.d.ts +3 -1
- package/dist/render/temporalPass.js +9 -1
- package/package.json +6 -6
- package/src/index.ts +3 -0
- package/src/render/backend/api.ts +19 -2
- package/src/render/backend/webgl2/motionTarget.ts +299 -0
- package/src/render/backend/webgl2/pointSkinFeedback.ts +49 -14
- package/src/render/backend/webgl2/renderer.ts +411 -9
- package/src/render/backend/webgpu/pointSkinPass.ts +90 -23
- package/src/render/backend/webgpu/renderer.ts +163 -3
- package/src/render/baseDecals.ts +93 -0
- package/src/render/emissiveFlow.ts +66 -0
- package/src/render/fixtureAtlas.ts +26 -7
- package/src/render/globalMedium.ts +31 -0
- package/src/render/globalMediumPass.ts +3 -7
- package/src/render/iridescentOverlay.ts +177 -0
- package/src/render/mesh.ts +82 -0
- package/src/render/pointSkin.ts +64 -5
- package/src/render/recon/mover.ts +3 -2
- package/src/render/sceneTarget.ts +3 -0
- package/src/render/shaders/flat/baseDecals.ts +71 -0
- package/src/render/shaders/flat/emissiveFlow.ts +45 -0
- package/src/render/shaders/flat/glassTint.ts +7 -1
- package/src/render/shaders/flat/index.ts +25 -0
- package/src/render/shaders/flat/iridescentOverlay.ts +65 -0
- package/src/render/shaders/flat/layered.ts +4 -4
- package/src/render/shaders/flat/main.ts +12 -1
- package/src/render/shaders/flat/mapReads.ts +7 -3
- package/src/render/shaders/flat/worldUv.ts +6 -5
- package/src/render/shaders/generated/flat.wgsl.ts +519 -55
- package/src/render/shaders/generated/temporalResolve.wgsl.ts +15 -5
- package/src/render/shaders/temporalResolve.ts +25 -9
- package/src/render/surfaceTexture.ts +32 -0
- package/src/render/temporalPass.ts +8 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A surface's iridescent overlay on its base colour, before it is lit:
|
|
3
|
+
* `SurfaceMaterial.iridescentOverlay`, packed into `uIridescence` by `iridescentOverlay.ts`, whose
|
|
4
|
+
* `iridescentBase` is this arithmetic on the CPU and says what each term is and what it gives up.
|
|
5
|
+
*
|
|
6
|
+
* **Called once the normal is mapped and turned to the viewer**, so the view term reads the surface
|
|
7
|
+
* a pixel shows, and before any light is added, so the lights below read the colour it makes. The
|
|
8
|
+
* mask is read in uniform control flow, under the lighting branch and this switch's, so its implicit
|
|
9
|
+
* level is legal: AGENTS.md 2026-08-07.
|
|
10
|
+
*
|
|
11
|
+
* **A lit switch, `IRIDESCENT_OVERLAY`**, off until a material first asks, declared after
|
|
12
|
+
* `EMISSIVE_FLOW` so each switch before it keeps its id. Compiled out, its thirty-six vectors are
|
|
13
|
+
* not declared and the call is a constant.
|
|
14
|
+
*/
|
|
15
|
+
export function iridescentOverlayGlsl(on: boolean): string {
|
|
16
|
+
if (!on) {
|
|
17
|
+
return /* glsl */ `
|
|
18
|
+
const bool IRIDESCENT_OVERLAY = false; // wgsl:override
|
|
19
|
+
bool iridescent() { return false; }
|
|
20
|
+
vec3 iridescentBase(vec3 base, vec3 n, vec2 uv) { return base; }
|
|
21
|
+
`;
|
|
22
|
+
}
|
|
23
|
+
return /* glsl */ `
|
|
24
|
+
/* Whether this program lays an iridescent overlay. Off but where a material has asked. */
|
|
25
|
+
const bool IRIDESCENT_OVERLAY = true; // wgsl:override
|
|
26
|
+
/*
|
|
27
|
+
* Thirty-six vectors, as iridescentOverlay.ts packs them: the direction toward the sheen and the
|
|
28
|
+
* blend (0); the contrast, the tiling, the weight and 1 for on (1); the mask's array, 0 none, 1 ORM,
|
|
29
|
+
* 2 model, 3 albedo, 4 emissive, its layer and its channel (2); what takes the material's
|
|
30
|
+
* coordinates back to the mesh's own (3); then the ramp, thirty-two colours.
|
|
31
|
+
*/
|
|
32
|
+
uniform vec4 uIridescence[36]; // wgsl:material
|
|
33
|
+
|
|
34
|
+
bool iridescent() { return uIridescence[1].w > 0.5; }
|
|
35
|
+
|
|
36
|
+
/* The mask's channel at the material's coordinates; 1 where it names no array. */
|
|
37
|
+
float iridescentMask(vec2 uv) {
|
|
38
|
+
float source = uIridescence[2].x;
|
|
39
|
+
if (source < 0.5) return 1.0;
|
|
40
|
+
vec3 at = vec3(uv, uIridescence[2].y);
|
|
41
|
+
vec4 texel = source < 1.5 ? texture(uOrmMap, at)
|
|
42
|
+
: source < 2.5 ? texture(uModelMap, at)
|
|
43
|
+
: source < 3.5 ? texture(uAlbedo, at)
|
|
44
|
+
: texture(uEmissiveMap, at);
|
|
45
|
+
return texel[int(uIridescence[2].z + 0.5)];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
vec3 iridescentBase(vec3 base, vec3 n, vec2 uv) {
|
|
49
|
+
vec3 toEye = normalize(uCameraPos - vWorldPos);
|
|
50
|
+
vec3 halfway = toEye + uIridescence[0].xyz;
|
|
51
|
+
float span = length(halfway);
|
|
52
|
+
float nh = span > 0.0 ? dot(n, halfway / span) : 0.0;
|
|
53
|
+
float sheen = nh > 0.0 ? clamp(pow(nh, uIridescence[1].x), 0.0, 1.0) : 0.0;
|
|
54
|
+
float nv = dot(n, toEye);
|
|
55
|
+
vec2 own = vUv.xy * uIridescence[3].xy + uIridescence[3].zw;
|
|
56
|
+
float x = nv + own.x + uIridescence[0].w * (sheen - nv);
|
|
57
|
+
float t = clamp(fract(x * uIridescence[1].y), 0.0, 1.0);
|
|
58
|
+
float at = t * 31.0;
|
|
59
|
+
int below = min(int(floor(at)), 30);
|
|
60
|
+
vec3 o = mix(uIridescence[4 + below].rgb, uIridescence[5 + below].rgb, at - float(below));
|
|
61
|
+
vec3 blended = mix(2.0 * base * o, 1.0 - 2.0 * (1.0 - base) * (1.0 - o), step(0.5, base));
|
|
62
|
+
return base + (blended - base) * (x * iridescentMask(uv) * uIridescence[1].z);
|
|
63
|
+
}
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
@@ -41,7 +41,7 @@ vec3 layeredTexel() { return vec3(0.0, 0.0, 1.0); }
|
|
|
41
41
|
bool layeredMeshNormal() { return false; }
|
|
42
42
|
vec3 layeredMeshTexel() { return vec3(0.0, 0.0, 1.0); }
|
|
43
43
|
bool layeredGlows() { return false; }
|
|
44
|
-
vec3 layeredEmissive() { return vec3(0.0); }
|
|
44
|
+
vec3 layeredEmissive(vec2 shift) { return vec3(0.0); }
|
|
45
45
|
float layeredAmbient() { return 1.0; }
|
|
46
46
|
float layeredSpecular(float own) { return own; }
|
|
47
47
|
`;
|
|
@@ -254,10 +254,10 @@ bool layeredGlows() {
|
|
|
254
254
|
return uLayers[1].z > -0.5;
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
/* The emissive map at its layer's place, glowing by that layer's share. */
|
|
258
|
-
vec3 layeredEmissive() {
|
|
257
|
+
/* The emissive map at its layer's place, moved by its scroll, glowing by that layer's share. */
|
|
258
|
+
vec3 layeredEmissive(vec2 shift) {
|
|
259
259
|
int glow = int(uLayers[1].z + 0.5);
|
|
260
|
-
return texture(uEmissiveMap, layerAt(glow)).rgb * layerShare(glow);
|
|
260
|
+
return texture(uEmissiveMap, layerAt(glow) + vec3(shift, 0.0)).rgb * layerShare(glow);
|
|
261
261
|
}
|
|
262
262
|
`;
|
|
263
263
|
}
|
|
@@ -399,6 +399,8 @@ export const MAIN_GLSL = `void main() {
|
|
|
399
399
|
if (backFace) n = -n;
|
|
400
400
|
/* A blending rim, on the base colour every light below reads: overlay.ts. */
|
|
401
401
|
if (SURFACE_OVERLAY) albedo = overlayRimBase(albedo, surfaceAt.xy, n);
|
|
402
|
+
/* And a view-turned hue over it, before any light reads it: iridescentOverlay.ts. */
|
|
403
|
+
if (IRIDESCENT_OVERLAY && iridescent()) albedo = iridescentBase(albedo, n, surfaceAt.xy);
|
|
402
404
|
/*
|
|
403
405
|
* A model's surface, gathered once, on a branch on the switches alone (models.ts) — and whether
|
|
404
406
|
* there is one, asked once: every site below is a branch on these two, which a pipeline with no
|
|
@@ -407,6 +409,13 @@ export const MAIN_GLSL = `void main() {
|
|
|
407
409
|
bool modelled = modelOn();
|
|
408
410
|
bool modelledBehind = modelSeesBehind();
|
|
409
411
|
if (modelled) modelSurface(n, albedo, surfaceRoughness, metal, surfaceAt);
|
|
412
|
+
/*
|
|
413
|
+
* The frame's decals laid into the colour light falls on, by the geometric normal, after the
|
|
414
|
+
* model has made its own (baseDecals.ts). The colour a glow takes where the mesh names none is
|
|
415
|
+
* kept from before them: a decal marks what the surface is lit as and leaves what it emits.
|
|
416
|
+
*/
|
|
417
|
+
vec3 glowBase = albedo;
|
|
418
|
+
if (BASE_DECALS) albedo = baseDecals(albedo, vWorldPos, normalize(vNormal));
|
|
410
419
|
/*
|
|
411
420
|
* Skin's colour half leaves here, with the colour its spread light is multiplied by, and a whole
|
|
412
421
|
* alpha a multisampled edge resolves to its coverage. A branch on the switches alone, so uniform.
|
|
@@ -1988,7 +1997,7 @@ export const MAIN_GLSL = `void main() {
|
|
|
1988
1997
|
lit += through * glassGlow * (thin * (1.0 - metal));
|
|
1989
1998
|
}
|
|
1990
1999
|
diffuseAlone = lit;
|
|
1991
|
-
vec3 emissiveTint = vEmissiveColor.r < 0.0 ?
|
|
2000
|
+
vec3 emissiveTint = vEmissiveColor.r < 0.0 ? glowBase : vEmissiveColor;
|
|
1992
2001
|
/*
|
|
1993
2002
|
* Where the surface glows, from an image, or everywhere if it binds none.
|
|
1994
2003
|
*
|
|
@@ -2008,6 +2017,8 @@ export const MAIN_GLSL = `void main() {
|
|
|
2008
2017
|
vec3 emissiveMapped = vec3(1.0);
|
|
2009
2018
|
if (uMaterialFlags.z != 0) {
|
|
2010
2019
|
emissiveMapped = emissiveTexel(surfaceAt) * uEmissiveScale;
|
|
2020
|
+
/* Held to where the mask keeps it, at the mesh's own coordinates: emissiveFlow.ts. */
|
|
2021
|
+
if (EMISSIVE_FLOW) emissiveMapped *= emissiveMask();
|
|
2011
2022
|
}
|
|
2012
2023
|
/* Pulse, flicker and fade from the layer's effects; exactly 1 where it names none. */
|
|
2013
2024
|
float fxGlow = fx4.z + fx5.x + fx5.w > 0.0 ? fxEmission(surfaceAt.z) : 1.0;
|
|
@@ -30,9 +30,13 @@ vec3 ormTexel(vec3 at) {
|
|
|
30
30
|
return texture(uOrmMap, at).rgb;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/* The emissive map, moved by its scroll wherever it is read: emissiveFlow.ts. Behind its switch,
|
|
34
|
+
which a WebGPU pipeline built before a material asked has off, so the mask and the scroll come
|
|
35
|
+
on together rather than the scroll a few frames ahead. */
|
|
33
36
|
vec3 emissiveTexel(vec3 at) {
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
return
|
|
37
|
+
vec2 shift = EMISSIVE_FLOW ? emissiveShift() : vec2(0.0);
|
|
38
|
+
if (LAYERED && layered() && layeredGlows()) return layeredEmissive(shift);
|
|
39
|
+
if (WORLD_UVS && triplanar()) return triplanarEmissive(at.z, shift);
|
|
40
|
+
return texture(uEmissiveMap, vec3(at.xy + shift, at.z)).rgb;
|
|
37
41
|
}
|
|
38
42
|
`;
|
|
@@ -28,7 +28,7 @@ bool triplanar() { return false; }
|
|
|
28
28
|
vec2 planarAt() { return vec2(0.0); }
|
|
29
29
|
vec4 triplanarAlbedo(float layer) { return vec4(0.0); }
|
|
30
30
|
vec3 triplanarOrm(float layer) { return vec3(0.0); }
|
|
31
|
-
vec3 triplanarEmissive(float layer) { return vec3(0.0); }
|
|
31
|
+
vec3 triplanarEmissive(float layer, vec2 shift) { return vec3(0.0); }
|
|
32
32
|
vec3 triplanarNormal(vec3 n, float layer) { return n; }
|
|
33
33
|
`;
|
|
34
34
|
}
|
|
@@ -76,12 +76,13 @@ vec3 triplanarOrm(float layer) {
|
|
|
76
76
|
texture(uOrmMap, vec3(p.xz, layer)).rgb * w.y + texture(uOrmMap, vec3(p.xy, layer)).rgb * w.z;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
/* The emissive map on the three planes, each moved by the scroll: emissiveFlow.ts. */
|
|
80
|
+
vec3 triplanarEmissive(float layer, vec2 shift) {
|
|
80
81
|
vec3 w = triplanarWeights();
|
|
81
82
|
vec3 p = vWorldPos * uWorldUv.y;
|
|
82
|
-
return texture(uEmissiveMap, vec3(p.zy, layer)).rgb * w.x +
|
|
83
|
-
texture(uEmissiveMap, vec3(p.xz, layer)).rgb * w.y +
|
|
84
|
-
texture(uEmissiveMap, vec3(p.xy, layer)).rgb * w.z;
|
|
83
|
+
return texture(uEmissiveMap, vec3(p.zy + shift, layer)).rgb * w.x +
|
|
84
|
+
texture(uEmissiveMap, vec3(p.xz + shift, layer)).rgb * w.y +
|
|
85
|
+
texture(uEmissiveMap, vec3(p.xy + shift, layer)).rgb * w.z;
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
/* A tangent-space normal off the map, its z rebuilt where a two-channel map stored none. */
|