reze-engine 0.65.0 → 0.66.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/dist/engine.d.ts +156 -42
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +874 -185
- package/dist/graph/compile.d.ts.map +1 -1
- package/dist/graph/compile.js +5 -0
- package/dist/graph/presets/body.d.ts.map +1 -1
- package/dist/graph/presets/body.js +26 -24
- package/dist/graph/presets/cloth_rough.js +8 -8
- package/dist/graph/presets/cloth_smooth.js +8 -8
- package/dist/graph/presets/default.js +4 -4
- package/dist/graph/presets/eye.js +10 -10
- package/dist/graph/presets/face.d.ts.map +1 -1
- package/dist/graph/presets/face.js +28 -26
- package/dist/graph/presets/hair.js +6 -6
- package/dist/graph/presets/metal.js +8 -8
- package/dist/graph/presets/stockings.d.ts.map +1 -1
- package/dist/graph/presets/stockings.js +4 -11
- package/dist/graph/presets/unlit.d.ts.map +1 -1
- package/dist/graph/presets/unlit.js +9 -13
- package/dist/graph/registry.d.ts.map +1 -1
- package/dist/graph/registry.js +128 -157
- package/dist/graph/render-class.d.ts +5 -2
- package/dist/graph/render-class.d.ts.map +1 -1
- package/dist/graph/slots.d.ts.map +1 -1
- package/dist/graph/slots.js +5 -1
- package/dist/model.d.ts +14 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +27 -1
- package/dist/pmx-loader.d.ts +4 -0
- package/dist/pmx-loader.d.ts.map +1 -1
- package/dist/pmx-loader.js +11 -2
- package/dist/shaders/anchor-table.d.ts +11 -0
- package/dist/shaders/anchor-table.d.ts.map +1 -1
- package/dist/shaders/anchor-table.js +9 -3
- package/dist/shaders/directives.d.ts +42 -5
- package/dist/shaders/directives.d.ts.map +1 -1
- package/dist/shaders/directives.js +51 -4
- package/dist/shaders/lights.d.ts +11 -7
- package/dist/shaders/lights.d.ts.map +1 -1
- package/dist/shaders/lights.js +315 -271
- package/dist/shaders/materials/common.d.ts.map +1 -1
- package/dist/shaders/materials/common.js +26 -3
- package/dist/shaders/materials/nodes.d.ts +1 -1
- package/dist/shaders/materials/nodes.d.ts.map +1 -1
- package/dist/shaders/materials/nodes.js +191 -271
- package/dist/shaders/passes/composite.d.ts +1 -1
- package/dist/shaders/passes/composite.d.ts.map +1 -1
- package/dist/shaders/passes/composite.js +3 -5
- package/dist/shaders/passes/ground.js +1 -1
- package/dist/shaders/passes/particles.d.ts.map +1 -1
- package/dist/shaders/passes/particles.js +9 -3
- package/dist/shaders/passes/probe.d.ts +45 -0
- package/dist/shaders/passes/probe.d.ts.map +1 -0
- package/dist/shaders/passes/probe.js +230 -0
- package/dist/shaders/passes/scene-contract.d.ts +13 -0
- package/dist/shaders/passes/scene-contract.d.ts.map +1 -1
- package/dist/shaders/passes/scene-contract.js +4 -0
- package/dist/shaders/scene-light-api.d.ts.map +1 -1
- package/dist/shaders/scene-light-api.js +1 -0
- package/dist/unity/globals.d.ts +7 -0
- package/dist/unity/globals.d.ts.map +1 -1
- package/dist/unity/globals.js +4 -3
- package/dist/unity/host.d.ts +3 -0
- package/dist/unity/host.d.ts.map +1 -1
- package/dist/unity/host.js +41 -7
- package/dist/unity/looks.d.ts +42 -0
- package/dist/unity/looks.d.ts.map +1 -1
- package/dist/unity/looks.js +131 -4
- package/dist/unity/stage.d.ts +17 -0
- package/dist/unity/stage.d.ts.map +1 -1
- package/dist/unity/stage.js +22 -5
- package/package.json +1 -1
- package/src/engine.ts +947 -214
- package/src/graph/compile.ts +4 -0
- package/src/graph/presets/body.ts +26 -24
- package/src/graph/presets/cloth_rough.ts +8 -8
- package/src/graph/presets/cloth_smooth.ts +8 -8
- package/src/graph/presets/default.ts +4 -4
- package/src/graph/presets/eye.ts +10 -10
- package/src/graph/presets/face.ts +28 -26
- package/src/graph/presets/hair.ts +6 -6
- package/src/graph/presets/metal.ts +8 -8
- package/src/graph/presets/stockings.ts +4 -11
- package/src/graph/presets/unlit.ts +9 -13
- package/src/graph/registry.ts +133 -158
- package/src/graph/render-class.ts +5 -2
- package/src/graph/slots.ts +5 -1
- package/src/model.ts +33 -1
- package/src/pmx-loader.ts +11 -2
- package/src/shaders/anchor-table.ts +15 -3
- package/src/shaders/directives.ts +88 -6
- package/src/shaders/lights.ts +464 -415
- package/src/shaders/materials/common.ts +26 -3
- package/src/shaders/materials/nodes.ts +191 -271
- package/src/shaders/passes/composite.ts +3 -5
- package/src/shaders/passes/ground.ts +1 -1
- package/src/shaders/passes/particles.ts +9 -3
- package/src/shaders/passes/probe.ts +240 -0
- package/src/shaders/passes/scene-contract.ts +17 -0
- package/src/shaders/scene-light-api.ts +1 -0
- package/src/unity/globals.ts +7 -3
- package/src/unity/host.ts +36 -6
- package/src/unity/looks.ts +161 -7
- package/src/unity/stage.ts +28 -5
- package/dist/physics-debug.d.ts +0 -30
- package/dist/physics-debug.d.ts.map +0 -1
- package/dist/physics-debug.js +0 -526
- package/dist/shaders/agx-lut.d.ts +0 -11
- package/dist/shaders/agx-lut.d.ts.map +0 -1
- package/dist/shaders/agx-lut.js +0 -29
- package/dist/shaders/dfg_lut.d.ts +0 -3
- package/dist/shaders/dfg_lut.d.ts.map +0 -1
- package/dist/shaders/dfg_lut.js +0 -129
- package/dist/shaders/ltc_mag_lut.d.ts +0 -3
- package/dist/shaders/ltc_mag_lut.d.ts.map +0 -1
- package/dist/shaders/ltc_mag_lut.js +0 -1033
- package/dist/shaders/materials/body.d.ts +0 -2
- package/dist/shaders/materials/body.d.ts.map +0 -1
- package/dist/shaders/materials/body.js +0 -95
- package/dist/shaders/materials/cloth_rough.d.ts +0 -2
- package/dist/shaders/materials/cloth_rough.d.ts.map +0 -1
- package/dist/shaders/materials/cloth_rough.js +0 -69
- package/dist/shaders/materials/cloth_smooth.d.ts +0 -2
- package/dist/shaders/materials/cloth_smooth.d.ts.map +0 -1
- package/dist/shaders/materials/cloth_smooth.js +0 -61
- package/dist/shaders/materials/default.d.ts +0 -2
- package/dist/shaders/materials/default.d.ts.map +0 -1
- package/dist/shaders/materials/default.js +0 -43
- package/dist/shaders/materials/eye.d.ts +0 -2
- package/dist/shaders/materials/eye.d.ts.map +0 -1
- package/dist/shaders/materials/eye.js +0 -60
- package/dist/shaders/materials/face.d.ts +0 -2
- package/dist/shaders/materials/face.d.ts.map +0 -1
- package/dist/shaders/materials/face.js +0 -95
- package/dist/shaders/materials/hair.d.ts +0 -2
- package/dist/shaders/materials/hair.d.ts.map +0 -1
- package/dist/shaders/materials/hair.js +0 -90
- package/dist/shaders/materials/metal.d.ts +0 -2
- package/dist/shaders/materials/metal.d.ts.map +0 -1
- package/dist/shaders/materials/metal.js +0 -77
- package/dist/shaders/materials/mmd_classic.d.ts +0 -2
- package/dist/shaders/materials/mmd_classic.d.ts.map +0 -1
- package/dist/shaders/materials/mmd_classic.js +0 -66
- package/dist/shaders/materials/stockings.d.ts +0 -2
- package/dist/shaders/materials/stockings.d.ts.map +0 -1
- package/dist/shaders/materials/stockings.js +0 -122
- package/dist/shaders/passes/physics-debug.d.ts +0 -2
- package/dist/shaders/passes/physics-debug.d.ts.map +0 -1
- package/dist/shaders/passes/physics-debug.js +0 -69
- package/src/shaders/dfg_lut.ts +0 -131
- package/src/shaders/ltc_mag_lut.ts +0 -1035
package/dist/unity/host.js
CHANGED
|
@@ -18,6 +18,26 @@
|
|
|
18
18
|
// the device has one), depth tests flip with the engine's reversed depth, and
|
|
19
19
|
// the pass's MSAA count and formats are the engine's.
|
|
20
20
|
import { blendState, colorMask, cull, depthCompare, stencilState, zwrite } from "./state";
|
|
21
|
+
/** Whether two values carry the same numbers (and the same integer-ness). */
|
|
22
|
+
export function sameValue(a, b) {
|
|
23
|
+
if (typeof a === "number" || typeof b === "number")
|
|
24
|
+
return a === b;
|
|
25
|
+
if (a.length !== b.length)
|
|
26
|
+
return false;
|
|
27
|
+
if (a instanceof Uint32Array !== b instanceof Uint32Array)
|
|
28
|
+
return false;
|
|
29
|
+
for (let i = 0; i < a.length; i++) {
|
|
30
|
+
const x = a[i];
|
|
31
|
+
const y = b[i];
|
|
32
|
+
if (typeof x === "number" || typeof y === "number") {
|
|
33
|
+
if (x !== y)
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
else if (!sameValue(x, y))
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
21
41
|
/** Members read as integers rather than floats (the shader asint()s them). */
|
|
22
42
|
const INT_MEMBERS = new Set(["unity_LightIndices"]);
|
|
23
43
|
/** "in_u002e_var_u002e_TEXCOORD2_" -> "TEXCOORD2"; TEXCOORD alone is 0. */
|
|
@@ -44,16 +64,26 @@ export function wrapFragment(frag, ids) {
|
|
|
44
64
|
if (at < 0)
|
|
45
65
|
throw new Error("native shader: no fragment entry point");
|
|
46
66
|
const head = frag.slice(at);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
67
|
+
// A target narrower than four channels (a float3 SV_Target) leaves the rest
|
|
68
|
+
// unwritten: widened here with zeros and an alpha of one.
|
|
69
|
+
const sig = /->\s*@location\(0\)\s*(vec4<f32>|vec3<f32>|vec2<f32>|f32)\s*\{/;
|
|
70
|
+
const kind = sig.exec(head)?.[1];
|
|
71
|
+
if (!kind)
|
|
72
|
+
throw new Error("native shader: the fragment entry does not return one float target");
|
|
50
73
|
let body = head.replace(sig, "-> RzNativeOut {");
|
|
51
74
|
const ret = /return\s+(_e\d+)\s*;\s*\}\s*$/;
|
|
52
75
|
const m = ret.exec(body);
|
|
53
76
|
if (!m)
|
|
54
77
|
throw new Error("native shader: the fragment entry's return is not the translator's");
|
|
55
|
-
const
|
|
56
|
-
|
|
78
|
+
const e = m[1];
|
|
79
|
+
const v = kind === "vec4<f32>"
|
|
80
|
+
? e
|
|
81
|
+
: kind === "vec3<f32>"
|
|
82
|
+
? `vec4f(${e}, 1.0)`
|
|
83
|
+
: kind === "vec2<f32>"
|
|
84
|
+
? `vec4f(${e}, 0.0, 1.0)`
|
|
85
|
+
: `vec4f(${e}, 0.0, 0.0, 1.0)`;
|
|
86
|
+
body = body.replace(ret, `let rzColor = ${v};\n return RzNativeOut(rzColor, vec4f(1.0, 1.0, 0.0, rzColor.a)${ids ? ", vec2u(0u)" : ""});\n}\n`);
|
|
57
87
|
const struct = `struct RzNativeOut {\n @location(0) color: vec4f,\n @location(1) mask: vec4f,\n${ids ? " @location(2) id: vec2u,\n" : ""}};\n`;
|
|
58
88
|
// After the module's directives (diagnostic, enable): WGSL wants them first.
|
|
59
89
|
const pre = frag.slice(0, at);
|
|
@@ -491,16 +521,20 @@ export class NativeHost {
|
|
|
491
521
|
return this.sampler;
|
|
492
522
|
const bare = name.replace(/^sampler_?/, "");
|
|
493
523
|
const tex = info.bindings[bare] ? bare : info.bindings[`_${bare}`] ? `_${bare}` : bare;
|
|
494
|
-
return samplers[tex] ?? this.sampler;
|
|
524
|
+
return samplers[tex] ?? samplers[tex.replace(/_+$/, "")] ?? this.sampler;
|
|
495
525
|
}
|
|
496
526
|
textureView(name, type, textures) {
|
|
497
|
-
|
|
527
|
+
// naga renames a binding that ends in a digit with a trailing "_", as it
|
|
528
|
+
// does a member (lookupFrom): _AlbedoTex_1 is declared _AlbedoTex_1_
|
|
529
|
+
const v = textures[name] ?? (name.endsWith("_") ? textures[name.replace(/_+$/, "")] : undefined);
|
|
498
530
|
if (v)
|
|
499
531
|
return v;
|
|
500
532
|
if (/texture_depth/.test(type))
|
|
501
533
|
return this.fallback.depth;
|
|
502
534
|
if (/texture_cube/.test(type))
|
|
503
535
|
return this.fallback.blackCube;
|
|
536
|
+
if (/texture_3d/.test(type))
|
|
537
|
+
return this.fallback.emptyVolume;
|
|
504
538
|
return this.fallback.white;
|
|
505
539
|
}
|
|
506
540
|
/** Forget a draw's buffers (its model left). */
|
package/dist/unity/looks.d.ts
CHANGED
|
@@ -8,6 +8,12 @@ export type NativeTexture = {
|
|
|
8
8
|
data: Uint8Array;
|
|
9
9
|
/** Colour (sRGB) or data (linear) — how the shader expects to read it. */
|
|
10
10
|
srgb: boolean;
|
|
11
|
+
/** Unity's wrap mode as the game imported it (Repeat, Clamp, Mirror,
|
|
12
|
+
* MirrorOnce); repeating when absent. A clamped mask sampled past its edge
|
|
13
|
+
* reads its border, not the far side. */
|
|
14
|
+
wrap?: string;
|
|
15
|
+
/** Unity's filter mode (Point, Bilinear, Trilinear); bilinear when absent. */
|
|
16
|
+
filter?: string;
|
|
11
17
|
};
|
|
12
18
|
export type NativeMaterialSpec = {
|
|
13
19
|
/** The model's materials this dresses, by name. */
|
|
@@ -30,6 +36,12 @@ export type NativeLook = {
|
|
|
30
36
|
textures: Record<string, NativeTexture>;
|
|
31
37
|
materials: NativeMaterialSpec[];
|
|
32
38
|
rig?: CharacterRig;
|
|
39
|
+
/** The game vertex streams the model's PMX carries, by semantic: the
|
|
40
|
+
* additional UV channel (1–4) that holds each, four floats a vertex, keyed
|
|
41
|
+
* over time by that channel's UV morphs (PMX types 4–7) — a particle's
|
|
42
|
+
* colour over its life on a mesh's own vertex colours. A stream named here
|
|
43
|
+
* reads that channel; any other reads as Unity binds a missing one. */
|
|
44
|
+
streams?: Record<string, number>;
|
|
33
45
|
};
|
|
34
46
|
/** What the engine lends for one model. */
|
|
35
47
|
export type NativeModel = {
|
|
@@ -53,6 +65,18 @@ export type NativeModel = {
|
|
|
53
65
|
headRest: [number, number, number];
|
|
54
66
|
/** Its rendering-layer bits, for a look without a rig. */
|
|
55
67
|
layers: number;
|
|
68
|
+
/** A PMX additional UV channel (1–4), four floats a vertex, or null. */
|
|
69
|
+
additionalUv: (channel: number) => Float32Array | null;
|
|
70
|
+
/** Its morphs, in the order of morphWeights. */
|
|
71
|
+
morphs: readonly {
|
|
72
|
+
type: number;
|
|
73
|
+
uvOffsets?: {
|
|
74
|
+
vertexIndex: number;
|
|
75
|
+
offset: [number, number, number, number];
|
|
76
|
+
}[];
|
|
77
|
+
}[];
|
|
78
|
+
/** The current effective (group-resolved, clamped) morph weights. */
|
|
79
|
+
morphWeights: () => Float32Array;
|
|
56
80
|
};
|
|
57
81
|
export declare class NativeLooks {
|
|
58
82
|
private device;
|
|
@@ -68,6 +92,9 @@ export declare class NativeLooks {
|
|
|
68
92
|
private scale;
|
|
69
93
|
constructor(device: GPUDevice, host: NativeHost);
|
|
70
94
|
get size(): number;
|
|
95
|
+
private samplerCache;
|
|
96
|
+
/** A texture's sampler: its wrap and filter, shared by every texture alike. */
|
|
97
|
+
private sampler;
|
|
71
98
|
has(model: string): boolean;
|
|
72
99
|
/** Resolves once every pass of the model's look has its pipeline — until
|
|
73
100
|
* then those draws sit out (NativeHost never compiles at a draw). */
|
|
@@ -81,6 +108,21 @@ export declare class NativeLooks {
|
|
|
81
108
|
* character's block; the frame's Unity globals come computed (engine.ts).
|
|
82
109
|
*/
|
|
83
110
|
prepare(encoder: GPUCommandEncoder, globals: Record<string, NativeValue>, scale: number, textures: Record<string, GPUTextureView | undefined>): void;
|
|
111
|
+
/** Each carried stream at the model's current morph weights: its rest values
|
|
112
|
+
* plus every one of its channel's morphs at its weight, rebuilt and uploaded
|
|
113
|
+
* only when one of those weights moved. */
|
|
114
|
+
private keyStreams;
|
|
115
|
+
/**
|
|
116
|
+
* Set some of one dressed material's values (its Unity material properties,
|
|
117
|
+
* as the look's `values` hold them) — what a game animates on a material
|
|
118
|
+
* over a take. Each value stands until set again; the look's own stand
|
|
119
|
+
* under it. Only names the material's spec carries are taken: they are the
|
|
120
|
+
* ones its draws' uniform blocks read per draw. A value equal to the one
|
|
121
|
+
* already set keeps that one's object, so the host, which refills a
|
|
122
|
+
* uniform member only when its value object changes, writes nothing for
|
|
123
|
+
* it. Returns whether the model wears a look that dresses this material.
|
|
124
|
+
*/
|
|
125
|
+
setUniforms(model: string, material: string, values: Record<string, NativeValue>): boolean;
|
|
84
126
|
private streams;
|
|
85
127
|
private drawPass;
|
|
86
128
|
/** Every dressed material whose queue is in range, in queue order. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"looks.d.ts","sourceRoot":"","sources":["../../src/unity/looks.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"looks.d.ts","sourceRoot":"","sources":["../../src/unity/looks.ts"],"names":[],"mappings":"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"}
|
package/dist/unity/looks.js
CHANGED
|
@@ -14,9 +14,16 @@
|
|
|
14
14
|
// 3. the eyes' see-through-hair passes, Override1 for all, then 2, then 3;
|
|
15
15
|
// and the transparent queue in the engine's transparent phase. Shadows are the
|
|
16
16
|
// engine's: a native material still casts through its pass.
|
|
17
|
+
import { sameValue } from "./host";
|
|
17
18
|
import { UNITY_SKIN_WGSL, tangentsFor } from "./skin";
|
|
18
19
|
import { characterBlock } from "./character";
|
|
19
20
|
import { engineToGame, gameToEngine } from "./globals";
|
|
21
|
+
const WRAP = {
|
|
22
|
+
Repeat: "repeat",
|
|
23
|
+
Clamp: "clamp-to-edge",
|
|
24
|
+
Mirror: "mirror-repeat",
|
|
25
|
+
MirrorOnce: "mirror-repeat",
|
|
26
|
+
};
|
|
20
27
|
const OPAQUE_MODES = ["ALWAYS", "FORWARDBASE"];
|
|
21
28
|
const CHARACTER_MODES = ["CHARHAIRSHADOW", "CHARFACESHADOW", "CHARHAIRTRANSE"];
|
|
22
29
|
const OVERRIDE_MODES = ["OVERRIDE1", "OVERRIDE2", "OVERRIDE3"];
|
|
@@ -29,6 +36,7 @@ export class NativeLooks {
|
|
|
29
36
|
this.globals = {};
|
|
30
37
|
this.frameTextures = {};
|
|
31
38
|
this.scale = 8;
|
|
39
|
+
this.samplerCache = new Map();
|
|
32
40
|
this.host = host;
|
|
33
41
|
this.skinPipeline = device.createComputePipeline({
|
|
34
42
|
label: "native skinning",
|
|
@@ -58,6 +66,25 @@ export class NativeLooks {
|
|
|
58
66
|
get size() {
|
|
59
67
|
return this.installs.size;
|
|
60
68
|
}
|
|
69
|
+
/** A texture's sampler: its wrap and filter, shared by every texture alike. */
|
|
70
|
+
sampler(t) {
|
|
71
|
+
const wrap = WRAP[t.wrap ?? "Repeat"] ?? "repeat";
|
|
72
|
+
const filter = t.filter === "Point" ? "nearest" : "linear";
|
|
73
|
+
const key = `${wrap}|${filter}`;
|
|
74
|
+
let s = this.samplerCache.get(key);
|
|
75
|
+
if (!s) {
|
|
76
|
+
s = this.device.createSampler({
|
|
77
|
+
label: `native look sampler ${key}`,
|
|
78
|
+
addressModeU: wrap,
|
|
79
|
+
addressModeV: wrap,
|
|
80
|
+
magFilter: filter,
|
|
81
|
+
minFilter: filter,
|
|
82
|
+
mipmapFilter: filter,
|
|
83
|
+
});
|
|
84
|
+
this.samplerCache.set(key, s);
|
|
85
|
+
}
|
|
86
|
+
return s;
|
|
87
|
+
}
|
|
61
88
|
has(model) {
|
|
62
89
|
return this.installs.has(model);
|
|
63
90
|
}
|
|
@@ -77,8 +104,11 @@ export class NativeLooks {
|
|
|
77
104
|
for (const s of look.shaders)
|
|
78
105
|
this.host.register(s);
|
|
79
106
|
const views = new Map();
|
|
107
|
+
const samplers = new Map();
|
|
80
108
|
const textures = [];
|
|
81
109
|
for (const [key, t] of Object.entries(look.textures)) {
|
|
110
|
+
if (t.wrap || t.filter)
|
|
111
|
+
samplers.set(key, this.sampler(t));
|
|
82
112
|
const tex = d.createTexture({
|
|
83
113
|
label: `${model.name}: ${key}`,
|
|
84
114
|
size: [t.width, t.height],
|
|
@@ -126,12 +156,28 @@ export class NativeLooks {
|
|
|
126
156
|
for (const draw of model.draws) {
|
|
127
157
|
const spec = look.materials.find((m) => m.materials.includes(draw.materialName));
|
|
128
158
|
if (spec)
|
|
129
|
-
dressed.push({ draw, spec });
|
|
159
|
+
dressed.push({ draw, spec, values: {} });
|
|
160
|
+
}
|
|
161
|
+
const carried = new Map();
|
|
162
|
+
for (const [semantic, channel] of Object.entries(look.streams ?? {})) {
|
|
163
|
+
const base = model.additionalUv(channel);
|
|
164
|
+
if (!base || base.length < n * 4)
|
|
165
|
+
continue;
|
|
166
|
+
const morphs = model.morphs
|
|
167
|
+
.map((m, index) => ({ index, type: m.type, offsets: m.uvOffsets ?? [] }))
|
|
168
|
+
.filter((m) => m.type === 3 + channel && m.offsets.length)
|
|
169
|
+
.map(({ index, offsets }) => ({ index, offsets }));
|
|
170
|
+
const buffer = buf(`stream ${semantic}`, n * 4, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST);
|
|
171
|
+
const data = new Float32Array(base.subarray(0, n * 4));
|
|
172
|
+
d.queue.writeBuffer(buffer, 0, data);
|
|
173
|
+
// NaN: the first prepare builds the stream whatever the weights are
|
|
174
|
+
carried.set(semantic, { buffer, base: data.slice(), data, morphs, weights: new Float32Array(morphs.length).fill(NaN) });
|
|
130
175
|
}
|
|
131
176
|
const install = {
|
|
132
177
|
model,
|
|
133
178
|
look,
|
|
134
179
|
views,
|
|
180
|
+
samplers,
|
|
135
181
|
textures,
|
|
136
182
|
pos,
|
|
137
183
|
nrm,
|
|
@@ -141,6 +187,7 @@ export class NativeLooks {
|
|
|
141
187
|
skinBind,
|
|
142
188
|
dressed,
|
|
143
189
|
block: {},
|
|
190
|
+
carried,
|
|
144
191
|
};
|
|
145
192
|
this.installs.set(model.name, install);
|
|
146
193
|
// Every pass this look will draw, compiled now and side by side — the
|
|
@@ -159,7 +206,7 @@ export class NativeLooks {
|
|
|
159
206
|
return;
|
|
160
207
|
this.installs.delete(name);
|
|
161
208
|
this.host.release(`${name}|`);
|
|
162
|
-
const bufs = [i.pos, i.nrm, i.tan, i.restTan, i.params];
|
|
209
|
+
const bufs = [i.pos, i.nrm, i.tan, i.restTan, i.params, ...[...i.carried.values()].map((c) => c.buffer)];
|
|
163
210
|
const texs = i.textures;
|
|
164
211
|
// Freed once the GPU is done with the frames that may still name them.
|
|
165
212
|
void this.device.queue.onSubmittedWorkDone().then(() => {
|
|
@@ -189,11 +236,87 @@ export class NativeLooks {
|
|
|
189
236
|
: {
|
|
190
237
|
unity_RenderingLayer: new Uint32Array([i.model.layers >>> 0, 0, 0, 0]),
|
|
191
238
|
};
|
|
239
|
+
if (i.carried.size)
|
|
240
|
+
this.keyStreams(i);
|
|
192
241
|
}
|
|
193
242
|
pass.end();
|
|
194
243
|
}
|
|
244
|
+
/** Each carried stream at the model's current morph weights: its rest values
|
|
245
|
+
* plus every one of its channel's morphs at its weight, rebuilt and uploaded
|
|
246
|
+
* only when one of those weights moved. */
|
|
247
|
+
keyStreams(i) {
|
|
248
|
+
const weights = i.model.morphWeights();
|
|
249
|
+
for (const c of i.carried.values()) {
|
|
250
|
+
if (!c.morphs.length)
|
|
251
|
+
continue;
|
|
252
|
+
let moved = false;
|
|
253
|
+
for (let k = 0; k < c.morphs.length; k++) {
|
|
254
|
+
const w = weights[c.morphs[k].index] ?? 0;
|
|
255
|
+
if (w !== c.weights[k]) {
|
|
256
|
+
c.weights[k] = w;
|
|
257
|
+
moved = true;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (!moved)
|
|
261
|
+
continue;
|
|
262
|
+
c.data.set(c.base);
|
|
263
|
+
for (let k = 0; k < c.morphs.length; k++) {
|
|
264
|
+
const w = c.weights[k];
|
|
265
|
+
if (!w)
|
|
266
|
+
continue;
|
|
267
|
+
for (const o of c.morphs[k].offsets) {
|
|
268
|
+
const at = o.vertexIndex * 4;
|
|
269
|
+
if (at + 3 >= c.data.length)
|
|
270
|
+
continue;
|
|
271
|
+
c.data[at] += o.offset[0] * w;
|
|
272
|
+
c.data[at + 1] += o.offset[1] * w;
|
|
273
|
+
c.data[at + 2] += o.offset[2] * w;
|
|
274
|
+
c.data[at + 3] += o.offset[3] * w;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
this.device.queue.writeBuffer(c.buffer, 0, c.data);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Set some of one dressed material's values (its Unity material properties,
|
|
282
|
+
* as the look's `values` hold them) — what a game animates on a material
|
|
283
|
+
* over a take. Each value stands until set again; the look's own stand
|
|
284
|
+
* under it. Only names the material's spec carries are taken: they are the
|
|
285
|
+
* ones its draws' uniform blocks read per draw. A value equal to the one
|
|
286
|
+
* already set keeps that one's object, so the host, which refills a
|
|
287
|
+
* uniform member only when its value object changes, writes nothing for
|
|
288
|
+
* it. Returns whether the model wears a look that dresses this material.
|
|
289
|
+
*/
|
|
290
|
+
setUniforms(model, material, values) {
|
|
291
|
+
const i = this.installs.get(model);
|
|
292
|
+
if (!i)
|
|
293
|
+
return false;
|
|
294
|
+
let found = false;
|
|
295
|
+
for (const d of i.dressed) {
|
|
296
|
+
if (d.draw.materialName !== material)
|
|
297
|
+
continue;
|
|
298
|
+
found = true;
|
|
299
|
+
for (const name in values) {
|
|
300
|
+
const v = values[name];
|
|
301
|
+
if (v === undefined || v === null || !(name in d.spec.values))
|
|
302
|
+
continue;
|
|
303
|
+
const was = d.values[name];
|
|
304
|
+
if (was === undefined || !sameValue(was, v))
|
|
305
|
+
d.values[name] = v;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return found;
|
|
309
|
+
}
|
|
195
310
|
streams(i, shader) {
|
|
196
311
|
return this.host.inputs(shader).map(({ semantic }) => {
|
|
312
|
+
const carried = i.carried.get(semantic);
|
|
313
|
+
if (carried)
|
|
314
|
+
return {
|
|
315
|
+
buffer: carried.buffer,
|
|
316
|
+
offset: 0,
|
|
317
|
+
stride: 16,
|
|
318
|
+
format: "float32x4",
|
|
319
|
+
};
|
|
197
320
|
if (semantic === "POSITION")
|
|
198
321
|
return {
|
|
199
322
|
buffer: i.pos,
|
|
@@ -258,8 +381,11 @@ export class NativeLooks {
|
|
|
258
381
|
const textures = {
|
|
259
382
|
...this.frameTextures,
|
|
260
383
|
};
|
|
261
|
-
|
|
384
|
+
const samplers = {};
|
|
385
|
+
for (const [slot, key] of Object.entries(d.spec.textures)) {
|
|
262
386
|
textures[slot] = key === "@diffuse" ? d.draw.diffuse : i.views.get(key);
|
|
387
|
+
samplers[slot] = i.samplers.get(key);
|
|
388
|
+
}
|
|
263
389
|
this.host.draw(pass, {
|
|
264
390
|
shader: p.shader,
|
|
265
391
|
state: p.state,
|
|
@@ -270,8 +396,9 @@ export class NativeLooks {
|
|
|
270
396
|
offset: d.draw.firstIndex * 4,
|
|
271
397
|
count: d.draw.count,
|
|
272
398
|
},
|
|
273
|
-
sources: [perDraw, i.block, d.spec.values, this.globals],
|
|
399
|
+
sources: [perDraw, i.block, d.values, d.spec.values, this.globals],
|
|
274
400
|
textures,
|
|
401
|
+
samplers,
|
|
275
402
|
key: `${i.model.name}|${d.draw.materialName}|${p.lightMode}|${p.shader}`,
|
|
276
403
|
pass: "main",
|
|
277
404
|
});
|
package/dist/unity/stage.d.ts
CHANGED
|
@@ -63,6 +63,16 @@ export type NativeStageLights = {
|
|
|
63
63
|
direction: [number, number, number];
|
|
64
64
|
color: [number, number, number];
|
|
65
65
|
shadow: number;
|
|
66
|
+
/** As the game's pipeline packed it, recorded: _MainLightColor and
|
|
67
|
+
* SimMainLightColor (linear, intensity in w), SimMainLightColorNoInt. */
|
|
68
|
+
unity?: {
|
|
69
|
+
color: number[];
|
|
70
|
+
simColor: number[];
|
|
71
|
+
simColorNoInt: number[];
|
|
72
|
+
};
|
|
73
|
+
/** The Light's shadowBias and shadowNormalBias, in shadow-map texels. */
|
|
74
|
+
shadowBias?: number;
|
|
75
|
+
shadowNormalBias?: number;
|
|
66
76
|
};
|
|
67
77
|
additional: {
|
|
68
78
|
position: [number, number, number];
|
|
@@ -112,6 +122,13 @@ export declare class NativeStage {
|
|
|
112
122
|
min: [number, number, number];
|
|
113
123
|
max: [number, number, number];
|
|
114
124
|
};
|
|
125
|
+
/**
|
|
126
|
+
* How far the stage reaches from the origin, in engine units: every
|
|
127
|
+
* renderer's box, casters or not. A game's sky is a dome in the stage
|
|
128
|
+
* (X317's reaches 1900 units out), and the camera's far plane has to reach it.
|
|
129
|
+
*/
|
|
130
|
+
get extent(): number;
|
|
131
|
+
private reach;
|
|
115
132
|
private buffers;
|
|
116
133
|
private textures;
|
|
117
134
|
private opaque;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../../src/unity/stage.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,UAAU,EAAwC,KAAK,WAAW,EAAoB,MAAM,QAAQ,CAAA;AAC7G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../../src/unity/stage.ts"],"names":[],"mappings":"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"}
|
package/dist/unity/stage.js
CHANGED
|
@@ -18,10 +18,20 @@
|
|
|
18
18
|
// engine's cascade tiles, as the game drew its own atlas — alpha-tested leaves
|
|
19
19
|
// cast their leaves, not their quads.
|
|
20
20
|
import { gameToEngine, invert4, mul4, scale4, flipY } from "./globals";
|
|
21
|
+
import { SHADOW_CASCADES } from "../shadow-cascades";
|
|
21
22
|
const MAIN_MODES = ["ALWAYS", "FORWARDBASE"];
|
|
22
23
|
export class NativeStage {
|
|
24
|
+
/**
|
|
25
|
+
* How far the stage reaches from the origin, in engine units: every
|
|
26
|
+
* renderer's box, casters or not. A game's sky is a dome in the stage
|
|
27
|
+
* (X317's reaches 1900 units out), and the camera's far plane has to reach it.
|
|
28
|
+
*/
|
|
29
|
+
get extent() {
|
|
30
|
+
return this.reach;
|
|
31
|
+
}
|
|
23
32
|
constructor(device, pkg) {
|
|
24
33
|
this.device = device;
|
|
34
|
+
this.reach = 0;
|
|
25
35
|
this.buffers = [];
|
|
26
36
|
this.textures = [];
|
|
27
37
|
this.opaque = [];
|
|
@@ -226,6 +236,7 @@ export class NativeStage {
|
|
|
226
236
|
];
|
|
227
237
|
const ex = b.size[0] / 2, ey = b.size[1] / 2, ez = b.size[2] / 2;
|
|
228
238
|
const half = [0, 1, 2].map((i) => (Math.abs(m[i]) * ex + Math.abs(m[4 + i]) * ey + Math.abs(m[8 + i]) * ez) * s);
|
|
239
|
+
this.reach = Math.max(this.reach, Math.hypot(center[0], center[1], center[2]) + Math.hypot(half[0], half[1], half[2]));
|
|
229
240
|
const world = Float32Array.from(m);
|
|
230
241
|
const det = m[0] * (m[5] * m[10] - m[9] * m[6]) - m[4] * (m[1] * m[10] - m[9] * m[2]) + m[8] * (m[1] * m[6] - m[5] * m[2]);
|
|
231
242
|
const perDraw = {
|
|
@@ -365,18 +376,24 @@ export class NativeStage {
|
|
|
365
376
|
/** One cascade tile of the engine's atlas: every caster's SHADOWCASTER pass. */
|
|
366
377
|
drawShadow(pass, host, globals, cascade, viewProj, engineScale) {
|
|
367
378
|
const vp = flipY(mul4(viewProj, gameToEngine(engineScale)));
|
|
368
|
-
// ShadowUtils.GetShadowBias as the game
|
|
369
|
-
//
|
|
370
|
-
// game units over its resolution
|
|
379
|
+
// ShadowUtils.GetShadowBias as the game sets it: (texel x the light's
|
|
380
|
+
// shadowBias, -texel x its shadowNormalBias), a texel being this tile's
|
|
381
|
+
// width in game units over its resolution. The stage's casters read it as
|
|
382
|
+
// _ShadowBias (Replica's CascadeShadowPass); the character's DrawShadowPass
|
|
383
|
+
// names it sim_ShadowBias. A package that predates the recorded biases
|
|
384
|
+
// takes half a texel of each.
|
|
371
385
|
const rowLen = Math.hypot(vp[0], vp[4], vp[8]);
|
|
372
|
-
const texel = rowLen > 0 ? 2 / rowLen /
|
|
386
|
+
const texel = rowLen > 0 ? 2 / rowLen / SHADOW_CASCADES[cascade].mapSize : 0;
|
|
387
|
+
const main = this.pkg.lights.main;
|
|
388
|
+
const bias = [texel * (main.shadowBias ?? 0.5), -texel * (main.shadowNormalBias ?? 0.5), 0, 0];
|
|
373
389
|
const g = {
|
|
374
390
|
...globals,
|
|
375
391
|
unity_MatrixVP: vp,
|
|
376
392
|
unity_MatrixV: scale4(1),
|
|
377
393
|
unity_MatrixP: vp,
|
|
378
394
|
glstate_matrix_projection: vp,
|
|
379
|
-
|
|
395
|
+
_ShadowBias: bias,
|
|
396
|
+
sim_ShadowBias: bias,
|
|
380
397
|
};
|
|
381
398
|
for (const it of this.casters)
|
|
382
399
|
this.draw(pass, host, it, g, {}, `|c${cascade}`);
|