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
@@ -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
- const sig = /->\s*@location\(0\)\s*vec4<f32>\s*\{/;
48
- if (!sig.test(head))
49
- throw new Error("native shader: the fragment entry does not return one vec4 target");
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 v = m[1];
56
- body = body.replace(ret, `return RzNativeOut(${v}, vec4f(1.0, 1.0, 0.0, ${v}.a)${ids ? ", vec2u(0u)" : ""});\n}\n`);
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
- const v = textures[name];
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). */
@@ -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,EAAE,KAAK,YAAY,EAAqB,KAAK,WAAW,EAAoB,MAAM,QAAQ,CAAA;AAC7G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAExC,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAG/D,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,6BAA6B;IAC7B,IAAI,EAAE,UAAU,CAAA;IAChB,0EAA0E;IAC1E,IAAI,EAAE,OAAO,CAAA;CACd,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,mDAAmD;IACnD,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,EAAE,CAAA;IACjE,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACnC;kCAC8B;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IACvC,SAAS,EAAE,kBAAkB,EAAE,CAAA;IAC/B,GAAG,CAAC,EAAE,YAAY,CAAA;CACnB,CAAA;AAED,2CAA2C;AAC3C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,YAAY,CAAA;IACtB,OAAO,EAAE,WAAW,CAAA;IACpB,YAAY,EAAE,SAAS,CAAA;IACvB,YAAY,EAAE,SAAS,CAAA;IACvB,aAAa,EAAE,SAAS,CAAA;IACxB,gBAAgB,EAAE,SAAS,CAAA;IAC3B,WAAW,EAAE,SAAS,CAAA;IACtB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAA;QACpB,UAAU,EAAE,MAAM,CAAA;QAClB,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,cAAc,CAAA;KACxB,EAAE,CAAA;IACH,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IACrC,wDAAwD;IACxD,QAAQ,EAAE,MAAM,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;IACxC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAsBD,qBAAa,WAAW;IAapB,OAAO,CAAC,MAAM;IAZhB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,OAAO,CAAC,QAAQ,CAA6B;IAC7C,gEAAgE;IAChE,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,IAAI,CAAW;IACvB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,aAAa,CAAiD;IACtE,OAAO,CAAC,KAAK,CAAI;gBAGP,MAAM,EAAE,SAAS,EACzB,IAAI,EAAE,UAAU;IA6BlB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI3B;0EACsE;IACtE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInC,yDAAyD;IACzD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAKjD,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI;IAmFnD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAc1B;;;OAGG;IACH,OAAO,CACL,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACpC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC,GACnD,IAAI;IAmBP,OAAO,CAAC,OAAO;IAgDf,OAAO,CAAC,QAAQ;IAoChB,sEAAsE;IACtE,OAAO,CAAC,IAAI;IAMZ,+EAA+E;IAC/E,UAAU,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI;IAQ5C,yCAAyC;IACzC,eAAe,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI;CAKlD"}
1
+ {"version":3,"file":"looks.d.ts","sourceRoot":"","sources":["../../src/unity/looks.ts"],"names":[],"mappings":"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"}
@@ -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
- for (const [slot, key] of Object.entries(d.spec.textures))
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
  });
@@ -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":"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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 = [];
@@ -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 set it: half a texel along the light
369
- // and half a texel in along the normal, a texel being this tile's width in
370
- // 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.
371
385
  const rowLen = Math.hypot(vp[0], vp[4], vp[8]);
372
- 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];
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
- sim_ShadowBias: [0.5 * texel, -0.5 * texel, 0, 0],
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}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reze-engine",
3
- "version": "0.65.0",
3
+ "version": "0.66.1",
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",