@forgeax/engine-render 0.1.32 → 0.1.33

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 (250) hide show
  1. package/README.md +379 -33
  2. package/dist/assembly/analytic-fog-registration.d.ts +3 -0
  3. package/dist/assembly/analytic-fog-registration.d.ts.map +1 -0
  4. package/dist/assembly/fxaa-registration.d.ts +4 -0
  5. package/dist/assembly/fxaa-registration.d.ts.map +1 -0
  6. package/dist/assembly/lod-observation.d.ts +4 -0
  7. package/dist/assembly/lod-observation.d.ts.map +1 -0
  8. package/dist/assembly/motion-blur-registration.d.ts +3 -0
  9. package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
  10. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  11. package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
  12. package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
  13. package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
  14. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
  15. package/dist/assembly/webgpu-ready.d.ts +1 -1
  16. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  17. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  18. package/dist/bloom-admission.d.ts +13 -0
  19. package/dist/bloom-admission.d.ts.map +1 -0
  20. package/dist/{chunk-DRR7D3KX.mjs → chunk-3RTCJTH4.mjs} +12 -9
  21. package/dist/chunk-3RTCJTH4.mjs.map +1 -0
  22. package/dist/{chunk-S665NJNF.mjs → chunk-LEAXOMYJ.mjs} +3 -3
  23. package/dist/{chunk-S665NJNF.mjs.map → chunk-LEAXOMYJ.mjs.map} +1 -1
  24. package/dist/{chunk-6TFBXLRJ.mjs → chunk-NB2S7ZRX.mjs} +155 -11
  25. package/dist/chunk-NB2S7ZRX.mjs.map +1 -0
  26. package/dist/{chunk-LULCA3OF.mjs → chunk-NNQL7CB3.mjs} +4 -4
  27. package/dist/{chunk-LULCA3OF.mjs.map → chunk-NNQL7CB3.mjs.map} +1 -1
  28. package/dist/{chunk-4NNZQCL3.mjs → chunk-OO3DRYK7.mjs} +66 -200
  29. package/dist/chunk-OO3DRYK7.mjs.map +1 -0
  30. package/dist/{chunk-GWCEMDVR.mjs → chunk-PLAXOOX5.mjs} +232 -7
  31. package/dist/chunk-PLAXOOX5.mjs.map +1 -0
  32. package/dist/{chunk-JRIPCMYC.mjs → chunk-VOZWDM3L.mjs} +283 -193
  33. package/dist/chunk-VOZWDM3L.mjs.map +1 -0
  34. package/dist/{chunk-JCIRYQ4V.mjs → chunk-ZDQWGQW7.mjs} +10 -4
  35. package/dist/chunk-ZDQWGQW7.mjs.map +1 -0
  36. package/dist/components/atmosphere.d.ts +2 -0
  37. package/dist/components/atmosphere.d.ts.map +1 -1
  38. package/dist/components/camera.d.ts +20 -4
  39. package/dist/components/camera.d.ts.map +1 -1
  40. package/dist/components/mesh-filter.d.ts +6 -5
  41. package/dist/components/mesh-filter.d.ts.map +1 -1
  42. package/dist/components/motion-blur.d.ts +1 -0
  43. package/dist/components/motion-blur.d.ts.map +1 -1
  44. package/dist/construct-renderer.mjs +2865 -526
  45. package/dist/construct-renderer.mjs.map +1 -1
  46. package/dist/device/gpu-residency.d.ts +6 -0
  47. package/dist/device/gpu-residency.d.ts.map +1 -1
  48. package/dist/environment/analytic-fog.d.ts +6 -0
  49. package/dist/environment/analytic-fog.d.ts.map +1 -0
  50. package/dist/errors/render.d.ts +6 -2
  51. package/dist/errors/render.d.ts.map +1 -1
  52. package/dist/extract/camera.d.ts.map +1 -1
  53. package/dist/extract/contracts.d.ts +7 -0
  54. package/dist/extract/contracts.d.ts.map +1 -1
  55. package/dist/extract/environment.d.ts +2 -0
  56. package/dist/extract/environment.d.ts.map +1 -1
  57. package/dist/features/error-reporting.d.ts +13 -0
  58. package/dist/features/error-reporting.d.ts.map +1 -0
  59. package/dist/features/host.d.ts +5 -0
  60. package/dist/features/host.d.ts.map +1 -1
  61. package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
  62. package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
  63. package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
  64. package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
  65. package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
  66. package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
  67. package/dist/features/plan.d.ts +7 -4
  68. package/dist/features/plan.d.ts.map +1 -1
  69. package/dist/features/prepared-gpu-work.d.ts +9 -5
  70. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  71. package/dist/features/render-graph-compute.d.ts.map +1 -1
  72. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  73. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  74. package/dist/gpu-driven/prepared-draw.d.ts +7 -0
  75. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  76. package/dist/gpu-driven/production-raster.d.ts +3 -1
  77. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  78. package/dist/gpu-driven/view-gpu.d.ts +9 -0
  79. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  80. package/dist/gpu-scene.d.ts +6 -1
  81. package/dist/gpu-scene.d.ts.map +1 -1
  82. package/dist/index.d.ts +5 -2
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.mjs +5 -5
  85. package/dist/inspection-types.d.ts +43 -2
  86. package/dist/inspection-types.d.ts.map +1 -1
  87. package/dist/instances.d.ts +8 -1
  88. package/dist/instances.d.ts.map +1 -1
  89. package/dist/internal.mjs +6 -6
  90. package/dist/pipeline/standard-post.d.ts +28 -19
  91. package/dist/pipeline/standard-post.d.ts.map +1 -1
  92. package/dist/pipeline-spec.d.ts +2 -2
  93. package/dist/record/frame-snapshot.d.ts +3 -0
  94. package/dist/record/frame-snapshot.d.ts.map +1 -1
  95. package/dist/record/frame-targets.d.ts.map +1 -1
  96. package/dist/record/frame.d.ts +5 -2
  97. package/dist/record/frame.d.ts.map +1 -1
  98. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  99. package/dist/record/mesh-ssbo.d.ts +6 -5
  100. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  101. package/dist/record/render-context.d.ts +12 -28
  102. package/dist/record/render-context.d.ts.map +1 -1
  103. package/dist/record/shadow-pass.d.ts.map +1 -1
  104. package/dist/record/skybox-post-pass.d.ts +5 -3
  105. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  106. package/dist/record/typed-frame-graph.d.ts +1 -1
  107. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  108. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  109. package/dist/render-contract.d.ts +24 -4
  110. package/dist/render-contract.d.ts.map +1 -1
  111. package/dist/render-pipeline.d.ts +3 -1
  112. package/dist/render-pipeline.d.ts.map +1 -1
  113. package/dist/render-system-extract-tail.d.ts.map +1 -1
  114. package/dist/render-system-extract.d.ts +8 -1
  115. package/dist/render-system-extract.d.ts.map +1 -1
  116. package/dist/render-system.d.ts +7 -1
  117. package/dist/render-system.d.ts.map +1 -1
  118. package/dist/scene/render-scene.d.ts +2 -0
  119. package/dist/scene/render-scene.d.ts.map +1 -1
  120. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  121. package/dist/temporal/frame.d.ts +7 -0
  122. package/dist/temporal/frame.d.ts.map +1 -1
  123. package/dist/temporal/index.mjs +5 -5
  124. package/dist/temporal/view.d.ts +6 -1
  125. package/dist/temporal/view.d.ts.map +1 -1
  126. package/dist/typed-render-graph-primitives.d.ts +10 -7
  127. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  128. package/dist/volume/component.d.ts +0 -1
  129. package/dist/volume/component.d.ts.map +1 -1
  130. package/dist/volume/passes.d.ts.map +1 -1
  131. package/dist/volume/temporal.d.ts +3 -1
  132. package/dist/volume/temporal.d.ts.map +1 -1
  133. package/package.json +21 -21
  134. package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
  135. package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
  136. package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
  137. package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
  138. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
  139. package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
  140. package/src/__tests__/environment-selection.unit.test.ts +12 -0
  141. package/src/__tests__/factory-contract.integration.test.ts +331 -68
  142. package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
  143. package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
  144. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
  145. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +1 -1
  146. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
  147. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +11 -0
  148. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
  149. package/src/__tests__/gpu-scene.unit.test.ts +91 -0
  150. package/src/__tests__/instances-store.unit.test.ts +75 -0
  151. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
  152. package/src/__tests__/motion-blur-compute.dawn.test.ts +583 -0
  153. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +21 -0
  154. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
  155. package/src/__tests__/public-surface.test-d.ts +8 -0
  156. package/src/__tests__/render-error-code-owner.test-d.ts +2 -0
  157. package/src/__tests__/render-feature-error-reporting.unit.test.ts +24 -0
  158. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
  159. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +31 -0
  160. package/src/__tests__/renderer-frame-transaction.integration.test.ts +7 -1
  161. package/src/__tests__/shader-manifest-fixture.ts +4 -4
  162. package/src/__tests__/skinned-shadow-caster.test.ts +2 -0
  163. package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
  164. package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
  165. package/src/__tests__/standard-pipeline.integration.test.ts +18 -8
  166. package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
  167. package/src/__tests__/temporal-view.unit.test.ts +2 -1
  168. package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
  169. package/src/__tests__/volume-optics-oracle.unit.test.ts +3 -1
  170. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +177 -13
  171. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +447 -61
  172. package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
  173. package/src/__tests__/volumetric-fog-topology.unit.test.ts +19 -3
  174. package/src/assembly/analytic-fog-registration.ts +14 -0
  175. package/src/assembly/fxaa-registration.ts +17 -0
  176. package/src/assembly/lod-observation.ts +12 -0
  177. package/src/assembly/motion-blur-registration.ts +17 -0
  178. package/src/assembly/renderer-facade.ts +2 -0
  179. package/src/assembly/temporal-post-process-prewarm.ts +40 -0
  180. package/src/assembly/webgpu-ready-contract.ts +8 -3
  181. package/src/assembly/webgpu-ready.ts +181 -245
  182. package/src/assembly/webgpu-renderer.ts +16 -31
  183. package/src/bloom-admission.ts +21 -0
  184. package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
  185. package/src/components/atmosphere.ts +4 -0
  186. package/src/components/camera.ts +66 -10
  187. package/src/components/mesh-filter.ts +11 -9
  188. package/src/components/motion-blur.ts +1 -0
  189. package/src/device/gpu-residency.ts +56 -12
  190. package/src/environment/analytic-fog.ts +44 -0
  191. package/src/environment/background.ts +2 -2
  192. package/src/errors/render.ts +14 -1
  193. package/src/extract/camera.ts +20 -7
  194. package/src/extract/contracts.ts +7 -0
  195. package/src/extract/environment.ts +4 -0
  196. package/src/features/error-reporting.ts +78 -0
  197. package/src/features/host.ts +25 -12
  198. package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
  199. package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
  200. package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
  201. package/src/features/motion-blur/motion-blur-params.ts +70 -2
  202. package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
  203. package/src/features/plan.ts +25 -8
  204. package/src/features/prepared-gpu-work.ts +86 -35
  205. package/src/features/render-graph-compute.ts +13 -5
  206. package/src/features/render-graph-contribution.ts +2 -0
  207. package/src/gpu-driven/material-artifacts.ts +2 -7
  208. package/src/gpu-driven/prepared-draw.ts +15 -10
  209. package/src/gpu-driven/production-raster.ts +83 -7
  210. package/src/gpu-driven/view-gpu.ts +17 -0
  211. package/src/gpu-scene.ts +188 -21
  212. package/src/index.ts +32 -0
  213. package/src/inspection-types.ts +60 -2
  214. package/src/instances.ts +80 -1
  215. package/src/pipeline/standard-post.ts +307 -78
  216. package/src/pipeline-spec.ts +5 -5
  217. package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
  218. package/src/record/__tests__/temporal-payload.unit.test.ts +2 -1
  219. package/src/record/frame-snapshot.ts +5 -1
  220. package/src/record/frame-targets.ts +10 -6
  221. package/src/record/frame.ts +163 -22
  222. package/src/record/main-pass-geometry.ts +30 -1
  223. package/src/record/main-pass-sprite-draws.ts +6 -1
  224. package/src/record/mesh-ssbo.ts +43 -6
  225. package/src/record/render-context.ts +12 -28
  226. package/src/record/shadow-pass.ts +6 -1
  227. package/src/record/skybox-post-pass.ts +122 -196
  228. package/src/record/typed-frame-graph.ts +153 -9
  229. package/src/recovery/render-system-candidate.ts +22 -10
  230. package/src/render-contract.ts +23 -4
  231. package/src/render-pipeline.ts +6 -1
  232. package/src/render-system-extract-tail.ts +16 -0
  233. package/src/render-system-extract.ts +45 -13
  234. package/src/render-system.ts +255 -120
  235. package/src/scene/render-scene.ts +85 -4
  236. package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
  237. package/src/temporal/frame-coordinator.ts +8 -1
  238. package/src/temporal/frame.ts +20 -0
  239. package/src/temporal/view.ts +13 -2
  240. package/src/typed-render-graph-primitives.ts +121 -48
  241. package/src/volume/component.ts +0 -1
  242. package/src/volume/passes.ts +8 -4
  243. package/src/volume/resources.ts +1 -1
  244. package/src/volume/temporal.ts +11 -0
  245. package/dist/chunk-4NNZQCL3.mjs.map +0 -1
  246. package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
  247. package/dist/chunk-DRR7D3KX.mjs.map +0 -1
  248. package/dist/chunk-GWCEMDVR.mjs.map +0 -1
  249. package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
  250. package/dist/chunk-JRIPCMYC.mjs.map +0 -1
