@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
@@ -9,9 +9,11 @@ import {
9
9
  type Result,
10
10
  RhiError,
11
11
  } from '@forgeax/engine-rhi';
12
+ import type { MaterialShaderArtifact } from '@forgeax/engine-shader';
12
13
  import type { Handle, MeshAsset, SamplerAsset, TextureAsset } from '@forgeax/engine-types';
13
14
  import { toShared } from '@forgeax/engine-types';
14
15
  import { standardBloomAdmitted } from '../bloom-admission';
16
+ import { cloudShadowResolutionForQuality } from '../cloud/parameters';
15
17
  import { createClusterBinScratch } from '../cluster-binner';
16
18
  import type { EnvironmentLifecycle } from '../environment/lifecycle';
17
19
  import {
@@ -29,8 +31,12 @@ import {
29
31
  type PostProcessShaderEntry,
30
32
  postProcessShaderEntrySignature,
31
33
  } from '../fullscreen-post-process-pass';
32
- import { collectGpuDrivenMaterialArtifacts } from '../gpu-driven/material-artifacts';
34
+ import {
35
+ collectGpuDrivenMaterialArtifacts,
36
+ requiresProbeBlendRecord,
37
+ } from '../gpu-driven/material-artifacts';
33
38
  import { GpuDrivenProduction } from '../gpu-driven/production-raster';
39
+ import { disposeInstanceBufferChunks, disposeInstanceBuffers } from '../instance-buffer-cache';
34
40
  import { inspectStandardLighting } from '../pipeline/standard-lighting/inspection';
35
41
  import { retireAutoExposureGpuResources } from '../pipeline/standard-output/auto-exposure/gpu';
36
42
  import {
@@ -38,12 +44,15 @@ import {
38
44
  resetStandardOutputForDeviceLoss,
39
45
  } from '../pipeline/standard-output/resources';
40
46
  import type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';
47
+ import { standardTopologyVariantSet } from '../pipeline-spec';
41
48
  import { inspectPointShadow } from '../point-shadow-inspection';
42
49
  import type { PreparedGraphicsResolver } from '../prepare/prepared-graphics-resolver';
43
50
  import { gpuDrivenMeshesForFrame, validateRenderables } from '../record/frame';
44
51
  import { prepareFrameLighting } from '../record/frame-lighting';
45
52
  import type { RenderFrameState, ValidatedRenderable } from '../record/frame-snapshot';
53
+ import { resolveGeometryInstanceBuffer } from '../record/main-pass-geometry';
46
54
  import { computeSplitLdrSprite } from '../record/main-pass-sprite-draws';
55
+ import { ensureProbeBlendRecordBuffer } from '../record/probe-blend-buffer';
47
56
  import {
48
57
  prepareRecoveryPipelineReadiness,
49
58
  type RecoveryPipelineReadiness,
@@ -53,6 +62,8 @@ import {
53
62
  ensureCompiledFrameGraph,
54
63
  getRenderFeatureGraphState,
55
64
  type RenderFeatureGraphCandidate,
65
+ retire as retireCompiledGraph,
66
+ shareRenderGraphGenerationAllocationOwner,
56
67
  } from '../record/typed-frame-graph';
57
68
  import { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID } from '../render-contract';
58
69
  import type {
@@ -62,6 +73,7 @@ import type {
62
73
  } from '../render-system-extract';
63
74
  import type { PersistentGpuDrivenCandidate, PersistentRenderScene } from '../scene/render-scene';
64
75
  import { SHADOW_ATLAS_DEFAULT_LAYERS } from '../shadow-atlas';
76
+ import { ReadonlyDynamicInputPage, type SurfaceDynamicInputFrame } from '../surface/dynamic-input';
65
77
  import { createTemporalFrameTransaction } from '../temporal/frame';
66
78
  import {
67
79
  getTemporalBindGroupResources,
@@ -93,6 +105,14 @@ export interface RecoveryFrameSeed {
93
105
  readonly resourceOwner: number;
94
106
  readonly width: number;
95
107
  readonly height: number;
108
+ /** Last submitted Surface page is reused while the replacement device warms. */
109
+ readonly surfaceDynamicInput?: SurfaceDynamicInputFrame;
110
+ /** Last submitted World/App time snapshot for the Surface frame ABI. */
111
+ readonly frameTime?: number;
112
+ /** Exact forward artifacts accepted by the submitted frame. */
113
+ readonly materialArtifacts?: ReadonlyMap<string, MaterialShaderArtifact>;
114
+ /** Exact ShadowCaster artifacts accepted by the submitted frame. */
115
+ readonly shadowMaterialArtifacts?: ReadonlyMap<string, MaterialShaderArtifact>;
96
116
  }
97
117
 
98
118
  export interface RenderSystemRecoveryDependencies {
@@ -213,9 +233,14 @@ export function createRenderSystemRecovery(
213
233
  let lastSuccessfulFrameSeed: RecoveryFrameSeed | undefined;
214
234
 
215
235
  const createRecoveryCandidateFrameState = (): RenderFrameState => {
216
- const { probeBlendRecordBuffer: discardedProbeBlendRecordBuffer, ...baseFrameState } =
217
- frameState;
236
+ const {
237
+ probeBlendRecordBuffer: discardedProbeBlendRecordBuffer,
238
+ instanceCollections: discardedInstanceInspection,
239
+ ...baseFrameState
240
+ } = frameState;
218
241
  void discardedProbeBlendRecordBuffer;
242
+ // Candidate uploads must not publish residency into the active inspection.
243
+ void discardedInstanceInspection;
219
244
  return {
220
245
  ...baseFrameState,
221
246
  successfulTemporalFrameIndex: 0,
@@ -256,15 +281,18 @@ export function createRenderSystemRecovery(
256
281
  retiredCompiledFrameGraphs: new Set(),
257
282
  currentFrameObservationSource: undefined,
258
283
  lastSuccessfulCameraAntialias: undefined,
284
+ lastSuccessfulBarrelDistortion: undefined,
259
285
  temporalGpuState: undefined,
260
286
  activeTemporalGpuState: undefined,
261
287
  retiringTemporalGpuStates: new Set(),
288
+ cloudHistoryActive: false,
262
289
  lastSuccessfulTemporalView: undefined,
263
290
  pendingTemporalCommit: { kind: 'none' },
264
291
  environmentGeneration: undefined,
265
292
  currentDirectionalShadowView: null,
266
293
  currentSpotShadowView: null,
267
294
  instanceBuffers: new Map(),
295
+ instanceBufferChunks: new Map(),
268
296
  morphBuffers: new Map(),
269
297
  hdrpClusterBinScratch: createClusterBinScratch(),
270
298
  hdrpClusterGridScratch: null,
@@ -299,6 +327,18 @@ export function createRenderSystemRecovery(
299
327
  candidate.recoveryReadiness.assertPreparedCache();
300
328
  }
301
329
  const previousFeatureHost = internals.featureHost;
330
+ // The candidate graph proves topology and pipeline readiness before the
331
+ // publication boundary, but its imported display view was acquired before
332
+ // the shared canvas context was reconfigured for the replacement device.
333
+ // Retire that frame-bound graph and preserve the prepared owners/caches;
334
+ // the first recovered frame recompiles the same topology against the
335
+ // newly configured context instead of submitting a view from the lost
336
+ // device generation.
337
+ const candidateDisplayGraph = candidate.frameState.compiledFrameGraph;
338
+ candidate.frameState.compiledFrameGraph = null;
339
+ candidate.frameState.compiledFrameGraphTopologyKey = null;
340
+ candidate.frameState.perFrameGraph = null;
341
+ candidateDisplayGraph?.retire().catch(() => undefined);
302
342
  // The caller enters this method only after the active generation swap and
303
343
  // after resetForRecover() has shed every lost-device owner. Replace the
304
344
  // whole device-bound frame projection so no stale cache/map/temporal view
@@ -370,6 +410,9 @@ export function createRenderSystemRecovery(
370
410
  if (camera === undefined) return { kind: 'no-seed' };
371
411
 
372
412
  const candidateFrameState = createRecoveryCandidateFrameState();
413
+ // Candidate graph generations are one renderer-owned allocation stream;
414
+ // publication changes their role, not their accounting owner.
415
+ shareRenderGraphGenerationAllocationOwner(frameState, candidateFrameState);
373
416
  resetStandardOutputForDeviceLoss(candidateFrameState, runtime.internals.deviceScope.generation);
374
417
  Object.assign(candidateFrameState, {
375
418
  temporalFrame: undefined,
@@ -382,6 +425,7 @@ export function createRenderSystemRecovery(
382
425
  let candidateFeatureHost: RenderFeatureHost | undefined;
383
426
  let candidateFeatureGpuWork: RenderFeatureGpuWorkOwner | undefined;
384
427
  let candidatePointsLines: RecoveryPointsLinesCandidate | undefined;
428
+ let candidateSurfacePage: ReadonlyDynamicInputPage | undefined;
385
429
  let candidateFeatureGraph: RenderFeatureGraphCandidate = {
386
430
  plans: Object.freeze([]),
387
431
  fullscreenEffects: new Map(),
@@ -406,7 +450,7 @@ export function createRenderSystemRecovery(
406
450
  candidateFrameState.compiledFrameGraph = null;
407
451
  candidateFrameState.perFrameGraph = null;
408
452
  try {
409
- graph?.retire().catch(() => undefined);
453
+ if (graph !== null) retireCompiledGraph(candidateFrameState, graph);
410
454
  } catch {
411
455
  // Candidate cleanup continues through every independent owner.
412
456
  }
@@ -430,10 +474,21 @@ export function createRenderSystemRecovery(
430
474
  candidateGpuDrivenScene = undefined;
431
475
  candidatePointsLines?.release();
432
476
  candidatePointsLines = undefined;
477
+ candidateSurfacePage?.release();
478
+ candidateSurfacePage = undefined;
479
+ disposeInstanceBuffers(candidateFrameState.instanceBuffers, runtime.internals.errorRegistry);
480
+ if (candidateFrameState.instanceBufferChunks !== undefined) {
481
+ disposeInstanceBufferChunks(
482
+ candidateFrameState.instanceBufferChunks,
483
+ runtime.internals.errorRegistry,
484
+ );
485
+ }
433
486
  candidateGpuStore.destroyAll();
434
487
  };
435
488
  const markPublished = (): void => {
436
489
  candidatePointsLines?.publish();
490
+ candidateSurfacePage?.release();
491
+ candidateSurfacePage = undefined;
437
492
  candidatePublished = true;
438
493
  };
439
494
  const failed = (
@@ -457,11 +512,101 @@ export function createRenderSystemRecovery(
457
512
  );
458
513
  if (!gpuScene.ok) return failed('candidate GPU scene preparation failed', gpuScene.error);
459
514
  candidateGpuDrivenScene = gpuScene.value;
515
+ candidateValidated = validateRenderables(
516
+ runtime.internals,
517
+ seed.worlds[seed.cameraOwner] as World,
518
+ seed.worlds,
519
+ runtime.pipelineState,
520
+ candidateFrameState,
521
+ seed.frame.renderables,
522
+ seed.frame.dispatch,
523
+ );
524
+ if (candidateValidated.length !== seed.frame.renderables.length) {
525
+ return failed('candidate validation did not retain every LKG-visible renderable');
526
+ }
527
+ const lighting = prepareFrameLighting(
528
+ runtime.internals,
529
+ candidateFrameState,
530
+ seed.frame.lights,
531
+ camera,
532
+ runtime.pipelineState,
533
+ );
534
+ if (!lighting.ok) return failed('candidate lighting preparation failed');
535
+ let recoverySurfaceDynamicInput = seed.surfaceDynamicInput;
536
+ if (
537
+ recoverySurfaceDynamicInput !== undefined &&
538
+ recoverySurfaceDynamicInput.page.deviceGeneration !==
539
+ runtime.internals.deviceScope.generation
540
+ ) {
541
+ const source = recoverySurfaceDynamicInput;
542
+ const created = ReadonlyDynamicInputPage.create({
543
+ sourceId: source.page.sourceId,
544
+ pageId: source.page.pageId,
545
+ schema: source.page.schema,
546
+ });
547
+ if (!created.ok) {
548
+ return failed('candidate Surface recovery page creation failed', created.error);
549
+ }
550
+ candidateSurfacePage = created.value;
551
+ // Preserve CPU-authored parameters before preparing the replacement GPU page.
552
+ candidateSurfacePage.bytes.set(source.page.bytes);
553
+ const reconfigured = candidateSurfacePage.reconfigureDevice(
554
+ runtime.internals.deviceScope.generation,
555
+ );
556
+ if (!reconfigured.ok) {
557
+ return failed('candidate Surface recovery page generation failed', reconfigured.error);
558
+ }
559
+ const ranges = (source.ranges ?? []).map((range) => {
560
+ const reserved = candidateSurfacePage?.reserveRange({
561
+ domain: range.domain,
562
+ recordStart: range.recordStart,
563
+ recordCount: range.recordCount,
564
+ instanceIndex: range.instanceIndex,
565
+ member: range.member,
566
+ });
567
+ if (reserved === undefined || !reserved.ok) {
568
+ throw reserved?.error ?? new Error('candidate Surface recovery range unavailable');
569
+ }
570
+ return reserved.value;
571
+ });
572
+ recoverySurfaceDynamicInput = {
573
+ page: candidateSurfacePage,
574
+ ranges,
575
+ projectionRevision: source.projectionRevision + 1,
576
+ frameTime: source.frameTime,
577
+ };
578
+ }
460
579
  if (candidateGpuDrivenScene.state !== undefined) {
461
580
  candidateGpuDrivenProduction = GpuDrivenProduction.forDevice(
462
581
  runtime.internals.device,
463
582
  gpuDrivenShaderFactory,
464
583
  );
584
+ const clustered = lighting.value.standard?.kind === 'clustered';
585
+ const standardVariantSet = standardTopologyVariantSet(
586
+ lighting.value.standard,
587
+ runtime.internals.device.caps.storageBuffer,
588
+ false,
589
+ );
590
+ const standardPbrArtifact = runtime.internals.getMaterialShaderArtifact?.(
591
+ 'forgeax::default-standard-pbr',
592
+ {
593
+ vertexColorAvailable: false,
594
+ deformation: 'rigid',
595
+ pass: 'forward',
596
+ address: 'scene-index',
597
+ variantSet: standardVariantSet,
598
+ },
599
+ );
600
+ const standardPbrSkinArtifact = runtime.internals.getMaterialShaderArtifact?.(
601
+ 'forgeax::pbr-skin',
602
+ {
603
+ vertexColorAvailable: false,
604
+ deformation: 'skin',
605
+ pass: 'forward',
606
+ address: 'scene-index',
607
+ variantSet: standardVariantSet,
608
+ },
609
+ );
465
610
  const shadowProjection = persistentRenderScene.shadowCasterProjection();
466
611
  // The retained scene owns prepared draw receipts. The extraction seed
467
612
  // precedes GPU admission and must not stand in for that projection.
@@ -482,20 +627,45 @@ export function createRenderSystemRecovery(
482
627
  },
483
628
  renderableIndex,
484
629
  }));
485
- const { materialArtifacts, shadowMaterialArtifacts, firstArtifact, firstSkinArtifact } =
486
- collectGpuDrivenMaterialArtifacts({
487
- rows: artifactRows(seed.frame.renderables),
488
- shadowRows: artifactRows(shadowProjection?.renderables ?? []),
489
- dispatch: seed.frame.dispatch,
490
- shadowDispatch: shadowProjection?.dispatch ?? seed.frame.dispatch,
491
- resolve: runtime.internals.getMaterialShaderArtifact,
492
- clustered:
493
- seed.frame.lights.point.length +
494
- seed.frame.lights.spot.length +
495
- seed.frame.lights.rect.length >
496
- 0 || candidateFrameState.installedPipelineConfig?.ssao?.enabled === true,
497
- reflectionFallback: candidateFrameState.reflectionFallbackDemand === true,
498
- });
630
+ const collectedArtifacts = collectGpuDrivenMaterialArtifacts({
631
+ rows: artifactRows(seed.frame.renderables),
632
+ shadowRows: artifactRows(shadowProjection?.renderables ?? []),
633
+ dispatch: seed.frame.dispatch,
634
+ shadowDispatch: shadowProjection?.dispatch ?? seed.frame.dispatch,
635
+ resolve: runtime.internals.getMaterialShaderArtifact,
636
+ clustered:
637
+ seed.frame.lights.point.length +
638
+ seed.frame.lights.spot.length +
639
+ seed.frame.lights.rect.length >
640
+ 0 || candidateFrameState.installedPipelineConfig?.ssao?.enabled === true,
641
+ reflectionFallback: candidateFrameState.reflectionFallbackDemand === true,
642
+ });
643
+ const materialArtifacts =
644
+ collectedArtifacts.materialArtifacts.size > 0
645
+ ? collectedArtifacts.materialArtifacts
646
+ : (seed.materialArtifacts ?? new Map());
647
+ const shadowMaterialArtifacts =
648
+ collectedArtifacts.shadowMaterialArtifacts.size > 0
649
+ ? collectedArtifacts.shadowMaterialArtifacts
650
+ : (seed.shadowMaterialArtifacts ?? new Map());
651
+ const firstMaterialArtifact = materialArtifacts.values().next().value as
652
+ | MaterialShaderArtifact
653
+ | undefined;
654
+ const firstSkinArtifact = [...materialArtifacts.values()].find(
655
+ (artifact) => artifact.receipt?.skinPaletteAddress !== undefined,
656
+ );
657
+ const firstArtifact = firstMaterialArtifact ?? standardPbrArtifact;
658
+ const materialSkinArtifact = firstSkinArtifact ?? standardPbrSkinArtifact;
659
+ const probeBlendRequested = [...materialArtifacts.values()].some((artifact) =>
660
+ requiresProbeBlendRecord(artifact),
661
+ );
662
+ const probeBlendRecordBuffer = probeBlendRequested
663
+ ? ensureProbeBlendRecordBuffer(
664
+ runtime.internals.device,
665
+ candidateFrameState,
666
+ candidateGpuDrivenScene.state.probeBlend,
667
+ )
668
+ : undefined;
499
669
  const prepared = candidateGpuDrivenProduction.prepare({
500
670
  scene: candidateGpuDrivenScene.state,
501
671
  camera,
@@ -507,11 +677,21 @@ export function createRenderSystemRecovery(
507
677
  ),
508
678
  viewBindGroupLayout: runtime.pipelineState.viewBindGroupLayout,
509
679
  meshResidencyEpoch: runtime.internals.gpuStore.meshResidencyEpoch,
510
-
680
+ hdrp:
681
+ clustered &&
682
+ ((lighting.value.standard?.prepared.local.length ?? 0) > 0 ||
683
+ candidateFrameState.installedPipelineConfig?.ssao?.enabled === true),
684
+ clustered,
511
685
  ...(firstArtifact === undefined ? {} : { materialArtifact: firstArtifact }),
512
- ...(firstSkinArtifact === undefined ? {} : { materialSkinArtifact: firstSkinArtifact }),
686
+ ...(materialSkinArtifact === undefined ? {} : { materialSkinArtifact }),
513
687
  ...(materialArtifacts.size === 0 ? {} : { materialArtifacts }),
514
688
  ...(shadowMaterialArtifacts.size === 0 ? {} : { shadowMaterialArtifacts }),
689
+ ...(probeBlendRecordBuffer === undefined ? {} : { probeBlendRecordBuffer }),
690
+ ...(seed.frameTime === undefined ? {} : { frameTime: seed.frameTime }),
691
+ ...(recoverySurfaceDynamicInput === undefined
692
+ ? {}
693
+ : { surfaceDynamicInput: recoverySurfaceDynamicInput }),
694
+ deviceGeneration: runtime.internals.deviceScope.generation,
515
695
  materialPipelineState: runtime.pipelineState,
516
696
  ...(runtime.internals.getMaterialShaderPipelineEntry === undefined
517
697
  ? {}
@@ -520,6 +700,25 @@ export function createRenderSystemRecovery(
520
700
  if (!prepared.ok) return failed('candidate GPU-driven preparation failed', prepared.error);
521
701
  preparedGpuDriven = prepared.value;
522
702
  }
703
+ // A fully GPU-owned frame recovers through GPU Scene above. Only mixed
704
+ // or direct frames need the legacy instance-buffer closure as well.
705
+ if (!preparedGpuDriven?.ownsAllDrawItems || !preparedGpuDriven.ownsAllShadowCasters) {
706
+ for (const entry of candidateValidated) {
707
+ if (entry.source.instances === undefined) continue;
708
+ const prepared = resolveGeometryInstanceBuffer(
709
+ {
710
+ runtime: runtime.internals,
711
+ pipelineState: runtime.pipelineState,
712
+ frameState: candidateFrameState,
713
+ bindGroupCounts: { createBindGroup: 0, keys: [] },
714
+ },
715
+ entry,
716
+ [],
717
+ false,
718
+ );
719
+ if (prepared === null) return failed('candidate instance preparation failed');
720
+ }
721
+ }
523
722
  candidateFeatureHost = runtime.internals.featureHost;
524
723
  if (candidateFeatureHost !== undefined && candidateFeatureHost.size > 0) {
525
724
  candidateFeatureGpuWork = createFeatureGpuWorkOwner(runtime.internals);
@@ -529,11 +728,13 @@ export function createRenderSystemRecovery(
529
728
  colorAttachmentFormat: runtime.pipelineState.colorAttachmentFormat,
530
729
  storageBuffer: runtime.internals.device.caps.storageBuffer,
531
730
  multisample: runtime.internals.device.caps.backendKind !== 'wgpu-webgl2',
731
+ cloudHistory: seed.frame.cloudLayer !== undefined,
532
732
  });
533
733
  const featureFrame = runRenderFeatureFrame(candidateFeatureHost, {
534
734
  worlds: seed.worlds,
535
735
  owner: seed.resourceOwner,
536
736
  frameNumber: candidateFrameState.frameNumber,
737
+ selectedCamera: camera,
537
738
  frameSize: {
538
739
  width: runtime.internals.canvas.width,
539
740
  height: runtime.internals.canvas.height,
@@ -557,7 +758,7 @@ export function createRenderSystemRecovery(
557
758
  gpuWork: candidateFeatureGpuWork,
558
759
  });
559
760
  if (featureFrame.errors.length > 0) {
560
- return failed('candidate render-feature preparation failed');
761
+ return failed('candidate render-feature preparation failed', featureFrame.errors[0]);
561
762
  }
562
763
  const featurePreparationIncomplete = featureFrame.plans.some((planned) => {
563
764
  const execution = getRenderFeaturePlanExecutionProjection(planned);
@@ -586,6 +787,7 @@ export function createRenderSystemRecovery(
586
787
  candidateFeatureGraph = {
587
788
  plans: featureFrame.plans,
588
789
  fullscreenEffects: featureFrame.fullscreenEffects,
790
+ postProcessIdentities: featureFrame.postProcessIdentities,
589
791
  ...(batches.length === 0
590
792
  ? {}
591
793
  : { preparedResourceKey: `recovery-${runtime.internals.deviceScope.generation}` }),
@@ -678,26 +880,6 @@ export function createRenderSystemRecovery(
678
880
  }
679
881
  }
680
882
  }
681
- candidateValidated = validateRenderables(
682
- runtime.internals,
683
- resourceWorld,
684
- seed.worlds,
685
- runtime.pipelineState,
686
- candidateFrameState,
687
- seed.frame.renderables,
688
- seed.frame.dispatch,
689
- );
690
- if (candidateValidated.length !== seed.frame.renderables.length) {
691
- return failed('candidate validation did not retain every LKG-visible renderable');
692
- }
693
- const lighting = prepareFrameLighting(
694
- runtime.internals,
695
- candidateFrameState,
696
- seed.frame.lights,
697
- camera,
698
- runtime.pipelineState,
699
- );
700
- if (!lighting.ok) return failed('candidate lighting preparation failed');
701
883
  candidatePointsLines = pointsLinesOwner.prepareRecoveryCandidate(
702
884
  candidateValidated,
703
885
  lighting.value.standard?.kind === 'clustered',
@@ -723,7 +905,11 @@ export function createRenderSystemRecovery(
723
905
  });
724
906
  const candidatePostProcessIds = new Set<string>([
725
907
  ...(candidateFrameState.installedPipelineConfig?.postEffects ?? []),
726
- ...candidateFeatureGraph.fullscreenEffects.keys(),
908
+ // Required identities include effects disabled for this frame. Warm only
909
+ // published entries, using their public identity rather than graph aliases.
910
+ ...(candidateFeatureGraph.postProcessIdentities ?? []).filter((id) =>
911
+ candidateFeatureGraph.fullscreenEffects.has(id),
912
+ ),
727
913
  ]);
728
914
  const configuredPostEffects = candidateFrameState.installedPipelineConfig?.postEffects ?? [];
729
915
  const postProcessPipeline = runtime.internals.getPostProcessPipeline;
@@ -855,6 +1041,13 @@ export function createRenderSystemRecovery(
855
1041
  (error) => {
856
1042
  recoveryGraphFailure ??= error;
857
1043
  },
1044
+ undefined,
1045
+ undefined,
1046
+ false,
1047
+ false,
1048
+ seed.frame.cloudLayer === undefined
1049
+ ? undefined
1050
+ : cloudShadowResolutionForQuality(seed.frame.cloudLayer.params.quality),
858
1051
  );
859
1052
  if (graph === null) return failed('candidate frame graph compilation failed');
860
1053
  if (recoveryReadiness === undefined)
@@ -397,9 +397,13 @@ export class ReflectionProbeRecordOwner {
397
397
  this.lastFactCount = facts.length;
398
398
  this.lastScheduledRawFaces = 0;
399
399
  this.lastScheduledFilteredSteps = 0;
400
- const firstSelection = selections.values().next().value as
401
- | ReflectionProbeSelectionResult
402
- | undefined;
400
+ // The fallback MRT has one representative readback, so choose a stable
401
+ // non-neutral probe consumer when the scene contains one. Renderable map
402
+ // order is not a source-selection contract: the first entry is commonly
403
+ // an outside panel while the local probe consumer appears later.
404
+ const firstSelection =
405
+ [...selections.values()].find((selection) => selection.kind === 'probe') ??
406
+ (selections.values().next().value as ReflectionProbeSelectionResult | undefined);
403
407
  this.lastSelection =
404
408
  firstSelection?.kind === 'probe'
405
409
  ? {
@@ -3,7 +3,12 @@ import type { World } from '@forgeax/engine-ecs';
3
3
  import type { RenderReadLease } from '@forgeax/engine-ecs/projection';
4
4
  import type { Vec3 } from '@forgeax/engine-math';
5
5
  import type { ProfileFrameToken, Profiler } from '@forgeax/engine-profiler';
6
- import type { ColorValueDomain, RenderGraphError } from '@forgeax/engine-render-graph';
6
+ import type {
7
+ ColorValueDomain,
8
+ RenderGraphError,
9
+ RenderGraphGenerationAllocationInspection,
10
+ RenderGraphResourceAllocationInspection,
11
+ } from '@forgeax/engine-render-graph';
7
12
  import type {
8
13
  BindGroupLayout,
9
14
  Buffer,
@@ -24,6 +29,8 @@ import type {
24
29
  import type { SkinError } from '@forgeax/engine-skinning';
25
30
  import type { ImageError } from '@forgeax/engine-types';
26
31
  import type { RhiBackendInstrumentation } from './assembly/backend-contract.js';
32
+ import type { CloudLayerInspection } from './cloud/inspection.js';
33
+ import type { BarrelDistortionData } from './components/barrel-distortion.js';
27
34
  import type { Antialias, BloomEnabled, CameraExposure, Tonemap } from './components/camera.js';
28
35
  import type { DynamicResolutionData } from './components/dynamic-resolution.js';
29
36
  import type { ScreenSpaceReflectionData } from './components/screen-space-reflection.js';
@@ -53,7 +60,7 @@ import type {
53
60
  TemporalTargetInspection,
54
61
  TransmissionInspection,
55
62
  } from './inspection-types.js';
56
- import type { InstanceCollectionInspection, InstanceCollectionStore } from './instances.js';
63
+ import type { InstanceCollectionInspection } from './instances.js';
57
64
  import type { RenderExtent } from './pipeline/render-extent.js';
58
65
  import type { RenderSceneBounds } from './scene/render-scene-types.js';
59
66
  import type { SsrAdmissionIdentity } from './ssr/identity.js';
@@ -94,6 +101,7 @@ import type {
94
101
  GpuPassTimingOptions,
95
102
  } from './record/gpu-pass-timing/index.js';
96
103
  import type { VolumeTimingObservation } from './record/gpu-timing.js';
104
+ import type { SurfaceDynamicInputFrame } from './surface/dynamic-input.js';
97
105
  import type { TemporalView } from './temporal/view.js';
98
106
  import type { VolumetricFogInspection } from './volume/inspection.js';
99
107
 
@@ -189,6 +197,8 @@ export interface CameraSnapshot {
189
197
  /** Target presentation rate; zero follows the accepted frame interval. */
190
198
  readonly targetFps?: number;
191
199
  };
200
+ /** Optional active-camera barrel projection, copied from the ECS schema. */
201
+ readonly barrelDistortion?: BarrelDistortionData;
192
202
  }
193
203
 
194
204
  /** Stable identity owned by the Standard feature host for output transform. */
@@ -370,6 +380,11 @@ export interface AtmosphereShaderSources {
370
380
  * and never reach into AssetRegistry or World.
371
381
  */
372
382
  export interface VolumetricFogFrameContext {
383
+ readonly additional?: readonly {
384
+ readonly densityTexture: Texture;
385
+ readonly densityView: TextureView;
386
+ readonly densityGeneration: number;
387
+ }[];
373
388
  readonly densityTexture: Texture;
374
389
  readonly densityView: TextureView;
375
390
  readonly paramsBuffer: Buffer;
@@ -407,8 +422,8 @@ export interface SpotLightProjectorFrameContext {
407
422
  * leases, receipts, inspection PODs, and recovery Result values.
408
423
  */
409
424
  export interface Renderer {
410
- /** Renderer-owned authoring and update path for large instance collections. */
411
- readonly instances: InstanceCollectionStore;
425
+ /** Publish one renderer-owned read-only Surface dynamic page for the next frame. */
426
+ setSurfaceDynamicInput(frame: SurfaceDynamicInputFrame | undefined): void;
412
427
  attach(world: World): RenderResult<RenderWorldLease, RenderError>;
413
428
  /** Prepare a standard MeshAsset for the active device generation. */
414
429
  prepareDynamicGeometry(
@@ -499,6 +514,8 @@ export type RendererEvent =
499
514
  readonly kind: 'frame-submitted';
500
515
  readonly frameId: number;
501
516
  readonly deviceGeneration: number;
517
+ /** Compiled graph identity paired with the submitted picture. */
518
+ readonly graphGeneration?: number;
502
519
  /** The exact draw receipt, for observation when App owns the draw loop. */
503
520
  readonly receipt: FrameReceipt;
504
521
  };
@@ -553,13 +570,25 @@ export interface FrameObservationRequest {
553
570
  export interface FrameReceipt {
554
571
  readonly frameId: number;
555
572
  readonly deviceGeneration: number;
573
+ /** Whether this frame can present the active scene without a readiness fallback. */
574
+ readonly presentation: FramePresentation;
556
575
  /** Backend identity captured at submit and checked before observation. */
557
576
  readonly backendId?: RhiCaps['backendKind'];
558
577
  /** Monotonic compiled graph identity used by renderer-issued observations. */
559
578
  readonly graphGeneration?: number;
579
+ /**
580
+ * Effective output mapping for the submitted camera, including identity
581
+ * when this receipt has an accepted camera context. `undefined` means that
582
+ * no submitted display context is available; consumers must fail closed and
583
+ * must not infer identity or read the live World camera.
584
+ */
585
+ readonly barrelDistortion?: import('./barrel-distortion.js').BarrelDistortionMapping;
560
586
  readonly completed: Promise<RenderResult<void, RenderError>>;
561
587
  }
562
588
 
589
+ /** Producer-derived presentation readiness for one submitted frame. */
590
+ export type FramePresentation = 'pending' | 'ready';
591
+
563
592
  /**
564
593
  * The sole public draw input; World objects never cross this boundary. Render
565
594
  * owns extraction and graph interpretation, while the host owns encoding,
@@ -586,6 +615,12 @@ export interface RenderFrameInput {
586
615
  readonly fixedStep?: number;
587
616
  /** Optional profiler correlation token owned by App and consumed by Render. */
588
617
  readonly profileFrame?: ProfileFrameToken;
618
+ /**
619
+ * Select the geometry submission command lane while retaining the same
620
+ * extracted scene and material inputs. This is an acceptance/debug seam;
621
+ * both lanes remain subject to the ordinary resource and generation gates.
622
+ */
623
+ readonly geometryLane?: 'automatic' | 'direct';
589
624
  }
590
625
 
591
626
  /** Detached, bounded observation metadata tied to one FrameReceipt and request. */
@@ -719,8 +754,12 @@ export interface RenderInspection {
719
754
  readonly frameId: number;
720
755
  readonly deviceGeneration: number;
721
756
  };
757
+ /** Effective output mapping and accepted/LKG identity for the last picture. */
758
+ readonly barrelDistortion: import('./inspection-types').BarrelDistortionInspection;
722
759
  /** Renderer-owned authored volume projection and submit/LKG state. */
723
760
  readonly volumetricFog?: VolumetricFogInspection;
761
+ /** Renderer-owned procedural cloud projection from the latest resource-owner extract. */
762
+ readonly cloudLayer?: CloudLayerInspection;
724
763
  readonly features: readonly string[];
725
764
  /** Truthful lifecycle facts for every registered declarative feature. */
726
765
  readonly featureDiagnostics: readonly RenderFeatureDiagnostics[];
@@ -737,6 +776,10 @@ export interface RenderInspection {
737
776
  /** Standard MeshAsset dynamic-candidate lifecycle facts. */
738
777
  readonly dynamicGeometry?: DynamicGeometryInspection;
739
778
  readonly renderScene: RenderSceneInspection;
779
+ /** Detached logical allocation facts for graph-created render targets. */
780
+ readonly renderGraphResourceAllocation?: RenderGraphResourceAllocationInspection;
781
+ /** Detached logical allocation facts across graph generations. */
782
+ readonly renderGraphGenerationAllocation?: RenderGraphGenerationAllocationInspection;
740
783
  readonly reflectionProbes: ReflectionProbeInspection;
741
784
  /** Renderer-owned SSR dependency seam; consumer facts are projected from live owners. */
742
785
  readonly ssrDependencies: SsrDependenciesInspection;
@@ -832,6 +875,7 @@ export type DrawOwnerOptions = {
832
875
  /** Explicit pause/resume or replay lifecycle boundary for temporal owners. */
833
876
  readonly temporalReset?: boolean;
834
877
  readonly profileFrame?: ProfileFrameToken;
878
+ readonly geometryLane?: 'automatic' | 'direct';
835
879
  };
836
880
 
837
881
  /** Information attached to a device-loss notification. */
@@ -586,7 +586,13 @@ function dispatchFullscreenPass(
586
586
  detail: { readsKey: reads[0] ?? 'ldrColor', passName: name },
587
587
  });
588
588
  }
589
- recordFxaaPass(requireRenderGraphRecordContext(ctx), resolveCtx, graphPass, paramsOverride);
589
+ recordFxaaPass(
590
+ requireRenderGraphRecordContext(ctx),
591
+ resolveCtx,
592
+ graphPass,
593
+ paramsOverride,
594
+ graphOutputFormat,
595
+ );
590
596
  return;
591
597
  }
592
598
  const lookup = ctx.runtime.lookupPostProcess;