reze-engine 0.65.0 → 0.66.1

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 (151) hide show
  1. package/dist/engine.d.ts +156 -42
  2. package/dist/engine.d.ts.map +1 -1
  3. package/dist/engine.js +876 -186
  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 +5 -1
  26. package/dist/model.d.ts +14 -1
  27. package/dist/model.d.ts.map +1 -1
  28. package/dist/model.js +27 -1
  29. package/dist/pmx-loader.d.ts +4 -0
  30. package/dist/pmx-loader.d.ts.map +1 -1
  31. package/dist/pmx-loader.js +11 -2
  32. package/dist/shaders/anchor-table.d.ts +11 -0
  33. package/dist/shaders/anchor-table.d.ts.map +1 -1
  34. package/dist/shaders/anchor-table.js +9 -3
  35. package/dist/shaders/directives.d.ts +42 -5
  36. package/dist/shaders/directives.d.ts.map +1 -1
  37. package/dist/shaders/directives.js +51 -4
  38. package/dist/shaders/lights.d.ts +11 -7
  39. package/dist/shaders/lights.d.ts.map +1 -1
  40. package/dist/shaders/lights.js +315 -271
  41. package/dist/shaders/materials/common.d.ts.map +1 -1
  42. package/dist/shaders/materials/common.js +26 -3
  43. package/dist/shaders/materials/nodes.d.ts +1 -1
  44. package/dist/shaders/materials/nodes.d.ts.map +1 -1
  45. package/dist/shaders/materials/nodes.js +191 -271
  46. package/dist/shaders/passes/composite.d.ts +1 -1
  47. package/dist/shaders/passes/composite.d.ts.map +1 -1
  48. package/dist/shaders/passes/composite.js +3 -5
  49. package/dist/shaders/passes/ground.js +1 -1
  50. package/dist/shaders/passes/particles.d.ts.map +1 -1
  51. package/dist/shaders/passes/particles.js +9 -3
  52. package/dist/shaders/passes/probe.d.ts +45 -0
  53. package/dist/shaders/passes/probe.d.ts.map +1 -0
  54. package/dist/shaders/passes/probe.js +230 -0
  55. package/dist/shaders/passes/scene-contract.d.ts +13 -0
  56. package/dist/shaders/passes/scene-contract.d.ts.map +1 -1
  57. package/dist/shaders/passes/scene-contract.js +4 -0
  58. package/dist/shaders/scene-light-api.d.ts.map +1 -1
  59. package/dist/shaders/scene-light-api.js +1 -0
  60. package/dist/unity/globals.d.ts +7 -0
  61. package/dist/unity/globals.d.ts.map +1 -1
  62. package/dist/unity/globals.js +4 -3
  63. package/dist/unity/host.d.ts +3 -0
  64. package/dist/unity/host.d.ts.map +1 -1
  65. package/dist/unity/host.js +41 -7
  66. package/dist/unity/looks.d.ts +42 -0
  67. package/dist/unity/looks.d.ts.map +1 -1
  68. package/dist/unity/looks.js +131 -4
  69. package/dist/unity/stage.d.ts +17 -0
  70. package/dist/unity/stage.d.ts.map +1 -1
  71. package/dist/unity/stage.js +22 -5
  72. package/package.json +1 -1
  73. package/src/engine.ts +949 -215
  74. package/src/graph/compile.ts +4 -0
  75. package/src/graph/presets/body.ts +26 -24
  76. package/src/graph/presets/cloth_rough.ts +8 -8
  77. package/src/graph/presets/cloth_smooth.ts +8 -8
  78. package/src/graph/presets/default.ts +4 -4
  79. package/src/graph/presets/eye.ts +10 -10
  80. package/src/graph/presets/face.ts +28 -26
  81. package/src/graph/presets/hair.ts +6 -6
  82. package/src/graph/presets/metal.ts +8 -8
  83. package/src/graph/presets/stockings.ts +4 -11
  84. package/src/graph/presets/unlit.ts +9 -13
  85. package/src/graph/registry.ts +133 -158
  86. package/src/graph/render-class.ts +5 -2
  87. package/src/graph/slots.ts +5 -1
  88. package/src/model.ts +33 -1
  89. package/src/pmx-loader.ts +11 -2
  90. package/src/shaders/anchor-table.ts +15 -3
  91. package/src/shaders/directives.ts +88 -6
  92. package/src/shaders/lights.ts +464 -415
  93. package/src/shaders/materials/common.ts +26 -3
  94. package/src/shaders/materials/nodes.ts +191 -271
  95. package/src/shaders/passes/composite.ts +3 -5
  96. package/src/shaders/passes/ground.ts +1 -1
  97. package/src/shaders/passes/particles.ts +9 -3
  98. package/src/shaders/passes/probe.ts +240 -0
  99. package/src/shaders/passes/scene-contract.ts +17 -0
  100. package/src/shaders/scene-light-api.ts +1 -0
  101. package/src/unity/globals.ts +7 -3
  102. package/src/unity/host.ts +36 -6
  103. package/src/unity/looks.ts +161 -7
  104. package/src/unity/stage.ts +28 -5
  105. package/dist/physics-debug.d.ts +0 -30
  106. package/dist/physics-debug.d.ts.map +0 -1
  107. package/dist/physics-debug.js +0 -526
  108. package/dist/shaders/agx-lut.d.ts +0 -11
  109. package/dist/shaders/agx-lut.d.ts.map +0 -1
  110. package/dist/shaders/agx-lut.js +0 -29
  111. package/dist/shaders/dfg_lut.d.ts +0 -3
  112. package/dist/shaders/dfg_lut.d.ts.map +0 -1
  113. package/dist/shaders/dfg_lut.js +0 -129
  114. package/dist/shaders/ltc_mag_lut.d.ts +0 -3
  115. package/dist/shaders/ltc_mag_lut.d.ts.map +0 -1
  116. package/dist/shaders/ltc_mag_lut.js +0 -1033
  117. package/dist/shaders/materials/body.d.ts +0 -2
  118. package/dist/shaders/materials/body.d.ts.map +0 -1
  119. package/dist/shaders/materials/body.js +0 -95
  120. package/dist/shaders/materials/cloth_rough.d.ts +0 -2
  121. package/dist/shaders/materials/cloth_rough.d.ts.map +0 -1
  122. package/dist/shaders/materials/cloth_rough.js +0 -69
  123. package/dist/shaders/materials/cloth_smooth.d.ts +0 -2
  124. package/dist/shaders/materials/cloth_smooth.d.ts.map +0 -1
  125. package/dist/shaders/materials/cloth_smooth.js +0 -61
  126. package/dist/shaders/materials/default.d.ts +0 -2
  127. package/dist/shaders/materials/default.d.ts.map +0 -1
  128. package/dist/shaders/materials/default.js +0 -43
  129. package/dist/shaders/materials/eye.d.ts +0 -2
  130. package/dist/shaders/materials/eye.d.ts.map +0 -1
  131. package/dist/shaders/materials/eye.js +0 -60
  132. package/dist/shaders/materials/face.d.ts +0 -2
  133. package/dist/shaders/materials/face.d.ts.map +0 -1
  134. package/dist/shaders/materials/face.js +0 -95
  135. package/dist/shaders/materials/hair.d.ts +0 -2
  136. package/dist/shaders/materials/hair.d.ts.map +0 -1
  137. package/dist/shaders/materials/hair.js +0 -90
  138. package/dist/shaders/materials/metal.d.ts +0 -2
  139. package/dist/shaders/materials/metal.d.ts.map +0 -1
  140. package/dist/shaders/materials/metal.js +0 -77
  141. package/dist/shaders/materials/mmd_classic.d.ts +0 -2
  142. package/dist/shaders/materials/mmd_classic.d.ts.map +0 -1
  143. package/dist/shaders/materials/mmd_classic.js +0 -66
  144. package/dist/shaders/materials/stockings.d.ts +0 -2
  145. package/dist/shaders/materials/stockings.d.ts.map +0 -1
  146. package/dist/shaders/materials/stockings.js +0 -122
  147. package/dist/shaders/passes/physics-debug.d.ts +0 -2
  148. package/dist/shaders/passes/physics-debug.d.ts.map +0 -1
  149. package/dist/shaders/passes/physics-debug.js +0 -69
  150. package/src/shaders/dfg_lut.ts +0 -131
  151. package/src/shaders/ltc_mag_lut.ts +0 -1035