package/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # `@forgeax/engine-render`
2
2
 
3
+ > [!NOTE]
4
+ > This package-owner README contains physical `@forgeax/engine-render` imports
5
+ > in internal ownership examples. Game-facing code should use the public
6
+ > facade `@forgeax/engine/render`; the Bloom consumer route is documented in
7
+ > [hello-bloom](../../apps/hello/bloom/README.md).
8
+
3
9
  > [!IMPORTANT]
4
10
  > The Standard pipeline keeps dark-gradient color in `rgba16float` until one
5
11
  > `outputTransform` reaches the `surface.storage.raw` endpoint; `inspect()` and
@@ -8,6 +14,16 @@
8
14
 
9
15
  ## Public frame contract
10
16
 
17
+ `Fog` provides distance fog with exponential height density through one
18
+ finite-depth fullscreen pass before temporal resolve, Bloom and tone mapping.
19
+ `density`, `heightFalloff`, linear `color` and `maxOpacity` are selected from
20
+ the frame's resource owner. Disabled or zero-density fog allocates no fog target;
21
+ there is no 3D texture, froxel grid or temporal history. The authored sky remains
22
+ unchanged. FXAA, TAA and no-AA use single-sample depth; MSAA is rejected until a
23
+ matching depth resolve is available. Translucent surfaces that do not write depth
24
+ use the opaque background depth. Use `VolumetricFog` for spatial density and
25
+ lighting/scattering effects; the meadow-style distance haze needs only `Fog`.
26
+
11
27
  ## 灯光最短入口
