@forgeax/engine-render 0.1.33 → 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 (518) hide show
  1. package/README.md +1010 -124
  2. package/dist/assembly/backend-contract.d.ts +2 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
  5. package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
  6. package/dist/assembly/canvas-draw-guard.d.ts +3 -0
  7. package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
  8. package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
  9. package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
  10. package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
  11. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  12. package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
  13. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
  14. package/dist/assembly/factory.d.ts +1 -1
  15. package/dist/assembly/factory.d.ts.map +1 -1
  16. package/dist/assembly/host-contract.d.ts +3 -3
  17. package/dist/assembly/host-contract.d.ts.map +1 -1
  18. package/dist/assembly/material/assembly.d.ts.map +1 -1
  19. package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
  20. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
  21. package/dist/assembly/material-shader-policy.d.ts +16 -2
  22. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  23. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
  24. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  25. package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
  26. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  27. package/dist/assembly/render-feature-post-processes.d.ts +6 -0
  28. package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
  29. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  30. package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
  31. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
  32. package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
  33. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  34. package/dist/assembly/renderer-inspection.d.ts +11 -0
  35. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  36. package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
  37. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
  38. package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
  39. package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
  40. package/dist/assembly/webgpu-ready.d.ts +1 -1
  41. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  42. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
  43. package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
  44. package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
  45. package/dist/assembly/webgpu-renderer.d.ts +1 -1
  46. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  47. package/dist/authoring.mjs +1 -1
  48. package/dist/barrel-distortion.d.ts +47 -0
  49. package/dist/barrel-distortion.d.ts.map +1 -0
  50. package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
  51. package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
  52. package/dist/{chunk-ZDQWGQW7.mjs → chunk-HEB564WF.mjs} +4 -4
  53. package/dist/{chunk-ZDQWGQW7.mjs.map → chunk-HEB564WF.mjs.map} +1 -1
  54. package/dist/{chunk-VOZWDM3L.mjs → chunk-MKDIT2EM.mjs} +1307 -188
  55. package/dist/chunk-MKDIT2EM.mjs.map +1 -0
  56. package/dist/{chunk-LEAXOMYJ.mjs → chunk-OCDLEI6I.mjs} +3 -3
  57. package/dist/{chunk-LEAXOMYJ.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
  58. package/dist/chunk-ODZWR6JQ.mjs +4927 -0
  59. package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
  60. package/dist/{chunk-3RTCJTH4.mjs → chunk-SHFUFJ5N.mjs} +184 -13
  61. package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
  62. package/dist/{chunk-OO3DRYK7.mjs → chunk-UI5SFODX.mjs} +176 -96
  63. package/dist/chunk-UI5SFODX.mjs.map +1 -0
  64. package/dist/{chunk-PLAXOOX5.mjs → chunk-UINHLCZA.mjs} +561 -79
  65. package/dist/chunk-UINHLCZA.mjs.map +1 -0
  66. package/dist/{chunk-NB2S7ZRX.mjs → chunk-WEX45HKH.mjs} +127 -386
  67. package/dist/chunk-WEX45HKH.mjs.map +1 -0
  68. package/dist/cloud/density.d.ts +55 -0
  69. package/dist/cloud/density.d.ts.map +1 -0
  70. package/dist/cloud/extract.d.ts +25 -0
  71. package/dist/cloud/extract.d.ts.map +1 -0
  72. package/dist/cloud/feature.d.ts +57 -0
  73. package/dist/cloud/feature.d.ts.map +1 -0
  74. package/dist/cloud/frame-context.d.ts +8 -0
  75. package/dist/cloud/frame-context.d.ts.map +1 -0
  76. package/dist/cloud/inspection.d.ts +59 -0
  77. package/dist/cloud/inspection.d.ts.map +1 -0
  78. package/dist/cloud/optics.d.ts +56 -0
  79. package/dist/cloud/optics.d.ts.map +1 -0
  80. package/dist/cloud/parameters.d.ts +73 -0
  81. package/dist/cloud/parameters.d.ts.map +1 -0
  82. package/dist/cloud/resources.d.ts +60 -0
  83. package/dist/cloud/resources.d.ts.map +1 -0
  84. package/dist/cloud/shadow.d.ts +42 -0
  85. package/dist/cloud/shadow.d.ts.map +1 -0
  86. package/dist/cloud/temporal.d.ts +74 -0
  87. package/dist/cloud/temporal.d.ts.map +1 -0
  88. package/dist/components/barrel-distortion.d.ts +13 -0
  89. package/dist/components/barrel-distortion.d.ts.map +1 -0
  90. package/dist/components/cloud-layer.d.ts +29 -0
  91. package/dist/components/cloud-layer.d.ts.map +1 -0
  92. package/dist/components/index.d.ts +2 -0
  93. package/dist/components/index.d.ts.map +1 -1
  94. package/dist/components/instances.d.ts +20 -6
  95. package/dist/components/instances.d.ts.map +1 -1
  96. package/dist/construct-renderer.d.ts +1 -1
  97. package/dist/construct-renderer.d.ts.map +1 -1
  98. package/dist/construct-renderer.mjs +6759 -2875
  99. package/dist/construct-renderer.mjs.map +1 -1
  100. package/dist/dynamic-geometry.d.ts +5 -1
  101. package/dist/dynamic-geometry.d.ts.map +1 -1
  102. package/dist/errors/cloud.d.ts +59 -0
  103. package/dist/errors/cloud.d.ts.map +1 -0
  104. package/dist/errors/render.d.ts +18 -4
  105. package/dist/errors/render.d.ts.map +1 -1
  106. package/dist/examples/single-layer-medium-surface.d.ts +47 -0
  107. package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
  108. package/dist/extract/camera.d.ts.map +1 -1
  109. package/dist/extract/contracts.d.ts +5 -1
  110. package/dist/extract/contracts.d.ts.map +1 -1
  111. package/dist/features/barrel-distortion.d.ts +29 -0
  112. package/dist/features/barrel-distortion.d.ts.map +1 -0
  113. package/dist/features/error-reporting.d.ts +6 -2
  114. package/dist/features/error-reporting.d.ts.map +1 -1
  115. package/dist/features/host.d.ts +10 -0
  116. package/dist/features/host.d.ts.map +1 -1
  117. package/dist/features/plan.d.ts +8 -0
  118. package/dist/features/plan.d.ts.map +1 -1
  119. package/dist/features/render-graph-contribution.d.ts +5 -0
  120. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  121. package/dist/features/render-graph-raster.d.ts +1 -0
  122. package/dist/features/render-graph-raster.d.ts.map +1 -1
  123. package/dist/features/targets.d.ts +2 -0
  124. package/dist/features/targets.d.ts.map +1 -1
  125. package/dist/features/types.d.ts +44 -0
  126. package/dist/features/types.d.ts.map +1 -1
  127. package/dist/fullscreen-post-process-pass.d.ts +15 -7
  128. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  129. package/dist/gpu-dirty-ranges.d.ts +11 -0
  130. package/dist/gpu-dirty-ranges.d.ts.map +1 -0
  131. package/dist/gpu-driven/batch-topology.d.ts +17 -0
  132. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  133. package/dist/gpu-driven/material-artifacts.d.ts +6 -0
  134. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  135. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  136. package/dist/gpu-driven/production-raster-material.d.ts +178 -0
  137. package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
  138. package/dist/gpu-driven/production-raster.d.ts +47 -3
  139. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  140. package/dist/gpu-driven/resource-allocation.d.ts +31 -0
  141. package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
  142. package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
  143. package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
  144. package/dist/gpu-driven/view-gpu.d.ts +26 -2
  145. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  146. package/dist/gpu-scene.d.ts +5 -0
  147. package/dist/gpu-scene.d.ts.map +1 -1
  148. package/dist/hdrp-buffers.d.ts +2 -2
  149. package/dist/hdrp-buffers.d.ts.map +1 -1
  150. package/dist/ibl/skylight-bind-group.d.ts +10 -1
  151. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  152. package/dist/index.d.ts +27 -7
  153. package/dist/index.d.ts.map +1 -1
  154. package/dist/index.mjs +258 -8
  155. package/dist/index.mjs.map +1 -1
  156. package/dist/inspection-types.d.ts +135 -1
  157. package/dist/inspection-types.d.ts.map +1 -1
  158. package/dist/instance-buffer-cache.d.ts +4 -4
  159. package/dist/instance-buffer-cache.d.ts.map +1 -1
  160. package/dist/instances.d.ts +48 -100
  161. package/dist/instances.d.ts.map +1 -1
  162. package/dist/internal.mjs +7 -7
  163. package/dist/pbr-pipeline.d.ts +19 -1
  164. package/dist/pbr-pipeline.d.ts.map +1 -1
  165. package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
  166. package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
  167. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  168. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  169. package/dist/pipeline/standard-output/types.d.ts +4 -2
  170. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  171. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  172. package/dist/pipeline/standard-post.d.ts.map +1 -1
  173. package/dist/pipeline-builder.d.ts +1 -1
  174. package/dist/pipeline-builder.d.ts.map +1 -1
  175. package/dist/plugin.d.ts.map +1 -1
  176. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
  177. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  178. package/dist/record/barrel-distortion-frame.d.ts +15 -0
  179. package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
  180. package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
  181. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
  182. package/dist/record/fold-buckets.d.ts +95 -0
  183. package/dist/record/fold-buckets.d.ts.map +1 -0
  184. package/dist/record/fold-instance-buffer.d.ts +6 -0
  185. package/dist/record/fold-instance-buffer.d.ts.map +1 -0
  186. package/dist/record/frame-lighting.d.ts +1 -0
  187. package/dist/record/frame-lighting.d.ts.map +1 -1
  188. package/dist/record/frame-snapshot.d.ts +37 -3
  189. package/dist/record/frame-snapshot.d.ts.map +1 -1
  190. package/dist/record/frame.d.ts +10 -61
  191. package/dist/record/frame.d.ts.map +1 -1
  192. package/dist/record/gpu-draw-receipts.d.ts +11 -0
  193. package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
  194. package/dist/record/gpu-timing.d.ts +8 -0
  195. package/dist/record/gpu-timing.d.ts.map +1 -1
  196. package/dist/record/main-pass-geometry.d.ts +21 -5
  197. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  198. package/dist/record/main-pass-material.d.ts +7 -1
  199. package/dist/record/main-pass-material.d.ts.map +1 -1
  200. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  201. package/dist/record/main-pass.d.ts +13 -2
  202. package/dist/record/main-pass.d.ts.map +1 -1
  203. package/dist/record/motion-blur-receipt.d.ts +11 -0
  204. package/dist/record/motion-blur-receipt.d.ts.map +1 -0
  205. package/dist/record/probe-blend-buffer.d.ts +16 -0
  206. package/dist/record/probe-blend-buffer.d.ts.map +1 -0
  207. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  208. package/dist/record/render-context.d.ts +22 -3
  209. package/dist/record/render-context.d.ts.map +1 -1
  210. package/dist/record/shadow-pass.d.ts +2 -0
  211. package/dist/record/shadow-pass.d.ts.map +1 -1
  212. package/dist/record/skybox-post-pass.d.ts +1 -1
  213. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  214. package/dist/record/typed-frame-graph.d.ts +22 -2
  215. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  216. package/dist/record/view-ubo.d.ts +11 -3
  217. package/dist/record/view-ubo.d.ts.map +1 -1
  218. package/dist/record/volume-params.d.ts +9 -0
  219. package/dist/record/volume-params.d.ts.map +1 -0
  220. package/dist/recovery/render-system-candidate.d.ts +10 -0
  221. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  222. package/dist/reflection/record-owner.d.ts.map +1 -1
  223. package/dist/render-contract.d.ts +42 -4
  224. package/dist/render-contract.d.ts.map +1 -1
  225. package/dist/render-graph-primitives.d.ts.map +1 -1
  226. package/dist/render-pipeline.d.ts +103 -2
  227. package/dist/render-pipeline.d.ts.map +1 -1
  228. package/dist/render-system-extract-tail.d.ts +3 -2
  229. package/dist/render-system-extract-tail.d.ts.map +1 -1
  230. package/dist/render-system-extract.d.ts +16 -9
  231. package/dist/render-system-extract.d.ts.map +1 -1
  232. package/dist/render-system-presentation.d.ts +23 -0
  233. package/dist/render-system-presentation.d.ts.map +1 -0
  234. package/dist/render-system-producer-roots.d.ts +10 -0
  235. package/dist/render-system-producer-roots.d.ts.map +1 -0
  236. package/dist/render-system-residency.d.ts +12 -0
  237. package/dist/render-system-residency.d.ts.map +1 -0
  238. package/dist/render-system.d.ts +19 -14
  239. package/dist/render-system.d.ts.map +1 -1
  240. package/dist/scene/probe-blend.d.ts +27 -0
  241. package/dist/scene/probe-blend.d.ts.map +1 -1
  242. package/dist/scene/render-scene.d.ts +12 -5
  243. package/dist/scene/render-scene.d.ts.map +1 -1
  244. package/dist/ssao-buffers.d.ts +9 -0
  245. package/dist/ssao-buffers.d.ts.map +1 -1
  246. package/dist/surface/dynamic-input.d.ts +133 -0
  247. package/dist/surface/dynamic-input.d.ts.map +1 -0
  248. package/dist/surface/gpu-driven.d.ts +41 -0
  249. package/dist/surface/gpu-driven.d.ts.map +1 -0
  250. package/dist/surface/submission-observation.d.ts +136 -0
  251. package/dist/surface/submission-observation.d.ts.map +1 -0
  252. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  253. package/dist/temporal/gpu.d.ts +13 -1
  254. package/dist/temporal/gpu.d.ts.map +1 -1
  255. package/dist/temporal/index.mjs +5 -5
  256. package/dist/temporal/inspection.d.ts.map +1 -1
  257. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  258. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
  259. package/dist/transmission/single-layer-medium.d.ts +89 -0
  260. package/dist/transmission/single-layer-medium.d.ts.map +1 -0
  261. package/dist/typed-render-graph-primitives.d.ts +14 -2
  262. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  263. package/dist/volume/component.d.ts +9 -4
  264. package/dist/volume/component.d.ts.map +1 -1
  265. package/dist/volume/extract.d.ts +1 -1
  266. package/dist/volume/extract.d.ts.map +1 -1
  267. package/dist/volume/inspection.d.ts +2 -0
  268. package/dist/volume/inspection.d.ts.map +1 -1
  269. package/dist/volume/passes.d.ts +4 -1
  270. package/dist/volume/passes.d.ts.map +1 -1
  271. package/dist/volume/resources.d.ts.map +1 -1
  272. package/package.json +22 -21
  273. package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
  274. package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
  275. package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
  276. package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
  277. package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
  278. package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
  279. package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
  280. package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
  281. package/src/__tests__/factory-contract.integration.test.ts +295 -45
  282. package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
  283. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
  284. package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
  285. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
  286. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
  287. package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
  288. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
  289. package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
  290. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +6 -5
  291. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +94 -6
  292. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
  293. package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
  294. package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
  295. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
  296. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
  297. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
  298. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
  299. package/src/__tests__/gpu-scene.unit.test.ts +119 -9
  300. package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
  301. package/src/__tests__/instances-culling.integration.test.ts +10 -36
  302. package/src/__tests__/instances-store.unit.test.ts +97 -305
  303. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  304. package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
  305. package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
  306. package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
  307. package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
  308. package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
  309. package/src/__tests__/motion-blur-compute.dawn.test.ts +13 -7
  310. package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
  311. package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
  312. package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
  313. package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
  314. package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
  315. package/src/__tests__/probe-bindings.unit.test.ts +582 -1
  316. package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
  317. package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
  318. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
  319. package/src/__tests__/render-error-code-owner.test-d.ts +7 -0
  320. package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
  321. package/src/__tests__/render-feature-error-reporting.unit.test.ts +21 -1
  322. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
  323. package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
  324. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
  325. package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
  326. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +20 -20
  327. package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
  328. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
  329. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
  330. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
  331. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
  332. package/src/__tests__/renderer-frame-transaction.integration.test.ts +26 -10
  333. package/src/__tests__/resource-allocation.unit.test.ts +123 -0
  334. package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
  335. package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
  336. package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
  337. package/src/__tests__/skinned-shadow-caster.test.ts +15 -0
  338. package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
  339. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
  340. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
  341. package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
  342. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
  343. package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
  344. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
  345. package/src/__tests__/standard-pipeline.integration.test.ts +182 -1
  346. package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
  347. package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
  348. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
  349. package/src/__tests__/temporal-performance.integration.test.ts +3 -3
  350. package/src/__tests__/visibility-instances.integration.test.ts +7 -19
  351. package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
  352. package/src/__tests__/volume-optics-oracle.unit.test.ts +4 -2
  353. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +30 -20
  354. package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
  355. package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
  356. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
  357. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +113 -9
  358. package/src/__tests__/volumetric-fog-topology.unit.test.ts +5 -3
  359. package/src/assembly/backend-contract.ts +30 -0
  360. package/src/assembly/barrel-distortion-inspection.ts +22 -0
  361. package/src/assembly/canvas-draw-guard.ts +11 -0
  362. package/src/assembly/cloud-shadow-entry.ts +22 -0
  363. package/src/assembly/dynamic-geometry-host.ts +65 -37
  364. package/src/assembly/dynamic-geometry-runtime.ts +7 -1
  365. package/src/assembly/factory.ts +2 -30
  366. package/src/assembly/host-contract.ts +3 -3
  367. package/src/assembly/material/assembly.ts +25 -13
  368. package/src/assembly/material/pipeline-helpers.ts +53 -12
  369. package/src/assembly/material-shader-policy.ts +55 -0
  370. package/src/assembly/material-shader-prewarm.ts +21 -10
  371. package/src/assembly/recovery/device-loss-fanout.ts +13 -0
  372. package/src/assembly/recovery/renderer-recover.ts +41 -18
  373. package/src/assembly/render-feature-post-processes.ts +54 -0
  374. package/src/assembly/renderer-facade.ts +4 -1
  375. package/src/assembly/renderer-feature-inspection.ts +8 -2
  376. package/src/assembly/renderer-frame-transaction.ts +23 -0
  377. package/src/assembly/renderer-inspection.ts +28 -0
  378. package/src/assembly/skin-palette-owner.ts +1 -1
  379. package/src/assembly/temporal-post-process-prewarm.ts +3 -3
  380. package/src/assembly/webgpu-pbr-ready.ts +9 -1
  381. package/src/assembly/webgpu-ready-per-pass.ts +104 -0
  382. package/src/assembly/webgpu-ready.ts +115 -61
  383. package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
  384. package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
  385. package/src/assembly/webgpu-renderer.ts +214 -252
  386. package/src/assembly/webgpu-vertex-layouts.ts +1 -1
  387. package/src/barrel-distortion.ts +247 -0
  388. package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
  389. package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
  390. package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
  391. package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
  392. package/src/cloud/density.ts +600 -0
  393. package/src/cloud/extract.ts +110 -0
  394. package/src/cloud/feature.ts +1810 -0
  395. package/src/cloud/frame-context.ts +42 -0
  396. package/src/cloud/inspection.ts +130 -0
  397. package/src/cloud/optics.ts +285 -0
  398. package/src/cloud/parameters.ts +255 -0
  399. package/src/cloud/resources.ts +122 -0
  400. package/src/cloud/shadow.ts +167 -0
  401. package/src/cloud/temporal.ts +226 -0
  402. package/src/components/barrel-distortion.ts +46 -0
  403. package/src/components/cloud-layer.ts +47 -0
  404. package/src/components/index.ts +2 -0
  405. package/src/components/instances.ts +18 -45
  406. package/src/components/sprite-instances.ts +1 -1
  407. package/src/construct-renderer.ts +1 -1
  408. package/src/dynamic-geometry.ts +12 -1
  409. package/src/errors/cloud.ts +103 -0
  410. package/src/errors/render.ts +44 -7
  411. package/src/examples/single-layer-medium-surface.ts +59 -0
  412. package/src/extract/camera.ts +15 -1
  413. package/src/extract/contracts.ts +5 -0
  414. package/src/features/barrel-distortion.ts +172 -0
  415. package/src/features/error-reporting.ts +26 -6
  416. package/src/features/host.ts +115 -14
  417. package/src/features/plan.ts +8 -0
  418. package/src/features/render-graph-contribution.ts +9 -0
  419. package/src/features/render-graph-raster.ts +45 -3
  420. package/src/features/targets.ts +66 -0
  421. package/src/features/types.ts +47 -0
  422. package/src/fullscreen-post-process-pass.ts +41 -9
  423. package/src/gpu-dirty-ranges.ts +48 -0
  424. package/src/gpu-driven/batch-topology.ts +53 -0
  425. package/src/gpu-driven/material-artifacts.ts +33 -25
  426. package/src/gpu-driven/prepared-draw.ts +12 -4
  427. package/src/gpu-driven/production-raster-material.ts +1894 -0
  428. package/src/gpu-driven/production-raster.ts +825 -784
  429. package/src/gpu-driven/resource-allocation.ts +142 -0
  430. package/src/gpu-driven/shadow-ownership.ts +71 -0
  431. package/src/gpu-driven/view-gpu.ts +164 -10
  432. package/src/gpu-scene.ts +75 -84
  433. package/src/hdrp-buffers.ts +4 -3
  434. package/src/ibl/skylight-bind-group.ts +49 -7
  435. package/src/index.ts +196 -9
  436. package/src/inspection-types.ts +162 -0
  437. package/src/instance-buffer-cache.ts +4 -4
  438. package/src/instances.ts +149 -569
  439. package/src/pbr-pipeline.ts +219 -13
  440. package/src/pipeline/single-layer-medium-passes.ts +267 -0
  441. package/src/pipeline/standard-forward-lane.ts +313 -57
  442. package/src/pipeline/standard-output/graph.ts +8 -2
  443. package/src/pipeline/standard-output/types.ts +12 -1
  444. package/src/pipeline/standard-pipeline.ts +291 -18
  445. package/src/pipeline/standard-post.ts +90 -24
  446. package/src/pipeline-builder.ts +1 -1
  447. package/src/plugin.ts +4 -0
  448. package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
  449. package/src/prepare/prepared-graphics-resolver.ts +2 -0
  450. package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
  451. package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
  452. package/src/record/__tests__/temporal-payload.unit.test.ts +1 -1
  453. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
  454. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
  455. package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
  456. package/src/record/barrel-distortion-frame.ts +110 -0
  457. package/src/record/dynamic-geometry-consumption.ts +39 -9
  458. package/src/record/fold-buckets.ts +852 -0
  459. package/src/record/fold-instance-buffer.ts +51 -0
  460. package/src/record/frame-lighting.ts +36 -2
  461. package/src/record/frame-snapshot.ts +39 -3
  462. package/src/record/frame.ts +217 -1084
  463. package/src/record/gpu-draw-receipts.ts +38 -0
  464. package/src/record/gpu-timing.ts +48 -5
  465. package/src/record/main-pass-geometry.ts +251 -82
  466. package/src/record/main-pass-material.ts +66 -4
  467. package/src/record/main-pass-sprite-draws.ts +7 -65
  468. package/src/record/main-pass.ts +156 -20
  469. package/src/record/motion-blur-receipt.ts +91 -0
  470. package/src/record/probe-blend-buffer.ts +180 -0
  471. package/src/record/recovery-pipeline.ts +35 -3
  472. package/src/record/render-context.ts +39 -3
  473. package/src/record/shadow-pass.ts +30 -1
  474. package/src/record/skybox-post-pass.ts +28 -4
  475. package/src/record/typed-frame-graph.ts +770 -134
  476. package/src/record/view-ubo.ts +26 -3
  477. package/src/record/volume-params.ts +225 -0
  478. package/src/recovery/render-system-candidate.ts +235 -42
  479. package/src/reflection/record-owner.ts +7 -3
  480. package/src/render-contract.ts +48 -4
  481. package/src/render-graph-primitives.ts +7 -1
  482. package/src/render-pipeline.ts +130 -0
  483. package/src/render-system-extract-tail.ts +57 -61
  484. package/src/render-system-extract.ts +74 -76
  485. package/src/render-system-presentation.ts +56 -0
  486. package/src/render-system-producer-roots.ts +96 -0
  487. package/src/render-system-residency.ts +159 -0
  488. package/src/render-system.ts +347 -363
  489. package/src/scene/probe-blend.ts +96 -4
  490. package/src/scene/render-scene.ts +349 -280
  491. package/src/ssao-buffers.ts +95 -2
  492. package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
  493. package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
  494. package/src/surface/dynamic-input.ts +658 -0
  495. package/src/surface/gpu-driven.ts +147 -0
  496. package/src/surface/submission-observation.ts +517 -0
  497. package/src/systems/skin-palette-allocator.ts +4 -1
  498. package/src/temporal/gpu.ts +101 -17
  499. package/src/temporal/inspection.ts +7 -1
  500. package/src/temporal/standard-scene-data.ts +5 -0
  501. package/src/temporal/target-coverage-attachment.ts +4 -0
  502. package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
  503. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
  504. package/src/transmission/single-layer-medium.ts +322 -0
  505. package/src/typed-render-graph-primitives.ts +70 -2
  506. package/src/volume/component.ts +10 -9
  507. package/src/volume/extract.ts +11 -5
  508. package/src/volume/inspection.ts +3 -0
  509. package/src/volume/passes.ts +87 -4
  510. package/src/volume/resources.ts +2 -1
  511. package/dist/chunk-3RTCJTH4.mjs.map +0 -1
  512. package/dist/chunk-NB2S7ZRX.mjs.map +0 -1
  513. package/dist/chunk-NNQL7CB3.mjs +0 -1713
  514. package/dist/chunk-NNQL7CB3.mjs.map +0 -1
  515. package/dist/chunk-OO3DRYK7.mjs.map +0 -1
  516. package/dist/chunk-PA5DRJNI.mjs.map +0 -1
  517. package/dist/chunk-PLAXOOX5.mjs.map +0 -1
  518. package/dist/chunk-VOZWDM3L.mjs.map +0 -1
@@ -1,11 +1,10 @@
1
- import type {
2
- GraphTextureDescriptor,
3
- RenderGraphBuilder,
4
- RenderGraphError,
5
- } from '@forgeax/engine-render-graph';
1
+ import type { GraphTextureDescriptor, RenderGraphBuilder } from '@forgeax/engine-render-graph';
2
+ import { RenderGraphError } from '@forgeax/engine-render-graph';
6
3
  import { err, ok, type Result } from '@forgeax/engine-types';
4
+ import { CLOUD_LAYER_FEATURE_IDENTITY } from '../cloud/feature';
7
5
  import { addAtmosphereBackground } from '../environment/background';
8
6
  import { SceneDataUnavailableError } from '../errors/render';
7
+ import { BARREL_DISTORTION_FEATURE_IDENTITY } from '../features/barrel-distortion';
9
8
  import {
10
9
  GPU_TEXTURE_USAGE_COPY_SRC,
11
10
  GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,
@@ -14,12 +13,14 @@ import {
14
13
  import type {
15
14
  RenderPipeline,
16
15
  RenderPipelineFrame,
16
+ RenderPipelineSurfaceMediumPair,
17
17
  RenderPipelineTopology,
18
18
  } from '../render-pipeline';
19
19
  import {
20
20
  createRenderPipelineTarget,
21
21
  importRenderPipelineSurface,
22
22
  type RenderPipelineTarget,
23
+ renderPipelineCloudHistoryTargets,
23
24
  } from '../render-pipeline';
24
25
  import {
25
26
  addStandardSceneDataPass,
@@ -43,6 +44,11 @@ import {
43
44
  import { addTypedShadowPasses } from '../typed-shadow-passes';
44
45
  import { addAuthoredVolumetricFogPasses } from '../volume/passes';
45
46
  import { renderExtentSize } from './render-extent';
47
+ import {
48
+ addSingleLayerMediumMsaaPairProducer,
49
+ addSingleLayerMediumPasses,
50
+ addSingleLayerMediumRawDepthProducer,
51
+ } from './single-layer-medium-passes';
46
52
  import type { StandardPipelineBuildContext } from './standard-build-context';
47
53
  import {
48
54
  addStandardClusterMembershipPass,
@@ -71,6 +77,10 @@ function buildUrp(
71
77
 
72
78
  const internalSize =
73
79
  topology.extent === undefined ? 'surface' : renderExtentSize(topology.extent, 'internal');
80
+ const internalCopySize =
81
+ topology.extent === undefined
82
+ ? { width: topology.surface.width, height: topology.surface.height }
83
+ : renderExtentSize(topology.extent, 'internal');
74
84
 
75
85
  const clearOnly = topology.clearOnly === true;
76
86
  const msaa = !clearOnly && topology.camera.antialias === 'msaa' && topology.lane.multisample;
@@ -93,7 +103,7 @@ function buildUrp(
93
103
  });
94
104
  const needsTemporalIntermediate = temporalDemand.targetCount === 1;
95
105
  const sceneFormat =
96
- hdr || linearLdr || rawOnly || needsTemporalIntermediate
106
+ hdr || linearLdr || rawOnly || needsTemporalIntermediate || topology.singleLayerMedium === true
97
107
  ? 'rgba16float'
98
108
  : topology.surface.storageFormat;
99
109
 
@@ -113,7 +123,13 @@ function buildUrp(
113
123
  domain: 'display-encoded',
114
124
  })
115
125
  : ok(surface.value.display)
116
- : hdr || fxaa || linearLdr || msaa || rawOnly || needsTemporalIntermediate
126
+ : hdr ||
127
+ fxaa ||
128
+ linearLdr ||
129
+ msaa ||
130
+ rawOnly ||
131
+ needsTemporalIntermediate ||
132
+ topology.singleLayerMedium === true
117
133
  ? target(graph, 'scene-color', {
118
134
  format: sceneFormat,
119
135
  size: internalSize,
@@ -147,6 +163,27 @@ function buildUrp(
147
163
  : sceneResolved;
148
164
  if (!scene.ok) return scene;
149
165
 
166
+ const mediumTargets =
167
+ topology.singleLayerMedium === true
168
+ ? (() => {
169
+ const nearestLayer = target(graph, 'single-layer-medium-nearest-layer', {
170
+ format: scene.value.format,
171
+ size: internalSize,
172
+ sampleCount: msaa ? 4 : 1,
173
+ domain: 'linear-ldr',
174
+ });
175
+ if (!nearestLayer.ok) return nearestLayer;
176
+ const nearestDepth = target(graph, 'single-layer-medium-nearest-depth', {
177
+ format: 'depth24plus-stencil8',
178
+ size: internalSize,
179
+ sampleCount: msaa ? 4 : 1,
180
+ });
181
+ if (!nearestDepth.ok) return nearestDepth;
182
+ return ok({ nearestLayer: nearestLayer.value, nearestDepth: nearestDepth.value });
183
+ })()
184
+ : ok(undefined);
185
+ if (!mediumTargets.ok) return mediumTargets;
186
+
150
187
  const reflectionFallback = topology.reflectionFallback?.enabled
151
188
  ? target(graph, 'reflection-fallback-linear-hdr', {
152
189
  format: 'rgba16float',
@@ -214,10 +251,96 @@ function buildUrp(
214
251
  });
215
252
  if (!gpuDriven.ok) return gpuDriven;
216
253
  const transmissionDemand = transmissionDemandForTopology(topology);
254
+ const backdropDemand = {
255
+ activeCount: transmissionDemand.activeCount + (topology.singleLayerMedium === true ? 1 : 0),
256
+ needsRoughMips: transmissionDemand.needsRoughMips,
257
+ };
217
258
  const transmissionActive = resolveTransmissionBackdropTopology({
218
259
  demand: transmissionDemand,
219
260
  sourceSampleCount: scene.value.sampleCount,
220
261
  }).active;
262
+ const backdropActive = resolveTransmissionBackdropTopology({
263
+ demand: backdropDemand,
264
+ sourceSampleCount: scene.value.sampleCount,
265
+ }).active;
266
+ const featureRasterWork =
267
+ context.hasFeatureRasterWork?.(CLOUD_LAYER_FEATURE_IDENTITY, 'scene') === true;
268
+ const cloudScene =
269
+ featureRasterWork && !msaa
270
+ ? target(graph, 'cloud-layer-scene-color', {
271
+ format: sceneResolved.value.format,
272
+ size: internalSize,
273
+ sampleCount: 1,
274
+ domain: hdr ? 'linear-hdr' : 'linear-ldr',
275
+ usage:
276
+ GPU_TEXTURE_USAGE_COPY_SRC |
277
+ GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |
278
+ GPU_TEXTURE_USAGE_TEXTURE_BINDING,
279
+ })
280
+ : ok(undefined);
281
+ if (!cloudScene.ok) return cloudScene;
282
+ const cloudShadow =
283
+ featureRasterWork && context.cloudShadowResolution !== undefined
284
+ ? target(graph, 'cloud-layer-shadow', {
285
+ format: 'rgba16float',
286
+ size: {
287
+ width: context.cloudShadowResolution,
288
+ height: context.cloudShadowResolution,
289
+ depthOrArrayLayers: 1,
290
+ },
291
+ sampleCount: 1,
292
+ domain: 'linear-hdr',
293
+ usage:
294
+ GPU_TEXTURE_USAGE_COPY_SRC |
295
+ GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |
296
+ GPU_TEXTURE_USAGE_TEXTURE_BINDING,
297
+ })
298
+ : ok(undefined);
299
+ if (!cloudShadow.ok) return cloudShadow;
300
+ const featureTargets = [
301
+ {
302
+ name: 'linear-hdr',
303
+ kind: 'scene-color',
304
+ texture: sceneResolved.value.texture,
305
+ view: sceneResolved.value.view,
306
+ format: sceneResolved.value.format,
307
+ sampleCount: 1,
308
+ },
309
+ {
310
+ kind: 'scene-depth',
311
+ texture: depth.value.texture,
312
+ view: depth.value.view,
313
+ format: depth.value.format,
314
+ sampleCount: depth.value.sampleCount,
315
+ },
316
+ ...(cloudShadow.value === undefined
317
+ ? []
318
+ : [
319
+ {
320
+ name: 'cloud-shadow',
321
+ kind: 'scene-color' as const,
322
+ texture: cloudShadow.value.texture,
323
+ view: cloudShadow.value.view,
324
+ format: cloudShadow.value.format,
325
+ sampleCount: 1 as const,
326
+ },
327
+ ]),
328
+ ...(context.cloudHistory === undefined
329
+ ? []
330
+ : renderPipelineCloudHistoryTargets(context.cloudHistory)),
331
+ ] as const;
332
+ // Produce the density cache and spatial receiver shadow before opaque
333
+ // shading. The cloud composite is a later scene pass, so it cannot be
334
+ // projected in this call without being overwritten by `main`.
335
+ const shadowFeatures = context.contributeFeatures(
336
+ featureTargets,
337
+ [],
338
+ cloudShadow.value === undefined ? {} : { 'cloud-shadow': cloudShadow.value },
339
+ [],
340
+ 'scene',
341
+ ['cloud-layer-density-cache', 'cloud-layer-shadow'],
342
+ );
343
+ if (!shadowFeatures.ok) return shadowFeatures;
221
344
  const main = addTypedScenePass(graph, {
222
345
  environment: atmosphere.value,
223
346
  name: 'main',
@@ -231,20 +354,68 @@ function buildUrp(
231
354
  ...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
232
355
  shadows.value.spot,
233
356
  ...(shadows.value.point === undefined ? [] : [shadows.value.point]),
357
+ ...(cloudShadow.value === undefined ? [] : [cloudShadow.value]),
234
358
  ],
235
359
  ...(shadows.value.directional === undefined
236
360
  ? {}
237
361
  : { directionalShadow: shadows.value.directional }),
238
362
  spotShadow: shadows.value.spot,
363
+ cloudShadow: cloudShadow.value,
239
364
  selector: { LightMode: ['Forward'] },
240
365
  colorLoadOp: 'load',
241
366
  extraAccesses: clusterReads,
242
- ...(transmissionActive ? { recordMode: 'opaque' as const } : {}),
367
+ // Opaque, transmission and ordinary transparency are separate queue
368
+ // segments. Keeping the opaque filter unconditional prevents an
369
+ // ordinary transparent material from being drawn before the cloud pass.
370
+ recordMode: 'opaque' as const,
371
+ ...(backdropActive && gpuDriven.value !== undefined
372
+ ? { gpuDrivenFilter: 'opaque' as const }
373
+ : {}),
243
374
  ...(gpuDriven.value === undefined ? {} : { gpuDriven: gpuDriven.value }),
244
375
  ...(context.occlusion === undefined ? {} : { occlusion: context.occlusion }),
245
376
  });
246
377
  if (!main.ok) return main;
247
378
 
379
+ const opaqueMediumPair =
380
+ topology.singleLayerMedium === true && msaa
381
+ ? addSingleLayerMediumMsaaPairProducer({
382
+ graph,
383
+ label: 'single-layer-medium-opaque-resolve',
384
+ sourceColor: scene.value,
385
+ sourceDepth: depth.value,
386
+ size: internalSize,
387
+ })
388
+ : ok(undefined);
389
+ if (!opaqueMediumPair.ok) return opaqueMediumPair;
390
+ if (cloudScene.value !== undefined) {
391
+ const compositeFeatures = context.contributeFeatures(
392
+ featureTargets,
393
+ [],
394
+ {
395
+ 'motion-input': sceneResolved.value,
396
+ 'motion-output': cloudScene.value,
397
+ ...(cloudShadow.value === undefined ? {} : { 'cloud-shadow': cloudShadow.value }),
398
+ ...(context.cloudHistory === undefined
399
+ ? {}
400
+ : {
401
+ 'cloud-history-radiance-current': context.cloudHistory.currentRadiance,
402
+ 'cloud-history-radiance-previous': context.cloudHistory.previousRadiance,
403
+ 'cloud-history-transmittance-current': context.cloudHistory.currentTransmittance,
404
+ 'cloud-history-transmittance-previous': context.cloudHistory.previousTransmittance,
405
+ 'cloud-history-depth-current': context.cloudHistory.currentDepth,
406
+ 'cloud-history-depth-previous': context.cloudHistory.previousDepth,
407
+ }),
408
+ },
409
+ [],
410
+ 'scene',
411
+ // One half-resolution transport MRT produces radiance, transmittance and
412
+ // representative depth; the full-resolution resolve consumes that same
413
+ // frame and advances the ping-pong history on submit.
414
+ ['cloud-layer-transport', 'cloud-layer-resolve'],
415
+ );
416
+ if (!compositeFeatures.ok) return compositeFeatures;
417
+ }
418
+
248
419
  const temporalLane = topology.lane.compute ? 'clustered' : 'cpu-webgl2';
249
420
  const temporalAdmission = standardTemporalLaneAdmission({
250
421
  lane: temporalLane,
@@ -284,62 +455,135 @@ function buildUrp(
284
455
  if (!coverage.ok) return coverage;
285
456
  }
286
457
 
458
+ let sceneForLater: RenderPipelineTarget = scene.value;
459
+ let sceneResolvedForLater: RenderPipelineTarget = sceneResolved.value;
460
+ if (cloudScene.value !== undefined) {
461
+ sceneForLater = cloudScene.value;
462
+ sceneResolvedForLater = cloudScene.value;
463
+ }
464
+
287
465
  const transmission = addTransmissionBackdropPasses({
288
466
  graph,
289
- source: sceneResolved.value,
290
- demand: transmissionDemand,
291
- copySize: { width: topology.surface.width, height: topology.surface.height },
467
+ source: sceneResolvedForLater,
468
+ demand: backdropDemand,
469
+ copySize: internalCopySize,
292
470
  encodeRoughMip: context.encodeTransmissionMip,
293
471
  includeConsumerPasses: false,
294
472
  });
295
473
  if (!transmission.ok) return transmission;
296
- if (transmission.value.topology.active) {
297
- const transmissionPass = addTypedScenePass(graph, {
298
- environment: atmosphere.value,
299
- name: 'transmission-forward',
300
- color: scene.value,
301
- depth: depth.value,
302
- ...(msaa ? { resolve: sceneResolved.value } : {}),
303
- sampled: [
304
- ...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
305
- shadows.value.spot,
306
- ...(shadows.value.point === undefined ? [] : [shadows.value.point]),
307
- ],
308
- directionalShadow: shadows.value.directional,
309
- spotShadow: shadows.value.spot,
310
- selector: { LightMode: ['Forward'] },
311
- colorLoadOp: 'load',
312
- depthLoadOp: 'load',
313
- recordMode: 'transmission',
314
- extraAccesses: clusterReads,
315
- // Inject the complete backdrop view so the Standard shader can select
316
- // the producer's optional roughness mip level. mipViews[0] is only the
317
- // copy destination view and intentionally exposes one level.
318
- transmissionBackdrop: transmission.value.backdrop?.view,
319
- });
320
- if (!transmissionPass.ok) return transmissionPass;
321
-
322
- const transparentPass = addTypedScenePass(graph, {
323
- environment: atmosphere.value,
324
- name: 'transparent',
325
- color: scene.value,
474
+ if (topology.singleLayerMedium === true) {
475
+ const nearestTargets = mediumTargets.value;
476
+ const backdrop = transmission.value.backdrop?.view;
477
+ if (nearestTargets === undefined || backdrop === undefined) {
478
+ return err(
479
+ new RenderGraphError({
480
+ code: 'resource-descriptor-invalid',
481
+ expected: 'single-layer medium graph has nearest targets and an opaque backdrop',
482
+ hint: 'keep the shared transmission backdrop copy ahead of the Surface passes',
483
+ detail: {
484
+ resourceLabel: 'single-layer-medium',
485
+ field: 'backdrop',
486
+ expected: 'resolved graph texture view',
487
+ actual: 'missing',
488
+ },
489
+ }),
490
+ );
491
+ }
492
+ let rawDepthTarget: RenderPipelineTarget | undefined = opaqueMediumPair.value?.depth;
493
+ if (rawDepthTarget === undefined) {
494
+ const rawDepth = addSingleLayerMediumRawDepthProducer({
495
+ graph,
496
+ sourceColor: sceneResolvedForLater,
497
+ sourceDepth: depth.value,
498
+ size: internalSize,
499
+ });
500
+ if (!rawDepth.ok) return rawDepth;
501
+ rawDepthTarget = rawDepth.value;
502
+ }
503
+ const surfacePair: RenderPipelineSurfaceMediumPair = {
504
+ opaqueColor: opaqueMediumPair.value?.color.view ?? backdrop,
505
+ rawDepth:
506
+ rawDepthTarget === undefined
507
+ ? { status: 'unavailable', reason: 'depth-copy-unavailable' }
508
+ : { status: 'available', view: rawDepthTarget.view },
509
+ };
510
+ const mediumPasses = addSingleLayerMediumPasses({
511
+ graph,
512
+ size: internalSize,
513
+ ...nearestTargets,
514
+ color: sceneForLater,
515
+ ...(msaa ? { colorResolve: sceneResolvedForLater } : {}),
326
516
  depth: depth.value,
327
- ...(msaa ? { resolve: sceneResolved.value } : {}),
328
517
  sampled: [
329
518
  ...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
330
519
  shadows.value.spot,
331
520
  ...(shadows.value.point === undefined ? [] : [shadows.value.point]),
521
+ ...(cloudShadow.value === undefined ? [] : [cloudShadow.value]),
332
522
  ],
333
523
  directionalShadow: shadows.value.directional,
334
524
  spotShadow: shadows.value.spot,
335
- selector: { LightMode: ['Forward'] },
336
- colorLoadOp: 'load',
337
- depthLoadOp: 'load',
338
- recordMode: 'transparent',
525
+ cloudShadow: cloudShadow.value,
339
526
  extraAccesses: clusterReads,
527
+ surfacePair,
528
+ ...(gpuDriven.value === undefined ? {} : { gpuDriven: gpuDriven.value }),
340
529
  });
341
- if (!transparentPass.ok) return transparentPass;
342
- const temporal = addTransmissionBackdropTemporalPass(graph, sceneResolved.value);
530
+ if (!mediumPasses.ok) return mediumPasses;
531
+ }
532
+ if (backdropActive) {
533
+ if (transmissionActive) {
534
+ const transmissionPass = addTypedScenePass(graph, {
535
+ environment: atmosphere.value,
536
+ name: 'transmission-forward',
537
+ color: sceneForLater,
538
+ depth: depth.value,
539
+ ...(msaa ? { resolve: sceneResolvedForLater } : {}),
540
+ sampled: [
541
+ ...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
542
+ shadows.value.spot,
543
+ ...(shadows.value.point === undefined ? [] : [shadows.value.point]),
544
+ ...(cloudShadow.value === undefined ? [] : [cloudShadow.value]),
545
+ ],
546
+ directionalShadow: shadows.value.directional,
547
+ spotShadow: shadows.value.spot,
548
+ cloudShadow: cloudShadow.value,
549
+ selector: { LightMode: ['Forward'] },
550
+ colorLoadOp: 'load',
551
+ depthLoadOp: 'load',
552
+ recordMode: 'transmission',
553
+ extraAccesses: clusterReads,
554
+ // Inject the complete backdrop view so the Standard shader can select
555
+ // the producer's optional roughness mip level. mipViews[0] is only the
556
+ // copy destination view and intentionally exposes one level.
557
+ transmissionBackdrop: transmission.value.backdrop?.view,
558
+ });
559
+ if (!transmissionPass.ok) return transmissionPass;
560
+ }
561
+ }
562
+ const transparentPass = addTypedScenePass(graph, {
563
+ environment: atmosphere.value,
564
+ name: 'transparent',
565
+ color: sceneForLater,
566
+ depth: depth.value,
567
+ ...(msaa ? { resolve: sceneResolvedForLater } : {}),
568
+ sampled: [
569
+ ...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
570
+ shadows.value.spot,
571
+ ...(shadows.value.point === undefined ? [] : [shadows.value.point]),
572
+ ...(cloudShadow.value === undefined ? [] : [cloudShadow.value]),
573
+ ],
574
+ directionalShadow: shadows.value.directional,
575
+ spotShadow: shadows.value.spot,
576
+ cloudShadow: cloudShadow.value,
577
+ selector: { LightMode: ['Forward'] },
578
+ colorLoadOp: 'load',
579
+ depthLoadOp: 'load',
580
+ recordMode: 'transparent',
581
+ transparentDepthWrite: true,
582
+ extraAccesses: clusterReads,
583
+ });
584
+ if (!transparentPass.ok) return transparentPass;
585
+ if (backdropActive) {
586
+ const temporal = addTransmissionBackdropTemporalPass(graph, sceneResolvedForLater);
343
587
  if (!temporal.ok) return temporal;
344
588
  }
345
589
 
@@ -353,25 +597,31 @@ function buildUrp(
353
597
  const volume = addAuthoredVolumetricFogPasses(
354
598
  graph,
355
599
  topology,
356
- sceneResolved.value,
600
+ sceneResolvedForLater,
357
601
  depthSample.value,
358
602
  shadows.value.directional?.view,
359
603
  shadows.value.spot.view,
360
604
  clusterBuffers.value,
605
+ cloudShadow.value?.view,
361
606
  );
362
607
  if (!volume.ok) return volume;
363
608
  }
364
609
 
610
+ // Project the remaining generic post features after every scene producer has
611
+ // finished. The forward lane may have replaced the scene target with the
612
+ // cloud-resolved target; keep the MSAA resolve target paired with that final
613
+ // color target so feature attachments observe the same surface that the
614
+ // Standard observation reads.
365
615
  const features = context.contributeFeatures(
366
616
  [
367
617
  {
368
618
  name: 'linear-hdr',
369
619
  kind: 'scene-color',
370
- texture: scene.value.texture,
371
- view: scene.value.view,
372
- ...(msaa ? { resolveTarget: sceneResolved.value.view } : {}),
373
- format: scene.value.format,
374
- sampleCount: scene.value.sampleCount,
620
+ texture: sceneForLater.texture,
621
+ view: sceneForLater.view,
622
+ ...(msaa ? { resolveTarget: sceneResolvedForLater.view } : {}),
623
+ format: sceneForLater.format,
624
+ sampleCount: sceneForLater.sampleCount,
375
625
  },
376
626
  {
377
627
  kind: 'scene-depth',
@@ -385,17 +635,23 @@ function buildUrp(
385
635
  {},
386
636
  [
387
637
  ...clusterReads,
388
- ...[shadows.value.directional, shadows.value.spot, shadows.value.point].flatMap((target) =>
638
+ ...[
639
+ shadows.value.directional,
640
+ shadows.value.spot,
641
+ shadows.value.point,
642
+ cloudShadow.value,
643
+ ].flatMap((target) =>
389
644
  target === undefined ? [] : [{ resource: target.view, usage: 'sampled-read' as const }],
390
645
  ),
391
646
  ],
647
+ { exclude: [BARREL_DISTORTION_FEATURE_IDENTITY] },
392
648
  );
393
649
  if (!features.ok) return features;
394
650
 
395
651
  if (hdr || linearLdr || rawOnly) {
396
652
  const observation = addTypedFrameObservationPass(
397
653
  graph,
398
- sceneResolved.value,
654
+ sceneResolvedForLater,
399
655
  'forgeax::standard',
400
656
  );
401
657
  if (!observation.ok) return observation;
@@ -411,7 +667,7 @@ function buildUrp(
411
667
  const post = addStandardPost(
412
668
  context,
413
669
  topology,
414
- sceneResolved.value,
670
+ sceneResolvedForLater,
415
671
  depth.value,
416
672
  surface.value,
417
673
  temporal.value?.temporal,
@@ -31,6 +31,7 @@ function requestedStages(input: StandardOutputRequest): StandardOutputLogicalSta
31
31
  if (input.exposure || input.whiteBalance) stages.push('exposure-white-balance');
32
32
  stages.push('tone');
33
33
  if (input.lut) stages.push('lut');
34
+ if (input.barrelDistortion === true) stages.push('barrel-distortion');
34
35
  if (input.fxaa) stages.push('fxaa');
35
36
  stages.push('output-encoding');
36
37
  return stages;
@@ -50,6 +51,7 @@ function physicalStages(
50
51
  case 'tone':
51
52
  return { name, input: LINEAR_HDR_DOMAIN, output: LINEAR_LDR_DOMAIN };
52
53
  case 'lut':
54
+ case 'barrel-distortion':
53
55
  case 'fxaa':
54
56
  return { name, input: LINEAR_LDR_DOMAIN, output: LINEAR_LDR_DOMAIN };
55
57
  case 'output-encoding':
@@ -62,8 +64,11 @@ function physicalStages(
62
64
 
63
65
  export function createStandardOutputPlan(input: StandardOutputRequest): StandardOutputPlan {
64
66
  const logicalStages = requestedStages(input);
65
- const incrementalResources = input.lut ? ['standard-color-lut'] : [];
66
- const incrementalBindings = input.lut ? 2 : 0;
67
+ const incrementalResources = [
68
+ ...(input.lut ? ['standard-color-lut'] : []),
69
+ ...(input.barrelDistortion === true ? ['standard-barrel-distortion'] : []),
70
+ ];
71
+ const incrementalBindings = (input.lut ? 2 : 0) + (input.barrelDistortion === true ? 3 : 0);
67
72
  return {
68
73
  lane: input.lane,
69
74
  features: {
@@ -74,6 +79,7 @@ export function createStandardOutputPlan(input: StandardOutputRequest): Standard
74
79
  exposure: input.exposure,
75
80
  whiteBalance: input.whiteBalance,
76
81
  lut: input.lut,
82
+ barrelDistortion: input.barrelDistortion === true,
77
83
  fxaa: input.fxaa,
78
84
  },
79
85
  outputEncoding: input.outputEncoding,
@@ -8,6 +8,7 @@ export const STANDARD_OUTPUT_LOGICAL_STAGES = [
8
8
  'exposure-white-balance',
9
9
  'tone',
10
10
  'lut',
11
+ 'barrel-distortion',
11
12
  'fxaa',
12
13
  'output-encoding',
13
14
  ] as const;
@@ -32,6 +33,8 @@ export interface StandardOutputRequest {
32
33
  readonly exposure: boolean;
33
34
  readonly whiteBalance: boolean;
34
35
  readonly lut: boolean;
36
+ /** Output-space barrel warp; runs after LUT in linear-LDR. */
37
+ readonly barrelDistortion?: boolean;
35
38
  readonly fxaa: boolean;
36
39
  readonly outputEncoding: StandardOutputEncoding;
37
40
  }
@@ -47,7 +50,15 @@ export interface StandardOutputPlan {
47
50
  readonly features: Readonly<
48
51
  Pick<
49
52
  StandardOutputRequest,
50
- 'temporal' | 'meter' | 'bloom' | 'dof' | 'exposure' | 'whiteBalance' | 'lut' | 'fxaa'
53
+ | 'temporal'
54
+ | 'meter'
55
+ | 'bloom'
56
+ | 'dof'
57
+ | 'exposure'
58
+ | 'whiteBalance'
59
+ | 'lut'
60
+ | 'barrelDistortion'
61
+ | 'fxaa'
51
62
  >
52
63
  >;
53
64
  readonly outputEncoding: StandardOutputEncoding;