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
@@ -214,20 +214,51 @@ ${sceneIdPadWgsl("out")}
214
214
  `;
215
215
  }
216
216
  /**
217
- * The mirror in the SHADOW pass — the frame throwing shade on the floor.
218
- *
219
- * Its own shader because the mirror has no vertex buffer and no skeleton: the
220
- * quad is six generated vertices and the model matrix is the whole of it, while
221
- * the ordinary shadow shader is built for skinned geometry with an alpha test.
222
- *
223
- * Depth only, no fragment stage. The pane is opaque across its whole rectangle
224
- * — glass included, because this glass is not see-through — so there is nothing
225
- * to alpha-test and nothing to colour.
226
- *
227
- * The cascade index arrives in its own tiny uniform rather than as a dynamic
228
- * offset: the cascade matrices sit 64 bytes apart in one array, and a dynamic
229
- * uniform offset has to be 256-aligned.
217
+ * Downsample for the reflection's COLOUR chain, one pass per mip level: the
218
+ * Jimenez/COD 13-tap dual box — five weighted 2x2 averages, which rejects the
219
+ * nyquist ringing a plain box would leave in a blurred reflection.
230
220
  */
221
+ export const MIRROR_DOWNSAMPLE_WGSL = /* wgsl */ `
222
+ @vertex fn vs(@builtin(vertex_index) vi: u32) -> @builtin(position) vec4f {
223
+ let x = f32((vi & 1u) << 2u) - 1.0;
224
+ let y = f32((vi & 2u) << 1u) - 1.0;
225
+ return vec4f(x, y, 0.0, 1.0);
226
+ }
227
+
228
+ @group(0) @binding(0) var srcTex: texture_2d<f32>;
229
+ @group(0) @binding(1) var srcSamp: sampler;
230
+
231
+ fn samp(uv: vec2f, off: vec2f) -> vec3f {
232
+ return textureSampleLevel(srcTex, srcSamp, uv + off, 0.0).rgb;
233
+ }
234
+
235
+ @fragment fn fs(@builtin(position) p: vec4f) -> @location(0) vec4f {
236
+ let srcDims = vec2f(textureDimensions(srcTex));
237
+ let t = 1.0 / srcDims;
238
+ // fragCoord.xy reports pixel centers (e.g. 0.5,0.5 for first pixel) — divide by dst dims directly.
239
+ let dstDims = srcDims * 0.5;
240
+ let uv = p.xy / max(dstDims, vec2f(1.0));
241
+ let A = samp(uv, t * vec2f(-2.0, -2.0));
242
+ let B = samp(uv, t * vec2f( 0.0, -2.0));
243
+ let C = samp(uv, t * vec2f( 2.0, -2.0));
244
+ let D = samp(uv, t * vec2f(-1.0, -1.0));
245
+ let E = samp(uv, t * vec2f( 1.0, -1.0));
246
+ let F = samp(uv, t * vec2f(-2.0, 0.0));
247
+ let G = samp(uv, t * vec2f( 0.0, 0.0));
248
+ let H = samp(uv, t * vec2f( 2.0, 0.0));
249
+ let I = samp(uv, t * vec2f(-1.0, 1.0));
250
+ let J = samp(uv, t * vec2f( 1.0, 1.0));
251
+ let K = samp(uv, t * vec2f(-2.0, 2.0));
252
+ let L = samp(uv, t * vec2f( 0.0, 2.0));
253
+ let M = samp(uv, t * vec2f( 2.0, 2.0));
254
+ var o = (D + E + I + J) * (0.5 / 4.0);
255
+ o = o + (A + B + G + F) * (0.125 / 4.0);
256
+ o = o + (B + C + H + G) * (0.125 / 4.0);
257
+ o = o + (F + G + L + K) * (0.125 / 4.0);
258
+ o = o + (G + H + M + L) * (0.125 / 4.0);
259
+ return vec4f(o, 1.0);
260
+ }
261
+ `;
231
262
  /**
232
263
  * Downsample for the reflection's COVERAGE chain.
233
264
  *
@@ -258,6 +289,21 @@ struct VSOut { @builtin(position) pos: vec4f, @location(0) uv: vec2f, };
258
289
  return textureSampleLevel(src, samp, in.uv, 0.0);
259
290
  }
260
291
  `;
