reze-engine 0.64.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 +300 -94
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +1628 -787
- 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 +12 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/model.d.ts +23 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +41 -1
- package/dist/outline-normals.d.ts +12 -0
- package/dist/outline-normals.d.ts.map +1 -0
- package/dist/outline-normals.js +100 -0
- package/dist/pmx-loader.d.ts +7 -0
- package/dist/pmx-loader.d.ts.map +1 -1
- package/dist/pmx-loader.js +17 -3
- 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 +30 -5
- 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/bloom.d.ts +4 -3
- package/dist/shaders/passes/bloom.d.ts.map +1 -1
- package/dist/shaders/passes/bloom.js +58 -87
- 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 +121 -77
- package/dist/shaders/passes/ground.js +1 -1
- package/dist/shaders/passes/mirror.d.ts +18 -12
- package/dist/shaders/passes/mirror.d.ts.map +1 -1
- package/dist/shaders/passes/mirror.js +59 -13
- package/dist/shaders/passes/outline.d.ts.map +1 -1
- package/dist/shaders/passes/outline.js +71 -14
- 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 +18 -0
- package/dist/unity/host.d.ts.map +1 -1
- package/dist/unity/host.js +144 -70
- package/dist/unity/looks.d.ts +47 -0
- package/dist/unity/looks.d.ts.map +1 -1
- package/dist/unity/looks.js +150 -6
- package/dist/unity/skin.d.ts.map +1 -1
- package/dist/unity/skin.js +5 -2
- package/dist/unity/stage.d.ts +24 -0
- package/dist/unity/stage.d.ts.map +1 -1
- package/dist/unity/stage.js +59 -7
- package/package.json +1 -1
- package/src/engine.ts +2010 -1033
- 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 +12 -2
- package/src/index.ts +1 -0
- package/src/model.ts +50 -1
- package/src/outline-normals.ts +110 -0
- package/src/pmx-loader.ts +18 -3
- 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 +30 -5
- package/src/shaders/materials/nodes.ts +191 -271
- package/src/shaders/passes/bloom.ts +59 -87
- package/src/shaders/passes/composite.ts +121 -77
- package/src/shaders/passes/ground.ts +1 -1
- package/src/shaders/passes/mirror.ts +60 -13
- package/src/shaders/passes/outline.ts +71 -14
- 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 +93 -20
- package/src/unity/looks.ts +182 -9
- package/src/unity/skin.ts +5 -2
- package/src/unity/stage.ts +66 -7
- 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/agx-lut.ts +0 -30
- package/src/shaders/dfg_lut.ts +0 -131
- package/src/shaders/ltc_mag_lut.ts +0 -1035
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"];
|
|
@@ -24,9 +31,12 @@ export class NativeLooks {
|
|
|
24
31
|
constructor(device, host) {
|
|
25
32
|
this.device = device;
|
|
26
33
|
this.installs = new Map();
|
|
34
|
+
/** Per model: its passes' pipelines compiling (see install). */
|
|
35
|
+
this.warming = new Map();
|
|
27
36
|
this.globals = {};
|
|
28
37
|
this.frameTextures = {};
|
|
29
38
|
this.scale = 8;
|
|
39
|
+
this.samplerCache = new Map();
|
|
30
40
|
this.host = host;
|
|
31
41
|
this.skinPipeline = device.createComputePipeline({
|
|
32
42
|
label: "native skinning",
|
|
@@ -56,9 +66,33 @@ export class NativeLooks {
|
|
|
56
66
|
get size() {
|
|
57
67
|
return this.installs.size;
|
|
58
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
|
+
}
|
|
59
88
|
has(model) {
|
|
60
89
|
return this.installs.has(model);
|
|
61
90
|
}
|
|
91
|
+
/** Resolves once every pass of the model's look has its pipeline — until
|
|
92
|
+
* then those draws sit out (NativeHost never compiles at a draw). */
|
|
93
|
+
ready(model) {
|
|
94
|
+
return this.warming.get(model) ?? Promise.resolve();
|
|
95
|
+
}
|
|
62
96
|
/** Is this model's material drawn by its native look? */
|
|
63
97
|
dresses(model, material) {
|
|
64
98
|
const i = this.installs.get(model);
|
|
@@ -70,8 +104,11 @@ export class NativeLooks {
|
|
|
70
104
|
for (const s of look.shaders)
|
|
71
105
|
this.host.register(s);
|
|
72
106
|
const views = new Map();
|
|
107
|
+
const samplers = new Map();
|
|
73
108
|
const textures = [];
|
|
74
109
|
for (const [key, t] of Object.entries(look.textures)) {
|
|
110
|
+
if (t.wrap || t.filter)
|
|
111
|
+
samplers.set(key, this.sampler(t));
|
|
75
112
|
const tex = d.createTexture({
|
|
76
113
|
label: `${model.name}: ${key}`,
|
|
77
114
|
size: [t.width, t.height],
|
|
@@ -119,12 +156,28 @@ export class NativeLooks {
|
|
|
119
156
|
for (const draw of model.draws) {
|
|
120
157
|
const spec = look.materials.find((m) => m.materials.includes(draw.materialName));
|
|
121
158
|
if (spec)
|
|
122
|
-
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) });
|
|
123
175
|
}
|
|
124
|
-
|
|
176
|
+
const install = {
|
|
125
177
|
model,
|
|
126
178
|
look,
|
|
127
179
|
views,
|
|
180
|
+
samplers,
|
|
128
181
|
textures,
|
|
129
182
|
pos,
|
|
130
183
|
nrm,
|
|
@@ -134,7 +187,18 @@ export class NativeLooks {
|
|
|
134
187
|
skinBind,
|
|
135
188
|
dressed,
|
|
136
189
|
block: {},
|
|
137
|
-
|
|
190
|
+
carried,
|
|
191
|
+
};
|
|
192
|
+
this.installs.set(model.name, install);
|
|
193
|
+
// Every pass this look will draw, compiled now and side by side — the
|
|
194
|
+
// shader, its state and the streams are all known here.
|
|
195
|
+
const drawn = [...OPAQUE_MODES, ...CHARACTER_MODES, ...OVERRIDE_MODES];
|
|
196
|
+
const jobs = [];
|
|
197
|
+
for (const d of dressed)
|
|
198
|
+
for (const p of d.spec.passes)
|
|
199
|
+
if (drawn.includes(p.lightMode))
|
|
200
|
+
jobs.push(this.host.warm(p.shader, p.state, this.streams(install, p.shader)));
|
|
201
|
+
this.warming.set(model.name, Promise.all(jobs).then(() => { }));
|
|
138
202
|
}
|
|
139
203
|
remove(name) {
|
|
140
204
|
const i = this.installs.get(name);
|
|
@@ -142,7 +206,7 @@ export class NativeLooks {
|
|
|
142
206
|
return;
|
|
143
207
|
this.installs.delete(name);
|
|
144
208
|
this.host.release(`${name}|`);
|
|
145
|
-
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)];
|
|
146
210
|
const texs = i.textures;
|
|
147
211
|
// Freed once the GPU is done with the frames that may still name them.
|
|
148
212
|
void this.device.queue.onSubmittedWorkDone().then(() => {
|
|
@@ -172,11 +236,87 @@ export class NativeLooks {
|
|
|
172
236
|
: {
|
|
173
237
|
unity_RenderingLayer: new Uint32Array([i.model.layers >>> 0, 0, 0, 0]),
|
|
174
238
|
};
|
|
239
|
+
if (i.carried.size)
|
|
240
|
+
this.keyStreams(i);
|
|
175
241
|
}
|
|
176
242
|
pass.end();
|
|
177
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
|
+
}
|
|
178
310
|
streams(i, shader) {
|
|
179
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
|
+
};
|
|
180
320
|
if (semantic === "POSITION")
|
|
181
321
|
return {
|
|
182
322
|
buffer: i.pos,
|
|
@@ -241,8 +381,11 @@ export class NativeLooks {
|
|
|
241
381
|
const textures = {
|
|
242
382
|
...this.frameTextures,
|
|
243
383
|
};
|
|
244
|
-
|
|
384
|
+
const samplers = {};
|
|
385
|
+
for (const [slot, key] of Object.entries(d.spec.textures)) {
|
|
245
386
|
textures[slot] = key === "@diffuse" ? d.draw.diffuse : i.views.get(key);
|
|
387
|
+
samplers[slot] = i.samplers.get(key);
|
|
388
|
+
}
|
|
246
389
|
this.host.draw(pass, {
|
|
247
390
|
shader: p.shader,
|
|
248
391
|
state: p.state,
|
|
@@ -253,8 +396,9 @@ export class NativeLooks {
|
|
|
253
396
|
offset: d.draw.firstIndex * 4,
|
|
254
397
|
count: d.draw.count,
|
|
255
398
|
},
|
|
256
|
-
sources: [perDraw, i.block, d.spec.values, this.globals],
|
|
399
|
+
sources: [perDraw, i.block, d.values, d.spec.values, this.globals],
|
|
257
400
|
textures,
|
|
401
|
+
samplers,
|
|
258
402
|
key: `${i.model.name}|${d.draw.materialName}|${p.lightMode}|${p.shader}`,
|
|
259
403
|
pass: "main",
|
|
260
404
|
});
|
package/dist/unity/skin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skin.d.ts","sourceRoot":"","sources":["../../src/unity/skin.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,eAAe,g0EA8C3B,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"skin.d.ts","sourceRoot":"","sources":["../../src/unity/skin.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,eAAe,g0EA8C3B,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CA6DjG"}
|
package/dist/unity/skin.js
CHANGED
|
@@ -74,8 +74,11 @@ export function tangentsFor(verts, indices) {
|
|
|
74
74
|
const p = (v, k) => verts[v * 8 + k];
|
|
75
75
|
const e1 = [p(b, 0) - p(a, 0), p(b, 1) - p(a, 1), p(b, 2) - p(a, 2)];
|
|
76
76
|
const e2 = [p(c, 0) - p(a, 0), p(c, 1) - p(a, 1), p(c, 2) - p(a, 2)];
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
// v measured upward, as Unity builds tangent space: a PMX uv runs v down,
|
|
78
|
+
// and taken as it is the bitangent — the handedness in w — comes out
|
|
79
|
+
// reversed, which a game normal map reads as its green channel inverted.
|
|
80
|
+
const du1 = p(b, 6) - p(a, 6), dv1 = p(a, 7) - p(b, 7);
|
|
81
|
+
const du2 = p(c, 6) - p(a, 6), dv2 = p(a, 7) - p(c, 7);
|
|
79
82
|
const det = du1 * dv2 - du2 * dv1;
|
|
80
83
|
if (Math.abs(det) < 1e-12)
|
|
81
84
|
continue;
|
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;
|
|
@@ -135,6 +152,13 @@ export declare class NativeStage {
|
|
|
135
152
|
/** Every renderer's draws, resolved once: the stage does not move. */
|
|
136
153
|
private build;
|
|
137
154
|
private addItems;
|
|
155
|
+
/**
|
|
156
|
+
* Every pass's pipeline, compiled before the stage reports loaded (see
|
|
157
|
+
* NativeHost.warm) — side by side, and never at the first draw. Needs only
|
|
158
|
+
* the meshes' stream layouts, so it runs while the pictures decode. The
|
|
159
|
+
* passes are the ones build() keeps: casters that cast, and the main modes.
|
|
160
|
+
*/
|
|
161
|
+
private warm;
|
|
138
162
|
private streams;
|
|
139
163
|
private draw;
|
|
140
164
|
/** One cascade tile of the engine's atlas: every caster's SHADOWCASTER pass. */
|
|
@@ -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 = [];
|
|
@@ -98,6 +108,9 @@ export class NativeStage {
|
|
|
98
108
|
meshes.set(m.id, { info: m, buffer });
|
|
99
109
|
tick();
|
|
100
110
|
}));
|
|
111
|
+
// Loaded means drawable: every pass's pipeline is compiled before this
|
|
112
|
+
// resolves, rather than one at a time in the frames after it.
|
|
113
|
+
const warming = st.warm(hosts, meshes);
|
|
101
114
|
const textures = new Map();
|
|
102
115
|
await Promise.all(pkg.textures.map(async (t) => {
|
|
103
116
|
try {
|
|
@@ -109,6 +122,7 @@ export class NativeStage {
|
|
|
109
122
|
tick(texWeight(t));
|
|
110
123
|
}));
|
|
111
124
|
st.build(meshes, textures, tools.fallback);
|
|
125
|
+
await warming;
|
|
112
126
|
return st;
|
|
113
127
|
}
|
|
114
128
|
async loadTexture(t, read, mipmaps) {
|
|
@@ -222,6 +236,7 @@ export class NativeStage {
|
|
|
222
236
|
];
|
|
223
237
|
const ex = b.size[0] / 2, ey = b.size[1] / 2, ez = b.size[2] / 2;
|
|
224
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]));
|
|
225
240
|
const world = Float32Array.from(m);
|
|
226
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]);
|
|
227
242
|
const perDraw = {
|
|
@@ -257,9 +272,12 @@ export class NativeStage {
|
|
|
257
272
|
const samplers = {
|
|
258
273
|
...globalSamplers,
|
|
259
274
|
};
|
|
260
|
-
// an empty slot reads what the shader declared it defaults to
|
|
275
|
+
// an empty slot reads what the shader declared it defaults to. A default
|
|
276
|
+
// with no name ("") is no picture at all — a cube's, usually — and is
|
|
277
|
+
// left to the host, which stands in by the binding's own kind.
|
|
261
278
|
for (const [slot, def] of Object.entries(mat.defaults ?? {}))
|
|
262
|
-
|
|
279
|
+
if (def && fallback[def])
|
|
280
|
+
views[slot] = fallback[def];
|
|
263
281
|
for (const [slot, id] of [...Object.entries(mat.textures), ...Object.entries(r.textures)]) {
|
|
264
282
|
const t = textures.get(id);
|
|
265
283
|
if (!t)
|
|
@@ -291,6 +309,34 @@ export class NativeStage {
|
|
|
291
309
|
}
|
|
292
310
|
});
|
|
293
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Every pass's pipeline, compiled before the stage reports loaded (see
|
|
314
|
+
* NativeHost.warm) — side by side, and never at the first draw. Needs only
|
|
315
|
+
* the meshes' stream layouts, so it runs while the pictures decode. The
|
|
316
|
+
* passes are the ones build() keeps: casters that cast, and the main modes.
|
|
317
|
+
*/
|
|
318
|
+
warm(hosts, meshes) {
|
|
319
|
+
const jobs = [];
|
|
320
|
+
const mats = new Map(this.pkg.materials.map((m) => [m.id, m]));
|
|
321
|
+
for (const r of this.pkg.renderers) {
|
|
322
|
+
const mesh = meshes.get(r.mesh);
|
|
323
|
+
if (!mesh)
|
|
324
|
+
continue;
|
|
325
|
+
r.materials.forEach((mid, sub) => {
|
|
326
|
+
const mat = mid ? mats.get(mid) : undefined;
|
|
327
|
+
if (!mat || sub >= mesh.info.submeshes.length)
|
|
328
|
+
return;
|
|
329
|
+
for (const pass of mat.passes) {
|
|
330
|
+
const caster = pass.lightMode === "SHADOWCASTER";
|
|
331
|
+
if (caster ? !r.castShadows : !MAIN_MODES.includes(pass.lightMode))
|
|
332
|
+
continue;
|
|
333
|
+
const host = caster ? hosts.shadow : hosts.scene;
|
|
334
|
+
jobs.push(host.warm(pass.shader, pass.state, this.streams(host, { mesh, pass })));
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
return Promise.all(jobs).then(() => { });
|
|
339
|
+
}
|
|
294
340
|
streams(host, it) {
|
|
295
341
|
const info = it.mesh.info;
|
|
296
342
|
return host.inputs(it.pass.shader).map(({ semantic }) => {
|
|
@@ -330,18 +376,24 @@ export class NativeStage {
|
|
|
330
376
|
/** One cascade tile of the engine's atlas: every caster's SHADOWCASTER pass. */
|
|
331
377
|
drawShadow(pass, host, globals, cascade, viewProj, engineScale) {
|
|
332
378
|
const vp = flipY(mul4(viewProj, gameToEngine(engineScale)));
|
|
333
|
-
// ShadowUtils.GetShadowBias as the game
|
|
334
|
-
//
|
|
335
|
-
// 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.
|
|
336
385
|
const rowLen = Math.hypot(vp[0], vp[4], vp[8]);
|
|
337
|
-
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];
|
|
338
389
|
const g = {
|
|
339
390
|
...globals,
|
|
340
391
|
unity_MatrixVP: vp,
|
|
341
392
|
unity_MatrixV: scale4(1),
|
|
342
393
|
unity_MatrixP: vp,
|
|
343
394
|
glstate_matrix_projection: vp,
|
|
344
|
-
|
|
395
|
+
_ShadowBias: bias,
|
|
396
|
+
sim_ShadowBias: bias,
|
|
345
397
|
};
|
|
346
398
|
for (const it of this.casters)
|
|
347
399
|
this.draw(pass, host, it, g, {}, `|c${cascade}`);
|