@@ -15,7 +15,7 @@
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
17
 
18
- import { NativeHost, type NativeShader, type NativeStream, type NativeValue, type ValueSource } from "./host"
18
+ import { NativeHost, sameValue, type NativeShader, type NativeStream, type NativeValue, type ValueSource } from "./host"
19
19
  import type { PassState } from "./state"
20
20
  import { UNITY_SKIN_WGSL, tangentsFor } from "./skin"
21
21
  import { characterBlock, type CharacterRig } from "./character"
@@ -28,6 +28,19 @@ export type NativeTexture = {
28
28
  data: Uint8Array
29
29
  /** Colour (sRGB) or data (linear) — how the shader expects to read it. */
30
30
  srgb: boolean
31
+ /** Unity's wrap mode as the game imported it (Repeat, Clamp, Mirror,
32
+ * MirrorOnce); repeating when absent. A clamped mask sampled past its edge
33
+ * reads its border, not the far side. */
34
+ wrap?: string
35
+ /** Unity's filter mode (Point, Bilinear, Trilinear); bilinear when absent. */
36
+ filter?: string
37
+ }
38
+
39
+ const WRAP: Record<string, GPUAddressMode> = {
40
+ Repeat: "repeat",
41
+ Clamp: "clamp-to-edge",
42
+ Mirror: "mirror-repeat",
43
+ MirrorOnce: "mirror-repeat",
31
44
  }
