reze-engine 0.68.8 → 0.68.9
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/dist/engine.d.ts +2 -6
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +39 -41
- package/dist/graph/presets/pool_floor.d.ts +3 -0
- package/dist/graph/presets/pool_floor.d.ts.map +1 -0
- package/dist/graph/presets/pool_floor.js +42 -0
- package/dist/graph/presets/water.d.ts +3 -0
- package/dist/graph/presets/water.d.ts.map +1 -0
- package/dist/graph/presets/water.js +31 -0
- package/dist/graph/slots.d.ts.map +1 -1
- package/dist/graph/slots.js +5 -4
- package/dist/jelly-eyes.d.ts.map +1 -1
- package/dist/jelly-eyes.js +43 -17
- package/dist/physics/autofit.d.ts +147 -0
- package/dist/physics/autofit.d.ts.map +1 -0
- package/dist/physics/autofit.js +501 -0
- package/dist/shaders/agx-lut.d.ts +11 -0
- package/dist/shaders/agx-lut.d.ts.map +1 -0
- package/dist/shaders/agx-lut.js +29 -0
- package/dist/shaders/dfg_lut.d.ts +3 -0
- package/dist/shaders/dfg_lut.d.ts.map +1 -0
- package/dist/shaders/dfg_lut.js +129 -0
- package/dist/shaders/ltc_mag_lut.d.ts +3 -0
- package/dist/shaders/ltc_mag_lut.d.ts.map +1 -0
- package/dist/shaders/ltc_mag_lut.js +1033 -0
- package/dist/shaders/materials/common.d.ts +6 -0
- package/dist/shaders/materials/common.d.ts.map +1 -1
- package/dist/shaders/materials/common.js +67 -60
- package/dist/shaders/passes/depth-prepass.d.ts.map +1 -1
- package/dist/shaders/passes/depth-prepass.js +11 -3
- package/dist/shaders/passes/field-blit.d.ts +26 -0
- package/dist/shaders/passes/field-blit.d.ts.map +1 -0
- package/dist/shaders/passes/field-blit.js +65 -0
- package/dist/shaders/passes/ghosts.d.ts +22 -0
- package/dist/shaders/passes/ghosts.d.ts.map +1 -0
- package/dist/shaders/passes/ghosts.js +75 -0
- package/dist/shaders/passes/ground-noise.d.ts +7 -0
- package/dist/shaders/passes/ground-noise.d.ts.map +1 -0
- package/dist/shaders/passes/ground-noise.js +88 -0
- package/dist/shaders/passes/shadow.d.ts +1 -1
- package/dist/shaders/passes/shadow.d.ts.map +1 -1
- package/dist/shaders/passes/shadow.js +11 -3
- package/dist/shaders/passes/sim.d.ts +34 -0
- package/dist/shaders/passes/sim.d.ts.map +1 -0
- package/dist/shaders/passes/sim.js +169 -0
- package/dist/shaders/score-api.d.ts +10 -0
- package/dist/shaders/score-api.d.ts.map +1 -0
- package/dist/shaders/score-api.js +114 -0
- package/dist/shaders/shadow-api.d.ts +29 -0
- package/dist/shaders/shadow-api.d.ts.map +1 -0
- package/dist/shaders/shadow-api.js +112 -0
- package/package.json +1 -1
- package/src/engine.ts +39 -47
- package/src/graph/slots.ts +5 -4
- package/src/jelly-eyes.ts +41 -17
- package/src/shaders/materials/common.ts +68 -60
- package/src/shaders/passes/depth-prepass.ts +11 -3
- package/src/shaders/passes/shadow.ts +11 -3
- package/dist/_dbg-loader.mjs +0 -1100
package/src/graph/slots.ts
CHANGED
|
@@ -102,13 +102,14 @@ function prelude(renderClass: RenderClass, alphaMode: AlphaMode, blend: StyleBle
|
|
|
102
102
|
// camera-averted fragments change (front surfaces have dot(n,v) > 0 and are
|
|
103
103
|
// untouched), unlike a front_facing test, which PMX's clockwise winding
|
|
104
104
|
// inverts. Fixes inner skirt linings (裙子白1-style flipped-normal copies)
|
|
105
|
-
// shading near-black through sheer outer layers. Eye is exempt:
|
|
106
|
-
//
|
|
105
|
+
// shading near-black through sheer outer layers. Eye is exempt: its normals
|
|
106
|
+
// shade as authored.
|
|
107
107
|
const flip =
|
|
108
108
|
renderClass === "eye" ? "" : "\n n = select(-n, n, dot(n, v) >= 0.0);"
|
|
109
109
|
return `@fragment fn fs(input: VertexOutput) -> FSOut {
|
|
110
|
-
${PLAIN_SAMPLE} // MMD alpha semantics: material alpha × texture alpha
|
|
111
|
-
|
|
110
|
+
${PLAIN_SAMPLE} // MMD alpha semantics: material alpha × texture alpha, capped at 1 as MMD
|
|
111
|
+
// does (a PMX can author alpha above 1; blended, it burns the material white).
|
|
112
|
+
let alpha = saturate(material.alpha * tex_s.a);
|
|
112
113
|
${discard}
|
|
113
114
|
|
|
114
115
|
// ── Dissolve ──
|
package/src/jelly-eyes.ts
CHANGED
|
@@ -90,23 +90,23 @@ const HL_SCALE_MIN = 0.85
|
|
|
90
90
|
const HL_SCALE_MAX = 1.2
|
|
91
91
|
// The roll: while a closing expression holds, the iris turns about its eye
|
|
92
92
|
// bone's X axis (左目/右目, the eyeball's centre), rolling down with the lid —
|
|
93
|
-
// the angle at weight 1, and simultaneous expressions add.
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
// exactly, which the lid hides; here the roll follows on a spring
|
|
97
|
-
// pace
|
|
98
|
-
//
|
|
93
|
+
// the angle at weight 1, and simultaneous expressions add. It comes forward
|
|
94
|
+
// only with the spring (iris radii): pushed with the expression as well, a
|
|
95
|
+
// shut eye's iris came through a lid set close in front of it (白里黑子). The MME rolls with the lid
|
|
96
|
+
// exactly, which the lid hides; here the roll follows on a spring twice the
|
|
97
|
+
// blink's pace with its decay, so as the eye opens the iris swings up past rest
|
|
98
|
+
// and wobbles back, where it can be seen. At the blink's own pace it trailed
|
|
99
|
+
// the opening lid and swung a third of an iris past centre: a jump.
|
|
99
100
|
const ROLL: Record<string, number> = {
|
|
100
101
|
まばたき: -15, blink: -15, Blink: -15, eye_close: -15, Fcl_EYE_Close: -15, はぅ: -15, 笑い: -5,
|
|
101
102
|
ウィンク: -5, ウィンク: -5, wink: -5, Wink: -5, ウィンク2: -15, ウィンク2: -15, blink_L: -15, Fcl_EYE_Close_L: -15,
|
|
102
103
|
ウィンク右: -5, ウィンク右: -5, wink_R: -5, Wink_R: -5, ウィンク2右: -15, ウィンク2右: -15, blink_R: -15, Fcl_EYE_Close_R: -15,
|
|
103
104
|
}
|
|
104
|
-
const ROLL_HZ =
|
|
105
|
-
const ROLL_ZETA = Math.LN2 / HALF_LIFE / (2 * Math.PI *
|
|
106
|
-
// How much of the spring's swing about the expression angle shows:
|
|
107
|
-
// of
|
|
108
|
-
const ROLL_SWING = 0.
|
|
109
|
-
const PUSH_EXPRESSION = 0.15
|
|
105
|
+
const ROLL_HZ = 6
|
|
106
|
+
const ROLL_ZETA = Math.LN2 / HALF_LIFE / (2 * Math.PI * ROLL_HZ)
|
|
107
|
+
// How much of the spring's swing about the expression angle shows: a
|
|
108
|
+
// twenty-fifth of an iris radius past centre after a blink.
|
|
109
|
+
const ROLL_SWING = 0.25
|
|
110
110
|
const PUSH_ELASTIC = 0.04
|
|
111
111
|
// A highlight sheet by name, for rigs that keep it on its own material.
|
|
112
112
|
const HIGHLIGHT = /ハイライト|ハイライト|高光|highlight|hilight|(^|[^a-z])hl([^a-z]|$)/i
|
|
@@ -288,10 +288,23 @@ export class JellyEyes {
|
|
|
288
288
|
const l = index("左目")
|
|
289
289
|
const r = index("右目")
|
|
290
290
|
this.headBone = index("頭")
|
|
291
|
-
const
|
|
292
|
-
const
|
|
291
|
+
const all = model.getMorphing().morphs
|
|
292
|
+
const names = all.map((m) => m.name)
|
|
293
|
+
// The weights read are resolved, so a group whose every target is named
|
|
294
|
+
// (Reze's まばたき is ウィンク2 + ウィンク2右) arrives through its
|
|
295
|
+
// leaves; counted as well, a blink rolled the iris twice as far.
|
|
296
|
+
const known = new Set([...BOTH, ...LEFT, ...RIGHT])
|
|
297
|
+
const resolved = (i: number) => {
|
|
298
|
+
const refs = all[i].groupReferences
|
|
299
|
+
return !!refs?.length && refs.every((r) => known.has(names[r.morphIndex]))
|
|
300
|
+
}
|
|
301
|
+
const morphIndex = (n: string) => {
|
|
302
|
+
const i = names.indexOf(n)
|
|
303
|
+
return i >= 0 && !resolved(i) ? i : -1
|
|
304
|
+
}
|
|
305
|
+
const find = (list: string[]) => list.map(morphIndex).filter((i) => i >= 0)
|
|
293
306
|
this.morphs = [find(BOTH), find(LEFT), find(RIGHT)]
|
|
294
|
-
const rolls = (list: string[]) => list.map((n) => ({ morph:
|
|
307
|
+
const rolls = (list: string[]) => list.map((n) => ({ morph: morphIndex(n), deg: ROLL[n] ?? 0 })).filter((r) => r.morph >= 0 && r.deg !== 0)
|
|
295
308
|
this.rolls = [rolls([...BOTH, ...LEFT]), rolls([...BOTH, ...RIGHT])]
|
|
296
309
|
this.rest = findIrises(model, l, r, both)
|
|
297
310
|
// The bone that carries each iris, which may be under the eye bone.
|
|
@@ -423,7 +436,7 @@ export class JellyEyes {
|
|
|
423
436
|
const pivot = rest.pivot
|
|
424
437
|
o.set(pivot ? [pivot[0], pivot[1], pivot[2], (this.roll[e] + (s.roll - this.roll[e]) * ROLL_SWING) * DEG * g] : [0, 0, 0, 0], 80 + e * 4)
|
|
425
438
|
const hs = (k: 0 | 1) => Math.max(HL_SCALE_MIN, Math.min(HL_SCALE_MAX, 1 + x * HL_SCALE[k] * g))
|
|
426
|
-
o.set([hs(0), hs(1),
|
|
439
|
+
o.set([hs(0), hs(1), Math.min(Math.abs(x), SPRING_LIMIT) * PUSH_ELASTIC * r * g, 0], 88 + e * 4)
|
|
427
440
|
}
|
|
428
441
|
}
|
|
429
442
|
|
|
@@ -550,6 +563,11 @@ function blink(s: EyeState, dt: number): void {
|
|
|
550
563
|
* As draw ids (1-based over the materials that draw, as the engine numbers
|
|
551
564
|
* MaterialUniforms.materialId), at most two. A rig whose highlight is painted
|
|
552
565
|
* into the iris has none, and only the iris moves.
|
|
566
|
+
*
|
|
567
|
+
* A layer drawn on vertices an earlier layer already uses is a copy of that
|
|
568
|
+
* layer (白里黑子's ☆ and ❤ are star and heart irises on the iris's own
|
|
569
|
+
* vertices), so it moves with it. Slid as a highlight, a copy of the dome sits
|
|
570
|
+
* in front of the iris on one half, flipping sides with the tremble.
|
|
553
571
|
*/
|
|
554
572
|
function findHighlights(model: Model, rest: [EyeRest, EyeRest]): number[] {
|
|
555
573
|
const materials = model.getMaterials?.() ?? []
|
|
@@ -557,6 +575,7 @@ function findHighlights(model: Model, rest: [EyeRest, EyeRest]): number[] {
|
|
|
557
575
|
const iris = new Set([...rest[0].verts, ...rest[1].verts])
|
|
558
576
|
if (!materials.length || !indices.length || !iris.size) return []
|
|
559
577
|
const layers: { id: number; name: string; minX: number; maxX: number; minY: number; maxY: number }[] = []
|
|
578
|
+
const used = new Set<number>()
|
|
560
579
|
let start = 0
|
|
561
580
|
let id = 0
|
|
562
581
|
for (const m of materials) {
|
|
@@ -564,16 +583,21 @@ function findHighlights(model: Model, rest: [EyeRest, EyeRest]): number[] {
|
|
|
564
583
|
if (count === 0) continue
|
|
565
584
|
id++
|
|
566
585
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity
|
|
586
|
+
let copy = true
|
|
587
|
+
const mine: number[] = []
|
|
567
588
|
for (let k = start; k < start + count; k++) {
|
|
568
589
|
const v = indices[k]
|
|
569
590
|
if (!iris.has(v)) continue
|
|
591
|
+
if (!used.has(v)) copy = false
|
|
592
|
+
mine.push(v)
|
|
570
593
|
minX = Math.min(minX, positions[v * 3])
|
|
571
594
|
maxX = Math.max(maxX, positions[v * 3])
|
|
572
595
|
minY = Math.min(minY, positions[v * 3 + 1])
|
|
573
596
|
maxY = Math.max(maxY, positions[v * 3 + 1])
|
|
574
597
|
}
|
|
575
598
|
start += count
|
|
576
|
-
|
|
599
|
+
for (const v of mine) used.add(v)
|
|
600
|
+
if (minX <= maxX && !copy) layers.push({ id, name: m.name, minX, maxX, minY, maxY })
|
|
577
601
|
}
|
|
578
602
|
const out: number[] = []
|
|
579
603
|
layers.forEach((l, i) => {
|
|
@@ -26,6 +26,73 @@ import { WORLD_AMBIENT_WGSL } from "../lights"
|
|
|
26
26
|
// group(1): per-model skinning
|
|
27
27
|
// group(2): per-material (diffuse texture + material uniforms)
|
|
28
28
|
|
|
29
|
+
/** The jelly eyes' vertex move (jelly-eyes.ts). Every pass that places model
|
|
30
|
+
* vertices takes it, or a pass that skips it draws the iris where it was —
|
|
31
|
+
* the shadow map then shades half the moved iris with its own unmoved copy.
|
|
32
|
+
* Reads `objectLight.jelly` and `material.materialId`, which the including
|
|
33
|
+
* module declares. */
|
|
34
|
+
export const JELLY_VERTEX_WGSL = /* wgsl */ `
|
|
35
|
+
fn _rzJellyTurn(q: vec2f, a: f32) -> vec2f {
|
|
36
|
+
let c = cos(a);
|
|
37
|
+
let s = sin(a);
|
|
38
|
+
return vec2f(c * q.x - s * q.y, s * q.x + c * q.y);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Where the jelly puts an iris vertex. The iris is the part of the eye the eye
|
|
43
|
+
* bones carry, so it is moved as a whole, in bind space before skinning:
|
|
44
|
+
* scaled about its centre (the CPU composes the blink's spring, the lid's
|
|
45
|
+
* press and her motion's knock into one scale), turned and drifted a hair on
|
|
46
|
+
* the spring, brought forward a hair, and rolled about the eye bone with a
|
|
47
|
+
* closing expression — inside the white, which stays where it is. A highlight
|
|
48
|
+
* layer (this draw's material is one of jelly[1].w's) takes the iris's move,
|
|
49
|
+
* then its own scale, turn and tremble, before the roll. Vertices take it by their weight on the eye bones
|
|
50
|
+
* (jelly[2].w, jelly[3].w), so nothing else on the face moves.
|
|
51
|
+
*/
|
|
52
|
+
fn rzJellyVertex(p: vec3f, joints: vec4<u32>, nw: vec4f) -> vec3f {
|
|
53
|
+
let j = objectLight.jelly;
|
|
54
|
+
let ids = u32(j[1].w);
|
|
55
|
+
let mid = u32(material.materialId);
|
|
56
|
+
let hl = mid > 0u && (mid == (ids & 4095u) || mid == (ids >> 12u));
|
|
57
|
+
var out = p;
|
|
58
|
+
for (var e = 0u; e < 2u; e++) {
|
|
59
|
+
let bone = j[2u + e].w;
|
|
60
|
+
if (bone < 0.0) { continue; }
|
|
61
|
+
let b = u32(bone);
|
|
62
|
+
let w = dot(nw, select(vec4f(0.0), vec4f(1.0), joints == vec4<u32>(b)));
|
|
63
|
+
if (w <= 0.0) { continue; }
|
|
64
|
+
let c = j[e].xyz;
|
|
65
|
+
// A rig that carries both eyes on one bone: each vertex follows its own side.
|
|
66
|
+
if (j[2].w == j[3].w && e == 0u && distance(p.xy, j[1].xy) < distance(p.xy, j[0].xy)) { continue; }
|
|
67
|
+
if (j[2].w == j[3].w && e == 1u && distance(p.xy, j[0].xy) <= distance(p.xy, j[1].xy)) { continue; }
|
|
68
|
+
let t = j[4u + e];
|
|
69
|
+
let m = j[6u + e];
|
|
70
|
+
let h = j[10u + e];
|
|
71
|
+
var q = _rzJellyTurn((p.xy - c.xy) * t.xy, t.z) + m.xy;
|
|
72
|
+
// Forward is −Z (MMD faces −Z).
|
|
73
|
+
var push = h.z;
|
|
74
|
+
if (hl) {
|
|
75
|
+
// Sliding over the iris's dome on its own, a highlight sheet a hair in
|
|
76
|
+
// front of it would sink into it where the dome bulges more and the two
|
|
77
|
+
// fight for depth; so it comes forward by as far as it slid — a slope of
|
|
78
|
+
// one, steeper than the dome anywhere it draws.
|
|
79
|
+
let before = q;
|
|
80
|
+
q = _rzJellyTurn(q * h.xy, t.w) + m.zw;
|
|
81
|
+
push += length(q - before);
|
|
82
|
+
}
|
|
83
|
+
var moved = vec3f(c.xy + q, p.z - push);
|
|
84
|
+
let roll = j[8u + e];
|
|
85
|
+
if (roll.w != 0.0) {
|
|
86
|
+
let d = moved - roll.xyz;
|
|
87
|
+
let rd = _rzJellyTurn(d.yz, roll.w);
|
|
88
|
+
moved = roll.xyz + vec3f(d.x, rd.x, rd.y);
|
|
89
|
+
}
|
|
90
|
+
out = mix(p, moved, w);
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
`
|
|
95
|
+
|
|
29
96
|
export const COMMON_BINDINGS_WGSL = /* wgsl */ `
|
|
30
97
|
|
|
31
98
|
struct CameraUniforms {
|
|
@@ -234,66 +301,7 @@ fn _rzCastShadow(wp: vec3f) -> f32 {
|
|
|
234
301
|
struct ObjectLight { layers: vec4u, ambient: vec4f, sh: array<vec4f, 9>, fill: vec4f, jelly: array<vec4f, 12> }
|
|
235
302
|
@group(1) @binding(1) var<uniform> objectLight: ObjectLight;
|
|
236
303
|
|
|
237
|
-
|
|
238
|
-
let c = cos(a);
|
|
239
|
-
let s = sin(a);
|
|
240
|
-
return vec2f(c * q.x - s * q.y, s * q.x + c * q.y);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Where the jelly puts an iris vertex. The iris is the part of the eye the eye
|
|
245
|
-
* bones carry, so it is moved as a whole, in bind space before skinning:
|
|
246
|
-
* scaled about its centre (the CPU composes the blink's spring, the lid's
|
|
247
|
-
* press and her motion's knock into one scale), turned and drifted a hair on
|
|
248
|
-
* the spring, brought forward a hair, and rolled about the eye bone with a
|
|
249
|
-
* closing expression — inside the white, which stays where it is. A highlight
|
|
250
|
-
* layer (this draw's material is one of jelly[1].w's) takes the iris's move,
|
|
251
|
-
* then its own scale, turn and tremble, before the roll. Vertices take it by their weight on the eye bones
|
|
252
|
-
* (jelly[2].w, jelly[3].w), so nothing else on the face moves.
|
|
253
|
-
*/
|
|
254
|
-
fn rzJellyVertex(p: vec3f, joints: vec4<u32>, nw: vec4f) -> vec3f {
|
|
255
|
-
let j = objectLight.jelly;
|
|
256
|
-
let ids = u32(j[1].w);
|
|
257
|
-
let mid = u32(material.materialId);
|
|
258
|
-
let hl = mid > 0u && (mid == (ids & 4095u) || mid == (ids >> 12u));
|
|
259
|
-
var out = p;
|
|
260
|
-
for (var e = 0u; e < 2u; e++) {
|
|
261
|
-
let bone = j[2u + e].w;
|
|
262
|
-
if (bone < 0.0) { continue; }
|
|
263
|
-
let b = u32(bone);
|
|
264
|
-
let w = dot(nw, select(vec4f(0.0), vec4f(1.0), joints == vec4<u32>(b)));
|
|
265
|
-
if (w <= 0.0) { continue; }
|
|
266
|
-
let c = j[e].xyz;
|
|
267
|
-
// A rig that carries both eyes on one bone: each vertex follows its own side.
|
|
268
|
-
if (j[2].w == j[3].w && e == 0u && distance(p.xy, j[1].xy) < distance(p.xy, j[0].xy)) { continue; }
|
|
269
|
-
if (j[2].w == j[3].w && e == 1u && distance(p.xy, j[0].xy) <= distance(p.xy, j[1].xy)) { continue; }
|
|
270
|
-
let t = j[4u + e];
|
|
271
|
-
let m = j[6u + e];
|
|
272
|
-
let h = j[10u + e];
|
|
273
|
-
var q = _rzJellyTurn((p.xy - c.xy) * t.xy, t.z) + m.xy;
|
|
274
|
-
// Forward is −Z (MMD faces −Z).
|
|
275
|
-
var push = h.z;
|
|
276
|
-
if (hl) {
|
|
277
|
-
// Sliding over the iris's dome on its own, a highlight sheet a hair in
|
|
278
|
-
// front of it would sink into it where the dome bulges more and the two
|
|
279
|
-
// fight for depth; so it comes forward by as far as it slid — a slope of
|
|
280
|
-
// one, steeper than the dome anywhere it draws.
|
|
281
|
-
let before = q;
|
|
282
|
-
q = _rzJellyTurn(q * h.xy, t.w) + m.zw;
|
|
283
|
-
push += length(q - before);
|
|
284
|
-
}
|
|
285
|
-
var moved = vec3f(c.xy + q, p.z - push);
|
|
286
|
-
let roll = j[8u + e];
|
|
287
|
-
if (roll.w != 0.0) {
|
|
288
|
-
let d = moved - roll.xyz;
|
|
289
|
-
let rd = _rzJellyTurn(d.yz, roll.w);
|
|
290
|
-
moved = roll.xyz + vec3f(d.x, rd.x, rd.y);
|
|
291
|
-
}
|
|
292
|
-
out = mix(p, moved, w);
|
|
293
|
-
}
|
|
294
|
-
return out;
|
|
295
|
-
}
|
|
296
|
-
|
|
304
|
+
${JELLY_VERTEX_WGSL}
|
|
297
305
|
/** The light arriving at a surface of this object facing n: its own ambient
|
|
298
306
|
* where loaded data gave it one (a stage's probes, a character's), else the
|
|
299
307
|
* world's. The same polynomial rzWorldAmbient evaluates. */
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
// attachment, and that answer does not exist at import time. The constant could
|
|
28
28
|
// not have taken the outputs at all, which is most of why it did not have them.
|
|
29
29
|
|
|
30
|
-
import { DISSOLVE_WGSL } from "../materials/common"
|
|
30
|
+
import { DISSOLVE_WGSL, JELLY_VERTEX_WGSL } from "../materials/common"
|
|
31
31
|
import { sceneFsOutWgsl, sceneIdPadWgsl } from "./scene-contract"
|
|
32
32
|
|
|
33
33
|
export function transparentDepthPrepassWgsl(): string {
|
|
@@ -44,13 +44,20 @@ struct MaterialUniforms {
|
|
|
44
44
|
alpha: f32,
|
|
45
45
|
_skip0: vec4f,
|
|
46
46
|
_skip1: vec4f,
|
|
47
|
-
_skip2:
|
|
47
|
+
_skip2: f32,
|
|
48
|
+
materialId: f32,
|
|
49
|
+
_skip3: f32,
|
|
48
50
|
dissolve: f32,
|
|
49
51
|
};
|
|
50
52
|
|
|
51
53
|
@group(0) @binding(0) var<uniform> camera: CameraUniforms;
|
|
52
54
|
@group(0) @binding(2) var diffuseSampler: sampler;
|
|
53
55
|
@group(1) @binding(0) var<storage, read> skinMats: array<mat4x4f>;
|
|
56
|
+
// The model's ObjectLight, for its jelly eyes: depth goes down where the colour
|
|
57
|
+
// pass will draw the iris.
|
|
58
|
+
struct ObjectLight { layers: vec4u, ambient: vec4f, sh: array<vec4f, 9>, fill: vec4f, jelly: array<vec4f, 12> }
|
|
59
|
+
@group(1) @binding(1) var<uniform> objectLight: ObjectLight;
|
|
60
|
+
${JELLY_VERTEX_WGSL}
|
|
54
61
|
@group(2) @binding(0) var diffuseTexture: texture_2d<f32>;
|
|
55
62
|
@group(2) @binding(1) var<uniform> material: MaterialUniforms;
|
|
56
63
|
|
|
@@ -74,10 +81,11 @@ struct VSOut {
|
|
|
74
81
|
@location(3) joints0: vec4<u32>,
|
|
75
82
|
@location(4) weights0: vec4<f32>,
|
|
76
83
|
) -> VSOut {
|
|
77
|
-
let pos4 = vec4f(position, 1.0);
|
|
78
84
|
let weightSum = weights0.x + weights0.y + weights0.z + weights0.w;
|
|
79
85
|
let invWeightSum = select(1.0, 1.0 / weightSum, weightSum > 0.0001);
|
|
80
86
|
let w = select(vec4f(1.0, 0.0, 0.0, 0.0), weights0 * invWeightSum, weightSum > 0.0001);
|
|
87
|
+
var pos4 = vec4f(position, 1.0);
|
|
88
|
+
if (objectLight.jelly[0].w > 0.0) { pos4 = vec4f(rzJellyVertex(position, joints0, w), 1.0); }
|
|
81
89
|
var skinned = vec4f(0.0);
|
|
82
90
|
for (var i = 0u; i < 4u; i++) {
|
|
83
91
|
skinned += (skinMats[joints0[i]] * pos4) * w[i];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DISSOLVE_WGSL } from "../materials/common"
|
|
1
|
+
import { DISSOLVE_WGSL, JELLY_VERTEX_WGSL } from "../materials/common"
|
|
2
2
|
|
|
3
3
|
// Shadow map depth pass. Skinned VS + alpha-test FS (depth-only attachment, no
|
|
4
4
|
// color targets): texels where diffuse-texture alpha × material alpha fall below
|
|
@@ -21,10 +21,17 @@ struct MaterialDiffuse {
|
|
|
21
21
|
diffuse: vec4f,
|
|
22
22
|
_skip0: vec4f,
|
|
23
23
|
_skip1: vec4f,
|
|
24
|
-
_skip2:
|
|
24
|
+
_skip2: f32,
|
|
25
|
+
materialId: f32,
|
|
26
|
+
_skip3: f32,
|
|
25
27
|
dissolve: f32,
|
|
26
28
|
};
|
|
27
29
|
@group(1) @binding(1) var<uniform> material: MaterialDiffuse;
|
|
30
|
+
// The model's ObjectLight, for its jelly eyes: the map must hold the iris where
|
|
31
|
+
// the colour pass draws it.
|
|
32
|
+
struct ObjectLight { layers: vec4u, ambient: vec4f, sh: array<vec4f, 9>, fill: vec4f, jelly: array<vec4f, 12> }
|
|
33
|
+
@group(0) @binding(3) var<uniform> objectLight: ObjectLight;
|
|
34
|
+
${JELLY_VERTEX_WGSL}
|
|
28
35
|
|
|
29
36
|
struct VSOut {
|
|
30
37
|
@builtin(position) position: vec4f,
|
|
@@ -38,10 +45,11 @@ struct VSOut {
|
|
|
38
45
|
|
|
39
46
|
@vertex fn vs(@location(0) position: vec3f, @location(1) normal: vec3f, @location(2) uv: vec2f,
|
|
40
47
|
@location(3) joints0: vec4<u32>, @location(4) weights0: vec4<f32>) -> VSOut {
|
|
41
|
-
let pos4 = vec4f(position, 1.0);
|
|
42
48
|
let ws = weights0.x + weights0.y + weights0.z + weights0.w;
|
|
43
49
|
let inv = select(1.0, 1.0 / ws, ws > 0.0001);
|
|
44
50
|
let nw = select(vec4f(1.0,0.0,0.0,0.0), weights0 * inv, ws > 0.0001);
|
|
51
|
+
var pos4 = vec4f(position, 1.0);
|
|
52
|
+
if (objectLight.jelly[0].w > 0.0) { pos4 = vec4f(rzJellyVertex(position, joints0, nw), 1.0); }
|
|
45
53
|
var sp = vec4f(0.0);
|
|
46
54
|
for (var i = 0u; i < 4u; i++) { sp += (skinMats[joints0[i]] * pos4) * nw[i]; }
|
|
47
55
|
var out: VSOut;
|