292
+ /**
293
+ * The mirror in the SHADOW pass — the frame throwing shade on the floor.
294
+ *
295
+ * Its own shader because the mirror has no vertex buffer and no skeleton: the
296
+ * quad is six generated vertices and the model matrix is the whole of it, while
297
+ * the ordinary shadow shader is built for skinned geometry with an alpha test.
298
+ *
299
+ * Depth only, no fragment stage. The pane is opaque across its whole rectangle
300
+ * — glass included, because this glass is not see-through — so there is nothing
301
+ * to alpha-test and nothing to colour.
302
+ *
303
+ * The cascade index arrives in its own tiny uniform rather than as a dynamic
304
+ * offset: the cascade matrices sit 64 bytes apart in one array, and a dynamic
305
+ * uniform offset has to be 256-aligned.
306
+ */
261
307
  export function mirrorShadowWgsl(cascades) {
262
308
  return /* wgsl */ `
263
309
  struct LightVP { viewProj: array<mat4x4f, ${cascades}>, };
@@ -1 +1 @@
1
- {"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/outline.ts"],"names":[],"mappings":"AAqBA;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAA;AAE5C,wBAAgB,iBAAiB,IAAI,MAAM,CAoI1C"}
1
+ {"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/outline.ts"],"names":[],"mappings":"AAqBA;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAA;AAE5C,wBAAgB,iBAAiB,IAAI,MAAM,CA6L1C"}
@@ -69,14 +69,39 @@ struct VertexOutput {
69
69
  /** The triangle's own threshold, flat — see the material VertexOutput. The
70
70
  * hull traces the body's faces, so it has to lose the same ones. */
71
71
  @location(2) @interpolate(flat) faceT: f32,
72
+ /** How much of a pixel-wide line this one really is (1 = all of it): a line
73
+ * held at the minimum width fades by what it was short. */
74
+ @location(3) coverage: f32,
72
75
  };
73
76
 
77
+ /**
78
+ * Half the frame height (engine units, at the subject) below which a line keeps
79
+ * its constant screen width; wider than that it thins as a world-size line.
80
+ * 12.5 = a frame 25 units tall — a full figure (an MMD model is ~20) with
81
+ * room around her.
82
+ *
83
+ * Not the game's own break (w = 1 game unit = 8 engine units). The game's
84
+ * near width is ~3× MMD's 2·edgeSize px; its world-size line comes down to
85
+ * MMD's width only at a full-figure framing, so that is where the break goes:
86
+ * close-ups and full figures keep today's width, and past that the game's rule
87
+ * holds — NDC offset ∝ 1/w, scaled by the zoom as its projection._m11 scales
88
+ * it. At the game's 8 the demo's own camera (33 units) drew a quarter of
89
+ * today's width, which put every line on the faded minimum.
90
+ */
91
+ const RZ_OUTLINE_FULL_FIGURE = 12.5;
92
+ /** The thinnest a line is drawn, in pixels at 1080p (and never under this many
93
+ * device pixels). A line due to be thinner is drawn this wide and faded by
94
+ * the shortfall, so far lines thin out without aliasing into dashes. */
95
+ const RZ_OUTLINE_MIN_PX = 1.5;
96
+
74
97
  @vertex fn vs(
75
98
  @location(0) position: vec3f,
76
99
  @location(1) normal: vec3f,
77
100
  @location(2) uv: vec2f,
78
101
  @location(3) joints0: vec4<u32>,
79
- @location(4) weights0: vec4<f32>
102
+ @location(4) weights0: vec4<f32>,
103
+ /** xyz: the smoothed rest normal (outline-normals.ts), w: PMX edge scale. */
104
+ @location(5) outlineNormal: vec4f
80
105
  ) -> VertexOutput {
81
106
  var output: VertexOutput;
82
107
  let pos4 = vec4f(position, 1.0);
@@ -93,30 +118,58 @@ struct VertexOutput {
93
118
  let m = skinMats[j];
94
119
  skinnedPos += (m * pos4) * w;
95
120
  let r3 = mat3x3f(m[0].xyz, m[1].xyz, m[2].xyz);
96
- skinnedNrm += (r3 * normal) * w;
121
+ skinnedNrm += (r3 * outlineNormal.xyz) * w;
97
122
  }
98
123
  let worldPos = skinnedPos.xyz;
99
124
  let worldNormal = normalize(skinnedNrm);
100
125
 
101
126
  let clipPos = camera.projection * camera.view * vec4f(worldPos, 1.0);
102
127
 
103
- // babylon-mmd: screenNormal = normalize((view * worldNormal).xy)
128
+ // The push direction is the view-space normal's XY, NOT renormalized — the
129
+ // game's: full length at the silhouette, where the normal lies across the
130
+ // view, and shrinking on surfaces turned toward the camera, so creases
131
+ // facing her draw finer than the rim. Skinned exactly as the colour pass
132
+ // skins the normal, from the smoothed rest normal, so every vertex sharing a
133
+ // position pushes the same way and the hull stays closed over hard edges
134
+ // and UV seams.
104
135
  let viewNormal = (camera.view * vec4f(worldNormal, 0.0)).xyz;
105
- let snLen = length(viewNormal.xy);
106
- let screenNormal = select(vec2f(0.0, 0.0), viewNormal.xy / snLen, snLen > 1e-5);
107
136
 
108
137
  // Reference-height normalization (babylon-mmd ships this variant commented
109
- // out as \`renderHeight = 1080\`): thickness is a constant FRACTION of the
110
- // frame — 2·edgeSize px at 1080p — so retina DPR and 4K export don't thin
111
- // the rims to sub-pixel. Width follows the projection aspect.
138
+ // out as \`renderHeight = 1080\`): the near width is a constant FRACTION of
139
+ // the frame — 2·edgeSize px at 1080p — so retina DPR and 4K export don't
140
+ // thin the rims to sub-pixel. Width follows the projection aspect.
112
141
  // projection[1][1]/projection[0][0] = width/height for a symmetric frustum.
113
142
  let aspect = camera.projection[1][1] / camera.projection[0][0];
114
- let viewport = vec2f(1080.0 * aspect, 1080.0);
143
+ let refViewport = vec2f(1080.0 * aspect, 1080.0);
144
+ let deviceViewport = vec2f(camera.viewportHeight * aspect, camera.viewportHeight);
145
+
146
+ // The game's width (Character/Debug.shader, pass "Outline"): the clip offset
147
+ // is the near offset × min(w, break depth). Up close the ×w cancels the
148
+ // perspective divide — constant screen width; past the break it stops
149
+ // growing, so the NDC offset falls as 1/w like a line of fixed world width.
150
+ // The break is the depth at which the frame is a full figure tall, so a
151
+ // zoomed lens moves it out (see RZ_OUTLINE_FULL_FIGURE). Under an
152
+ // orthographic camera w is 1 and the same min() makes the line world-size
153
+ // once the frame is taller than a figure. The PMX per-vertex edge scale
154
+ // multiplies it all, as vertex colour alpha does in the game.
155
+ let w = max(clipPos.w, 1e-4);
156
+ let breakDepth = RZ_OUTLINE_FULL_FIGURE * camera.projection[1][1];
157
+ let nearNdc = viewNormal.xy * (material.edgeSize * outlineNormal.w * 4.0 / refViewport);
158
+ var ndc = nearNdc * (min(w, breakDepth) / w);
115
159
 
116
- // NDC offset = edgeSize · 4/viewport, ×w so the perspective divide cancels:
117
- // constant screen thickness at any distance (babylon-mmd parity).
118
- let offset = screenNormal * (material.edgeSize * 4.0 / viewport) * clipPos.w;
119
- output.position = vec4f(clipPos.xy + offset, clipPos.z, clipPos.w);
160
+ // Antialiased minimum (the game's _OutlineAntialias): held at the minimum
161
+ // width and faded by the shortfall, never thinner. The game fades by
162
+ // sqrt(coverage.x · coverage.y), per axis; for one width that is the ratio
163
+ // itself.
164
+ let px = length(ndc * deviceViewport * 0.5);
165
+ let minPx = RZ_OUTLINE_MIN_PX * max(1.0, camera.viewportHeight / 1080.0);
166
+ var coverage = 1.0;
167
+ if (px < minPx) {
168
+ coverage = px / minPx;
169
+ ndc = select(vec2f(0.0), ndc * (minPx / px), px > 1e-6);
170
+ }
171
+ output.coverage = coverage;
172
+ output.position = vec4f(clipPos.xy + ndc * w, clipPos.z, clipPos.w);
120
173
  output.uv = uv;
121
174
  output.restPos = position;
122
175
  output.faceT = rz_dissolve_threshold(position);
@@ -151,7 +204,11 @@ ${sceneFsOutWgsl({ name: "FSOut", aux: "mask" })}
151
204
  discard;
152
205
  }
153
206
  var out: FSOut;
154
- out.color = vec4f(material.edgeColor.rgb, material.edgeColor.a * texA);
207
+ // Blended, not alpha-to-coverage: this pass already blends (the texture
208
+ // alpha above), it is drawn right after the surface it traces so what lies
209
+ // under a faded line is already there, and 4× MSAA would quantize a fade to
210
+ // four steps.
211
+ out.color = vec4f(material.edgeColor.rgb, material.edgeColor.a * texA * input.coverage);
155
212
  out.mask = vec4f(1.0, 1.0, 0.0, out.color.a);
156
213
  ${sceneIdPadWgsl("out")} return out;
157
214
  }
@@ -1 +1 @@
1
- {"version":3,"file":"particles.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/particles.ts"],"names":[],"mappings":"AAgCA,sEAAsE;AACtE,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;IACb;;mFAE+E;IAC/E,UAAU,EAAE,MAAM,CAAA;IAClB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB,CAAA;AAkCD,qDAAqD;AACrD;0EAC0E;AAC1E,KAAK,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAA;AAEpD,KAAK,cAAc,GAAG;IACpB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,aAAa,CAAA;IACpB,qEAAqE;IACrE,KAAK,EAAE,OAAO,CAAA;IACd;;+BAE2B;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;iEAK6D;IAC7D,KAAK,EAAE,OAAO,CAAA;IACd;;;;;;;yEAOqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;;;;;kFAO8E;IAC9E,IAAI,EAAE,OAAO,CAAA;IACb;;;wEAGoE;IACpE,QAAQ,EAAE,MAAM,CAAA;IAChB;mDAC+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,0FAA0F;AAC1F,eAAO,MAAM,sBAAsB,KAAK,CAAA;AACxC,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC;;sDAEsD;AACtD,eAAO,MAAM,yBAAyB,KAAK,CAAA;AAC3C,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC;uCACuC;AACvC,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAC1C,eAAO,MAAM,gCAAgC,KAAK,CAAA;AAClD,eAAO,MAAM,6BAA6B,KAAK,CAAA;AAE/C,oEAAoE;AACpE,eAAO,MAAM,eAAe,KAAK,CAAA;AAwDjC;;2EAE2E;AAC3E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CASnJ;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CA6ExF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAiMvF"}
1
+ {"version":3,"file":"particles.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/particles.ts"],"names":[],"mappings":"AAgCA,sEAAsE;AACtE,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;IACb;;mFAE+E;IAC/E,UAAU,EAAE,MAAM,CAAA;IAClB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB,CAAA;AAkCD,qDAAqD;AACrD;0EAC0E;AAC1E,KAAK,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAA;AAEpD,KAAK,cAAc,GAAG;IACpB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,aAAa,CAAA;IACpB,qEAAqE;IACrE,KAAK,EAAE,OAAO,CAAA;IACd;;+BAE2B;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;iEAK6D;IAC7D,KAAK,EAAE,OAAO,CAAA;IACd;;;;;;;yEAOqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;;;;;kFAO8E;IAC9E,IAAI,EAAE,OAAO,CAAA;IACb;;;wEAGoE;IACpE,QAAQ,EAAE,MAAM,CAAA;IAChB;mDAC+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,0FAA0F;AAC1F,eAAO,MAAM,sBAAsB,KAAK,CAAA;AACxC,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC;;sDAEsD;AACtD,eAAO,MAAM,yBAAyB,KAAK,CAAA;AAC3C,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC;uCACuC;AACvC,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAC1C,eAAO,MAAM,gCAAgC,KAAK,CAAA;AAClD,eAAO,MAAM,6BAA6B,KAAK,CAAA;AAE/C,oEAAoE;AACpE,eAAO,MAAM,eAAe,KAAK,CAAA;AAwDjC;;2EAE2E;AAC3E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CASnJ;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CA6ExF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAuMvF"}
@@ -290,9 +290,15 @@ ${src.orient ? ` // the author's own plane (particleOrient): a card on a surfac
290
290
  let o = particleOrient(p, ii);
291
291
  right = o[0];
292
292
  up = o[1];
293
- ` : ""} let s = sin(p.rot);
293
+ ` : ""}${/\bfn\s+particlePivot\s*\(/.test(src.wgsl) ? ` // the card's pivot (particlePivot, in half-size units of the quad): the
294
+ // corners are offset by it BEFORE the turn, so the card turns about its
295
+ // pivot rather than its centre — Unity's renderer pivot, a lighthouse beam
296
+ // whose card starts at the lamp instead of straddling it
297
+ let cp = c + particlePivot(p, ii);
298
+ ` : ` let cp = c;
299
+ `} let s = sin(p.rot);
294
300
  let k = cos(p.rot);
295
- var r = vec2f(c.x * k - c.y * s, c.x * s + c.y * k);
301
+ var r = vec2f(cp.x * k - cp.y * s, cp.x * s + cp.y * k);
296
302
  // Stretched along the direction of travel ON SCREEN — which is not the world
297
303
  // direction once the camera is off-axis. Rain falling straight down is nearly
298
304
  // a point when viewed from above and a long streak from the side, and taking
@@ -304,7 +310,7 @@ ${src.orient ? ` // the author's own plane (particleOrient): a card on a surfac
304
310
  let vlen = length(vec2f(vr, vu));
305
311
  if (vlen > 1e-5) {
306
312
  let d = vec2f(vr, vu) / vlen;
307
- r = vec2f(d.y, -d.x) * c.x + d * (c.y * p.stretch);
313
+ r = vec2f(d.y, -d.x) * cp.x + d * (cp.y * p.stretch);
308
314
  }
309
315
  }
310
316
  let world = p.pos + (right * r.x + up * r.y) * p.size;
@@ -0,0 +1,45 @@
1
+ /** Face size of the capture, and of the cube the materials read. The game
2
+ * bakes 64²; the capture is twice that so the base level is antialiased. */
3
+ export declare const PROBE_CAPTURE_SIZE = 128;
4
+ export declare const PROBE_SIZE = 64;
5
+ /** 64² down to 1²: seven levels, the game's own count. */
6
+ export declare const PROBE_LEVELS = 7;
7
+ export declare const PROBE_CAPTURE_LEVELS = 8;
8
+ /**
9
+ * The perceptual roughness level m of the probe was convolved with, on
10
+ * Unity's probe curve: m = r·(1.7 − 0.7r)·6 (UNITY_SPECCUBE_LOD_STEPS), the
11
+ * convention the game's baked probes follow and its lookup (×8, clamped at 6)
12
+ * reads against. Level 0 is the unblurred capture.
13
+ */
14
+ export declare function probeLevelRoughness(level: number): number;
15
+ /**
16
+ * The perceptual roughness level m of the sky's equirect chain was convolved
17
+ * with: the engine's own lookup is lod = sqrt(r)·(levels − 1), so level m is
18
+ * r = (m / (levels − 1))².
19
+ */
20
+ export declare function skyLevelRoughness(level: number, levels: number): number;
21
+ /**
22
+ * The compose step: the stage as captured, with the world's sky laid in
23
+ * behind it wherever the capture's coverage says nothing was drawn — an open
24
+ * stage reflects its sky, an interior its walls. Built on the material
25
+ * prelude for rzWorldSpecularLod, which knows every kind of sky the scene may
26
+ * have (an HDRI, a gradient, one colour). Only the bindings it reads end up in
27
+ * its layout ("auto"): the light uniform, the sampler and the sky at group 0,
28
+ * and its own three past the material set's.
29
+ */
30
+ export declare const PROBE_COMPOSE_WGSL: string;
31
+ /**
32
+ * The cube's own passes: a mip from the level above (mode 0 — one bilinear
33
+ * tap at the child texel's direction is the 2×2 average), and the GGX
34
+ * convolution into the probe the materials read (mode 1).
35
+ */
36
+ export declare const PROBE_FILTER_WGSL: string;
37
+ /**
38
+ * The sky's mips, convolved: level m of the equirect the materials read
39
+ * (rzWorldSpecularLod) becomes the GGX-filtered sky at the roughness that
40
+ * level stands for, sampled from the box-averaged chain the upload built.
41
+ * Directions follow the composite's dome: u = 0.5 + atan2(x, z)/2π,
42
+ * v = 0.5 − asin(y)/π.
43
+ */
44
+ export declare const SKY_PREFILTER_WGSL: string;
45
+ //# sourceMappingURL=probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/probe.ts"],"names":[],"mappings":"AAgBA;6EAC6E;AAC7E,eAAO,MAAM,kBAAkB,MAAM,CAAA;AACrC,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B,0DAA0D;AAC1D,eAAO,MAAM,YAAY,IAAI,CAAA;AAC7B,eAAO,MAAM,oBAAoB,IAAI,CAAA;AAErC;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIvE;AA+DD;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,QAmB9B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,QAoC7B,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,QAmD9B,CAAA"}
@@ -0,0 +1,230 @@
1
+ // The reflection probe's GPU passes, and the sky's prefilter.
2
+ //
3
+ // A game does not reflect the sky alone: it bakes a cube of the stage itself
4
+ // from somewhere in the middle of it, prefilters it down its mips with the
5
+ // specular lobe, and every surface reads it box-projected onto the stage's
6
+ // bounds. The engine does the same once a stage has loaded (Engine:
7
+ // captureReflectionProbe): six renders of the stage into a 128² cube, the
8
+ // sky laid in wherever nothing was drawn, a mip chain, then a GGX convolution
9
+ // into the 64² cube the materials sample (rzProbeSpecular in nodes.ts).
10
+ //
11
+ // The world's sky gets the same convolution down its equirect mips, in place
12
+ // of the box average they were built from.
13
+ import { NODES_WGSL } from "../materials/nodes";
14
+ import { COMMON_MATERIAL_PRELUDE_WGSL, DISSOLVE_WGSL } from "../materials/common";
15
+ /** Face size of the capture, and of the cube the materials read. The game
16
+ * bakes 64²; the capture is twice that so the base level is antialiased. */
17
+ export const PROBE_CAPTURE_SIZE = 128;
18
+ export const PROBE_SIZE = 64;
19
+ /** 64² down to 1²: seven levels, the game's own count. */
20
+ export const PROBE_LEVELS = 7;
21
+ export const PROBE_CAPTURE_LEVELS = 8;
22
+ /**
23
+ * The perceptual roughness level m of the probe was convolved with, on
24
+ * Unity's probe curve: m = r·(1.7 − 0.7r)·6 (UNITY_SPECCUBE_LOD_STEPS), the
25
+ * convention the game's baked probes follow and its lookup (×8, clamped at 6)
26
+ * reads against. Level 0 is the unblurred capture.
27
+ */
28
+ export function probeLevelRoughness(level) {
29
+ if (level <= 0)
30
+ return 0;
31
+ const m = Math.min(level, 6);
32
+ return Math.min((10.2 - Math.sqrt(Math.max(104.04 - 16.8 * m, 0))) / 8.4, 1);
33
+ }
34
+ /**
35
+ * The perceptual roughness level m of the sky's equirect chain was convolved
36
+ * with: the engine's own lookup is lod = sqrt(r)·(levels − 1), so level m is
37
+ * r = (m / (levels − 1))².
38
+ */
39
+ export function skyLevelRoughness(level, levels) {
40
+ if (level <= 0 || levels <= 1)
41
+ return 0;
42
+ const t = level / (levels - 1);
43
+ return Math.min(t * t, 1);
44
+ }
45
+ /** A cube face's direction for a uv on it (uv.y down), in the convention the
46
+ * GPU samples a cube with — the same one the capture cameras render. */
47
+ const FACE_DIR_WGSL = /* wgsl */ `
48
+ fn rz_face_dir(face: u32, uv: vec2f) -> vec3f {
49
+ let s = uv.x * 2.0 - 1.0;
50
+ let t = uv.y * 2.0 - 1.0;
51
+ switch face {
52
+ case 0u: { return normalize(vec3f(1.0, -t, -s)); }
53
+ case 1u: { return normalize(vec3f(-1.0, -t, s)); }
54
+ case 2u: { return normalize(vec3f(s, 1.0, t)); }
55
+ case 3u: { return normalize(vec3f(s, -1.0, -t)); }
56
+ case 4u: { return normalize(vec3f(s, -t, 1.0)); }
57
+ default: { return normalize(vec3f(-s, -t, -1.0)); }
58
+ }
59
+ }
60
+
61
+ struct RzFullOut { @builtin(position) pos: vec4f, @location(0) uv: vec2f };
62
+
63
+ @vertex fn vs_full(@builtin(vertex_index) i: u32) -> RzFullOut {
64
+ var o: RzFullOut;
65
+ let x = f32(i32(i / 2u) * 4 - 1);
66
+ let y = f32(i32(i % 2u) * 4 - 1);
67
+ o.pos = vec4f(x, y, 0.0, 1.0);
68
+ o.uv = vec2f(x * 0.5 + 0.5, 0.5 - y * 0.5);
69
+ return o;
70
+ }
71
+ `;
72
+ /** GGX importance sampling, the filtered kind (Křivánek & Colbert): each
73
+ * sample reads the source at the mip whose texel matches its solid angle, so
74
+ * a few dozen taps integrate a wide lobe without the fireflies a point sample
75
+ * of a bright lamp would leave. */
76
+ const GGX_SAMPLING_WGSL = /* wgsl */ `
77
+ fn rz_hammersley(i: u32, n: u32) -> vec2f {
78
+ var b = (i << 16u) | (i >> 16u);
79
+ b = ((b & 0x55555555u) << 1u) | ((b & 0xAAAAAAAAu) >> 1u);
80
+ b = ((b & 0x33333333u) << 2u) | ((b & 0xCCCCCCCCu) >> 2u);
81
+ b = ((b & 0x0F0F0F0Fu) << 4u) | ((b & 0xF0F0F0F0u) >> 4u);
82
+ b = ((b & 0x00FF00FFu) << 8u) | ((b & 0xFF00FF00u) >> 8u);
83
+ return vec2f(f32(i) / f32(n), f32(b) * 2.3283064365386963e-10);
84
+ }
85
+
86
+ /** A half vector about N for the lobe at alpha = a (= perceptual r²). */
87
+ fn rz_ggx_half(xi: vec2f, N: vec3f, a: f32) -> vec3f {
88
+ let phi = 6.283185307 * xi.x;
89
+ let cosT = sqrt((1.0 - xi.y) / (1.0 + (a * a - 1.0) * xi.y));
90
+ let sinT = sqrt(max(1.0 - cosT * cosT, 0.0));
91
+ let h = vec3f(sinT * cos(phi), sinT * sin(phi), cosT);
92
+ let up = select(vec3f(1.0, 0.0, 0.0), vec3f(0.0, 0.0, 1.0), abs(N.z) < 0.999);
93
+ let tx = normalize(cross(up, N));
94
+ let ty = cross(N, tx);
95
+ return normalize(tx * h.x + ty * h.y + N * h.z);
96
+ }
97
+
98
+ fn rz_ggx_d(nh: f32, a: f32) -> f32 {
99
+ let a2 = a * a;
100
+ let d = nh * nh * (a2 - 1.0) + 1.0;
101
+ return a2 / (3.141592653589793 * d * d);
102
+ }
103
+ `;
104
+ /**
105
+ * The compose step: the stage as captured, with the world's sky laid in
106
+ * behind it wherever the capture's coverage says nothing was drawn — an open
107
+ * stage reflects its sky, an interior its walls. Built on the material
108
+ * prelude for rzWorldSpecularLod, which knows every kind of sky the scene may
109
+ * have (an HDRI, a gradient, one colour). Only the bindings it reads end up in
110
+ * its layout ("auto"): the light uniform, the sampler and the sky at group 0,
111
+ * and its own three past the material set's.
112
+ */
113
+ export const PROBE_COMPOSE_WGSL = NODES_WGSL +
114
+ COMMON_MATERIAL_PRELUDE_WGSL +
115
+ DISSOLVE_WGSL +
116
+ FACE_DIR_WGSL +
117
+ /* wgsl */ `
118
+ struct RzProbeStep { face: u32, lod: f32, roughness: f32, srcSize: f32 };
119
+ @group(0) @binding(20) var rzCaptureColor: texture_2d_array<f32>;
120
+ @group(0) @binding(21) var rzCaptureAux: texture_2d_array<f32>;
121
+ @group(0) @binding(22) var<uniform> rzStep: RzProbeStep;
122
+
123
+ @fragment fn fs_compose(in: RzFullOut) -> @location(0) vec4f {
124
+ let size = textureDimensions(rzCaptureColor);
125
+ let px = vec2u(min(in.pos.xy, vec2f(size) - vec2f(1.0)));
126
+ let c = textureLoad(rzCaptureColor, px, rzStep.face, 0).rgb;
127
+ let cover = saturate(textureLoad(rzCaptureAux, px, rzStep.face, 0).g);
128
+ let sky = rzWorldSpecularLod(rz_face_dir(rzStep.face, in.uv), 0.0, 0.0);
129
+ return vec4f(c + sky * (1.0 - cover), 1.0);
130
+ }
131
+ `;
132
+ /**
133
+ * The cube's own passes: a mip from the level above (mode 0 — one bilinear
134
+ * tap at the child texel's direction is the 2×2 average), and the GGX
135
+ * convolution into the probe the materials read (mode 1).
136
+ */
137
+ export const PROBE_FILTER_WGSL = FACE_DIR_WGSL +
138
+ GGX_SAMPLING_WGSL +
139
+ /* wgsl */ `
140
+ struct RzProbeStep { face: u32, lod: f32, roughness: f32, srcSize: f32, mode: u32 };
141
+ @group(0) @binding(0) var rzSrc: texture_cube<f32>;
142
+ @group(0) @binding(1) var rzSamp: sampler;
143
+ @group(0) @binding(2) var<uniform> rzStep: RzProbeStep;
144
+
145
+ const RZ_PROBE_SAMPLES: u32 = 128u;
146
+
147
+ @fragment fn fs_filter(in: RzFullOut) -> @location(0) vec4f {
148
+ let N = rz_face_dir(rzStep.face, in.uv);
149
+ let r = rzStep.roughness;
150
+ if (rzStep.mode == 0u || r < 0.002) {
151
+ return vec4f(textureSampleLevel(rzSrc, rzSamp, N, rzStep.lod).rgb, 1.0);
152
+ }
153
+ let a = r * r;
154
+ let texelSolid = 4.0 * 3.141592653589793 / (6.0 * rzStep.srcSize * rzStep.srcSize);
155
+ let maxLod = f32(textureNumLevels(rzSrc) - 1u);
156
+ var sum = vec3f(0.0);
157
+ var weight = 0.0;
158
+ for (var i = 0u; i < RZ_PROBE_SAMPLES; i++) {
159
+ let H = rz_ggx_half(rz_hammersley(i, RZ_PROBE_SAMPLES), N, a);
160
+ let L = 2.0 * dot(N, H) * H - N;
161
+ let nl = dot(N, L);
162
+ if (nl <= 0.0) { continue; }
163
+ // N = V: the pdf over L is D·(N·H)/(4·V·H) = D/4.
164
+ let pdf = rz_ggx_d(saturate(dot(N, H)), a) * 0.25;
165
+ let sampleSolid = 1.0 / (f32(RZ_PROBE_SAMPLES) * pdf + 1e-6);
166
+ let lod = clamp(0.5 * log2(sampleSolid / texelSolid) + 1.0, 0.0, maxLod);
167
+ sum += textureSampleLevel(rzSrc, rzSamp, L, lod).rgb * nl;
168
+ weight += nl;
169
+ }
170
+ return vec4f(sum / max(weight, 1e-4), 1.0);
171
+ }
172
+ `;
173
+ /**
174
+ * The sky's mips, convolved: level m of the equirect the materials read
175
+ * (rzWorldSpecularLod) becomes the GGX-filtered sky at the roughness that
176
+ * level stands for, sampled from the box-averaged chain the upload built.
177
+ * Directions follow the composite's dome: u = 0.5 + atan2(x, z)/2π,
178
+ * v = 0.5 − asin(y)/π.
179
+ */
180
+ export const SKY_PREFILTER_WGSL = GGX_SAMPLING_WGSL +
181
+ /* wgsl */ `
182
+ struct RzFullOut { @builtin(position) pos: vec4f, @location(0) uv: vec2f };
183
+
184
+ @vertex fn vs_full(@builtin(vertex_index) i: u32) -> RzFullOut {
185
+ var o: RzFullOut;
186
+ let x = f32(i32(i / 2u) * 4 - 1);
187
+ let y = f32(i32(i % 2u) * 4 - 1);
188
+ o.pos = vec4f(x, y, 0.0, 1.0);
189
+ o.uv = vec2f(x * 0.5 + 0.5, 0.5 - y * 0.5);
190
+ return o;
191
+ }
192
+
193
+ struct RzSkyStep { roughness: f32, srcWidth: f32, srcHeight: f32, spare: f32 };
194
+ @group(0) @binding(0) var rzSky: texture_2d<f32>;
195
+ @group(0) @binding(1) var rzSamp: sampler;
196
+ @group(0) @binding(2) var<uniform> rzStep: RzSkyStep;
197
+
198
+ const RZ_SKY_SAMPLES: u32 = 64u;
199
+
200
+ fn rz_sky_dir(uv: vec2f) -> vec3f {
201
+ let phi = (uv.x - 0.5) * 6.283185307;
202
+ let lat = (0.5 - uv.y) * 3.141592653589793;
203
+ return vec3f(cos(lat) * sin(phi), sin(lat), cos(lat) * cos(phi));
204
+ }
205
+
206
+ fn rz_sky_uv(d: vec3f) -> vec2f {
207
+ return vec2f(0.5 + atan2(d.x, d.z) * 0.15915494309, 0.5 - asin(clamp(d.y, -1.0, 1.0)) * 0.31830988618);
208
+ }
209
+
210
+ @fragment fn fs_sky(in: RzFullOut) -> @location(0) vec4f {
211
+ let N = rz_sky_dir(in.uv);
212
+ let a = rzStep.roughness * rzStep.roughness;
213
+ let texelSolid = 4.0 * 3.141592653589793 / (rzStep.srcWidth * rzStep.srcHeight);
214
+ let maxLod = f32(textureNumLevels(rzSky) - 1u);
215
+ var sum = vec3f(0.0);
216
+ var weight = 0.0;
217
+ for (var i = 0u; i < RZ_SKY_SAMPLES; i++) {
218
+ let H = rz_ggx_half(rz_hammersley(i, RZ_SKY_SAMPLES), N, a);
219
+ let L = 2.0 * dot(N, H) * H - N;
220
+ let nl = dot(N, L);
221
+ if (nl <= 0.0) { continue; }
222
+ let pdf = rz_ggx_d(saturate(dot(N, H)), a) * 0.25;
223
+ let sampleSolid = 1.0 / (f32(RZ_SKY_SAMPLES) * pdf + 1e-6);
224
+ let lod = clamp(0.5 * log2(sampleSolid / texelSolid) + 1.0, 0.0, maxLod);
225
+ sum += textureSampleLevel(rzSky, rzSamp, rz_sky_uv(L), lod).rgb * nl;
226
+ weight += nl;
227
+ }
228
+ return vec4f(sum / max(weight, 1e-4), 1.0);
229
+ }
230
+ `;
@@ -73,6 +73,12 @@ type SceneRenderClass =
73
73
  * X309's night sky was. Out of WRITES_ID for the mirror's reason — a sheet of
74
74
  * light is not an object anything should be able to pick or outline. */
75
75
  | "material-additive"
76
+ /** A material whose colour arrives ALREADY weighted by its coverage — a
77
+ * game's glass (Blend One OneMinusSrcAlpha): the pane's diffuse fades with
78
+ * its alpha while its reflection does not, which a src-alpha blend cannot
79
+ * express. Out of WRITES_ID for the mirror's reason: a window is not what a
80
+ * click on the figure behind it means. */
81
+ | "material-premultiplied"
76
82
  /** Particles and ribbons in their default, non-additive mode. */
77
83
  | "particle"
78
84
  /** Particles declaring `#blend additive` — LIGHT rather than matter, so
@@ -85,6 +91,13 @@ type SceneRenderClass =
85
91
  * whole, and an ordinary alpha-over aux so a ribbon's mask does not
86
92
  * saturate along every overlap. */
87
93
  | "trail"
94
+ /** Ribbons declaring `#blend over` — MATTER rather than light: laid over
95
+ * what is behind them by their own alpha, the way a game's trail material
96
+ * with Blend One OneMinusSrcAlpha draws. A dark band then darkens, which an
97
+ * additive ribbon can never do; it is how a deep-blue smoke tail reads as a
98
+ * tail at all. The fragment writes straight colour, so the colour blend is
99
+ * src-alpha like any other alpha-over class. */
100
+ | "trail-over"
88
101
  /** The transparent depth prepass: it exists to write DEPTH after the fabric's
89
102
  * colour blended, so an outline drawn later is occluded behind it. It must
90
103
  * therefore write no colour at all — the targets exist only to make the
@@ -1 +1 @@
1
- {"version":3,"file":"scene-contract.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/scene-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;uDAEuD;AACvD,MAAM,MAAM,YAAY,GAAG;IACzB,+CAA+C;IAC/C,GAAG,EAAE,gBAAgB,CAAA;IACrB,iEAAiE;IACjE,GAAG,EAAE,gBAAgB,CAAA;CACtB,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,gBAA6B,CAAA;AAkB3D,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAE3C;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;;;;;GAMG;AACH,KAAK,gBAAgB;AACnB,2DAA2D;AACzD,UAAU;AACZ;;+CAE+C;GAC7C,QAAQ;AACV,uEAAuE;GACrE,SAAS;AACX;;;;6EAI6E;GAC3E,QAAQ;AACV;;;;;;yEAMyE;GACvE,mBAAmB;AACrB,iEAAiE;GAC/D,UAAU;AACZ;;;mDAGmD;GACjD,mBAAmB;AACrB;;;oCAGoC;GAClC,OAAO;AACT;;;kDAGkD;GAChD,eAAe,CAAA;AAyFnB;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,GAAG,mBAAmB,EAAE,CAoBhG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAE3E;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAmB7E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD"}
1
+ {"version":3,"file":"scene-contract.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/scene-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;uDAEuD;AACvD,MAAM,MAAM,YAAY,GAAG;IACzB,+CAA+C;IAC/C,GAAG,EAAE,gBAAgB,CAAA;IACrB,iEAAiE;IACjE,GAAG,EAAE,gBAAgB,CAAA;CACtB,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,gBAA6B,CAAA;AAkB3D,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAE3C;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;;;;;GAMG;AACH,KAAK,gBAAgB;AACnB,2DAA2D;AACzD,UAAU;AACZ;;+CAE+C;GAC7C,QAAQ;AACV,uEAAuE;GACrE,SAAS;AACX;;;;6EAI6E;GAC3E,QAAQ;AACV;;;;;;yEAMyE;GACvE,mBAAmB;AACrB;;;;2CAI2C;GACzC,wBAAwB;AAC1B,iEAAiE;GAC/D,UAAU;AACZ;;;mDAGmD;GACjD,mBAAmB;AACrB;;;oCAGoC;GAClC,OAAO;AACT;;;;;iDAKiD;GAC/C,YAAY;AACd;;;kDAGkD;GAChD,eAAe,CAAA;AA6FnB;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,GAAG,mBAAmB,EAAE,CAoBhG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAE3E;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAmB7E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD"}
@@ -114,6 +114,9 @@ const BLENDS = {
114
114
  // The same pair the additive particles use: light into the colour target, and
115
115
  // coverage that still accumulates so bloom and the composite can see it.
116
116
  "material-additive": [ADD_KEEP_ALPHA, ADD_BOTH],
117
+ // The colour premultiplied by the graph (game_pbr's glass); the aux is
118
+ // written straight, as every material's is.
119
+ "material-premultiplied": [PREMULTIPLIED_OVER, ALPHA_OVER],
117
120
  // PREMULTIPLIED, like the ground and for the same reason: what a mirror
118
121
  // writes is a sample of the HDR target, and that target already holds colour
119
122
  // premultiplied by its own alpha. Handed to the src-alpha blend it would be
@@ -132,6 +135,7 @@ const BLENDS = {
132
135
  particle: [PREMULTIPLIED_OVER, ALPHA_OVER],
133
136
  "particle-additive": [ADD_KEEP_ALPHA, ADD_BOTH],
134
137
  trail: [ADD_PREMULTIPLIED, ALPHA_OVER],
138
+ "trail-over": [ALPHA_OVER, ALPHA_OVER],
135
139
  };
136
140
  /**
137
141
  * The colour targets a scene-pass pipeline of this class declares, in
@@ -1 +1 @@
1
- {"version":3,"file":"scene-light-api.d.ts","sourceRoot":"","sources":["../../src/shaders/scene-light-api.ts"],"names":[],"mappings":"AAkBA;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAI,GAAG,MAAM,WAwBzC,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,OAAO,CAAA;AAEjC,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,EAAE,KAAK,MAAM,EAAE,SAAS,MAAM,EAAE,IAAI,MAAM,WAkChF,CAAA;AAED,+DAA+D;AAC/D,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA2CjF"}
1
+ {"version":3,"file":"scene-light-api.d.ts","sourceRoot":"","sources":["../../src/shaders/scene-light-api.ts"],"names":[],"mappings":"AAkBA;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAI,GAAG,MAAM,WAwBzC,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,OAAO,CAAA;AAEjC,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,EAAE,KAAK,MAAM,EAAE,SAAS,MAAM,EAAE,IAAI,MAAM,WAkChF,CAAA;AAED,+DAA+D;AAC/D,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA4CjF"}
@@ -126,6 +126,7 @@ export function sceneLightApi(on, group, binding) {
126
126
  return /* wgsl */ `
127
127
  fn rzShadow(p: vec3f) -> f32 { return 1.0; }
128
128
  fn rzWorldAmbient(n: vec3f) -> vec3f { return vec3f(0.0); }
129
+ fn rzWorldAmbientAvg() -> vec3f { return vec3f(0.0); }
129
130
  `;
130
131
  }
131
132
  const n = SHADOW_CASCADES.length;
@@ -43,6 +43,13 @@ export type UnityFrameInput = {
43
43
  /** The direction the main light travels, unit; null for none. */
44
44
  sunDirection: [number, number, number] | null;
45
45
  sunColor: [number, number, number];
46
+ /** A game stage's own main light as its pipeline packed it (recorded), which
47
+ * its shaders get in place of sunColor; null for the scene sun's. */
48
+ sunUnity?: {
49
+ color: number[];
50
+ simColor: number[];
51
+ simColorNoInt: number[];
52
+ } | null;
46
53
  sunShadow: number;
47
54
  lights: UnityLight[];
48
55
  /** Ambient as the engine's folded SH9 (27 floats, ibl.ts), or null for flat. */
@@ -1 +1 @@
1
- {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../../src/unity/globals.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../../src/unity/globals.ts"],"names":[],"mappings":"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"}