12
28
 
13
29
  三条最短入口:
@@ -207,6 +223,8 @@ index path, not a second schema.
207
223
  import {
208
224
  ANTIALIAS_TAA,
209
225
  Atmosphere,
226
+ BLOOM_DISABLED,
227
+ CAMERA_EXPOSURE_MODE_MANUAL,
210
228
  Camera,
211
229
  Fog,
212
230
  type FramePlan,
@@ -229,6 +247,17 @@ code-specific `detail`; they do not create a second registry or silently pick
229
247
  the first entity. Frame facts contain IDs, revisions, and POD values only, not
230
248
  textures, buffers, devices, or other live GPU objects.
231
249
 
250
+ An Atmosphere also requires exactly one `DirectionalLight` sun. A direct render
251
+ extraction with no sun routes `SunCardinalityError` through the World-owned
252
+ error boundary (`console.error` with the structured error) before extraction
253
+ throws; that internal route is deliberately separate from `app.onError`.
254
+ `app.onError` receives errors returned by the App frame loop and renderer event
255
+ stream. Inspect `error.code` and `error.detail.value`, repair the owning World,
256
+ then retry the same extraction or the next frame. For zero suns, spawn one
257
+ `DirectionalLight`; for multiple suns, remove the extras so the Atmosphere has
258
+ one owner. The renderer does not manufacture a fallback sun or retain a
259
+ partially selected environment.
260
+
232
261
  The Standard graph renders an Atmosphere source as a 128-by-128, six-face
233
262
  `rgba16float` sky cube and a background pass before scene geometry. The selected
234
263
  DirectionalLight supplies the sun direction, color, and illuminance; the sun
@@ -240,6 +269,42 @@ Its color and intensity remain the lighting controls; no Skylight means no
240
269
  global ambient contribution. An explicit equirect keeps its image source.
241
270
  Use a neutral Skylight tint when comparing local captures against the sky.
242
271
 
272
+ ### Atmosphere controls and fixed-exposure comparisons
273
+
274
+ `Atmosphere` keeps the visible disc and the analytic sky response as separate
275
+ controls. `circumsolarStrength` and `circumsolarWidth` affect only the Mie
276
+ forward lobe used while producing the cached sky cube. The defaults preserve the
277
+ baseline response; `sunAngularRadius` still controls the separate disc in the
278
+ background pass and does not grow a halo.
279
+
280
+ | Field | Default | Valid range | Meaning |
281
+ |:--|:--:|:--|:--|
282
+ | `circumsolarStrength` | `1` | `[0, 4]` | Multiplier for the circumsolar Mie lobe |
283
+ | `circumsolarWidth` | `1` | `[0.25, 4]` | Relative lobe width; larger values broaden it, smaller values narrow it |
284
+ | `sunAngularRadius` | `0.004675` rad | `[0, +∞)` | Radius of the separate visible sun disc; `0` disables the disc |
285
+
286
+ For an angular or sunset sweep, hold the camera exposure in manual mode and
287
+ disable Bloom so the measurement belongs to the Atmosphere response. Vary the
288
+ two circumsolar fields while leaving `sunAngularRadius` unchanged:
289
+
290
+ ```ts
291
+ world.set(atmosphere, Atmosphere, {
292
+ circumsolarStrength: 1.5,
293
+ circumsolarWidth: 2,
294
+ sunAngularRadius: 0.004675,
295
+ }).unwrap();
296
+ world.set(camera, Camera, {
297
+ exposureMode: CAMERA_EXPOSURE_MODE_MANUAL,
298
+ exposure: 1,
299
+ bloom: BLOOM_DISABLED,
300
+ }).unwrap();
301
+ ```
302
+
303
+ The fixed exposure and Bloom setting are comparison setup, not additional
304
+ Atmosphere state. Use the renderer's submitted frame or a real Browser/Dawn
305
+ readback for visual claims; source values and a sky-cube upload do not prove a
306
+ pixel response.
307
+
243
308
  The cube has 786,432 texture payload bytes. Its 16-square irradiance cube and
244
309
  64-square, five-mip prefilter add 274,176 bytes; parameters and vertices total
245
310
  1,560 bytes, before backend allocation alignment. DeviceScope owns one cached
@@ -274,6 +339,8 @@ import { createRenderer } from '@forgeax/engine-runtime';
274
339
  const created = await createRenderer(canvas, { gpuPassTiming: {} });
275
340
  if (!created.ok) throw created.error;
276
341
  const renderer = created.value;
342
+ const ready = await renderer.initialization;
343
+ if (!ready.ok) throw ready.error;
277
344
  const attached = renderer.attach(world);
278
345
  if (!attached.ok) throw attached.error;
279
346
  const drawn = renderer.draw({
@@ -347,6 +414,168 @@ before publication; an invalid update keeps the renderer's last-known-good
347
414
  fog frame and exposes the structured failure through the existing inspection
348
415
  path. There is no app-local fog state.
349
416
 
417
+ ### VolumetricFog authoring, World time, and recovery
418
+
419
+ `VolumetricFog` is an authored, one-owner component backed by a linear 3D
420
+ `TextureAsset`. The selected light must be a live same-World
421
+ `DirectionalLight`, `PointLight`, or `SpotLight`; Point/Spot selection also
422
+ requires the corresponding `Transform`. Validate the authoring POD before
423
+ spawning the component, then let the existing RenderSystem extract it. The
424
+ World `Time` resource is the only simulation clock: `world.update(delta)`
425
+ advances it, and the volume parameter block receives that elapsed value.
426
+
427
+ ```ts
428
+ import { Time, World } from '@forgeax/engine-ecs';
429
+ import {
430
+ Atmosphere,
431
+ BLOOM_DISABLED,
432
+ CAMERA_EXPOSURE_MODE_MANUAL,
433
+ Camera,
434
+ DirectionalLight,
435
+ VolumetricFog,
436
+ extractVolumetricFog,
437
+ perspective,
438
+ resolveSelectedVolumetricLight,
439
+ validateVolumetricFog,
440
+ type VolumetricFogAuthoring,
441
+ type Renderer,
442
+ } from '@forgeax/engine-render';
443
+ import { Transform } from '@forgeax/engine-scene';
444
+ import type { TextureAsset } from '@forgeax/engine-types';
445
+
446
+ const world = new World();
447
+ const densityAsset: TextureAsset = {
448
+ kind: 'texture',
449
+ shape: { viewDimension: '3d', extent: { width: 4, height: 4, depth: 4 } },
450
+ format: 'r8unorm',
451
+ colorSpace: 'linear',
452
+ mips: { kind: 'none' },
453
+ data: new Uint8Array(4 * 4 * 4).fill(32),
454
+ };
455
+ const density = world.allocSharedRef('TextureAsset', densityAsset);
456
+ // A production project normally obtains this TextureAsset from its existing
457
+ // Pack/Catalog load path, then allocates the same shared handle in this World.
458
+ // The inline payload keeps this authoring example executable and deterministic.
459
+ const camera = world.spawn(
460
+ { component: Transform, data: { pos: [0, 0, 3] } },
461
+ { component: Camera, data: {
462
+ ...perspective({ fov: Math.PI / 4, aspect: 16 / 9 }),
463
+ exposureMode: CAMERA_EXPOSURE_MODE_MANUAL,
464
+ exposure: 1,
465
+ bloom: BLOOM_DISABLED,
466
+ } },
467
+ ).unwrap();
468
+ const sun = world.spawn({
469
+ component: DirectionalLight,
470
+ data: { direction: [-0.4, -0.8, -0.3], castShadow: true },
471
+ }).unwrap();
472
+ const atmosphere = world.spawn({
473
+ component: Atmosphere,
474
+ data: { circumsolarStrength: 1, circumsolarWidth: 1, sunAngularRadius: 0.004675 },
475
+ }).unwrap();
476
+
477
+ const authored: VolumetricFogAuthoring = {
478
+ light: sun,
479
+ density: {
480
+ guid: 'density-demo',
481
+ generation: 1,
482
+ shape: { viewDimension: '3d', extent: { width: 4, height: 4, depth: 4 } },
483
+ format: 'r8unorm',
484
+ colorSpace: 'linear',
485
+ },
486
+ bounds: { min: [-1, -1, -1], max: [1, 1, 1] },
487
+ extinction: [0.2, 0.2, 0.2],
488
+ albedo: [0.8, 0.8, 0.8],
489
+ emission: [0, 0, 0],
490
+ anisotropy: 0,
491
+ maxDistance: 50,
492
+ };
493
+ const checked = validateVolumetricFog(authored);
494
+ if (!checked.ok) throw checked.error;
495
+ const extracted = extractVolumetricFog([checked.value]);
496
+ if (!extracted.ok) throw extracted.error;
497
+ const selected = resolveSelectedVolumetricLight(world, sun);
498
+ if (selected.status === 'unresolved') {
499
+ throw new Error(`${selected.reason}: ${selected.hint}`);
500
+ }
501
+ world.spawn({
502
+ component: VolumetricFog,
503
+ data: {
504
+ light: sun,
505
+ density,
506
+ boundsMin: authored.bounds.min,
507
+ boundsMax: authored.bounds.max,
508
+ extinction: authored.extinction,
509
+ albedo: authored.albedo,
510
+ emission: authored.emission,
511
+ anisotropy: authored.anisotropy,
512
+ maxDistance: authored.maxDistance,
513
+ },
514
+ }).unwrap();
515
+
516
+ world.update(1 / 60).unwrap();
517
+ const elapsed = world.getResource(Time).elapsed; // the projected volume time
518
+ void camera;
519
+ void atmosphere;
520
+ void elapsed;
521
+ ```
522
+
523
+ If validation fails, read its structured `code`, `expected`, `hint`, and typed
524
+ `detail`. If light resolution is unresolved, read its `reason`, `expected`,
525
+ `actual`, and `hint`; repair the owning authoring field, and extract again.
526
+ Do not manufacture a light or a density fallback. After a submitted frame,
527
+ `renderer.inspect().volumetricFog` reports `status`, `resourceStage`, the
528
+ selected-light facts, and candidate/LKG generations. For a renderer device
529
+ loss, wait for the host recovery boundary, call `await renderer.recover()`,
530
+ then submit the same World again and inspect the replacement generation:
531
+
532
+ ```ts
533
+ import type { World } from '@forgeax/engine-ecs';
534
+ import type { Renderer } from '@forgeax/engine-render';
535
+
536
+ // After the existing createRenderer(canvas) happy path returns a Renderer,
537
+ // call `await recoverAndDraw(renderer, world)` with the World above.
538
+ async function recoverAndDraw(renderer: Renderer, world: World): Promise<void> {
539
+ const ready = await renderer.initialization;
540
+ if (!ready.ok) throw ready.error;
541
+ const attached = renderer.attach(world);
542
+ if (!attached.ok) throw attached.error;
543
+ const lease = attached.value;
544
+ if (renderer.state() === 'device-lost') {
545
+ const recovered = await renderer.recover();
546
+ if (!recovered.ok) throw recovered.error;
547
+ }
548
+ const retry = renderer.draw({
549
+ leases: [lease],
550
+ camera: { lease },
551
+ environment: { lease },
552
+ });
553
+ if (!retry.ok) throw retry.error;
554
+ const completed = await retry.value.completed;
555
+ if (!completed.ok) throw completed.error;
556
+ const volume = renderer.inspect().volumetricFog;
557
+ console.log(volume?.status, volume?.resourceStage, volume?.generation);
558
+ }
559
+ ```
560
+
561
+ The recovery call rebuilds renderer-owned resources; it is not a second volume
562
+ clock or registry. Pausing the simulation means withholding `world.update`.
563
+ Equal time and normal monotonic World ticks up to 100 ms retain eligible
564
+ volume history. Clock rollback, a larger jump, or changed time availability
565
+ invalidates it. Camera, light, medium, size and resource changes still invalidate
566
+ history. Integration and shadow visibility use stable cell centers, so a reset
567
+ does not expose render-frame random noise. The ray uses 96 base intervals;
568
+ segments within four interval lengths of a selected punctual source use four
569
+ midpoints to resolve its inverse-square peak and spot cone. This local refinement
570
+ keeps the density expression and packed shadow resolution unchanged. A real GPU
571
+ punctual-scattering oracle protects spatial accuracy alongside the continuous-frame
572
+ browser check; homogeneous transmittance alone cannot detect light-band artifacts.
573
+ History is clipped to the current
574
+ neighborhood and its weight decays with elapsed World time (at most 0.875 per
575
+ frame, about 87 ms half-life at 60 Hz or slower), limiting trails from animated
576
+ density. This route covers authored density and time projection only; it does
577
+ not add a procedural cloud API or a Voxel integration.
578
+
350
579
  Point shadows use one renderer-owned cube-array `ShadowAtlas`. The public
351
580
  `SHADOW_ATLAS_DEFAULT_FACE_SIZE` and `SHADOW_ATLAS_DEFAULT_LAYERS` constants
352
581
  are the only capacity owner; extract assigns `shadowAtlasLayer: -1` to
@@ -383,6 +612,8 @@ rebuild or cold-cook its source, then retry the same request.
383
612
  const created = await createRenderer(canvas);
384
613
  if (!created.ok) throw created.error;
385
614
  const renderer = created.value;
615
+ const ready = await renderer.initialization;
616
+ if (!ready.ok) throw ready.error;
386
617
  const attached = renderer.attach(world);
387
618
  if (!attached.ok) throw attached.error;
388
619
  const frame = renderer.draw({
@@ -911,20 +1142,131 @@ not from inspecting shader source text for a particular output structure.
911
1142
 
912
1143
  ## Motion Blur temporal consumer
913
1144
 
914
- The Standard camera may carry the presence-enabled `MotionBlur` component. Its
915
- validated parameters are `shutterAngle` in `[0, 360]`, `maxRadiusPixels` in
916
- `[0, 64]`, and integer `sampleCount` in `[4, 16]`. Zero shutter is an explicit
917
- zero-work case. The feature reads the shared `scene-data-temporal` sampled token
918
- and contributes one raster pass after optional TAA and before Bloom. It does
919
- not own a previous frame, write TAA history, allocate storage/compute state, or
920
- cache an RHI handle.
921
-
922
- `renderer.inspect()` exposes only detached Motion Blur POD facts when the
923
- component is active: status, bounded parameters, demand, pass identity, and
924
- the invariant `historyWrites: 0`. Invalid parameters and unavailable temporal
925
- data are structured failures with owner-specific recovery; callers should fix
926
- the component or capability and retry the same frame. The hello-taa carrier
927
- contains the four-lane smoke and falsifier evidence.
1145
+ The Standard camera enables Motion Blur by carrying the presence-enabled
1146
+ component. Authoring stays bounded and validated at the component boundary:
1147
+
1148
+ ```ts
1149
+ import { MotionBlur } from '@forgeax/engine-render';
1150
+
1151
+ const result = world.addComponent(cameraEntity, {
1152
+ component: MotionBlur,
1153
+ data: { shutterAngle: 180, maxRadiusPixels: 32, sampleCount: 8, targetFps: 60 },
1154
+ });
1155
+ if (!result.ok) throw result.error;
1156
+ ```
1157
+
1158
+ | Input / state | Contract |
1159
+ |:--|:--|
1160
+ | Parameters | `shutterAngle ∈ [0, 360]`, `maxRadiusPixels ∈ [0, 64]`, integer `sampleCount ∈ [4, 16]`, integer `targetFps ∈ [0, 240]`; zero shutter/radius is zero work. |
1161
+ | Temporal source | One renderer-owned `scene-data-temporal` sampled target. Motion validity and color reactivity are separate fields. |
1162
+ | Post order | TAA resolve → Motion Blur → auto exposure/Bloom/tone output. Motion Blur never writes TAA history. |
1163
+ | WebGPU/native lane | One 16×16 tile summary dispatch plus one fused reconstruction dispatch. Long vectors use an even-pixel half-resolution source lattice with depth guidance. |
1164
+ | Bounded work | Effective color tiers are exactly `0|4|8|16`; metadata probes are fixed and color work is linear in the tier. There is no radius-squared neighborhood, per-pixel scatter, or atomic accumulation. |
1165
+ | WebGL2 fallback | One directional raster gather, explicitly reported as `raster-limited`; it does not claim compute quality or timing parity. |
1166
+
1167
+ The authored integer sample count maps to one of the four execution tiers:
1168
+ `4..7 → 4`, `8..15 → 8`, and `16 → 16`; a zero-work bypass is `0`. The
1169
+ selected tier is the total color budget for every direction, including a
1170
+ bounded fallback when all candidates are rejected. There is no implicit
1171
+ center tap added to the budget.
1172
+
1173
+ For an uncovered moving support, accepted foreground coverage reconstructs a
1174
+ bounded portion of an opaque silhouette edge rather than averaging rejected
1175
+ support as black. The matching empty-background trail is attenuated by the
1176
+ same fixed factor, so the correction redistributes energy and does not add
1177
+ another sample. If no source is accepted, the receiver's center color remains
1178
+ the conservative fallback. A recovered midpoint anchor is still only partial
1179
+ evidence. Compute and raster-limited lanes share the rule without an extra
1180
+ pass or radius-sized neighborhood.
1181
+
1182
+ Reset and recovery remain observable through the existing temporal owner:
1183
+
1184
+ ```ts
1185
+ const inspection = renderer.inspect();
1186
+ if (
1187
+ inspection.motionBlur?.status === 'reset' &&
1188
+ inspection.motionBlur.resetReason === 'time-discontinuity' &&
1189
+ inspection.temporal.resetReason === 'time-discontinuity'
1190
+ ) {
1191
+ // The next successful draw commits the new baseline; retry the same renderer.
1192
+ renderer.draw(frameInput());
1193
+ }
1194
+ ```
1195
+
1196
+ After a rejected graph or queue submit, `motionBlur.lastFailure` is
1197
+ `'submit-failure'` while the previous successful temporal view remains the
1198
+ baseline. A `'scene-data-unavailable'` failure means the shared
1199
+ `standard-scene-data` producer or its `rgba16float` capability was not
1200
+ admitted; repair that producer/capability and retry the same frame. It never
1201
+ creates a private Motion Blur history target.
1202
+
1203
+ The renderer carries the raw host render sample timestamp through App/Worker
1204
+ and accepts it only after a successful submit. A gap greater than `100 ms`
1205
+ creates a `time-discontinuity` reset; a normal `30 Hz` interval remains valid,
1206
+ and a failed submit cannot advance the accepted temporal clock. Pause/resume
1207
+ also marks the next frame as a new baseline. Instance pose updates preserve
1208
+ the last submitted transform. Collection replacement mints new identity
1209
+ generations by default; a producer that keeps an instance through compaction
1210
+ or reorder can pass its prior generation tokens in the new order, allowing the
1211
+ record stage to pair each current transform with the real prior transform.
1212
+
1213
+ `renderer.inspect().motionBlur` exposes detached POD facts: status (`off`,
1214
+ `active`, `reset`, `limited`, or `invalid`), selected lane, effective tier,
1215
+ pass count, reset reason, last failure, and `historyWrites: 0`. Invalid public
1216
+ parameters return `MotionBlurValidationError` with code
1217
+ `motion-blur-invalid-params`; repair the named component field or capability
1218
+ and retry the same frame. The typed cause is preserved by the public draw
1219
+ result, so a caller can repair the named field without parsing `Error.message`:
1220
+
1221
+ ```ts
1222
+ const result = renderer.draw(frameInput);
1223
+ if (!result.ok && result.error.code === 'motion-blur-invalid-params') {
1224
+ console.error(result.error.detail.field, result.error.detail.value);
1225
+ // Repair the component field, then retry the same frame.
1226
+ }
1227
+ ```
1228
+
1229
+ The hello-taa carrier contains the Dawn, Browser, WebGL2, RhiNull, performance,
1230
+ and source-level falsifier paths.
1231
+
1232
+ ## Multiscale HDR Bloom
1233
+
1234
+ Bloom is a Camera-owned Standard post feature. `bloom` selects the enabled
1235
+ path, while `bloomIntensity` is bounded to `[0, 8]`, `bloomThreshold` to
1236
+ `[0, 65504]`, `bloomSoftKnee` to `[0, 1]`, and `bloomScatter` to `[0, 0.95]`.
1237
+ The defaults are intensity `1`, threshold `1`, soft knee `0.5`, and scatter
1238
+ `0.7`; the disabled value and intensity `0` are exact zero-work cases.
1239
+
1240
+ Game authors import this contract through the public umbrella facade:
1241
+
1242
+ ```ts
1243
+ import {
1244
+ BLOOM_ENABLED,
1245
+ Camera,
1246
+ TONEMAP_REINHARD_EXTENDED,
1247
+ } from '@forgeax/engine/render';
1248
+ ```
1249
+
1250
+ The physical `@forgeax/engine-render` package remains the repository ownership
1251
+ unit; it is not the recommended consumer import path.
1252
+
1253
+ An enabled frame stays in the linear HDR domain and uses one typed graph:
1254
+ five ceil-halved downsample levels `D0..D4`, four tent upsample levels
1255
+ `U3..U0`, then one HDR composite before tone mapping. `D0` applies the soft
1256
+ threshold per source texel and weights each texel by its exact source/target
1257
+ rectangle overlap, including odd extents. `D1..D4` use the shared 13-tap
1258
+ reduction; each upsample blends the current level with the next coarser level
1259
+ using the authored scatter. Composite adds only RGB bloom and preserves the
1260
+ scene alpha.
1261
+
1262
+ `renderer.inspect().bloom` is detached POD evidence from the compiled graph.
1263
+ Its level dimensions, `targetBytes`, pass topology, and
1264
+ `residentChildBytes` come from validated descriptors and active resource
1265
+ ownership, not from an expected-size calculation. A missing, forged, or
1266
+ invalid descriptor graph reports `invalid`; an off camera reports `empty` and
1267
+ zero target/resident bytes. Candidate generations remain behind the existing
1268
+ LKG fence and are released only after the submit fence; device recovery
1269
+ rehydrates the same Bloom bundle before a new receipt is accepted.
928
1270
 
929
1271
  > [!IMPORTANT]
930
1272
  > Render consumes the effective MaterialAsset snapshot produced by extract. Each texture slot carries its own coordinate set and transform into the built-in PBR binding layout; render records do not reinterpret authoring fields or manufacture shader artifacts. The effective `passes` are already validated.
@@ -962,7 +1304,7 @@ base-only root keeps `forward + deferred + shadow`, while declaring any
962
1304
  second-stage layer or physical texture selects `forward + shadow`.
963
1305
 
964
1306
  ```ts
965
- import { Materials } from '@forgeax/engine-render';
1307
+ import { Materials } from '@forgeax/engine/render';
966
1308
 
967
1309
  const material = Materials.standard({
968
1310
  baseColor: [0.72, 0.48, 0.22, 1],
@@ -1104,7 +1446,9 @@ renderer.instances.update(collection.collectionId, {
1104
1446
  transforms: patch,
1105
1447
  });
1106
1448
 
1107
- // Replacement keeps the logical identity and publishes a new revision.
1449
+ // Replacement publishes a new revision. Pass prior generation tokens in their
1450
+ // new order when compaction/reorder preserves logical instance identity;
1451
+ // omitted tokens intentionally seed replacement rows.
1108
1452
  renderer.instances.replace(collection.collectionId, identityMatrices(instanceCount + 1));
1109
1453
  const current = renderer.instances.inspect(collection.collectionId).unwrap();
1110
1454
  const detached = renderer.instances.snapshot(collection.collectionId).unwrap();
@@ -1412,8 +1756,8 @@ separate cache/recovery authority.
1412
1756
  > Owner: render vocabulary and the extract → prepare → record frame boundary. Runtime selects concrete services and calls this package; it does not re-own these tokens.
1413
1757
 
1414
1758
  ```ts
1415
- import { Camera, MeshFilter, MeshRenderer } from '@forgeax/engine-render';
1416
- import { createRenderer } from '@forgeax/engine-runtime';
1759
+ import { Camera, MeshFilter, MeshRenderer } from '@forgeax/engine/render';
1760
+ import { createRenderer } from '@forgeax/engine/runtime';
1417
1761
 
1418
1762
  const renderer = await createRenderer(canvas);
1419
1763
  const attached = renderer.attach(world);
@@ -1927,10 +2271,10 @@ ownership is [`@forgeax/engine-render-graph`](../render-graph/README.md).
1927
2271
  Dynamic consumers use the same boundary explicitly:
1928
2272
 
1929
2273
  ```ts
1930
- const { Camera, MeshFilter, MeshRenderer } = await import('@forgeax/engine-render');
2274
+ const { Camera, MeshFilter, MeshRenderer } = await import('@forgeax/engine/render');
1931
2275
  ```
1932
2276
 
1933
- `@forgeax/engine-runtime` remains the host assembly entry for `createRenderer` and backend policy. Import `Materials` from this package. Runtime is not a compatibility barrel for render components.
2277
+ `@forgeax/engine/runtime` remains the host assembly entry for `createRenderer` and backend policy. Import `Materials` from `@forgeax/engine/render`. Runtime is not a compatibility barrel for render components.
1934
2278
 
1935
2279
  Optional text, tilemap, and sprite authoring is intentionally isolated from the
1936
2280
  base vocabulary:
@@ -2309,19 +2653,21 @@ existing observable state; resource disposal is distinct from JavaScript GC.
2309
2653
 
2310
2654
  ### Volumetric density coordinates
2311
2655
 
2312
- `VolumetricFog.density` is a linear scalar field over `boundsMin` to `boundsMax`.
2313
- World positions map to `(position - boundsMin) / (boundsMax - boundsMin)` and
2314
- sample with clamp-to-edge addressing. The renderer clamps negative density at
2315
- the optical-depth boundary, but adds no bias, octave synthesis, repetition or
2316
- animation. White density means one; zero density contributes no extinction or
2317
- scattering. Noise synthesis belongs to the asset producer. The existing volume
2318
- passes integrate this field against scene depth before output tonemapping.
2319
-
2320
- Density integration uses fixed segment midpoints and the profile's logical
2321
- froxel depth, including the clipped final segment. It does not rotate density
2322
- samples with frame number: static authored air must not create temporal noise.
2323
- Shadow visibility uses matching froxel centers without per-frame XY jitter or
2324
- stochastic byte dithering. Shared PCF shadow filtering remains in effect.
2656
+ `VolumetricFog.density` is a producer-owned linear 3D source tile. The volume
2657
+ integrator samples that tile in repeated world-space coordinates, combines the
2658
+ same three scales used by the approved fog fixture, and uses World time for the
2659
+ continuous advection term. The renderer keeps the source texture resident; it
2660
+ does not rebuild noise data for each frame. Its source expression is mapped to a
2661
+ signed density and clamped only at the optical-depth boundary so Beer-Lambert
2662
+ extinction remains non-negative.
2663
+
2664
+ Density integration uses fixed midpoints over 96 base ray intervals, including
2665
+ the clipped final segment. Segments near a selected PointLight or SpotLight
2666
+ receive four local midpoints to resolve the inverse-square peak without making
2667
+ the whole ray uniformly expensive. Frame identity does not rotate density
2668
+ samples. Shadow visibility uses matching froxel centers without per-frame XY
2669
+ jitter or stochastic byte dithering; shared PCF shadow filtering remains in
2670
+ effect.
2325
2671
 
2326
2672
  ## Camera Depth of Field
2327
2673
 
@@ -0,0 +1,3 @@
1
+ import type { RenderSystem } from '../render-system';
2
+ export declare function registerAnalyticFogPostProcess(renderSystem: Pick<RenderSystem, 'registerBuiltinPostProcess'>, source: string, candidate: boolean): void;
3
+ //# sourceMappingURL=analytic-fog-registration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytic-fog-registration.d.ts","sourceRoot":"","sources":["../../src/assembly/analytic-fog-registration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,wBAAgB,8BAA8B,CAC5C,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,4BAA4B,CAAC,EAC9D,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO,GACjB,IAAI,CAON"}
@@ -0,0 +1,4 @@
1
+ import type { RenderSystem } from '../render-system';
2
+ /** Register the built-in FXAA post-process once for the active generation. */
3
+ export declare function registerFxaaPostProcess(renderSystem: Pick<RenderSystem, 'registerBuiltinPostProcess'>, source: string, registered: boolean): boolean;
4
+ //# sourceMappingURL=fxaa-registration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fxaa-registration.d.ts","sourceRoot":"","sources":["../../src/assembly/fxaa-registration.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,8EAA8E;AAC9E,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,4BAA4B,CAAC,EAC9D,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,OAAO,GAClB,OAAO,CAQT"}
@@ -0,0 +1,4 @@
1
+ import type { FrameReceipt } from '../render-contract';
2
+ import type { RenderSystem } from '../render-system';
3
+ export declare function observeLodOcclusionForReceipt(renderSystem: Pick<RenderSystem, 'observeLodOcclusion'>, receipt: Pick<FrameReceipt, 'frameId' | 'deviceGeneration'>): Promise<void>;
4
+ //# sourceMappingURL=lod-observation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lod-observation.d.ts","sourceRoot":"","sources":["../../src/assembly/lod-observation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,wBAAgB,6BAA6B,CAC3C,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,qBAAqB,CAAC,EACvD,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,kBAAkB,CAAC,GAC1D,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -0,0 +1,3 @@
1
+ import type { RenderSystem } from '../render-system';
2
+ export declare function registerMotionBlurPostProcess(renderSystem: Pick<RenderSystem, 'registerBuiltinPostProcess'>, source: string): void;
3
+ //# sourceMappingURL=motion-blur-registration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motion-blur-registration.d.ts","sourceRoot":"","sources":["../../src/assembly/motion-blur-registration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,wBAAgB,6BAA6B,CAC3C,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,4BAA4B,CAAC,EAC9D,MAAM,EAAE,MAAM,GACb,IAAI,CASN"}
@@ -1 +1 @@
1
- {"version":3,"file":"renderer-facade.d.ts","sourceRoot":"","sources":["../../src/assembly/renderer-facade.ts"],"names":[],"mappings":"AAWA,OAAO,EAGL,KAAK,sBAAsB,EAE5B,MAAM,kBAAkB,CAAC;AAM1B,OAAO,KAAK,EAEV,QAAQ,EAKR,aAAa,EAEd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAGlE,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,QAAQ,EAAE,0BAA0B,GAAG,QAAQ,CA6M7E;AAMD,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAG7C;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,sBAAsB,CA0BjG;AA2DD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CA6ChF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAMzE"}
1
+ {"version":3,"file":"renderer-facade.d.ts","sourceRoot":"","sources":["../../src/assembly/renderer-facade.ts"],"names":[],"mappings":"AAWA,OAAO,EAGL,KAAK,sBAAsB,EAE5B,MAAM,kBAAkB,CAAC;AAO1B,OAAO,KAAK,EAEV,QAAQ,EAKR,aAAa,EAEd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAGlE,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,QAAQ,EAAE,0BAA0B,GAAG,QAAQ,CA8M7E;AAMD,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAG7C;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,sBAAsB,CA0BjG;AA2DD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CA6ChF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAMzE"}
@@ -0,0 +1,13 @@
1
+ import type { Result, RhiDevice, RhiError, ShaderModule } from '@forgeax/engine-rhi';
2
+ import type { ManifestEntry } from '@forgeax/engine-types';
3
+ export type AsyncShaderModuleFactory = ((device: RhiDevice, desc: {
4
+ readonly code: string;
5
+ readonly label?: string;
6
+ }) => Promise<Result<ShaderModule, RhiError>>) | undefined;
7
+ /** Create the shared readiness prewarmer for temporal/fullscreen shader entries. */
8
+ export declare function createTemporalShaderPrewarmer(input: {
9
+ readonly device: RhiDevice;
10
+ readonly asyncCreateShaderModule: AsyncShaderModuleFactory;
11
+ readonly seedShaderModule: (label: string, module: ShaderModule) => void;
12
+ }): (entry: ManifestEntry | undefined, id: string) => Promise<void>;
13
+ //# sourceMappingURL=temporal-post-process-prewarm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal-post-process-prewarm.d.ts","sourceRoot":"","sources":["../../src/assembly/temporal-post-process-prewarm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAK3D,MAAM,MAAM,wBAAwB,GAChC,CAAC,CACC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KACrD,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,GAC7C,SAAS,CAAC;AAEd,oFAAoF;AACpF,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACnD,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,uBAAuB,EAAE,wBAAwB,CAAC;IAC3D,QAAQ,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;CAC1E,GAAG,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAqBlE"}
@@ -1,9 +1,10 @@
1
1
  /** Generation-scoped buffer and attachment constants used by the ready builder. */
2
2
  export declare const VIEW_UBO_BYTES: number;
3
3
  export declare const MIPMAP_PREWARM_FORMATS: readonly GPUTextureFormat[];
4
- export declare const BRIGHT_PARAMS_BYTES = 16;
5
- export declare const BLUR_PARAMS_BYTES = 16;
6
- export declare const COMPOSITE_PARAMS_BYTES = 16;
4
+ export declare const BLOOM_UNIFORM_PARAMS_STRIDE_BYTES = 256;
5
+ export declare const BLOOM_DOWNSAMPLE_PARAMS_BYTES: number;
6
+ export declare const BLOOM_UPSAMPLE_PARAMS_BYTES: number;
7
+ export declare const BLOOM_COMPOSITE_PARAMS_BYTES = 16;
7
8
  export declare const HDR_COLOR_ATTACHMENT_FORMAT: GPUTextureFormat;
8
9
  export declare const DEPTH_TEXTURE_FORMAT: GPUTextureFormat;
9
10
  //# sourceMappingURL=webgpu-ready-contract.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-ready-contract.d.ts","sourceRoot":"","sources":["../../src/assembly/webgpu-ready-contract.ts"],"names":[],"mappings":"AAEA,mFAAmF;AACnF,eAAO,MAAM,cAAc,QAA2B,CAAC;AACvD,eAAO,MAAM,sBAAsB,EAAE,SAAS,gBAAgB,EAI7D,CAAC;AACF,eAAO,MAAM,mBAAmB,KAAK,CAAC;AACtC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,2BAA2B,EAAE,gBAAgC,CAAC;AAC3E,eAAO,MAAM,oBAAoB,EAAE,gBAAyC,CAAC"}
1
+ {"version":3,"file":"webgpu-ready-contract.d.ts","sourceRoot":"","sources":["../../src/assembly/webgpu-ready-contract.ts"],"names":[],"mappings":"AAEA,mFAAmF;AACnF,eAAO,MAAM,cAAc,QAA2B,CAAC;AACvD,eAAO,MAAM,sBAAsB,EAAE,SAAS,gBAAgB,EAI7D,CAAC;AAKF,eAAO,MAAM,iCAAiC,MAAM,CAAC;AACrD,eAAO,MAAM,6BAA6B,QAAwC,CAAC;AACnF,eAAO,MAAM,2BAA2B,QAAwC,CAAC;AACjF,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAC/C,eAAO,MAAM,2BAA2B,EAAE,gBAAgC,CAAC;AAC3E,eAAO,MAAM,oBAAoB,EAAE,gBAAyC,CAAC"}
@@ -47,7 +47,7 @@ requiredFullscreenPostProcesses: readonly {
47
47
  readonly source: string;
48
48
  }[], setGrowMeshSsboHook: (hook: (neededSlots: number) => MeshSsboGrowResult, state: MeshSsboState) => void, seedShaderModule: (label: string, module: ShaderModule) => void, seedMaterialShaderPipelineCache: (key: string, pso: RenderPipeline, group2Contract: PipelineGroup2Contract) => void, registerBuiltinTonemap: (source: string) => void,
49
49
  /** Register the special FXAA pass' final-output policy params UBO. */
50
- registerBuiltinFxaa: (source: string) => void, registerBuiltinTemporalPostProcesses: (entries: {
50
+ registerBuiltinFxaa: (source: string) => void, registerBuiltinAnalyticFog: (source: string) => void, registerBuiltinTemporalPostProcesses: (entries: {
51
51
  readonly motionBlur?: string;
52
52
  readonly taaResolve?: string;
53
53
  }) => void, registerBuiltinDepthOfField: Parameters<typeof prewarmDepthOfField>[2],
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-ready.d.ts","sourceRoot":"","sources":["../../src/assembly/webgpu-ready.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAKV,cAAc,EACd,MAAM,EACN,SAAS,EAET,YAAY,EACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAM,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oDAAoD,CAAC;AAIzF,YAAY,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,yBAAyB,CAAC;AAwBjF,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE1E,OAAO,EAGL,KAAK,sBAAsB,EAG5B,MAAM,iBAAiB,CAAC;AAmBzB,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EAErB,KAAK,0BAA0B,EAChC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAmB1B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,WAAW,EAC1B,SAAS,EAAE,MAAM,aAAa,EAC9B,QAAQ,EAAE,iBAAiB,EAC3B,uBAAuB,EACnB,CAAC,CACC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,KAC/C,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,GAC7C,SAAS,EACb,aAAa,EAAE,wBAAwB;AACvC;;;;GAIG;AACH,uBAAuB,EAAE,SAAS,MAAM,EAAE,EAC1C,2BAA2B,EAAE,MAAM;AACnC,8EAA8E;AAC9E,+BAA+B,EAAE,SAAS;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,EAAE,EAUH,mBAAmB,EAAE,CACnB,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,kBAAkB,EACjD,KAAK,EAAE,aAAa,KACjB,IAAI,EAQT,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,EAQ/D,+BAA+B,EAAE,CAC/B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,cAAc,EACnB,cAAc,EAAE,sBAAsB,KACnC,IAAI,EAST,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI;AAChD,sEAAsE;AACtE,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAC7C,oCAAoC,EAAE,CAAC,OAAO,EAAE;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,KAAK,IAAI,EACV,2BAA2B,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC;AACtE,yFAAyF;AACzF,6BAA6B,EAAE,CAAC,OAAO,EAAE,0BAA0B,KAAK,IAAI;AAC5E,sFAAsF;AACtF,mBAAmB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI;AACxD,wFAAwF;AACxF,0BAA0B,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,GACrE,OAAO,CAAC,aAAa,CAAC,CAuxHxB"}
1
+ {"version":3,"file":"webgpu-ready.d.ts","sourceRoot":"","sources":["../../src/assembly/webgpu-ready.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAKV,cAAc,EACd,MAAM,EACN,SAAS,EAET,YAAY,EACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAM,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oDAAoD,CAAC;AAIzF,YAAY,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,yBAAyB,CAAC;AAwBjF,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE1E,OAAO,EAGL,KAAK,sBAAsB,EAG5B,MAAM,iBAAiB,CAAC;AAmBzB,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EAErB,KAAK,0BAA0B,EAChC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAoB1B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,WAAW,EAC1B,SAAS,EAAE,MAAM,aAAa,EAC9B,QAAQ,EAAE,iBAAiB,EAC3B,uBAAuB,EACnB,CAAC,CACC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,KAC/C,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,GAC7C,SAAS,EACb,aAAa,EAAE,wBAAwB;AACvC;;;;GAIG;AACH,uBAAuB,EAAE,SAAS,MAAM,EAAE,EAC1C,2BAA2B,EAAE,MAAM;AACnC,8EAA8E;AAC9E,+BAA+B,EAAE,SAAS;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,EAAE,EAUH,mBAAmB,EAAE,CACnB,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,kBAAkB,EACjD,KAAK,EAAE,aAAa,KACjB,IAAI,EAQT,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,EAQ/D,+BAA+B,EAAE,CAC/B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,cAAc,EACnB,cAAc,EAAE,sBAAsB,KACnC,IAAI,EAST,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI;AAChD,sEAAsE;AACtE,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAC7C,0BAA0B,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EACpD,oCAAoC,EAAE,CAAC,OAAO,EAAE;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,KAAK,IAAI,EACV,2BAA2B,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC;AACtE,yFAAyF;AACzF,6BAA6B,EAAE,CAAC,OAAO,EAAE,0BAA0B,KAAK,IAAI;AAC5E,sFAAsF;AACtF,mBAAmB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI;AACxD,wFAAwF;AACxF,0BAA0B,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,GACrE,OAAO,CAAC,aAAa,CAAC,CAqtHxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"webgpu-renderer.d.ts","sourceRoot":"","sources":["../../src/assembly/webgpu-renderer.ts"],"names":[],"mappings":"AAyCA,YAAY,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAyE1E,OAAO,KAAK,EAUV,eAAe,EAQhB,MAAM,oBAAoB,CAAC;AAgB5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAkEzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAUlF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAUhE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,YAAY,EACV,UAAU,EACV,6BAA6B,EAC7B,iCAAiC,GAClC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,2BAA2B,EAC3B,oCAAoC,EACpC,iCAAiC,EACjC,uCAAuC,EACvC,oCAAoC,EACpC,+BAA+B,EAC/B,+BAA+B,EAC/B,wCAAwC,EACxC,uBAAuB,EACvB,8BAA8B,EAC9B,wCAAwC,GACzC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,4BAA4B,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,gCAAgC,EAChC,4BAA4B,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,4CAA4C,GAC7C,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAI7E,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,iBAAiB,GAAG,eAAe,EAC3C,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,cAAc,GAAG,SAAS,GAClC,OAAO,CAAC,aAAa,CAAC,CAExB"}
1
+ {"version":3,"file":"webgpu-renderer.d.ts","sourceRoot":"","sources":["../../src/assembly/webgpu-renderer.ts"],"names":[],"mappings":"AAyCA,YAAY,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AA0E1E,OAAO,KAAK,EAUV,eAAe,EAQhB,MAAM,oBAAoB,CAAC;AAiB5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAqEzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAUlF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAUhE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,YAAY,EACV,UAAU,EACV,6BAA6B,EAC7B,iCAAiC,GAClC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,2BAA2B,EAC3B,oCAAoC,EACpC,iCAAiC,EACjC,uCAAuC,EACvC,oCAAoC,EACpC,+BAA+B,EAC/B,+BAA+B,EAC/B,wCAAwC,EACxC,uBAAuB,EACvB,8BAA8B,EAC9B,wCAAwC,GACzC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,4BAA4B,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,gCAAgC,EAChC,4BAA4B,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,4CAA4C,GAC7C,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAI7E,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,iBAAiB,GAAG,eAAe,EAC3C,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,cAAc,GAAG,SAAS,GAClC,OAAO,CAAC,aAAa,CAAC,CAExB"}
@@ -0,0 +1,13 @@
1
+ import type { BloomEnabled, Tonemap } from './components/camera';
2
+ /**
3
+ * The one effective Standard Bloom admission used by graph, resource, and
4
+ * record owners. Authoring remains Camera-owned; this is only the derived
5
+ * zero/non-zero topology decision.
6
+ */
7
+ export interface BloomAdmissionCamera {
8
+ readonly bloom: BloomEnabled;
9
+ readonly bloomIntensity: number;
10
+ readonly tonemap: Tonemap;
11
+ }
12
+ export declare function standardBloomAdmitted(camera: BloomAdmissionCamera | undefined): boolean;
13
+ //# sourceMappingURL=bloom-admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bloom-admission.d.ts","sourceRoot":"","sources":["../src/bloom-admission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,GAAG,OAAO,CAOvF"}