@forgeax/engine-render 0.1.32 → 0.1.34

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 (624) hide show
  1. package/README.md +1374 -142
  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/backend-contract.d.ts +2 -0
  5. package/dist/assembly/backend-contract.d.ts.map +1 -1
  6. package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
  7. package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
  8. package/dist/assembly/canvas-draw-guard.d.ts +3 -0
  9. package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
  10. package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
  11. package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
  12. package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
  13. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  14. package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
  15. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
  16. package/dist/assembly/factory.d.ts +1 -1
  17. package/dist/assembly/factory.d.ts.map +1 -1
  18. package/dist/assembly/fxaa-registration.d.ts +4 -0
  19. package/dist/assembly/fxaa-registration.d.ts.map +1 -0
  20. package/dist/assembly/host-contract.d.ts +3 -3
  21. package/dist/assembly/host-contract.d.ts.map +1 -1
  22. package/dist/assembly/lod-observation.d.ts +4 -0
  23. package/dist/assembly/lod-observation.d.ts.map +1 -0
  24. package/dist/assembly/material/assembly.d.ts.map +1 -1
  25. package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
  26. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
  27. package/dist/assembly/material-shader-policy.d.ts +16 -2
  28. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  29. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
  30. package/dist/assembly/motion-blur-registration.d.ts +3 -0
  31. package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
  32. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  33. package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
  34. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  35. package/dist/assembly/render-feature-post-processes.d.ts +6 -0
  36. package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
  37. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  38. package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
  39. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
  40. package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
  41. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  42. package/dist/assembly/renderer-inspection.d.ts +11 -0
  43. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  44. package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
  45. package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
  47. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
  48. package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
  49. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
  50. package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
  51. package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
  52. package/dist/assembly/webgpu-ready.d.ts +2 -2
  53. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  54. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
  55. package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
  56. package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
  57. package/dist/assembly/webgpu-renderer.d.ts +1 -1
  58. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  59. package/dist/authoring.mjs +1 -1
  60. package/dist/barrel-distortion.d.ts +47 -0
  61. package/dist/barrel-distortion.d.ts.map +1 -0
  62. package/dist/bloom-admission.d.ts +13 -0
  63. package/dist/bloom-admission.d.ts.map +1 -0
  64. package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
  65. package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
  66. package/dist/{chunk-JCIRYQ4V.mjs → chunk-HEB564WF.mjs} +10 -4
  67. package/dist/chunk-HEB564WF.mjs.map +1 -0
  68. package/dist/{chunk-JRIPCMYC.mjs → chunk-MKDIT2EM.mjs} +1584 -375
  69. package/dist/chunk-MKDIT2EM.mjs.map +1 -0
  70. package/dist/{chunk-S665NJNF.mjs → chunk-OCDLEI6I.mjs} +3 -3
  71. package/dist/{chunk-S665NJNF.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
  72. package/dist/chunk-ODZWR6JQ.mjs +4927 -0
  73. package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
  74. package/dist/{chunk-DRR7D3KX.mjs → chunk-SHFUFJ5N.mjs} +192 -18
  75. package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
  76. package/dist/{chunk-4NNZQCL3.mjs → chunk-UI5SFODX.mjs} +223 -277
  77. package/dist/chunk-UI5SFODX.mjs.map +1 -0
  78. package/dist/{chunk-GWCEMDVR.mjs → chunk-UINHLCZA.mjs} +787 -80
  79. package/dist/chunk-UINHLCZA.mjs.map +1 -0
  80. package/dist/{chunk-6TFBXLRJ.mjs → chunk-WEX45HKH.mjs} +222 -337
  81. package/dist/chunk-WEX45HKH.mjs.map +1 -0
  82. package/dist/cloud/density.d.ts +55 -0
  83. package/dist/cloud/density.d.ts.map +1 -0
  84. package/dist/cloud/extract.d.ts +25 -0
  85. package/dist/cloud/extract.d.ts.map +1 -0
  86. package/dist/cloud/feature.d.ts +57 -0
  87. package/dist/cloud/feature.d.ts.map +1 -0
  88. package/dist/cloud/frame-context.d.ts +8 -0
  89. package/dist/cloud/frame-context.d.ts.map +1 -0
  90. package/dist/cloud/inspection.d.ts +59 -0
  91. package/dist/cloud/inspection.d.ts.map +1 -0
  92. package/dist/cloud/optics.d.ts +56 -0
  93. package/dist/cloud/optics.d.ts.map +1 -0
  94. package/dist/cloud/parameters.d.ts +73 -0
  95. package/dist/cloud/parameters.d.ts.map +1 -0
  96. package/dist/cloud/resources.d.ts +60 -0
  97. package/dist/cloud/resources.d.ts.map +1 -0
  98. package/dist/cloud/shadow.d.ts +42 -0
  99. package/dist/cloud/shadow.d.ts.map +1 -0
  100. package/dist/cloud/temporal.d.ts +74 -0
  101. package/dist/cloud/temporal.d.ts.map +1 -0
  102. package/dist/components/atmosphere.d.ts +2 -0
  103. package/dist/components/atmosphere.d.ts.map +1 -1
  104. package/dist/components/barrel-distortion.d.ts +13 -0
  105. package/dist/components/barrel-distortion.d.ts.map +1 -0
  106. package/dist/components/camera.d.ts +20 -4
  107. package/dist/components/camera.d.ts.map +1 -1
  108. package/dist/components/cloud-layer.d.ts +29 -0
  109. package/dist/components/cloud-layer.d.ts.map +1 -0
  110. package/dist/components/index.d.ts +2 -0
  111. package/dist/components/index.d.ts.map +1 -1
  112. package/dist/components/instances.d.ts +20 -6
  113. package/dist/components/instances.d.ts.map +1 -1
  114. package/dist/components/mesh-filter.d.ts +6 -5
  115. package/dist/components/mesh-filter.d.ts.map +1 -1
  116. package/dist/components/motion-blur.d.ts +1 -0
  117. package/dist/components/motion-blur.d.ts.map +1 -1
  118. package/dist/construct-renderer.d.ts +1 -1
  119. package/dist/construct-renderer.d.ts.map +1 -1
  120. package/dist/construct-renderer.mjs +9751 -3528
  121. package/dist/construct-renderer.mjs.map +1 -1
  122. package/dist/device/gpu-residency.d.ts +6 -0
  123. package/dist/device/gpu-residency.d.ts.map +1 -1
  124. package/dist/dynamic-geometry.d.ts +5 -1
  125. package/dist/dynamic-geometry.d.ts.map +1 -1
  126. package/dist/environment/analytic-fog.d.ts +6 -0
  127. package/dist/environment/analytic-fog.d.ts.map +1 -0
  128. package/dist/errors/cloud.d.ts +59 -0
  129. package/dist/errors/cloud.d.ts.map +1 -0
  130. package/dist/errors/render.d.ts +23 -5
  131. package/dist/errors/render.d.ts.map +1 -1
  132. package/dist/examples/single-layer-medium-surface.d.ts +47 -0
  133. package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
  134. package/dist/extract/camera.d.ts.map +1 -1
  135. package/dist/extract/contracts.d.ts +12 -1
  136. package/dist/extract/contracts.d.ts.map +1 -1
  137. package/dist/extract/environment.d.ts +2 -0
  138. package/dist/extract/environment.d.ts.map +1 -1
  139. package/dist/features/barrel-distortion.d.ts +29 -0
  140. package/dist/features/barrel-distortion.d.ts.map +1 -0
  141. package/dist/features/error-reporting.d.ts +17 -0
  142. package/dist/features/error-reporting.d.ts.map +1 -0
  143. package/dist/features/host.d.ts +15 -0
  144. package/dist/features/host.d.ts.map +1 -1
  145. package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
  146. package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
  147. package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
  148. package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
  149. package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
  150. package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
  151. package/dist/features/plan.d.ts +15 -4
  152. package/dist/features/plan.d.ts.map +1 -1
  153. package/dist/features/prepared-gpu-work.d.ts +9 -5
  154. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  155. package/dist/features/render-graph-compute.d.ts.map +1 -1
  156. package/dist/features/render-graph-contribution.d.ts +5 -0
  157. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  158. package/dist/features/render-graph-raster.d.ts +1 -0
  159. package/dist/features/render-graph-raster.d.ts.map +1 -1
  160. package/dist/features/targets.d.ts +2 -0
  161. package/dist/features/targets.d.ts.map +1 -1
  162. package/dist/features/types.d.ts +44 -0
  163. package/dist/features/types.d.ts.map +1 -1
  164. package/dist/fullscreen-post-process-pass.d.ts +15 -7
  165. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  166. package/dist/gpu-dirty-ranges.d.ts +11 -0
  167. package/dist/gpu-dirty-ranges.d.ts.map +1 -0
  168. package/dist/gpu-driven/batch-topology.d.ts +17 -0
  169. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  170. package/dist/gpu-driven/material-artifacts.d.ts +6 -0
  171. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  172. package/dist/gpu-driven/prepared-draw.d.ts +7 -0
  173. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  174. package/dist/gpu-driven/production-raster-material.d.ts +178 -0
  175. package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
  176. package/dist/gpu-driven/production-raster.d.ts +50 -4
  177. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  178. package/dist/gpu-driven/resource-allocation.d.ts +31 -0
  179. package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
  180. package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
  181. package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
  182. package/dist/gpu-driven/view-gpu.d.ts +35 -2
  183. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  184. package/dist/gpu-scene.d.ts +11 -1
  185. package/dist/gpu-scene.d.ts.map +1 -1
  186. package/dist/hdrp-buffers.d.ts +2 -2
  187. package/dist/hdrp-buffers.d.ts.map +1 -1
  188. package/dist/ibl/skylight-bind-group.d.ts +10 -1
  189. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  190. package/dist/index.d.ts +31 -8
  191. package/dist/index.d.ts.map +1 -1
  192. package/dist/index.mjs +258 -8
  193. package/dist/index.mjs.map +1 -1
  194. package/dist/inspection-types.d.ts +178 -3
  195. package/dist/inspection-types.d.ts.map +1 -1
  196. package/dist/instance-buffer-cache.d.ts +4 -4
  197. package/dist/instance-buffer-cache.d.ts.map +1 -1
  198. package/dist/instances.d.ts +49 -94
  199. package/dist/instances.d.ts.map +1 -1
  200. package/dist/internal.mjs +7 -7
  201. package/dist/pbr-pipeline.d.ts +19 -1
  202. package/dist/pbr-pipeline.d.ts.map +1 -1
  203. package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
  204. package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
  205. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  206. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  207. package/dist/pipeline/standard-output/types.d.ts +4 -2
  208. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  209. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  210. package/dist/pipeline/standard-post.d.ts +28 -19
  211. package/dist/pipeline/standard-post.d.ts.map +1 -1
  212. package/dist/pipeline-builder.d.ts +1 -1
  213. package/dist/pipeline-builder.d.ts.map +1 -1
  214. package/dist/pipeline-spec.d.ts +2 -2
  215. package/dist/plugin.d.ts.map +1 -1
  216. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
  217. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  218. package/dist/record/barrel-distortion-frame.d.ts +15 -0
  219. package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
  220. package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
  221. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
  222. package/dist/record/fold-buckets.d.ts +95 -0
  223. package/dist/record/fold-buckets.d.ts.map +1 -0
  224. package/dist/record/fold-instance-buffer.d.ts +6 -0
  225. package/dist/record/fold-instance-buffer.d.ts.map +1 -0
  226. package/dist/record/frame-lighting.d.ts +1 -0
  227. package/dist/record/frame-lighting.d.ts.map +1 -1
  228. package/dist/record/frame-snapshot.d.ts +40 -3
  229. package/dist/record/frame-snapshot.d.ts.map +1 -1
  230. package/dist/record/frame-targets.d.ts.map +1 -1
  231. package/dist/record/frame.d.ts +14 -62
  232. package/dist/record/frame.d.ts.map +1 -1
  233. package/dist/record/gpu-draw-receipts.d.ts +11 -0
  234. package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
  235. package/dist/record/gpu-timing.d.ts +8 -0
  236. package/dist/record/gpu-timing.d.ts.map +1 -1
  237. package/dist/record/main-pass-geometry.d.ts +21 -5
  238. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  239. package/dist/record/main-pass-material.d.ts +7 -1
  240. package/dist/record/main-pass-material.d.ts.map +1 -1
  241. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  242. package/dist/record/main-pass.d.ts +13 -2
  243. package/dist/record/main-pass.d.ts.map +1 -1
  244. package/dist/record/mesh-ssbo.d.ts +6 -5
  245. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  246. package/dist/record/motion-blur-receipt.d.ts +11 -0
  247. package/dist/record/motion-blur-receipt.d.ts.map +1 -0
  248. package/dist/record/probe-blend-buffer.d.ts +16 -0
  249. package/dist/record/probe-blend-buffer.d.ts.map +1 -0
  250. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  251. package/dist/record/render-context.d.ts +34 -31
  252. package/dist/record/render-context.d.ts.map +1 -1
  253. package/dist/record/shadow-pass.d.ts +2 -0
  254. package/dist/record/shadow-pass.d.ts.map +1 -1
  255. package/dist/record/skybox-post-pass.d.ts +6 -4
  256. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  257. package/dist/record/typed-frame-graph.d.ts +22 -2
  258. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  259. package/dist/record/view-ubo.d.ts +11 -3
  260. package/dist/record/view-ubo.d.ts.map +1 -1
  261. package/dist/record/volume-params.d.ts +9 -0
  262. package/dist/record/volume-params.d.ts.map +1 -0
  263. package/dist/recovery/render-system-candidate.d.ts +10 -0
  264. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  265. package/dist/reflection/record-owner.d.ts.map +1 -1
  266. package/dist/render-contract.d.ts +66 -8
  267. package/dist/render-contract.d.ts.map +1 -1
  268. package/dist/render-graph-primitives.d.ts.map +1 -1
  269. package/dist/render-pipeline.d.ts +106 -3
  270. package/dist/render-pipeline.d.ts.map +1 -1
  271. package/dist/render-system-extract-tail.d.ts +3 -2
  272. package/dist/render-system-extract-tail.d.ts.map +1 -1
  273. package/dist/render-system-extract.d.ts +24 -10
  274. package/dist/render-system-extract.d.ts.map +1 -1
  275. package/dist/render-system-presentation.d.ts +23 -0
  276. package/dist/render-system-presentation.d.ts.map +1 -0
  277. package/dist/render-system-producer-roots.d.ts +10 -0
  278. package/dist/render-system-producer-roots.d.ts.map +1 -0
  279. package/dist/render-system-residency.d.ts +12 -0
  280. package/dist/render-system-residency.d.ts.map +1 -0
  281. package/dist/render-system.d.ts +26 -15
  282. package/dist/render-system.d.ts.map +1 -1
  283. package/dist/scene/probe-blend.d.ts +27 -0
  284. package/dist/scene/probe-blend.d.ts.map +1 -1
  285. package/dist/scene/render-scene.d.ts +14 -5
  286. package/dist/scene/render-scene.d.ts.map +1 -1
  287. package/dist/ssao-buffers.d.ts +9 -0
  288. package/dist/ssao-buffers.d.ts.map +1 -1
  289. package/dist/surface/dynamic-input.d.ts +133 -0
  290. package/dist/surface/dynamic-input.d.ts.map +1 -0
  291. package/dist/surface/gpu-driven.d.ts +41 -0
  292. package/dist/surface/gpu-driven.d.ts.map +1 -0
  293. package/dist/surface/submission-observation.d.ts +136 -0
  294. package/dist/surface/submission-observation.d.ts.map +1 -0
  295. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  296. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  297. package/dist/temporal/frame.d.ts +7 -0
  298. package/dist/temporal/frame.d.ts.map +1 -1
  299. package/dist/temporal/gpu.d.ts +13 -1
  300. package/dist/temporal/gpu.d.ts.map +1 -1
  301. package/dist/temporal/index.mjs +5 -5
  302. package/dist/temporal/inspection.d.ts.map +1 -1
  303. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  304. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
  305. package/dist/temporal/view.d.ts +6 -1
  306. package/dist/temporal/view.d.ts.map +1 -1
  307. package/dist/transmission/single-layer-medium.d.ts +89 -0
  308. package/dist/transmission/single-layer-medium.d.ts.map +1 -0
  309. package/dist/typed-render-graph-primitives.d.ts +24 -9
  310. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  311. package/dist/volume/component.d.ts +9 -5
  312. package/dist/volume/component.d.ts.map +1 -1
  313. package/dist/volume/extract.d.ts +1 -1
  314. package/dist/volume/extract.d.ts.map +1 -1
  315. package/dist/volume/inspection.d.ts +2 -0
  316. package/dist/volume/inspection.d.ts.map +1 -1
  317. package/dist/volume/passes.d.ts +4 -1
  318. package/dist/volume/passes.d.ts.map +1 -1
  319. package/dist/volume/resources.d.ts.map +1 -1
  320. package/dist/volume/temporal.d.ts +3 -1
  321. package/dist/volume/temporal.d.ts.map +1 -1
  322. package/package.json +22 -21
  323. package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
  324. package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
  325. package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
  326. package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
  327. package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
  328. package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
  329. package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
  330. package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
  331. package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
  332. package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
  333. package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
  334. package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
  335. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
  336. package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
  337. package/src/__tests__/environment-selection.unit.test.ts +12 -0
  338. package/src/__tests__/factory-contract.integration.test.ts +626 -113
  339. package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
  340. package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
  341. package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
  342. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
  343. package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
  344. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
  345. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
  346. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
  347. package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
  348. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
  349. package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
  350. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +7 -6
  351. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
  352. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +103 -4
  353. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
  354. package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
  355. package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
  356. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
  357. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
  358. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
  359. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
  360. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
  361. package/src/__tests__/gpu-scene.unit.test.ts +210 -9
  362. package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
  363. package/src/__tests__/instances-culling.integration.test.ts +10 -36
  364. package/src/__tests__/instances-store.unit.test.ts +105 -238
  365. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  366. package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
  367. package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
  368. package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
  369. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
  370. package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
  371. package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
  372. package/src/__tests__/motion-blur-compute.dawn.test.ts +589 -0
  373. package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
  374. package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
  375. package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
  376. package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
  377. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +21 -0
  378. package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
  379. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
  380. package/src/__tests__/probe-bindings.unit.test.ts +582 -1
  381. package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
  382. package/src/__tests__/public-surface.test-d.ts +8 -0
  383. package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
  384. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
  385. package/src/__tests__/render-error-code-owner.test-d.ts +9 -0
  386. package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
  387. package/src/__tests__/render-feature-error-reporting.unit.test.ts +44 -0
  388. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
  389. package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
  390. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
  391. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
  392. package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
  393. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +37 -6
  394. package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
  395. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
  396. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
  397. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
  398. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
  399. package/src/__tests__/renderer-frame-transaction.integration.test.ts +33 -11
  400. package/src/__tests__/resource-allocation.unit.test.ts +123 -0
  401. package/src/__tests__/shader-manifest-fixture.ts +4 -4
  402. package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
  403. package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
  404. package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
  405. package/src/__tests__/skinned-shadow-caster.test.ts +17 -0
  406. package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
  407. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
  408. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
  409. package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
  410. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
  411. package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
  412. package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
  413. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
  414. package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
  415. package/src/__tests__/standard-pipeline.integration.test.ts +200 -9
  416. package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
  417. package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
  418. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
  419. package/src/__tests__/temporal-performance.integration.test.ts +3 -3
  420. package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
  421. package/src/__tests__/temporal-view.unit.test.ts +2 -1
  422. package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
  423. package/src/__tests__/visibility-instances.integration.test.ts +7 -19
  424. package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
  425. package/src/__tests__/volume-optics-oracle.unit.test.ts +7 -3
  426. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +189 -15
  427. package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
  428. package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
  429. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
  430. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +558 -68
  431. package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
  432. package/src/__tests__/volumetric-fog-topology.unit.test.ts +23 -5
  433. package/src/assembly/analytic-fog-registration.ts +14 -0
  434. package/src/assembly/backend-contract.ts +30 -0
  435. package/src/assembly/barrel-distortion-inspection.ts +22 -0
  436. package/src/assembly/canvas-draw-guard.ts +11 -0
  437. package/src/assembly/cloud-shadow-entry.ts +22 -0
  438. package/src/assembly/dynamic-geometry-host.ts +65 -37
  439. package/src/assembly/dynamic-geometry-runtime.ts +7 -1
  440. package/src/assembly/factory.ts +2 -30
  441. package/src/assembly/fxaa-registration.ts +17 -0
  442. package/src/assembly/host-contract.ts +3 -3
  443. package/src/assembly/lod-observation.ts +12 -0
  444. package/src/assembly/material/assembly.ts +25 -13
  445. package/src/assembly/material/pipeline-helpers.ts +53 -12
  446. package/src/assembly/material-shader-policy.ts +55 -0
  447. package/src/assembly/material-shader-prewarm.ts +21 -10
  448. package/src/assembly/motion-blur-registration.ts +17 -0
  449. package/src/assembly/recovery/device-loss-fanout.ts +13 -0
  450. package/src/assembly/recovery/renderer-recover.ts +41 -18
  451. package/src/assembly/render-feature-post-processes.ts +54 -0
  452. package/src/assembly/renderer-facade.ts +6 -1
  453. package/src/assembly/renderer-feature-inspection.ts +8 -2
  454. package/src/assembly/renderer-frame-transaction.ts +23 -0
  455. package/src/assembly/renderer-inspection.ts +28 -0
  456. package/src/assembly/skin-palette-owner.ts +1 -1
  457. package/src/assembly/temporal-post-process-prewarm.ts +40 -0
  458. package/src/assembly/webgpu-pbr-ready.ts +9 -1
  459. package/src/assembly/webgpu-ready-contract.ts +8 -3
  460. package/src/assembly/webgpu-ready-per-pass.ts +104 -0
  461. package/src/assembly/webgpu-ready.ts +296 -306
  462. package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
  463. package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
  464. package/src/assembly/webgpu-renderer.ts +228 -281
  465. package/src/assembly/webgpu-vertex-layouts.ts +1 -1
  466. package/src/barrel-distortion.ts +247 -0
  467. package/src/bloom-admission.ts +21 -0
  468. package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
  469. package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
  470. package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
  471. package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
  472. package/src/cloud/density.ts +600 -0
  473. package/src/cloud/extract.ts +110 -0
  474. package/src/cloud/feature.ts +1810 -0
  475. package/src/cloud/frame-context.ts +42 -0
  476. package/src/cloud/inspection.ts +130 -0
  477. package/src/cloud/optics.ts +285 -0
  478. package/src/cloud/parameters.ts +255 -0
  479. package/src/cloud/resources.ts +122 -0
  480. package/src/cloud/shadow.ts +167 -0
  481. package/src/cloud/temporal.ts +226 -0
  482. package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
  483. package/src/components/atmosphere.ts +4 -0
  484. package/src/components/barrel-distortion.ts +46 -0
  485. package/src/components/camera.ts +66 -10
  486. package/src/components/cloud-layer.ts +47 -0
  487. package/src/components/index.ts +2 -0
  488. package/src/components/instances.ts +18 -45
  489. package/src/components/mesh-filter.ts +11 -9
  490. package/src/components/motion-blur.ts +1 -0
  491. package/src/components/sprite-instances.ts +1 -1
  492. package/src/construct-renderer.ts +1 -1
  493. package/src/device/gpu-residency.ts +56 -12
  494. package/src/dynamic-geometry.ts +12 -1
  495. package/src/environment/analytic-fog.ts +44 -0
  496. package/src/environment/background.ts +2 -2
  497. package/src/errors/cloud.ts +103 -0
  498. package/src/errors/render.ts +58 -8
  499. package/src/examples/single-layer-medium-surface.ts +59 -0
  500. package/src/extract/camera.ts +35 -8
  501. package/src/extract/contracts.ts +12 -0
  502. package/src/extract/environment.ts +4 -0
  503. package/src/features/barrel-distortion.ts +172 -0
  504. package/src/features/error-reporting.ts +98 -0
  505. package/src/features/host.ts +138 -24
  506. package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
  507. package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
  508. package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
  509. package/src/features/motion-blur/motion-blur-params.ts +70 -2
  510. package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
  511. package/src/features/plan.ts +33 -8
  512. package/src/features/prepared-gpu-work.ts +86 -35
  513. package/src/features/render-graph-compute.ts +13 -5
  514. package/src/features/render-graph-contribution.ts +11 -0
  515. package/src/features/render-graph-raster.ts +45 -3
  516. package/src/features/targets.ts +66 -0
  517. package/src/features/types.ts +47 -0
  518. package/src/fullscreen-post-process-pass.ts +41 -9
  519. package/src/gpu-dirty-ranges.ts +48 -0
  520. package/src/gpu-driven/batch-topology.ts +53 -0
  521. package/src/gpu-driven/material-artifacts.ts +35 -32
  522. package/src/gpu-driven/prepared-draw.ts +27 -14
  523. package/src/gpu-driven/production-raster-material.ts +1894 -0
  524. package/src/gpu-driven/production-raster.ts +904 -787
  525. package/src/gpu-driven/resource-allocation.ts +142 -0
  526. package/src/gpu-driven/shadow-ownership.ts +71 -0
  527. package/src/gpu-driven/view-gpu.ts +181 -10
  528. package/src/gpu-scene.ts +259 -101
  529. package/src/hdrp-buffers.ts +4 -3
  530. package/src/ibl/skylight-bind-group.ts +49 -7
  531. package/src/index.ts +228 -9
  532. package/src/inspection-types.ts +222 -2
  533. package/src/instance-buffer-cache.ts +4 -4
  534. package/src/instances.ts +151 -492
  535. package/src/pbr-pipeline.ts +219 -13
  536. package/src/pipeline/single-layer-medium-passes.ts +267 -0
  537. package/src/pipeline/standard-forward-lane.ts +313 -57
  538. package/src/pipeline/standard-output/graph.ts +8 -2
  539. package/src/pipeline/standard-output/types.ts +12 -1
  540. package/src/pipeline/standard-pipeline.ts +291 -18
  541. package/src/pipeline/standard-post.ts +397 -102
  542. package/src/pipeline-builder.ts +1 -1
  543. package/src/pipeline-spec.ts +5 -5
  544. package/src/plugin.ts +4 -0
  545. package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
  546. package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
  547. package/src/prepare/prepared-graphics-resolver.ts +2 -0
  548. package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
  549. package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
  550. package/src/record/__tests__/temporal-payload.unit.test.ts +3 -2
  551. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
  552. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
  553. package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
  554. package/src/record/barrel-distortion-frame.ts +110 -0
  555. package/src/record/dynamic-geometry-consumption.ts +39 -9
  556. package/src/record/fold-buckets.ts +852 -0
  557. package/src/record/fold-instance-buffer.ts +51 -0
  558. package/src/record/frame-lighting.ts +36 -2
  559. package/src/record/frame-snapshot.ts +44 -4
  560. package/src/record/frame-targets.ts +10 -6
  561. package/src/record/frame.ts +373 -1099
  562. package/src/record/gpu-draw-receipts.ts +38 -0
  563. package/src/record/gpu-timing.ts +48 -5
  564. package/src/record/main-pass-geometry.ts +281 -83
  565. package/src/record/main-pass-material.ts +66 -4
  566. package/src/record/main-pass-sprite-draws.ts +13 -66
  567. package/src/record/main-pass.ts +156 -20
  568. package/src/record/mesh-ssbo.ts +43 -6
  569. package/src/record/motion-blur-receipt.ts +91 -0
  570. package/src/record/probe-blend-buffer.ts +180 -0
  571. package/src/record/recovery-pipeline.ts +35 -3
  572. package/src/record/render-context.ts +51 -31
  573. package/src/record/shadow-pass.ts +36 -2
  574. package/src/record/skybox-post-pass.ts +150 -200
  575. package/src/record/typed-frame-graph.ts +824 -44
  576. package/src/record/view-ubo.ts +26 -3
  577. package/src/record/volume-params.ts +225 -0
  578. package/src/recovery/render-system-candidate.ts +257 -52
  579. package/src/reflection/record-owner.ts +7 -3
  580. package/src/render-contract.ts +71 -8
  581. package/src/render-graph-primitives.ts +7 -1
  582. package/src/render-pipeline.ts +136 -1
  583. package/src/render-system-extract-tail.ts +72 -60
  584. package/src/render-system-extract.ts +117 -87
  585. package/src/render-system-presentation.ts +56 -0
  586. package/src/render-system-producer-roots.ts +96 -0
  587. package/src/render-system-residency.ts +159 -0
  588. package/src/render-system.ts +601 -482
  589. package/src/scene/probe-blend.ts +96 -4
  590. package/src/scene/render-scene.ts +431 -281
  591. package/src/ssao-buffers.ts +95 -2
  592. package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
  593. package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
  594. package/src/surface/dynamic-input.ts +658 -0
  595. package/src/surface/gpu-driven.ts +147 -0
  596. package/src/surface/submission-observation.ts +517 -0
  597. package/src/systems/skin-palette-allocator.ts +4 -1
  598. package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
  599. package/src/temporal/frame-coordinator.ts +8 -1
  600. package/src/temporal/frame.ts +20 -0
  601. package/src/temporal/gpu.ts +101 -17
  602. package/src/temporal/inspection.ts +7 -1
  603. package/src/temporal/standard-scene-data.ts +5 -0
  604. package/src/temporal/target-coverage-attachment.ts +4 -0
  605. package/src/temporal/view.ts +13 -2
  606. package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
  607. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
  608. package/src/transmission/single-layer-medium.ts +322 -0
  609. package/src/typed-render-graph-primitives.ts +191 -50
  610. package/src/volume/component.ts +10 -10
  611. package/src/volume/extract.ts +11 -5
  612. package/src/volume/inspection.ts +3 -0
  613. package/src/volume/passes.ts +95 -8
  614. package/src/volume/resources.ts +2 -1
  615. package/src/volume/temporal.ts +11 -0
  616. package/dist/chunk-4NNZQCL3.mjs.map +0 -1
  617. package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
  618. package/dist/chunk-DRR7D3KX.mjs.map +0 -1
  619. package/dist/chunk-GWCEMDVR.mjs.map +0 -1
  620. package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
  621. package/dist/chunk-JRIPCMYC.mjs.map +0 -1
  622. package/dist/chunk-LULCA3OF.mjs +0 -1713
  623. package/dist/chunk-LULCA3OF.mjs.map +0 -1
  624. package/dist/chunk-PA5DRJNI.mjs.map +0 -1
@@ -5,9 +5,11 @@ import {
5
5
  type VolumeError,
6
6
  VolumeInvalidBoundsError,
7
7
  VolumeInvalidParametersError,
8
- VolumeOwnerConflictError,
9
8
  } from '../errors/render';
10
9
 
10
+ export const MAX_VOLUMETRIC_FOG_OWNERS = 8;
11
+ export const VolumetricFogSamplingValue = { noise: 0, density: 1 } as const;
12
+
11
13
  export interface VolumeDensityBinding {
12
14
  readonly guid: string;
13
15
  readonly generation: number;
@@ -35,7 +37,6 @@ export interface VolumetricFogAuthoring {
35
37
  readonly light: EntityHandle;
36
38
  /** The optional same-World SpotLight paired with a PointLight. */
37
39
  readonly spotLight?: EntityHandle;
38
- /** Linear scalar density over bounds; the renderer adds no noise or animation. */
39
40
  readonly density: VolumeDensityBinding;
40
41
  readonly bounds: VolumeBounds;
41
42
  readonly extinction: readonly [number, number, number];
@@ -43,16 +44,15 @@ export interface VolumetricFogAuthoring {
43
44
  readonly emission: readonly [number, number, number];
44
45
  readonly anisotropy: number;
45
46
  readonly maxDistance: number;
46
- readonly ownerCount?: number;
47
+ /** Noise grain is the atmospheric default; density samples local bounds directly. */
48
+ readonly sampling?: 'noise' | 'density';
47
49
  }
48
50
 
49
51
  export type VolumetricFogLightSelection =
50
52
  | { readonly light: EntityHandle; readonly spotLight?: undefined }
51
53
  | { readonly light: EntityHandle; readonly spotLight: EntityHandle };
52
54
 
53
- export interface ValidatedVolumetricFog extends VolumetricFogAuthoring {
54
- readonly ownerCount: 1;
55
- }
55
+ export type ValidatedVolumetricFog = VolumetricFogAuthoring;
56
56
 
57
57
  export const VolumetricFog = defineComponent('VolumetricFog', {
58
58
  light: { type: 'entity' },
@@ -65,6 +65,7 @@ export const VolumetricFog = defineComponent('VolumetricFog', {
65
65
  emission: { type: 'array<f32, 3>' },
66
66
  anisotropy: { type: 'f32', default: 0 },
67
67
  maxDistance: { type: 'f32', default: 100 },
68
+ sampling: { type: 'enum', labels: VolumetricFogSamplingValue, default: 0 },
68
69
  });
69
70
 
70
71
  function finiteVector(value: readonly [number, number, number]): boolean {
@@ -87,8 +88,6 @@ function validRange(
87
88
  export function validateVolumetricFog(
88
89
  input: VolumetricFogAuthoring,
89
90
  ): Result<ValidatedVolumetricFog, VolumeError> {
90
- const ownerCount = input.ownerCount ?? 1;
91
- if (ownerCount !== 1) return err(new VolumeOwnerConflictError(ownerCount));
92
91
  if (input.density.shape.viewDimension !== '3d' || input.density.colorSpace === 'srgb') {
93
92
  return err(
94
93
  new VolumeDensityShapeMismatchError(input.density.guid, input.density.shape.viewDimension),
@@ -103,9 +102,10 @@ export function validateVolumetricFog(
103
102
  input.anisotropy <= -1 ||
104
103
  input.anisotropy >= 1 ||
105
104
  !Number.isFinite(input.maxDistance) ||
106
- input.maxDistance <= 0
105
+ input.maxDistance <= 0 ||
106
+ (input.sampling !== undefined && input.sampling !== 'noise' && input.sampling !== 'density')
107
107
  ) {
108
108
  return err(new VolumeInvalidParametersError(input));
109
109
  }
110
- return ok({ ...input, ownerCount: 1 });
110
+ return ok(input);
111
111
  }
@@ -1,6 +1,7 @@
1
1
  import { err, ok, type Result } from '@forgeax/engine-types';
2
2
  import { type VolumeError, VolumeOwnerConflictError } from '../errors/render';
3
3
  import {
4
+ MAX_VOLUMETRIC_FOG_OWNERS,
4
5
  type ValidatedVolumetricFog,
5
6
  type VolumetricFogAuthoring,
6
7
  validateVolumetricFog,
@@ -8,14 +9,19 @@ import {
8
9
 
9
10
  export type VolumetricFogExtract =
10
11
  | { readonly status: 'off' }
11
- | { readonly status: 'available'; readonly fog: ValidatedVolumetricFog };
12
+ | { readonly status: 'available'; readonly fogs: readonly ValidatedVolumetricFog[] };
12
13
 
13
14
  export function extractVolumetricFog(
14
15
  inputs: readonly VolumetricFogAuthoring[],
15
16
  ): Result<VolumetricFogExtract, VolumeError> {
16
17
  if (inputs.length === 0) return ok({ status: 'off' });
17
- if (inputs.length !== 1) return err(new VolumeOwnerConflictError(inputs.length));
18
- const validated = validateVolumetricFog(inputs[0] as VolumetricFogAuthoring);
19
- if (!validated.ok) return validated;
20
- return ok({ status: 'available', fog: validated.value });
18
+ if (inputs.length > MAX_VOLUMETRIC_FOG_OWNERS)
19
+ return err(new VolumeOwnerConflictError(inputs.length));
20
+ const fogs: ValidatedVolumetricFog[] = [];
21
+ for (const input of inputs) {
22
+ const validated = validateVolumetricFog(input);
23
+ if (!validated.ok) return validated;
24
+ fogs.push(validated.value);
25
+ }
26
+ return ok({ status: 'available', fogs });
21
27
  }
@@ -7,6 +7,8 @@ export type VolumetricFogInspectionStatus = 'off' | 'available' | 'unavailable'
7
7
  export type VolumetricFogResourceStage = 'none' | 'candidate' | 'accepted' | 'lkg' | 'recovering';
8
8
 
9
9
  export interface VolumetricFogInspection {
10
+ /** Owners in the last successfully submitted volume collection. */
11
+ readonly ownerCount: number;
10
12
  readonly status: VolumetricFogInspectionStatus;
11
13
  readonly resourceStage: VolumetricFogResourceStage;
12
14
  readonly guid: string | undefined;
@@ -57,6 +59,7 @@ export function inspectVolumetricFog(input: VolumetricFogInspectionInput): Volum
57
59
  ? 'degraded'
58
60
  : 'available';
59
61
  return Object.freeze({
62
+ ownerCount: 0,
60
63
  status,
61
64
  resourceStage: resourceStage(input),
62
65
  guid: recovery?.guid,
@@ -25,6 +25,7 @@ import type {
25
25
  RenderPipelineTarget,
26
26
  RenderPipelineTopology,
27
27
  } from '../render-pipeline';
28
+ import { MAX_VOLUMETRIC_FOG_OWNERS } from './component';
28
29
  import type { VolumetricFogResources } from './resources';
29
30
  import {
30
31
  createVolumetricFogResources,
@@ -32,6 +33,7 @@ import {
32
33
  VOLUME_HISTORY_FORMAT,
33
34
  VOLUME_PACKING_Z,
34
35
  VOLUME_RESOLVED_FORMAT,
36
+ VOLUMETRIC_FOG_PARAMS_BYTES,
35
37
  } from './resources';
36
38
  import type { VolumeProjectorTuple } from './temporal';
37
39
 
@@ -79,6 +81,7 @@ export interface VolumetricFogPassInputs {
79
81
  readonly linearHdr: RenderPipelineTarget;
80
82
  readonly sceneDepth: GraphTextureView;
81
83
  readonly density: GraphTextureView;
84
+ readonly additionalDensities?: readonly GraphTextureView[];
82
85
  readonly params: GraphBuffer;
83
86
  readonly view: GraphBuffer;
84
87
  readonly directionalShadow?: GraphTextureView;
@@ -89,6 +92,8 @@ export interface VolumetricFogPassInputs {
89
92
  readonly clusterUniform: GraphBuffer;
90
93
  readonly selectedLightKind: 'directional' | 'point' | 'spot';
91
94
  readonly projector?: GraphTextureView;
95
+ /** Stable world-space cloud shadow map sampled at each volume point. */
96
+ readonly cloudShadow?: GraphTextureView;
92
97
  }
93
98
  function pipelineError(stage: string): RhiError {
94
99
  return new RhiError({
@@ -164,6 +169,7 @@ function importVolumeInputs(
164
169
  spotShadow: GraphTextureView,
165
170
  selectedLightKind: 'directional' | 'point' | 'spot' | undefined,
166
171
  clusterBuffers: StandardClusterGraphBuffers | null,
172
+ cloudShadow: GraphTextureView | undefined,
167
173
  ): Result<ImportedVolumeInputs | undefined, RenderGraphError> {
168
174
  const volume = topology.volumetricFog;
169
175
  if (volume?.enabled !== true || volume.format === undefined || volume.extent === undefined)
@@ -212,9 +218,45 @@ function importVolumeInputs(
212
218
  },
213
219
  );
214
220
  if (!density.ok) return density;
221
+ const additionalDensities: GraphTextureView[] = [];
222
+ for (const [index, member] of (volume.additional ?? []).entries()) {
223
+ const texture = graph.importTexture(
224
+ `volume-density-${index + 1}`,
225
+ {
226
+ format: member.format,
227
+ size: {
228
+ width: member.extent.width,
229
+ height: member.extent.height,
230
+ depthOrArrayLayers: member.extent.depth,
231
+ },
232
+ dimension: '3d',
233
+ usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING,
234
+ },
235
+ (frame) => {
236
+ const value = frame.volumetricFog?.additional?.[index];
237
+ if (value === undefined) throw pipelineError('local density residency');
238
+ return value.densityTexture;
239
+ },
240
+ );
241
+ if (!texture.ok) return texture;
242
+ const view = graph.importView(
243
+ texture.value,
244
+ { label: `volume-density-${index + 1}.view`, dimension: '3d' },
245
+ (frame) => {
246
+ const value = frame.volumetricFog?.additional?.[index];
247
+ if (value === undefined) throw pipelineError('local density view residency');
248
+ return value.densityView;
249
+ },
250
+ );
251
+ if (!view.ok) return view;
252
+ additionalDensities.push(view.value);
253
+ }
215
254
  const params = graph.importBuffer(
216
255
  'volume-params',
217
- { size: 128, usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST },
256
+ {
257
+ size: VOLUMETRIC_FOG_PARAMS_BYTES,
258
+ usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,
259
+ },
218
260
  (frame) => {
219
261
  const context = frame.volumetricFog as VolumetricFogFrameContext | undefined;
220
262
  if (context === undefined) throw pipelineError('parameter residency');
@@ -261,6 +303,7 @@ function importVolumeInputs(
261
303
  linearHdr,
262
304
  sceneDepth,
263
305
  density: density.value,
306
+ additionalDensities,
264
307
  params: params.value,
265
308
  view: view.value,
266
309
  ...(directionalShadow === undefined ? {} : { directionalShadow }),
@@ -269,6 +312,7 @@ function importVolumeInputs(
269
312
  clusterUniform: clusterBuffers.clusterUniform,
270
313
  selectedLightKind: selectedLightKind ?? 'directional',
271
314
  ...(projector === undefined ? {} : { projector }),
315
+ ...(cloudShadow === undefined ? {} : { cloudShadow }),
272
316
  });
273
317
  }
274
318
  export function addAuthoredVolumetricFogPasses(
@@ -279,6 +323,7 @@ export function addAuthoredVolumetricFogPasses(
279
323
  directionalShadow: GraphTextureView | undefined,
280
324
  spotShadow: GraphTextureView,
281
325
  clusterBuffers: StandardClusterGraphBuffers | null,
326
+ cloudShadow?: GraphTextureView,
282
327
  ): Result<void, RenderGraphError> {
283
328
  // A paired Point+Spot volume stores the Spot shadow lane as well. The
284
329
  // topology's primary light remains PointLight for radiance selection, but
@@ -297,6 +342,7 @@ export function addAuthoredVolumetricFogPasses(
297
342
  spotShadow,
298
343
  shadowLightKind,
299
344
  clusterBuffers,
345
+ cloudShadow,
300
346
  );
301
347
  if (!imported.ok) return imported;
302
348
  if (imported.value === undefined) return ok(undefined);
@@ -322,10 +368,7 @@ export function addVolumetricFogPasses(
322
368
  // 2D depth binding; use the always-present spot target as the inert binding
323
369
  // when directional shadows are disabled. Directional selection still uses
324
370
  // its own target whenever one exists, and spot selection uses spotShadow.
325
- const shadowResource =
326
- inputs.selectedLightKind === 'spot'
327
- ? inputs.spotShadow
328
- : (inputs.directionalShadow ?? inputs.spotShadow);
371
+ const shadowResource = inputs.directionalShadow ?? inputs.spotShadow;
329
372
  let inject: ComputeState | undefined;
330
373
  let integrate: ComputeState | undefined;
331
374
  let temporal: ComputeState | undefined;
@@ -345,6 +388,7 @@ export function addVolumetricFogPasses(
345
388
  ? []
346
389
  : [{ resource: inputs.projector, usage: 'sampled-read' as const }]),
347
390
  { resource: inputs.resources.froxelView, usage: 'storage-write' },
391
+ { resource: inputs.spotShadow, usage: 'sampled-read' },
348
392
  ],
349
393
  encode: ({ pass, frame, resources }) => {
350
394
  inject ??= computeState(frame, shaderSource(frame, 'inject'), 'volume_inject', [
@@ -363,8 +407,11 @@ export function addVolumetricFogPasses(
363
407
  },
364
408
  { binding: 7, visibility: 4, buffer: { type: 'read-only-storage' } },
365
409
  { binding: 8, visibility: 4, buffer: { type: 'uniform' } },
410
+ { binding: 9, visibility: 4, texture: { sampleType: 'depth', viewDimension: '2d' } },
366
411
  ]);
367
412
  const shadow = resources.textureView(shadowResource);
413
+ const spotShadow = resources.textureView(inputs.spotShadow);
414
+ if (!spotShadow.ok) throw spotShadow.error;
368
415
  const params = resources.buffer(inputs.params);
369
416
  const view = resources.buffer(inputs.view);
370
417
  const lightData = resources.buffer(inputs.lightData);
@@ -386,6 +433,7 @@ export function addVolumetricFogPasses(
386
433
  { binding: 6, resource: { kind: 'textureView', value: froxel.value as never } },
387
434
  { binding: 7, resource: { kind: 'buffer', value: { buffer: lightData.value } } },
388
435
  { binding: 8, resource: { kind: 'buffer', value: { buffer: clusterUniform.value } } },
436
+ { binding: 9, resource: { kind: 'textureView', value: spotShadow.value as never } },
389
437
  ]);
390
438
  pass.setPipeline(inject.pipeline);
391
439
  pass.setBindGroup(0, bindings);
@@ -398,6 +446,10 @@ export function addVolumetricFogPasses(
398
446
  { resource: inputs.resources.froxelView, usage: 'sampled-read' },
399
447
  { resource: inputs.sceneDepth, usage: 'sampled-read' },
400
448
  { resource: inputs.density, usage: 'sampled-read' },
449
+ ...(inputs.additionalDensities ?? []).map((resource) => ({
450
+ resource,
451
+ usage: 'sampled-read' as const,
452
+ })),
401
453
  { resource: inputs.resources.resolvedView, usage: 'storage-write' },
402
454
  { resource: inputs.resources.historyView, usage: 'storage-write' },
403
455
  { resource: inputs.resources.temporalView, usage: 'storage-write' },
@@ -408,6 +460,9 @@ export function addVolumetricFogPasses(
408
460
  ...(inputs.projector === undefined
409
461
  ? []
410
462
  : [{ resource: inputs.projector, usage: 'sampled-read' as const }]),
463
+ ...(inputs.cloudShadow === undefined
464
+ ? []
465
+ : [{ resource: inputs.cloudShadow, usage: 'sampled-read' as const }]),
411
466
  ],
412
467
  encode: ({ pass, frame, resources }) => {
413
468
  integrate ??= computeState(frame, shaderSource(frame, 'integrate'), 'volume_integrate', [
@@ -449,6 +504,13 @@ export function addVolumetricFogPasses(
449
504
  { binding: 11, visibility: 4, buffer: { type: 'uniform' } },
450
505
  { binding: 12, visibility: 4, texture: { sampleType: 'float', viewDimension: '2d' } },
451
506
  { binding: 13, visibility: 4, sampler: { type: 'filtering' } },
507
+ { binding: 16, visibility: 4, texture: { sampleType: 'float', viewDimension: '2d' } },
508
+ { binding: 17, visibility: 4, sampler: { type: 'filtering' } },
509
+ ...Array.from({ length: MAX_VOLUMETRIC_FOG_OWNERS - 1 }, (_, index) => ({
510
+ binding: 18 + index,
511
+ visibility: 4,
512
+ texture: { sampleType: 'float' as const, viewDimension: '3d' as const },
513
+ })),
452
514
  ]);
453
515
  const froxel = resources.textureView(inputs.resources.froxelView);
454
516
  const depth = resources.textureView(inputs.sceneDepth);
@@ -462,6 +524,8 @@ export function addVolumetricFogPasses(
462
524
  const clusterUniform = resources.buffer(inputs.clusterUniform);
463
525
  const projector =
464
526
  inputs.projector === undefined ? undefined : resources.textureView(inputs.projector);
527
+ const cloudShadow =
528
+ inputs.cloudShadow === undefined ? undefined : resources.textureView(inputs.cloudShadow);
465
529
  if (!froxel.ok) throw froxel.error;
466
530
  if (!depth.ok) throw depth.error;
467
531
  if (!density.ok) throw density.error;
@@ -473,6 +537,7 @@ export function addVolumetricFogPasses(
473
537
  if (!lightData.ok) throw lightData.error;
474
538
  if (!clusterUniform.ok) throw clusterUniform.error;
475
539
  if (projector !== undefined && !projector.ok) throw projector.error;
540
+ if (cloudShadow !== undefined && !cloudShadow.ok) throw cloudShadow.error;
476
541
  const sampler = frame.runtime.device.createSampler({
477
542
  minFilter: 'linear',
478
543
  magFilter: 'linear',
@@ -481,9 +546,9 @@ export function addVolumetricFogPasses(
481
546
  const densitySampler = frame.runtime.device.createSampler({
482
547
  minFilter: 'linear',
483
548
  magFilter: 'linear',
484
- addressModeU: 'clamp-to-edge',
485
- addressModeV: 'clamp-to-edge',
486
- addressModeW: 'clamp-to-edge',
549
+ addressModeU: 'repeat',
550
+ addressModeV: 'repeat',
551
+ addressModeW: 'repeat',
487
552
  });
488
553
  if (!densitySampler.ok) throw densitySampler.error;
489
554
  const bindings = volumeBindGroup(frame, integrate.layout, [
@@ -516,6 +581,28 @@ export function addVolumetricFogPasses(
516
581
  value: frame.volumetricFog?.projectorSampler ?? frame.pipelineState.defaultSampler,
517
582
  },
518
583
  },
584
+ {
585
+ binding: 16,
586
+ resource: {
587
+ kind: 'textureView',
588
+ value:
589
+ cloudShadow === undefined
590
+ ? frame.pipelineState.defaultWhiteTextureView
591
+ : (cloudShadow.value as never),
592
+ },
593
+ },
594
+ {
595
+ binding: 17,
596
+ resource: { kind: 'sampler', value: frame.pipelineState.defaultSampler },
597
+ },
598
+ ...Array.from({ length: MAX_VOLUMETRIC_FOG_OWNERS - 1 }, (_, index) => {
599
+ const view = resources.textureView(inputs.additionalDensities?.[index] ?? inputs.density);
600
+ if (!view.ok) throw view.error;
601
+ return {
602
+ binding: 18 + index,
603
+ resource: { kind: 'textureView' as const, value: view.value as never },
604
+ };
605
+ }),
519
606
  ]);
520
607
  pass.setPipeline(integrate.pipeline);
521
608
  pass.setBindGroup(0, bindings);
@@ -8,6 +8,7 @@ import type {
8
8
  } from '@forgeax/engine-render-graph';
9
9
  import { ok, type Result } from '@forgeax/engine-types';
10
10
  import type { RenderPipelineFrame } from '../render-pipeline';
11
+ import { MAX_VOLUMETRIC_FOG_OWNERS } from './component';
11
12
 
12
13
  export const VOLUME_FROXEL_FORMAT = 'rgba8unorm' as const;
13
14
  export const VOLUME_HISTORY_FORMAT = 'rgba16float' as const;
@@ -15,7 +16,7 @@ export const VOLUME_RESOLVED_FORMAT = 'rgba16float' as const;
15
16
  export const VOLUME_DEPTH_FORMAT = 'r32float' as const;
16
17
  export const VOLUME_PACKING_Z = 4;
17
18
  /** Renderer-owned parameter allocation shared by staging and inspection. */
18
- export const VOLUMETRIC_FOG_PARAMS_BYTES = 8 * 16;
19
+ export const VOLUMETRIC_FOG_PARAMS_BYTES = (1 + MAX_VOLUMETRIC_FOG_OWNERS) * 9 * 16;
19
20
 
20
21
  export interface VolumetricFogExtent {
21
22
  readonly width: number;
@@ -5,6 +5,8 @@ export interface VolumeTemporalSignature {
5
5
  readonly densityGeneration: number;
6
6
  readonly width: number;
7
7
  readonly height: number;
8
+ /** World-owned authored-medium time; render frame identity never advances the medium. */
9
+ readonly worldTimeSeconds?: number;
8
10
  readonly lightKind?: 'directional' | 'point' | 'spot';
9
11
  readonly lightEntity?: number;
10
12
  readonly pointLightEntity?: number;
@@ -28,6 +30,7 @@ export type VolumeTemporalResetReason =
28
30
  | 'fog-revision'
29
31
  | 'light-revision'
30
32
  | 'density-generation'
33
+ | 'simulation-time'
31
34
  | 'resize'
32
35
  | 'reprojection-out-of-screen'
33
36
  | 'reprojection-depth-discontinuity';
@@ -92,6 +95,14 @@ export function resolveVolumeTemporalReset(
92
95
  if (previous.lightShadowRevision !== next.lightShadowRevision) {
93
96
  return { reset: true, reason: 'light-revision' };
94
97
  }
98
+ if (previous.worldTimeSeconds !== next.worldTimeSeconds) {
99
+ const delta = (next.worldTimeSeconds ?? NaN) - (previous.worldTimeSeconds ?? NaN);
100
+ // Small monotonic ticks animate the same medium. Reset only on a clock
101
+ // discontinuity; rejecting every tick prevents temporal reuse in live play.
102
+ if (!Number.isFinite(delta) || delta < 0 || delta > 0.1) {
103
+ return { reset: true, reason: 'simulation-time' };
104
+ }
105
+ }
95
106
  if (previous.densityGeneration !== next.densityGeneration) {
96
107
  return { reset: true, reason: 'density-generation' };
97
108
  }