32
45
 
33
46
  export type NativeMaterialSpec = {
@@ -48,6 +61,12 @@ export type NativeLook = {
48
61
  textures: Record<string, NativeTexture>
49
62
  materials: NativeMaterialSpec[]
50
63
  rig?: CharacterRig
64
+ /** The game vertex streams the model's PMX carries, by semantic: the
65
+ * additional UV channel (1–4) that holds each, four floats a vertex, keyed
66
+ * over time by that channel's UV morphs (PMX types 4–7) — a particle's
67
+ * colour over its life on a mesh's own vertex colours. A stream named here
68
+ * reads that channel; any other reads as Unity binds a missing one. */
69
+ streams?: Record<string, number>
51
70
  }
52
71
 
53
72
  /** What the engine lends for one model. */
@@ -72,12 +91,30 @@ export type NativeModel = {
72
91
  headRest: [number, number, number]
73
92
  /** Its rendering-layer bits, for a look without a rig. */
74
93
  layers: number
94
+ /** A PMX additional UV channel (1–4), four floats a vertex, or null. */
95
+ additionalUv: (channel: number) => Float32Array | null
96
+ /** Its morphs, in the order of morphWeights. */
97
+ morphs: readonly { type: number; uvOffsets?: { vertexIndex: number; offset: [number, number, number, number] }[] }[]
98
+ /** The current effective (group-resolved, clamped) morph weights. */
99
+ morphWeights: () => Float32Array
100
+ }
101
+
102
+ /** A vertex stream out of an additional UV channel: its rest values, the
103
+ * channel's morphs, and the weights it was last built at. */
104
+ type CarriedStream = {
105
+ buffer: GPUBuffer
106
+ base: Float32Array
107
+ data: Float32Array
108
+ morphs: { index: number; offsets: { vertexIndex: number; offset: [number, number, number, number] }[] }[]
109
+ weights: Float32Array
75
110
  }
76
111
 
77
112
  type Install = {
78
113
  model: NativeModel
79
114
  look: NativeLook
80
115
  views: Map<string, GPUTextureView>
116
+ /** Per look texture: its sampler, as the game imported the texture. */
117
+ samplers: Map<string, GPUSampler>
81
118
  textures: GPUTexture[]
82
119
  pos: GPUBuffer
83
120
  nrm: GPUBuffer
@@ -85,9 +122,12 @@ type Install = {
85
122
  restTan: GPUBuffer
86
123
  params: GPUBuffer
87
124
  skinBind: GPUBindGroup
88
- /** Per draw of the model: the spec that dresses it, if any. */
89
- dressed: { draw: NativeModel["draws"][number]; spec: NativeMaterialSpec }[]
125
+ /** Per draw of the model: the spec that dresses it, and the values set on
126
+ * that material since (setUniforms), over the spec's. */
127
+ dressed: { draw: NativeModel["draws"][number]; spec: NativeMaterialSpec; values: Record<string, NativeValue> }[]
90
128
  block: Record<string, NativeValue>
129
+ /** The look's streams (NativeLook.streams), by semantic. */
130
+ carried: Map<string, CarriedStream>
91
131
  }
92
132
 
93
133
  const OPAQUE_MODES = ["ALWAYS", "FORWARDBASE"]
@@ -141,6 +181,28 @@ export class NativeLooks {
141
181
  return this.installs.size
142
182
  }
143
183
 
184
+ private samplerCache = new Map<string, GPUSampler>()
185
+
186
+ /** A texture's sampler: its wrap and filter, shared by every texture alike. */
187
+ private sampler(t: NativeTexture): GPUSampler {
188
+ const wrap = WRAP[t.wrap ?? "Repeat"] ?? "repeat"
189
+ const filter: GPUFilterMode = t.filter === "Point" ? "nearest" : "linear"
190
+ const key = `${wrap}|${filter}`
191
+ let s = this.samplerCache.get(key)
192
+ if (!s) {
193
+ s = this.device.createSampler({
194
+ label: `native look sampler ${key}`,
195
+ addressModeU: wrap,
196
+ addressModeV: wrap,
197
+ magFilter: filter,
198
+ minFilter: filter,
199
+ mipmapFilter: filter,
200
+ })
201
+ this.samplerCache.set(key, s)
202
+ }
203
+ return s
204
+ }
205
+
144
206
  has(model: string): boolean {
145
207
  return this.installs.has(model)
146
208
  }
@@ -162,8 +224,10 @@ export class NativeLooks {
162
224
  const d = this.device
163
225
  for (const s of look.shaders) this.host.register(s)
164
226
  const views = new Map<string, GPUTextureView>()
227
+ const samplers = new Map<string, GPUSampler>()
165
228
  const textures: GPUTexture[] = []
166
229
  for (const [key, t] of Object.entries(look.textures)) {
230
+ if (t.wrap || t.filter) samplers.set(key, this.sampler(t))
167
231
  const tex = d.createTexture({
168
232
  label: `${model.name}: ${key}`,
169
233
  size: [t.width, t.height],
@@ -211,12 +275,27 @@ export class NativeLooks {
211
275
  const dressed: Install["dressed"] = []
212
276
  for (const draw of model.draws) {
213
277
  const spec = look.materials.find((m) => m.materials.includes(draw.materialName))
214
- if (spec) dressed.push({ draw, spec })
278
+ if (spec) dressed.push({ draw, spec, values: {} })
279
+ }
280
+ const carried = new Map<string, CarriedStream>()
281
+ for (const [semantic, channel] of Object.entries(look.streams ?? {})) {
282
+ const base = model.additionalUv(channel)
283
+ if (!base || base.length < n * 4) continue
284
+ const morphs = model.morphs
285
+ .map((m, index) => ({ index, type: m.type, offsets: m.uvOffsets ?? [] }))
286
+ .filter((m) => m.type === 3 + channel && m.offsets.length)
287
+ .map(({ index, offsets }) => ({ index, offsets }))
288
+ const buffer = buf(`stream ${semantic}`, n * 4, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST)
289
+ const data = new Float32Array(base.subarray(0, n * 4))
290
+ d.queue.writeBuffer(buffer, 0, data)
291
+ // NaN: the first prepare builds the stream whatever the weights are
292
+ carried.set(semantic, { buffer, base: data.slice(), data, morphs, weights: new Float32Array(morphs.length).fill(NaN) })
215
293
  }
216
294
  const install: Install = {
217
295
  model,
218
296
  look,
219
297
  views,
298
+ samplers,
220
299
  textures,
221
300
  pos,
222
301
  nrm,
@@ -226,6 +305,7 @@ export class NativeLooks {
226
305
  skinBind,
227
306
  dressed,
228
307
  block: {},
308
+ carried,
229
309
  }
230
310
  this.installs.set(model.name, install)
231
311
  // Every pass this look will draw, compiled now and side by side — the
@@ -245,7 +325,7 @@ export class NativeLooks {
245
325
  if (!i) return
246
326
  this.installs.delete(name)
247
327
  this.host.release(`${name}|`)
248
- const bufs = [i.pos, i.nrm, i.tan, i.restTan, i.params]
328
+ const bufs = [i.pos, i.nrm, i.tan, i.restTan, i.params, ...[...i.carried.values()].map((c) => c.buffer)]
249
329
  const texs = i.textures
250
330
  // Freed once the GPU is done with the frames that may still name them.
251
331
  void this.device.queue.onSubmittedWorkDone().then(() => {
@@ -278,12 +358,81 @@ export class NativeLooks {
278
358
  : {
279
359
  unity_RenderingLayer: new Uint32Array([i.model.layers >>> 0, 0, 0, 0]),
280
360
  }
361
+ if (i.carried.size) this.keyStreams(i)
281
362
  }
282
363
  pass.end()
283
364
  }
284
365
 
366
+ /** Each carried stream at the model's current morph weights: its rest values
367
+ * plus every one of its channel's morphs at its weight, rebuilt and uploaded
368
+ * only when one of those weights moved. */
369
+ private keyStreams(i: Install): void {
370
+ const weights = i.model.morphWeights()
371
+ for (const c of i.carried.values()) {
372
+ if (!c.morphs.length) continue
373
+ let moved = false
374
+ for (let k = 0; k < c.morphs.length; k++) {
375
+ const w = weights[c.morphs[k].index] ?? 0
376
+ if (w !== c.weights[k]) {
377
+ c.weights[k] = w
378
+ moved = true
379
+ }
380
+ }
381
+ if (!moved) continue
382
+ c.data.set(c.base)
383
+ for (let k = 0; k < c.morphs.length; k++) {
384
+ const w = c.weights[k]
385
+ if (!w) continue
386
+ for (const o of c.morphs[k].offsets) {
387
+ const at = o.vertexIndex * 4
388
+ if (at + 3 >= c.data.length) continue
389
+ c.data[at] += o.offset[0] * w
390
+ c.data[at + 1] += o.offset[1] * w
391
+ c.data[at + 2] += o.offset[2] * w
392
+ c.data[at + 3] += o.offset[3] * w
393
+ }
394
+ }
395
+ this.device.queue.writeBuffer(c.buffer, 0, c.data as Float32Array<ArrayBuffer>)
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Set some of one dressed material's values (its Unity material properties,
401
+ * as the look's `values` hold them) — what a game animates on a material
402
+ * over a take. Each value stands until set again; the look's own stand
403
+ * under it. Only names the material's spec carries are taken: they are the
404
+ * ones its draws' uniform blocks read per draw. A value equal to the one
405
+ * already set keeps that one's object, so the host, which refills a
406
+ * uniform member only when its value object changes, writes nothing for
407
+ * it. Returns whether the model wears a look that dresses this material.
408
+ */
409
+ setUniforms(model: string, material: string, values: Record<string, NativeValue>): boolean {
410
+ const i = this.installs.get(model)
411
+ if (!i) return false
412
+ let found = false
413
+ for (const d of i.dressed) {
414
+ if (d.draw.materialName !== material) continue
415
+ found = true
416
+ for (const name in values) {
417
+ const v = values[name]
418
+ if (v === undefined || v === null || !(name in d.spec.values)) continue
419
+ const was = d.values[name]
420
+ if (was === undefined || !sameValue(was, v)) d.values[name] = v
421
+ }
422
+ }
423
+ return found
424
+ }
425
+
285
426
  private streams(i: Install, shader: string): NativeStream[] {
286
427
  return this.host.inputs(shader).map(({ semantic }) => {
428
+ const carried = i.carried.get(semantic)
429
+ if (carried)
430
+ return {
431
+ buffer: carried.buffer,
432
+ offset: 0,
433
+ stride: 16,
434
+ format: "float32x4" as const,
435
+ }
287
436
  if (semantic === "POSITION")
288
437
  return {
289
438
  buffer: i.pos,
@@ -348,7 +497,11 @@ export class NativeLooks {
348
497
  const textures: Record<string, GPUTextureView | undefined> = {
349
498
  ...this.frameTextures,
350
499
  }
351
- for (const [slot, key] of Object.entries(d.spec.textures)) textures[slot] = key === "@diffuse" ? d.draw.diffuse : i.views.get(key)
500
+ const samplers: Record<string, GPUSampler | undefined> = {}
501
+ for (const [slot, key] of Object.entries(d.spec.textures)) {
502
+ textures[slot] = key === "@diffuse" ? d.draw.diffuse : i.views.get(key)
503
+ samplers[slot] = i.samplers.get(key)
504
+ }
352
505
  this.host.draw(pass, {
353
506
  shader: p.shader,
354
507
  state: p.state,
@@ -359,8 +512,9 @@ export class NativeLooks {
359
512
  offset: d.draw.firstIndex * 4,
360
513
  count: d.draw.count,
361
514
  },
362
- sources: [perDraw, i.block, d.spec.values, this.globals],
515
+ sources: [perDraw, i.block, d.values, d.spec.values, this.globals],
363
516
  textures,
517
+ samplers,
364
518
  key: `${i.model.name}|${d.draw.materialName}|${p.lightMode}|${p.shader}`,
365
519
  pass: "main",
366
520
  })
@@ -21,6 +21,7 @@
21
21
  import { NativeHost, type NativeShader, type NativeStream, type NativeValue, type ValueSource } from "./host"
22
22
  import type { PassState } from "./state"
23
23
  import { gameToEngine, invert4, mul4, scale4, flipY } from "./globals"
24
+ import { SHADOW_CASCADES } from "../shadow-cascades"
24
25
 
25
26
  export type NativeStageMesh = {
26
27
  id: string
@@ -78,6 +79,12 @@ export type NativeStageLights = {
78
79
  direction: [number, number, number]
79
80
  color: [number, number, number]
80
81
  shadow: number
82
+ /** As the game's pipeline packed it, recorded: _MainLightColor and
83
+ * SimMainLightColor (linear, intensity in w), SimMainLightColorNoInt. */
84
+ unity?: { color: number[]; simColor: number[]; simColorNoInt: number[] }
85
+ /** The Light's shadowBias and shadowNormalBias, in shadow-map texels. */
86
+ shadowBias?: number
87
+ shadowNormalBias?: number
81
88
  }
82
89
  additional: {
83
90
  position: [number, number, number]
@@ -147,6 +154,15 @@ export class NativeStage {
147
154
  min: [number, number, number]
148
155
  max: [number, number, number]
149
156
  }
157
+ /**
158
+ * How far the stage reaches from the origin, in engine units: every
159
+ * renderer's box, casters or not. A game's sky is a dome in the stage
160
+ * (X317's reaches 1900 units out), and the camera's far plane has to reach it.
161
+ */
162
+ get extent(): number {
163
+ return this.reach
164
+ }
165
+ private reach = 0
150
166
  private buffers: GPUBuffer[] = []
151
167
  private textures: GPUTexture[] = []
152
168
  private opaque: Item[] = []
@@ -389,6 +405,7 @@ export class NativeStage {
389
405
  ey = b.size[1] / 2,
390
406
  ez = b.size[2] / 2
391
407
  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)
408
+ this.reach = Math.max(this.reach, Math.hypot(center[0], center[1], center[2]) + Math.hypot(half[0], half[1], half[2]))
392
409
  const world = Float32Array.from(m)
393
410
  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])
394
411
  const perDraw: ValueSource = {
@@ -550,18 +567,24 @@ export class NativeStage {
550
567
  engineScale: number,
551
568
  ): void {
552
569
  const vp = flipY(mul4(viewProj, gameToEngine(engineScale)))
553
- // ShadowUtils.GetShadowBias as the game set it: half a texel along the light
554
- // and half a texel in along the normal, a texel being this tile's width in
555
- // game units over its resolution (2048).
570
+ // ShadowUtils.GetShadowBias as the game sets it: (texel x the light's
571
+ // shadowBias, -texel x its shadowNormalBias), a texel being this tile's
572
+ // width in game units over its resolution. The stage's casters read it as
573
+ // _ShadowBias (Replica's CascadeShadowPass); the character's DrawShadowPass
574
+ // names it sim_ShadowBias. A package that predates the recorded biases
575
+ // takes half a texel of each.
556
576
  const rowLen = Math.hypot(vp[0], vp[4], vp[8])
557
- const texel = rowLen > 0 ? 2 / rowLen / 2048 : 0
577
+ const texel = rowLen > 0 ? 2 / rowLen / SHADOW_CASCADES[cascade].mapSize : 0
578
+ const main = this.pkg.lights.main
579
+ const bias = [texel * (main.shadowBias ?? 0.5), -texel * (main.shadowNormalBias ?? 0.5), 0, 0]
558
580
  const g: Record<string, NativeValue> = {
559
581
  ...globals,
560
582
  unity_MatrixVP: vp,
561
583
  unity_MatrixV: scale4(1),
562
584
  unity_MatrixP: vp,
563
585
  glstate_matrix_projection: vp,
564
- sim_ShadowBias: [0.5 * texel, -0.5 * texel, 0, 0],
586
+ _ShadowBias: bias,
587
+ sim_ShadowBias: bias,
565
588
  }
566
589
  for (const it of this.casters) this.draw(pass, host, it, g, {}, `|c${cascade}`)
567
590
  }
@@ -1,30 +0,0 @@
1
- import type { RezePhysics } from "./physics";
2
- export declare class PhysicsDebugRenderer {
3
- private device;
4
- private bindGroup;
5
- private wirePipelineSphere;
6
- private wirePipelineBox;
7
- private wirePipelineCapsule;
8
- private wireSphereBuffer;
9
- private wireBoxBuffer;
10
- private wireCapsuleBuffer;
11
- private wireSphereCount;
12
- private wireBoxCount;
13
- private wireCapsuleCount;
14
- private solidPipelineSphere;
15
- private solidPipelineBox;
16
- private solidPipelineCapsule;
17
- private solidSphereBuffer;
18
- private solidBoxBuffer;
19
- private solidCapsuleBuffer;
20
- private solidSphereCount;
21
- private solidBoxCount;
22
- private solidCapsuleCount;
23
- private instanceBuffer;
24
- private instanceData;
25
- private instanceCapacity;
26
- constructor(device: GPUDevice, cameraUniformBuffer: GPUBuffer, presentationFormat: GPUTextureFormat);
27
- render(pass: GPURenderPassEncoder, physics: RezePhysics): void;
28
- destroy(): void;
29
- }
30
- //# sourceMappingURL=physics-debug.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"physics-debug.d.ts","sourceRoot":"","sources":["../src/physics-debug.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAmB5C,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,SAAS,CAAc;IAG/B,OAAO,CAAC,kBAAkB,CAAmB;IAC7C,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,mBAAmB,CAAmB;IAC9C,OAAO,CAAC,gBAAgB,CAAW;IACnC,OAAO,CAAC,aAAa,CAAW;IAChC,OAAO,CAAC,iBAAiB,CAAW;IACpC,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,gBAAgB,CAAQ;IAIhC,OAAO,CAAC,mBAAmB,CAAmB;IAC9C,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,oBAAoB,CAAmB;IAC/C,OAAO,CAAC,iBAAiB,CAAW;IACpC,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,kBAAkB,CAAW;IACrC,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,iBAAiB,CAAQ;IAEjC,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,gBAAgB,CAAQ;gBAG9B,MAAM,EAAE,SAAS,EACjB,mBAAmB,EAAE,SAAS,EAC9B,kBAAkB,EAAE,gBAAgB;IA2HtC,MAAM,CAAC,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAmI9D,OAAO,IAAI,IAAI;CAShB"}