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.
Files changed (173) hide show
  1. package/dist/engine.d.ts +300 -94
  2. package/dist/engine.d.ts.map +1 -1
  3. package/dist/engine.js +1628 -787
  4. package/dist/graph/compile.d.ts.map +1 -1
  5. package/dist/graph/compile.js +5 -0
  6. package/dist/graph/presets/body.d.ts.map +1 -1
  7. package/dist/graph/presets/body.js +26 -24
  8. package/dist/graph/presets/cloth_rough.js +8 -8
  9. package/dist/graph/presets/cloth_smooth.js +8 -8
  10. package/dist/graph/presets/default.js +4 -4
  11. package/dist/graph/presets/eye.js +10 -10
  12. package/dist/graph/presets/face.d.ts.map +1 -1
  13. package/dist/graph/presets/face.js +28 -26
  14. package/dist/graph/presets/hair.js +6 -6
  15. package/dist/graph/presets/metal.js +8 -8
  16. package/dist/graph/presets/stockings.d.ts.map +1 -1
  17. package/dist/graph/presets/stockings.js +4 -11
  18. package/dist/graph/presets/unlit.d.ts.map +1 -1
  19. package/dist/graph/presets/unlit.js +9 -13
  20. package/dist/graph/registry.d.ts.map +1 -1
  21. package/dist/graph/registry.js +128 -157
  22. package/dist/graph/render-class.d.ts +5 -2
  23. package/dist/graph/render-class.d.ts.map +1 -1
  24. package/dist/graph/slots.d.ts.map +1 -1
  25. package/dist/graph/slots.js +12 -2
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/model.d.ts +23 -1
  29. package/dist/model.d.ts.map +1 -1
  30. package/dist/model.js +41 -1
  31. package/dist/outline-normals.d.ts +12 -0
  32. package/dist/outline-normals.d.ts.map +1 -0
  33. package/dist/outline-normals.js +100 -0
  34. package/dist/pmx-loader.d.ts +7 -0
  35. package/dist/pmx-loader.d.ts.map +1 -1
  36. package/dist/pmx-loader.js +17 -3
  37. package/dist/shaders/anchor-table.d.ts +11 -0
  38. package/dist/shaders/anchor-table.d.ts.map +1 -1
  39. package/dist/shaders/anchor-table.js +9 -3
  40. package/dist/shaders/directives.d.ts +42 -5
  41. package/dist/shaders/directives.d.ts.map +1 -1
  42. package/dist/shaders/directives.js +51 -4
  43. package/dist/shaders/lights.d.ts +11 -7
  44. package/dist/shaders/lights.d.ts.map +1 -1
  45. package/dist/shaders/lights.js +315 -271
  46. package/dist/shaders/materials/common.d.ts.map +1 -1
  47. package/dist/shaders/materials/common.js +30 -5
  48. package/dist/shaders/materials/nodes.d.ts +1 -1
  49. package/dist/shaders/materials/nodes.d.ts.map +1 -1
  50. package/dist/shaders/materials/nodes.js +191 -271
  51. package/dist/shaders/passes/bloom.d.ts +4 -3
  52. package/dist/shaders/passes/bloom.d.ts.map +1 -1
  53. package/dist/shaders/passes/bloom.js +58 -87
  54. package/dist/shaders/passes/composite.d.ts +1 -1
  55. package/dist/shaders/passes/composite.d.ts.map +1 -1
  56. package/dist/shaders/passes/composite.js +121 -77
  57. package/dist/shaders/passes/ground.js +1 -1
  58. package/dist/shaders/passes/mirror.d.ts +18 -12
  59. package/dist/shaders/passes/mirror.d.ts.map +1 -1
  60. package/dist/shaders/passes/mirror.js +59 -13
  61. package/dist/shaders/passes/outline.d.ts.map +1 -1
  62. package/dist/shaders/passes/outline.js +71 -14
  63. package/dist/shaders/passes/particles.d.ts.map +1 -1
  64. package/dist/shaders/passes/particles.js +9 -3
  65. package/dist/shaders/passes/probe.d.ts +45 -0
  66. package/dist/shaders/passes/probe.d.ts.map +1 -0
  67. package/dist/shaders/passes/probe.js +230 -0
  68. package/dist/shaders/passes/scene-contract.d.ts +13 -0
  69. package/dist/shaders/passes/scene-contract.d.ts.map +1 -1
  70. package/dist/shaders/passes/scene-contract.js +4 -0
  71. package/dist/shaders/scene-light-api.d.ts.map +1 -1
  72. package/dist/shaders/scene-light-api.js +1 -0
  73. package/dist/unity/globals.d.ts +7 -0
  74. package/dist/unity/globals.d.ts.map +1 -1
  75. package/dist/unity/globals.js +4 -3
  76. package/dist/unity/host.d.ts +18 -0
  77. package/dist/unity/host.d.ts.map +1 -1
  78. package/dist/unity/host.js +144 -70
  79. package/dist/unity/looks.d.ts +47 -0
  80. package/dist/unity/looks.d.ts.map +1 -1
  81. package/dist/unity/looks.js +150 -6
  82. package/dist/unity/skin.d.ts.map +1 -1
  83. package/dist/unity/skin.js +5 -2
  84. package/dist/unity/stage.d.ts +24 -0
  85. package/dist/unity/stage.d.ts.map +1 -1
  86. package/dist/unity/stage.js +59 -7
  87. package/package.json +1 -1
  88. package/src/engine.ts +2010 -1033
  89. package/src/graph/compile.ts +4 -0
  90. package/src/graph/presets/body.ts +26 -24
  91. package/src/graph/presets/cloth_rough.ts +8 -8
  92. package/src/graph/presets/cloth_smooth.ts +8 -8
  93. package/src/graph/presets/default.ts +4 -4
  94. package/src/graph/presets/eye.ts +10 -10
  95. package/src/graph/presets/face.ts +28 -26
  96. package/src/graph/presets/hair.ts +6 -6
  97. package/src/graph/presets/metal.ts +8 -8
  98. package/src/graph/presets/stockings.ts +4 -11
  99. package/src/graph/presets/unlit.ts +9 -13
  100. package/src/graph/registry.ts +133 -158
  101. package/src/graph/render-class.ts +5 -2
  102. package/src/graph/slots.ts +12 -2
  103. package/src/index.ts +1 -0
  104. package/src/model.ts +50 -1
  105. package/src/outline-normals.ts +110 -0
  106. package/src/pmx-loader.ts +18 -3
  107. package/src/shaders/anchor-table.ts +15 -3
  108. package/src/shaders/directives.ts +88 -6
  109. package/src/shaders/lights.ts +464 -415
  110. package/src/shaders/materials/common.ts +30 -5
  111. package/src/shaders/materials/nodes.ts +191 -271
  112. package/src/shaders/passes/bloom.ts +59 -87
  113. package/src/shaders/passes/composite.ts +121 -77
  114. package/src/shaders/passes/ground.ts +1 -1
  115. package/src/shaders/passes/mirror.ts +60 -13
  116. package/src/shaders/passes/outline.ts +71 -14
  117. package/src/shaders/passes/particles.ts +9 -3
  118. package/src/shaders/passes/probe.ts +240 -0
  119. package/src/shaders/passes/scene-contract.ts +17 -0
  120. package/src/shaders/scene-light-api.ts +1 -0
  121. package/src/unity/globals.ts +7 -3
  122. package/src/unity/host.ts +93 -20
  123. package/src/unity/looks.ts +182 -9
  124. package/src/unity/skin.ts +5 -2
  125. package/src/unity/stage.ts +66 -7
  126. package/dist/physics-debug.d.ts +0 -30
  127. package/dist/physics-debug.d.ts.map +0 -1
  128. package/dist/physics-debug.js +0 -526
  129. package/dist/shaders/agx-lut.d.ts +0 -11
  130. package/dist/shaders/agx-lut.d.ts.map +0 -1
  131. package/dist/shaders/agx-lut.js +0 -29
  132. package/dist/shaders/dfg_lut.d.ts +0 -3
  133. package/dist/shaders/dfg_lut.d.ts.map +0 -1
  134. package/dist/shaders/dfg_lut.js +0 -129
  135. package/dist/shaders/ltc_mag_lut.d.ts +0 -3
  136. package/dist/shaders/ltc_mag_lut.d.ts.map +0 -1
  137. package/dist/shaders/ltc_mag_lut.js +0 -1033
  138. package/dist/shaders/materials/body.d.ts +0 -2
  139. package/dist/shaders/materials/body.d.ts.map +0 -1
  140. package/dist/shaders/materials/body.js +0 -95
  141. package/dist/shaders/materials/cloth_rough.d.ts +0 -2
  142. package/dist/shaders/materials/cloth_rough.d.ts.map +0 -1
  143. package/dist/shaders/materials/cloth_rough.js +0 -69
  144. package/dist/shaders/materials/cloth_smooth.d.ts +0 -2
  145. package/dist/shaders/materials/cloth_smooth.d.ts.map +0 -1
  146. package/dist/shaders/materials/cloth_smooth.js +0 -61
  147. package/dist/shaders/materials/default.d.ts +0 -2
  148. package/dist/shaders/materials/default.d.ts.map +0 -1
  149. package/dist/shaders/materials/default.js +0 -43
  150. package/dist/shaders/materials/eye.d.ts +0 -2
  151. package/dist/shaders/materials/eye.d.ts.map +0 -1
  152. package/dist/shaders/materials/eye.js +0 -60
  153. package/dist/shaders/materials/face.d.ts +0 -2
  154. package/dist/shaders/materials/face.d.ts.map +0 -1
  155. package/dist/shaders/materials/face.js +0 -95
  156. package/dist/shaders/materials/hair.d.ts +0 -2
  157. package/dist/shaders/materials/hair.d.ts.map +0 -1
  158. package/dist/shaders/materials/hair.js +0 -90
  159. package/dist/shaders/materials/metal.d.ts +0 -2
  160. package/dist/shaders/materials/metal.d.ts.map +0 -1
  161. package/dist/shaders/materials/metal.js +0 -77
  162. package/dist/shaders/materials/mmd_classic.d.ts +0 -2
  163. package/dist/shaders/materials/mmd_classic.d.ts.map +0 -1
  164. package/dist/shaders/materials/mmd_classic.js +0 -66
  165. package/dist/shaders/materials/stockings.d.ts +0 -2
  166. package/dist/shaders/materials/stockings.d.ts.map +0 -1
  167. package/dist/shaders/materials/stockings.js +0 -122
  168. package/dist/shaders/passes/physics-debug.d.ts +0 -2
  169. package/dist/shaders/passes/physics-debug.d.ts.map +0 -1
  170. package/dist/shaders/passes/physics-debug.js +0 -69
  171. package/src/shaders/agx-lut.ts +0 -30
  172. package/src/shaders/dfg_lut.ts +0 -131
  173. package/src/shaders/ltc_mag_lut.ts +0 -1035
@@ -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
- this.installs.set(model.name, {
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
- for (const [slot, key] of Object.entries(d.spec.textures))
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
  });
@@ -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,CA0DjG"}
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"}
@@ -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
- const du1 = p(b, 6) - p(a, 6), dv1 = p(b, 7) - p(a, 7);
78
- const du2 = p(c, 6) - p(a, 6), dv2 = p(c, 7) - p(a, 7);
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;
@@ -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":"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"}
1
+ {"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../../src/unity/stage.ts"],"names":[],"mappings":"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"}
@@ -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
- views[slot] = fallback[def] ?? fallback.white;
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 set it: half a texel along the light
334
- // and half a texel in along the normal, a texel being this tile's width in
335
- // game units over its resolution (2048).
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 / 2048 : 0;
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
- sim_ShadowBias: [0.5 * texel, -0.5 * texel, 0, 0],
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}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reze-engine",
3
- "version": "0.64.0",
3
+ "version": "0.66.0",
4
4
  "description": "A lightweight WebGPU engine for real-time 3D MMD/PMX model rendering",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",