@forgeax/engine-render 0.1.32 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (624) hide show
  1. package/README.md +1374 -142
  2. package/dist/assembly/analytic-fog-registration.d.ts +3 -0
  3. package/dist/assembly/analytic-fog-registration.d.ts.map +1 -0
  4. package/dist/assembly/backend-contract.d.ts +2 -0
  5. package/dist/assembly/backend-contract.d.ts.map +1 -1
  6. package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
  7. package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
  8. package/dist/assembly/canvas-draw-guard.d.ts +3 -0
  9. package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
  10. package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
  11. package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
  12. package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
  13. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  14. package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
  15. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
  16. package/dist/assembly/factory.d.ts +1 -1
  17. package/dist/assembly/factory.d.ts.map +1 -1
  18. package/dist/assembly/fxaa-registration.d.ts +4 -0
  19. package/dist/assembly/fxaa-registration.d.ts.map +1 -0
  20. package/dist/assembly/host-contract.d.ts +3 -3
  21. package/dist/assembly/host-contract.d.ts.map +1 -1
  22. package/dist/assembly/lod-observation.d.ts +4 -0
  23. package/dist/assembly/lod-observation.d.ts.map +1 -0
  24. package/dist/assembly/material/assembly.d.ts.map +1 -1
  25. package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
  26. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
  27. package/dist/assembly/material-shader-policy.d.ts +16 -2
  28. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  29. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
  30. package/dist/assembly/motion-blur-registration.d.ts +3 -0
  31. package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
  32. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  33. package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
  34. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  35. package/dist/assembly/render-feature-post-processes.d.ts +6 -0
  36. package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
  37. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  38. package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
  39. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
  40. package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
  41. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  42. package/dist/assembly/renderer-inspection.d.ts +11 -0
  43. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  44. package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
  45. package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
  47. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
  48. package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
  49. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
  50. package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
  51. package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
  52. package/dist/assembly/webgpu-ready.d.ts +2 -2
  53. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  54. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
  55. package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
  56. package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
  57. package/dist/assembly/webgpu-renderer.d.ts +1 -1
  58. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  59. package/dist/authoring.mjs +1 -1
  60. package/dist/barrel-distortion.d.ts +47 -0
  61. package/dist/barrel-distortion.d.ts.map +1 -0
  62. package/dist/bloom-admission.d.ts +13 -0
  63. package/dist/bloom-admission.d.ts.map +1 -0
  64. package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
  65. package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
  66. package/dist/{chunk-JCIRYQ4V.mjs → chunk-HEB564WF.mjs} +10 -4
  67. package/dist/chunk-HEB564WF.mjs.map +1 -0
  68. package/dist/{chunk-JRIPCMYC.mjs → chunk-MKDIT2EM.mjs} +1584 -375
  69. package/dist/chunk-MKDIT2EM.mjs.map +1 -0
  70. package/dist/{chunk-S665NJNF.mjs → chunk-OCDLEI6I.mjs} +3 -3
  71. package/dist/{chunk-S665NJNF.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
  72. package/dist/chunk-ODZWR6JQ.mjs +4927 -0
  73. package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
  74. package/dist/{chunk-DRR7D3KX.mjs → chunk-SHFUFJ5N.mjs} +192 -18
  75. package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
  76. package/dist/{chunk-4NNZQCL3.mjs → chunk-UI5SFODX.mjs} +223 -277
  77. package/dist/chunk-UI5SFODX.mjs.map +1 -0
  78. package/dist/{chunk-GWCEMDVR.mjs → chunk-UINHLCZA.mjs} +787 -80
  79. package/dist/chunk-UINHLCZA.mjs.map +1 -0
  80. package/dist/{chunk-6TFBXLRJ.mjs → chunk-WEX45HKH.mjs} +222 -337
  81. package/dist/chunk-WEX45HKH.mjs.map +1 -0
  82. package/dist/cloud/density.d.ts +55 -0
  83. package/dist/cloud/density.d.ts.map +1 -0
  84. package/dist/cloud/extract.d.ts +25 -0
  85. package/dist/cloud/extract.d.ts.map +1 -0
  86. package/dist/cloud/feature.d.ts +57 -0
  87. package/dist/cloud/feature.d.ts.map +1 -0
  88. package/dist/cloud/frame-context.d.ts +8 -0
  89. package/dist/cloud/frame-context.d.ts.map +1 -0
  90. package/dist/cloud/inspection.d.ts +59 -0
  91. package/dist/cloud/inspection.d.ts.map +1 -0
  92. package/dist/cloud/optics.d.ts +56 -0
  93. package/dist/cloud/optics.d.ts.map +1 -0
  94. package/dist/cloud/parameters.d.ts +73 -0
  95. package/dist/cloud/parameters.d.ts.map +1 -0
  96. package/dist/cloud/resources.d.ts +60 -0
  97. package/dist/cloud/resources.d.ts.map +1 -0
  98. package/dist/cloud/shadow.d.ts +42 -0
  99. package/dist/cloud/shadow.d.ts.map +1 -0
  100. package/dist/cloud/temporal.d.ts +74 -0
  101. package/dist/cloud/temporal.d.ts.map +1 -0
  102. package/dist/components/atmosphere.d.ts +2 -0
  103. package/dist/components/atmosphere.d.ts.map +1 -1
  104. package/dist/components/barrel-distortion.d.ts +13 -0
  105. package/dist/components/barrel-distortion.d.ts.map +1 -0
  106. package/dist/components/camera.d.ts +20 -4
  107. package/dist/components/camera.d.ts.map +1 -1
  108. package/dist/components/cloud-layer.d.ts +29 -0
  109. package/dist/components/cloud-layer.d.ts.map +1 -0
  110. package/dist/components/index.d.ts +2 -0
  111. package/dist/components/index.d.ts.map +1 -1
  112. package/dist/components/instances.d.ts +20 -6
  113. package/dist/components/instances.d.ts.map +1 -1
  114. package/dist/components/mesh-filter.d.ts +6 -5
  115. package/dist/components/mesh-filter.d.ts.map +1 -1
  116. package/dist/components/motion-blur.d.ts +1 -0
  117. package/dist/components/motion-blur.d.ts.map +1 -1
  118. package/dist/construct-renderer.d.ts +1 -1
  119. package/dist/construct-renderer.d.ts.map +1 -1
  120. package/dist/construct-renderer.mjs +9751 -3528
  121. package/dist/construct-renderer.mjs.map +1 -1
  122. package/dist/device/gpu-residency.d.ts +6 -0
  123. package/dist/device/gpu-residency.d.ts.map +1 -1
  124. package/dist/dynamic-geometry.d.ts +5 -1
  125. package/dist/dynamic-geometry.d.ts.map +1 -1
  126. package/dist/environment/analytic-fog.d.ts +6 -0
  127. package/dist/environment/analytic-fog.d.ts.map +1 -0
  128. package/dist/errors/cloud.d.ts +59 -0
  129. package/dist/errors/cloud.d.ts.map +1 -0
  130. package/dist/errors/render.d.ts +23 -5
  131. package/dist/errors/render.d.ts.map +1 -1
  132. package/dist/examples/single-layer-medium-surface.d.ts +47 -0
  133. package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
  134. package/dist/extract/camera.d.ts.map +1 -1
  135. package/dist/extract/contracts.d.ts +12 -1
  136. package/dist/extract/contracts.d.ts.map +1 -1
  137. package/dist/extract/environment.d.ts +2 -0
  138. package/dist/extract/environment.d.ts.map +1 -1
  139. package/dist/features/barrel-distortion.d.ts +29 -0
  140. package/dist/features/barrel-distortion.d.ts.map +1 -0
  141. package/dist/features/error-reporting.d.ts +17 -0
  142. package/dist/features/error-reporting.d.ts.map +1 -0
  143. package/dist/features/host.d.ts +15 -0
  144. package/dist/features/host.d.ts.map +1 -1
  145. package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
  146. package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
  147. package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
  148. package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
  149. package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
  150. package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
  151. package/dist/features/plan.d.ts +15 -4
  152. package/dist/features/plan.d.ts.map +1 -1
  153. package/dist/features/prepared-gpu-work.d.ts +9 -5
  154. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  155. package/dist/features/render-graph-compute.d.ts.map +1 -1
  156. package/dist/features/render-graph-contribution.d.ts +5 -0
  157. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  158. package/dist/features/render-graph-raster.d.ts +1 -0
  159. package/dist/features/render-graph-raster.d.ts.map +1 -1
  160. package/dist/features/targets.d.ts +2 -0
  161. package/dist/features/targets.d.ts.map +1 -1
  162. package/dist/features/types.d.ts +44 -0
  163. package/dist/features/types.d.ts.map +1 -1
  164. package/dist/fullscreen-post-process-pass.d.ts +15 -7
  165. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  166. package/dist/gpu-dirty-ranges.d.ts +11 -0
  167. package/dist/gpu-dirty-ranges.d.ts.map +1 -0
  168. package/dist/gpu-driven/batch-topology.d.ts +17 -0
  169. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  170. package/dist/gpu-driven/material-artifacts.d.ts +6 -0
  171. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  172. package/dist/gpu-driven/prepared-draw.d.ts +7 -0
  173. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  174. package/dist/gpu-driven/production-raster-material.d.ts +178 -0
  175. package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
  176. package/dist/gpu-driven/production-raster.d.ts +50 -4
  177. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  178. package/dist/gpu-driven/resource-allocation.d.ts +31 -0
  179. package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
  180. package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
  181. package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
  182. package/dist/gpu-driven/view-gpu.d.ts +35 -2
  183. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  184. package/dist/gpu-scene.d.ts +11 -1
  185. package/dist/gpu-scene.d.ts.map +1 -1
  186. package/dist/hdrp-buffers.d.ts +2 -2
  187. package/dist/hdrp-buffers.d.ts.map +1 -1
  188. package/dist/ibl/skylight-bind-group.d.ts +10 -1
  189. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  190. package/dist/index.d.ts +31 -8
  191. package/dist/index.d.ts.map +1 -1
  192. package/dist/index.mjs +258 -8
  193. package/dist/index.mjs.map +1 -1
  194. package/dist/inspection-types.d.ts +178 -3
  195. package/dist/inspection-types.d.ts.map +1 -1
  196. package/dist/instance-buffer-cache.d.ts +4 -4
  197. package/dist/instance-buffer-cache.d.ts.map +1 -1
  198. package/dist/instances.d.ts +49 -94
  199. package/dist/instances.d.ts.map +1 -1
  200. package/dist/internal.mjs +7 -7
  201. package/dist/pbr-pipeline.d.ts +19 -1
  202. package/dist/pbr-pipeline.d.ts.map +1 -1
  203. package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
  204. package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
  205. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  206. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  207. package/dist/pipeline/standard-output/types.d.ts +4 -2
  208. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  209. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  210. package/dist/pipeline/standard-post.d.ts +28 -19
  211. package/dist/pipeline/standard-post.d.ts.map +1 -1
  212. package/dist/pipeline-builder.d.ts +1 -1
  213. package/dist/pipeline-builder.d.ts.map +1 -1
  214. package/dist/pipeline-spec.d.ts +2 -2
  215. package/dist/plugin.d.ts.map +1 -1
  216. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
  217. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  218. package/dist/record/barrel-distortion-frame.d.ts +15 -0
  219. package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
  220. package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
  221. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
  222. package/dist/record/fold-buckets.d.ts +95 -0
  223. package/dist/record/fold-buckets.d.ts.map +1 -0
  224. package/dist/record/fold-instance-buffer.d.ts +6 -0
  225. package/dist/record/fold-instance-buffer.d.ts.map +1 -0
  226. package/dist/record/frame-lighting.d.ts +1 -0
  227. package/dist/record/frame-lighting.d.ts.map +1 -1
  228. package/dist/record/frame-snapshot.d.ts +40 -3
  229. package/dist/record/frame-snapshot.d.ts.map +1 -1
  230. package/dist/record/frame-targets.d.ts.map +1 -1
  231. package/dist/record/frame.d.ts +14 -62
  232. package/dist/record/frame.d.ts.map +1 -1
  233. package/dist/record/gpu-draw-receipts.d.ts +11 -0
  234. package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
  235. package/dist/record/gpu-timing.d.ts +8 -0
  236. package/dist/record/gpu-timing.d.ts.map +1 -1
  237. package/dist/record/main-pass-geometry.d.ts +21 -5
  238. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  239. package/dist/record/main-pass-material.d.ts +7 -1
  240. package/dist/record/main-pass-material.d.ts.map +1 -1
  241. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  242. package/dist/record/main-pass.d.ts +13 -2
  243. package/dist/record/main-pass.d.ts.map +1 -1
  244. package/dist/record/mesh-ssbo.d.ts +6 -5
  245. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  246. package/dist/record/motion-blur-receipt.d.ts +11 -0
  247. package/dist/record/motion-blur-receipt.d.ts.map +1 -0
  248. package/dist/record/probe-blend-buffer.d.ts +16 -0
  249. package/dist/record/probe-blend-buffer.d.ts.map +1 -0
  250. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  251. package/dist/record/render-context.d.ts +34 -31
  252. package/dist/record/render-context.d.ts.map +1 -1
  253. package/dist/record/shadow-pass.d.ts +2 -0
  254. package/dist/record/shadow-pass.d.ts.map +1 -1
  255. package/dist/record/skybox-post-pass.d.ts +6 -4
  256. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  257. package/dist/record/typed-frame-graph.d.ts +22 -2
  258. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  259. package/dist/record/view-ubo.d.ts +11 -3
  260. package/dist/record/view-ubo.d.ts.map +1 -1
  261. package/dist/record/volume-params.d.ts +9 -0
  262. package/dist/record/volume-params.d.ts.map +1 -0
  263. package/dist/recovery/render-system-candidate.d.ts +10 -0
  264. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  265. package/dist/reflection/record-owner.d.ts.map +1 -1
  266. package/dist/render-contract.d.ts +66 -8
  267. package/dist/render-contract.d.ts.map +1 -1
  268. package/dist/render-graph-primitives.d.ts.map +1 -1
  269. package/dist/render-pipeline.d.ts +106 -3
  270. package/dist/render-pipeline.d.ts.map +1 -1
  271. package/dist/render-system-extract-tail.d.ts +3 -2
  272. package/dist/render-system-extract-tail.d.ts.map +1 -1
  273. package/dist/render-system-extract.d.ts +24 -10
  274. package/dist/render-system-extract.d.ts.map +1 -1
  275. package/dist/render-system-presentation.d.ts +23 -0
  276. package/dist/render-system-presentation.d.ts.map +1 -0
  277. package/dist/render-system-producer-roots.d.ts +10 -0
  278. package/dist/render-system-producer-roots.d.ts.map +1 -0
  279. package/dist/render-system-residency.d.ts +12 -0
  280. package/dist/render-system-residency.d.ts.map +1 -0
  281. package/dist/render-system.d.ts +26 -15
  282. package/dist/render-system.d.ts.map +1 -1
  283. package/dist/scene/probe-blend.d.ts +27 -0
  284. package/dist/scene/probe-blend.d.ts.map +1 -1
  285. package/dist/scene/render-scene.d.ts +14 -5
  286. package/dist/scene/render-scene.d.ts.map +1 -1
  287. package/dist/ssao-buffers.d.ts +9 -0
  288. package/dist/ssao-buffers.d.ts.map +1 -1
  289. package/dist/surface/dynamic-input.d.ts +133 -0
  290. package/dist/surface/dynamic-input.d.ts.map +1 -0
  291. package/dist/surface/gpu-driven.d.ts +41 -0
  292. package/dist/surface/gpu-driven.d.ts.map +1 -0
  293. package/dist/surface/submission-observation.d.ts +136 -0
  294. package/dist/surface/submission-observation.d.ts.map +1 -0
  295. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  296. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  297. package/dist/temporal/frame.d.ts +7 -0
  298. package/dist/temporal/frame.d.ts.map +1 -1
  299. package/dist/temporal/gpu.d.ts +13 -1
  300. package/dist/temporal/gpu.d.ts.map +1 -1
  301. package/dist/temporal/index.mjs +5 -5
  302. package/dist/temporal/inspection.d.ts.map +1 -1
  303. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  304. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
  305. package/dist/temporal/view.d.ts +6 -1
  306. package/dist/temporal/view.d.ts.map +1 -1
  307. package/dist/transmission/single-layer-medium.d.ts +89 -0
  308. package/dist/transmission/single-layer-medium.d.ts.map +1 -0
  309. package/dist/typed-render-graph-primitives.d.ts +24 -9
  310. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  311. package/dist/volume/component.d.ts +9 -5
  312. package/dist/volume/component.d.ts.map +1 -1
  313. package/dist/volume/extract.d.ts +1 -1
  314. package/dist/volume/extract.d.ts.map +1 -1
  315. package/dist/volume/inspection.d.ts +2 -0
  316. package/dist/volume/inspection.d.ts.map +1 -1
  317. package/dist/volume/passes.d.ts +4 -1
  318. package/dist/volume/passes.d.ts.map +1 -1
  319. package/dist/volume/resources.d.ts.map +1 -1
  320. package/dist/volume/temporal.d.ts +3 -1
  321. package/dist/volume/temporal.d.ts.map +1 -1
  322. package/package.json +22 -21
  323. package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
  324. package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
  325. package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
  326. package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
  327. package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
  328. package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
  329. package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
  330. package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
  331. package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
  332. package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
  333. package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
  334. package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
  335. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
  336. package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
  337. package/src/__tests__/environment-selection.unit.test.ts +12 -0
  338. package/src/__tests__/factory-contract.integration.test.ts +626 -113
  339. package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
  340. package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
  341. package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
  342. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
  343. package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
  344. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
  345. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
  346. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
  347. package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
  348. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
  349. package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
  350. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +7 -6
  351. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
  352. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +103 -4
  353. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
  354. package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
  355. package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
  356. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
  357. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
  358. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
  359. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
  360. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
  361. package/src/__tests__/gpu-scene.unit.test.ts +210 -9
  362. package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
  363. package/src/__tests__/instances-culling.integration.test.ts +10 -36
  364. package/src/__tests__/instances-store.unit.test.ts +105 -238
  365. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  366. package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
  367. package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
  368. package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
  369. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
  370. package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
  371. package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
  372. package/src/__tests__/motion-blur-compute.dawn.test.ts +589 -0
  373. package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
  374. package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
  375. package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
  376. package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
  377. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +21 -0
  378. package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
  379. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
  380. package/src/__tests__/probe-bindings.unit.test.ts +582 -1
  381. package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
  382. package/src/__tests__/public-surface.test-d.ts +8 -0
  383. package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
  384. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
  385. package/src/__tests__/render-error-code-owner.test-d.ts +9 -0
  386. package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
  387. package/src/__tests__/render-feature-error-reporting.unit.test.ts +44 -0
  388. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
  389. package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
  390. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
  391. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
  392. package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
  393. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +37 -6
  394. package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
  395. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
  396. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
  397. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
  398. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
  399. package/src/__tests__/renderer-frame-transaction.integration.test.ts +33 -11
  400. package/src/__tests__/resource-allocation.unit.test.ts +123 -0
  401. package/src/__tests__/shader-manifest-fixture.ts +4 -4
  402. package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
  403. package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
  404. package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
  405. package/src/__tests__/skinned-shadow-caster.test.ts +17 -0
  406. package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
  407. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
  408. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
  409. package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
  410. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
  411. package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
  412. package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
  413. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
  414. package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
  415. package/src/__tests__/standard-pipeline.integration.test.ts +200 -9
  416. package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
  417. package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
  418. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
  419. package/src/__tests__/temporal-performance.integration.test.ts +3 -3
  420. package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
  421. package/src/__tests__/temporal-view.unit.test.ts +2 -1
  422. package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
  423. package/src/__tests__/visibility-instances.integration.test.ts +7 -19
  424. package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
  425. package/src/__tests__/volume-optics-oracle.unit.test.ts +7 -3
  426. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +189 -15
  427. package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
  428. package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
  429. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
  430. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +558 -68
  431. package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
  432. package/src/__tests__/volumetric-fog-topology.unit.test.ts +23 -5
  433. package/src/assembly/analytic-fog-registration.ts +14 -0
  434. package/src/assembly/backend-contract.ts +30 -0
  435. package/src/assembly/barrel-distortion-inspection.ts +22 -0
  436. package/src/assembly/canvas-draw-guard.ts +11 -0
  437. package/src/assembly/cloud-shadow-entry.ts +22 -0
  438. package/src/assembly/dynamic-geometry-host.ts +65 -37
  439. package/src/assembly/dynamic-geometry-runtime.ts +7 -1
  440. package/src/assembly/factory.ts +2 -30
  441. package/src/assembly/fxaa-registration.ts +17 -0
  442. package/src/assembly/host-contract.ts +3 -3
  443. package/src/assembly/lod-observation.ts +12 -0
  444. package/src/assembly/material/assembly.ts +25 -13
  445. package/src/assembly/material/pipeline-helpers.ts +53 -12
  446. package/src/assembly/material-shader-policy.ts +55 -0
  447. package/src/assembly/material-shader-prewarm.ts +21 -10
  448. package/src/assembly/motion-blur-registration.ts +17 -0
  449. package/src/assembly/recovery/device-loss-fanout.ts +13 -0
  450. package/src/assembly/recovery/renderer-recover.ts +41 -18
  451. package/src/assembly/render-feature-post-processes.ts +54 -0
  452. package/src/assembly/renderer-facade.ts +6 -1
  453. package/src/assembly/renderer-feature-inspection.ts +8 -2
  454. package/src/assembly/renderer-frame-transaction.ts +23 -0
  455. package/src/assembly/renderer-inspection.ts +28 -0
  456. package/src/assembly/skin-palette-owner.ts +1 -1
  457. package/src/assembly/temporal-post-process-prewarm.ts +40 -0
  458. package/src/assembly/webgpu-pbr-ready.ts +9 -1
  459. package/src/assembly/webgpu-ready-contract.ts +8 -3
  460. package/src/assembly/webgpu-ready-per-pass.ts +104 -0
  461. package/src/assembly/webgpu-ready.ts +296 -306
  462. package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
  463. package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
  464. package/src/assembly/webgpu-renderer.ts +228 -281
  465. package/src/assembly/webgpu-vertex-layouts.ts +1 -1
  466. package/src/barrel-distortion.ts +247 -0
  467. package/src/bloom-admission.ts +21 -0
  468. package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
  469. package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
  470. package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
  471. package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
  472. package/src/cloud/density.ts +600 -0
  473. package/src/cloud/extract.ts +110 -0
  474. package/src/cloud/feature.ts +1810 -0
  475. package/src/cloud/frame-context.ts +42 -0
  476. package/src/cloud/inspection.ts +130 -0
  477. package/src/cloud/optics.ts +285 -0
  478. package/src/cloud/parameters.ts +255 -0
  479. package/src/cloud/resources.ts +122 -0
  480. package/src/cloud/shadow.ts +167 -0
  481. package/src/cloud/temporal.ts +226 -0
  482. package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
  483. package/src/components/atmosphere.ts +4 -0
  484. package/src/components/barrel-distortion.ts +46 -0
  485. package/src/components/camera.ts +66 -10
  486. package/src/components/cloud-layer.ts +47 -0
  487. package/src/components/index.ts +2 -0
  488. package/src/components/instances.ts +18 -45
  489. package/src/components/mesh-filter.ts +11 -9
  490. package/src/components/motion-blur.ts +1 -0
  491. package/src/components/sprite-instances.ts +1 -1
  492. package/src/construct-renderer.ts +1 -1
  493. package/src/device/gpu-residency.ts +56 -12
  494. package/src/dynamic-geometry.ts +12 -1
  495. package/src/environment/analytic-fog.ts +44 -0
  496. package/src/environment/background.ts +2 -2
  497. package/src/errors/cloud.ts +103 -0
  498. package/src/errors/render.ts +58 -8
  499. package/src/examples/single-layer-medium-surface.ts +59 -0
  500. package/src/extract/camera.ts +35 -8
  501. package/src/extract/contracts.ts +12 -0
  502. package/src/extract/environment.ts +4 -0
  503. package/src/features/barrel-distortion.ts +172 -0
  504. package/src/features/error-reporting.ts +98 -0
  505. package/src/features/host.ts +138 -24
  506. package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
  507. package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
  508. package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
  509. package/src/features/motion-blur/motion-blur-params.ts +70 -2
  510. package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
  511. package/src/features/plan.ts +33 -8
  512. package/src/features/prepared-gpu-work.ts +86 -35
  513. package/src/features/render-graph-compute.ts +13 -5
  514. package/src/features/render-graph-contribution.ts +11 -0
  515. package/src/features/render-graph-raster.ts +45 -3
  516. package/src/features/targets.ts +66 -0
  517. package/src/features/types.ts +47 -0
  518. package/src/fullscreen-post-process-pass.ts +41 -9
  519. package/src/gpu-dirty-ranges.ts +48 -0
  520. package/src/gpu-driven/batch-topology.ts +53 -0
  521. package/src/gpu-driven/material-artifacts.ts +35 -32
  522. package/src/gpu-driven/prepared-draw.ts +27 -14
  523. package/src/gpu-driven/production-raster-material.ts +1894 -0
  524. package/src/gpu-driven/production-raster.ts +904 -787
  525. package/src/gpu-driven/resource-allocation.ts +142 -0
  526. package/src/gpu-driven/shadow-ownership.ts +71 -0
  527. package/src/gpu-driven/view-gpu.ts +181 -10
  528. package/src/gpu-scene.ts +259 -101
  529. package/src/hdrp-buffers.ts +4 -3
  530. package/src/ibl/skylight-bind-group.ts +49 -7
  531. package/src/index.ts +228 -9
  532. package/src/inspection-types.ts +222 -2
  533. package/src/instance-buffer-cache.ts +4 -4
  534. package/src/instances.ts +151 -492
  535. package/src/pbr-pipeline.ts +219 -13
  536. package/src/pipeline/single-layer-medium-passes.ts +267 -0
  537. package/src/pipeline/standard-forward-lane.ts +313 -57
  538. package/src/pipeline/standard-output/graph.ts +8 -2
  539. package/src/pipeline/standard-output/types.ts +12 -1
  540. package/src/pipeline/standard-pipeline.ts +291 -18
  541. package/src/pipeline/standard-post.ts +397 -102
  542. package/src/pipeline-builder.ts +1 -1
  543. package/src/pipeline-spec.ts +5 -5
  544. package/src/plugin.ts +4 -0
  545. package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
  546. package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
  547. package/src/prepare/prepared-graphics-resolver.ts +2 -0
  548. package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
  549. package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
  550. package/src/record/__tests__/temporal-payload.unit.test.ts +3 -2
  551. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
  552. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
  553. package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
  554. package/src/record/barrel-distortion-frame.ts +110 -0
  555. package/src/record/dynamic-geometry-consumption.ts +39 -9
  556. package/src/record/fold-buckets.ts +852 -0
  557. package/src/record/fold-instance-buffer.ts +51 -0
  558. package/src/record/frame-lighting.ts +36 -2
  559. package/src/record/frame-snapshot.ts +44 -4
  560. package/src/record/frame-targets.ts +10 -6
  561. package/src/record/frame.ts +373 -1099
  562. package/src/record/gpu-draw-receipts.ts +38 -0
  563. package/src/record/gpu-timing.ts +48 -5
  564. package/src/record/main-pass-geometry.ts +281 -83
  565. package/src/record/main-pass-material.ts +66 -4
  566. package/src/record/main-pass-sprite-draws.ts +13 -66
  567. package/src/record/main-pass.ts +156 -20
  568. package/src/record/mesh-ssbo.ts +43 -6
  569. package/src/record/motion-blur-receipt.ts +91 -0
  570. package/src/record/probe-blend-buffer.ts +180 -0
  571. package/src/record/recovery-pipeline.ts +35 -3
  572. package/src/record/render-context.ts +51 -31
  573. package/src/record/shadow-pass.ts +36 -2
  574. package/src/record/skybox-post-pass.ts +150 -200
  575. package/src/record/typed-frame-graph.ts +824 -44
  576. package/src/record/view-ubo.ts +26 -3
  577. package/src/record/volume-params.ts +225 -0
  578. package/src/recovery/render-system-candidate.ts +257 -52
  579. package/src/reflection/record-owner.ts +7 -3
  580. package/src/render-contract.ts +71 -8
  581. package/src/render-graph-primitives.ts +7 -1
  582. package/src/render-pipeline.ts +136 -1
  583. package/src/render-system-extract-tail.ts +72 -60
  584. package/src/render-system-extract.ts +117 -87
  585. package/src/render-system-presentation.ts +56 -0
  586. package/src/render-system-producer-roots.ts +96 -0
  587. package/src/render-system-residency.ts +159 -0
  588. package/src/render-system.ts +601 -482
  589. package/src/scene/probe-blend.ts +96 -4
  590. package/src/scene/render-scene.ts +431 -281
  591. package/src/ssao-buffers.ts +95 -2
  592. package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
  593. package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
  594. package/src/surface/dynamic-input.ts +658 -0
  595. package/src/surface/gpu-driven.ts +147 -0
  596. package/src/surface/submission-observation.ts +517 -0
  597. package/src/systems/skin-palette-allocator.ts +4 -1
  598. package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
  599. package/src/temporal/frame-coordinator.ts +8 -1
  600. package/src/temporal/frame.ts +20 -0
  601. package/src/temporal/gpu.ts +101 -17
  602. package/src/temporal/inspection.ts +7 -1
  603. package/src/temporal/standard-scene-data.ts +5 -0
  604. package/src/temporal/target-coverage-attachment.ts +4 -0
  605. package/src/temporal/view.ts +13 -2
  606. package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
  607. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
  608. package/src/transmission/single-layer-medium.ts +322 -0
  609. package/src/typed-render-graph-primitives.ts +191 -50
  610. package/src/volume/component.ts +10 -10
  611. package/src/volume/extract.ts +11 -5
  612. package/src/volume/inspection.ts +3 -0
  613. package/src/volume/passes.ts +95 -8
  614. package/src/volume/resources.ts +2 -1
  615. package/src/volume/temporal.ts +11 -0
  616. package/dist/chunk-4NNZQCL3.mjs.map +0 -1
  617. package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
  618. package/dist/chunk-DRR7D3KX.mjs.map +0 -1
  619. package/dist/chunk-GWCEMDVR.mjs.map +0 -1
  620. package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
  621. package/dist/chunk-JRIPCMYC.mjs.map +0 -1
  622. package/dist/chunk-LULCA3OF.mjs +0 -1713
  623. package/dist/chunk-LULCA3OF.mjs.map +0 -1
  624. package/dist/chunk-PA5DRJNI.mjs.map +0 -1
@@ -14,7 +14,6 @@ import {
14
14
  } from '@forgeax/engine-geometry';
15
15
  import type {
16
16
  BindGroupLayout,
17
- Buffer,
18
17
  PipelineLayout,
19
18
  RenderPipeline,
20
19
  Result,
@@ -28,6 +27,9 @@ import {
28
27
  type MaterialShaderEntry,
29
28
  type MaterialShaderManifestEntry,
30
29
  ShaderCatalog,
30
+ SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_WGSL,
31
+ SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_WGSL,
32
+ SINGLE_LAYER_MEDIUM_RAW_DEPTH_WGSL,
31
33
  standardPhysicalTextureFields,
32
34
  } from '@forgeax/engine-shader';
33
35
  import type {
@@ -53,11 +55,16 @@ import {
53
55
  RenderFeatureCapabilityMissingError,
54
56
  RenderFeatureStageFailedError,
55
57
  } from '../errors/render';
58
+ import {
59
+ BARREL_DISTORTION_FEATURE_IDENTITY,
60
+ createBarrelDistortionRenderFeature,
61
+ } from '../features/barrel-distortion';
56
62
  import {
57
63
  dofInspection,
58
64
  registerDepthOfFieldBuiltins,
59
65
  } from '../features/depth-of-field/depth-of-field-assembly';
60
66
  import { createRenderFeatureHost } from '../features/host';
67
+ import { motionBlurDrawOptions } from '../features/motion-blur/motion-blur-runtime';
61
68
  import { RENDER_FEATURE_VERTEX_LAYOUTS } from '../features/prepared-graphics';
62
69
  import type { RenderFeature, RenderFeatureShaderModuleMode } from '../features/types';
63
70
  import {
@@ -66,16 +73,20 @@ import {
66
73
  } from '../fullscreen-post-process-pass';
67
74
  import { glyphTextLayoutSystem } from '../glyph-text-layout-system';
68
75
  import { GPU_SHADER_STAGE_FRAGMENT, GPU_SHADER_STAGE_VERTEX } from '../gpu-stage';
69
- import type { BloomInspection } from '../inspection-types';
76
+ import { type BloomInspection, emptyBloomInspection } from '../inspection-types';
70
77
  import { DeviceScope } from '../lifecycle';
71
78
  import {
72
79
  createHdrpBindGroupLayoutDescriptor,
73
80
  isCanonicalStandardPbrMaterialShader,
74
81
  isStandardPbrMaterialShader,
75
82
  type PipelineGroup2Contract,
76
- resolvePipelineGroup2Contract,
77
83
  SKIN_MATERIAL_SHADER_ID,
78
84
  } from '../pbr-pipeline';
85
+ import {
86
+ SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_POST_PROCESS_ID,
87
+ SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_POST_PROCESS_ID,
88
+ SINGLE_LAYER_MEDIUM_RAW_DEPTH_POST_PROCESS_ID,
89
+ } from '../pipeline/single-layer-medium-passes';
79
90
  import { standardPipeline } from '../pipeline/standard-pipeline';
80
91
  import { DEFAULT_STANDARD_PROFILE } from '../pipeline/standard-profile';
81
92
  import { buildPipelineForMaterialShader } from '../pipeline-builder';
@@ -146,13 +157,19 @@ import { postSpawnResolveJoints } from '../scene-instances/post-spawn-resolve-jo
146
157
  import type { RenderTarget } from '../targets/contracts';
147
158
  import { tilemapChunkExtractSystem } from '../tilemap-chunk-extract-system';
148
159
  import type { TypedFrameObservationCapture } from '../typed-render-graph-primitives';
160
+ import { registerAnalyticFogPostProcess } from './analytic-fog-registration';
149
161
  import type { RhiBackendPack } from './backend-contract';
162
+ import { inspectBarrelDistortion } from './barrel-distortion-inspection';
150
163
  import type { BundlerOptions } from './bundler-contract';
164
+ import { rejectZeroCanvasSize } from './canvas-draw-guard';
151
165
  import { createRendererDynamicGeometryController } from './dynamic-geometry-host';
166
+ import { registerFxaaPostProcess } from './fxaa-registration';
152
167
  import type { RendererAssemblyImplementation } from './host-contract';
168
+ import { observeLodOcclusionForReceipt } from './lod-observation';
153
169
  import {
154
170
  isEngineOwnedMaterialShader,
155
171
  resolveMaterialPipelineBindGroups,
172
+ resolveMaterialPipelineGroup2Contract,
156
173
  resolveMaterialPipelineShaderId,
157
174
  resolveMaterialPipelineVertexEntry,
158
175
  resolveRendererMaterialShaderArtifact,
@@ -165,6 +182,7 @@ import {
165
182
  type MaterialShaderBindingContract,
166
183
  makeShaderDeviceAdapter,
167
184
  normalizeMaterialShaderVariantSet,
185
+ prepareLowLimitMaterialShaderEntry,
168
186
  prepareMaterialShaders,
169
187
  resolveMaterialShaderBackendArtifactKey,
170
188
  resolveMaterialShaderBindingContract,
@@ -177,12 +195,14 @@ import {
177
195
  shouldDeferMissingPreparedMaterialShader,
178
196
  } from './material-shader-policy';
179
197
  import type { MeshSsboGrowResult, MeshSsboState } from './mesh-ssbo-grow';
198
+ import { registerMotionBlurPostProcess } from './motion-blur-registration';
180
199
  import {
181
200
  type GenerationAggregate,
182
201
  type GenerationPublication,
183
202
  publishGeneration,
184
203
  } from './recovery/generation';
185
204
  import { createRendererRecovery, type RendererRecovery } from './recovery/renderer-recover';
205
+ import { collectRequiredFullscreenPostProcesses } from './render-feature-post-processes';
186
206
  import { createRenderTargetHost } from './render-target-host';
187
207
  import {
188
208
  freezeRenderProfile,
@@ -193,6 +213,7 @@ import { projectRendererFeatureInspection } from './renderer-feature-inspection'
193
213
  import {
194
214
  type ContinuationTerminator,
195
215
  createContinuationTerminator,
216
+ guardFrameCompletion,
196
217
  } from './renderer-frame-transaction';
197
218
  import {
198
219
  ensureContextConfigured,
@@ -200,7 +221,7 @@ import {
200
221
  rendererInitializationPipelineError,
201
222
  wrapDisposeError,
202
223
  } from './renderer-helpers';
203
- import { projectRendererOutputInspection } from './renderer-inspection';
224
+ import { projectRendererOutputInspectionFromSurface } from './renderer-inspection';
204
225
  import {
205
226
  createRecoveryContinuation,
206
227
  createRecoveryDeadline,
@@ -224,7 +245,10 @@ import {
224
245
  type WebGPURendererInternals,
225
246
  } from './webgpu-renderer-bootstrap';
226
247
  import type { WebGPUOutcome } from './webgpu-renderer-contract';
227
- import { disposeObservationCaptureSet } from './webgpu-renderer-observation';
248
+ import {
249
+ createRendererObservationCaptureOwner,
250
+ type ObservationCaptureRead,
251
+ } from './webgpu-renderer-observation-owner';
228
252
  import {
229
253
  isPreparedMaterialVertexLayout,
230
254
  PREPARED_INSTANCE_VERTEX_ATTRS,
@@ -252,6 +276,7 @@ export {
252
276
  selectNoColorPbrVariant,
253
277
  selectPipelineLayoutForVariant,
254
278
  shouldDeferMissingPreparedMaterialShader,
279
+ stripCloudShadowBindingsForLowLimit,
255
280
  } from './material-shader-policy';
256
281
  export {
257
282
  createMeshSsboGrowController,
@@ -328,7 +353,13 @@ async function makeWebGPURenderer(
328
353
  let renderTargetDevice = internals.device;
329
354
  let renderTargetGeneration = 0;
330
355
  let renderSystemForTargetPromotion: RenderSystem | undefined;
331
- const featureHostResult = createRenderFeatureHost(internals.options?.features ?? []);
356
+ const requestedFeatures = internals.options?.features ?? [];
357
+ const featureHostFeatures = requestedFeatures.some(
358
+ (f) => f.identity === BARREL_DISTORTION_FEATURE_IDENTITY,
359
+ )
360
+ ? requestedFeatures
361
+ : [...requestedFeatures, createBarrelDistortionRenderFeature()];
362
+ const featureHostResult = createRenderFeatureHost(featureHostFeatures);
332
363
  if (!featureHostResult.ok) throw featureHostResult.error;
333
364
  internals.featureHost = featureHostResult.value;
334
365
  let rendererRecovery: RendererRecovery | undefined;
@@ -461,27 +492,8 @@ async function makeWebGPURenderer(
461
492
  featureHostResult.value.features.flatMap((feature) => feature.requiredMaterialShaders ?? []),
462
493
  );
463
494
  let requiredMaterialShaders = Object.freeze([...requiredMaterialShaderSet]);
464
- const collectRequiredFullscreenPostProcesses = (
465
- features: readonly RenderFeature<unknown>[],
466
- ): readonly { readonly identity: string; readonly source: string }[] => {
467
- const entries = new Map<string, { readonly identity: string; readonly source: string }>();
468
- for (const feature of features) {
469
- for (const entry of feature.requiredFullscreenPostProcesses ?? []) {
470
- const existing = entries.get(entry.identity);
471
- if (existing !== undefined && existing.source !== entry.source) {
472
- throw new RhiError({
473
- code: 'internal-error',
474
- expected: `fullscreen identity '${entry.identity}' has one source across render features`,
475
- hint: 'rename the conflicting fullscreen identity or make its WGSL source identical',
476
- });
477
- }
478
- entries.set(entry.identity, entry);
479
- }
480
- }
481
- return Object.freeze([...entries.values()]);
482
- };
483
- let requiredFullscreenPostProcesses = collectRequiredFullscreenPostProcesses(
484
- featureHostResult.value.features,
495
+ let requiredFullscreenPostProcesses = Object.freeze(
496
+ collectRequiredFullscreenPostProcesses(featureHostResult.value.features),
485
497
  );
486
498
  // Lazy ShaderCatalog instance (plan-strategy section S-10 / D-R10 / OQ-5
487
499
  // close): constructed on first access; subsequent accesses return the
@@ -531,7 +543,7 @@ async function makeWebGPURenderer(
531
543
  feature: RenderFeature<unknown>,
532
544
  ): Promise<Result<void, RhiError>> => {
533
545
  for (const postProcess of feature.requiredFullscreenPostProcesses ?? []) {
534
- const label = postProcessShaderModuleLabel(postProcess.identity, postProcess.source);
546
+ const label = postProcessShaderModuleLabel(postProcess.source);
535
547
  const shaderResult = internals.pack.createShaderModule
536
548
  ? await internals.pack.createShaderModule(internals.device, {
537
549
  code: postProcess.source,
@@ -1132,6 +1144,9 @@ async function makeWebGPURenderer(
1132
1144
  const lookup = getShader().findMaterialArtifact(materialShaderId);
1133
1145
  const source = lookup.ok ? lookup.value.source : '';
1134
1146
  const paramSchema = lookup.ok ? lookup.value.paramSchema : explicitParamSchema;
1147
+ const singleLayerMedium =
1148
+ materialShaderId === 'forgeax::single-layer-medium' ||
1149
+ (lookup.ok && lookup.value.receipt?.surface?.model === 'single-layer-medium');
1135
1150
  if (paramSchema === undefined) return null;
1136
1151
  const cacheKey = `${materialShaderId}:${layoutKind}:${clustered}`;
1137
1152
  const cached = cacheState.perShaderMaterialLayoutCache.get(cacheKey);
@@ -1150,7 +1165,12 @@ async function makeWebGPURenderer(
1150
1165
  isStandardPbrMaterialShader(materialShaderId) ||
1151
1166
  standardPhysicalTextureFields(paramSchema).length > 0;
1152
1167
  const isStandardMapLayout = requiresStandardMapLayout;
1153
- if (!clustered && !isStandardMapLayout && isSharedMaterialUserRegionCompatible(paramSchema)) {
1168
+ if (
1169
+ !clustered &&
1170
+ !singleLayerMedium &&
1171
+ !isStandardMapLayout &&
1172
+ isSharedMaterialUserRegionCompatible(paramSchema)
1173
+ ) {
1154
1174
  cacheState.perShaderMaterialLayoutCache.set(cacheKey, {
1155
1175
  source,
1156
1176
  paramSchema,
@@ -1160,7 +1180,11 @@ async function makeWebGPURenderer(
1160
1180
  return null;
1161
1181
  }
1162
1182
  const spec: PipelineSpec = {
1163
- shader: { id: materialShaderId, passKind: 'forward', variantSet: undefined },
1183
+ shader: {
1184
+ id: singleLayerMedium ? 'forgeax::single-layer-medium' : materialShaderId,
1185
+ passKind: 'forward',
1186
+ variantSet: undefined,
1187
+ },
1164
1188
  attachments: { colorFormats: [], depthFormat: undefined, sampleCount: 1 },
1165
1189
  geometry: { topology: 'triangle-list', vertexLayout: {} },
1166
1190
  renderState: undefined,
@@ -1339,22 +1363,14 @@ async function makeWebGPURenderer(
1339
1363
  tonemapRegistered = true;
1340
1364
  },
1341
1365
  (source: string) => {
1342
- if (fxaaRegistered) return;
1343
- renderSystem.registerBuiltinPostProcess(FXAA_POST_PROCESS_ID, {
1344
- source,
1345
- params: { byteSize: 16, defaultValue: new Uint8Array(16) },
1346
- reads: ['ldrColor'],
1347
- });
1348
- fxaaRegistered = true;
1366
+ fxaaRegistered = registerFxaaPostProcess(renderSystem, source, fxaaRegistered);
1349
1367
  },
1368
+ (source: string) =>
1369
+ registerAnalyticFogPostProcess(renderSystem, source, candidateBuildState !== undefined),
1350
1370
  (entries: { readonly motionBlur?: string; readonly taaResolve?: string }) => {
1351
1371
  if (candidateBuildState !== undefined || temporalPostProcessesRegistered) return;
1352
1372
  if (entries.motionBlur !== undefined) {
1353
- renderSystem.registerBuiltinPostProcess('forgeax.motion-blur', {
1354
- source: entries.motionBlur,
1355
- params: { byteSize: 16, defaultValue: new Uint8Array(16) },
1356
- reads: ['scene-color', 'scene-temporal'],
1357
- });
1373
+ registerMotionBlurPostProcess(renderSystem, entries.motionBlur);
1358
1374
  }
1359
1375
  if (entries.taaResolve !== undefined) {
1360
1376
  renderSystem.registerBuiltinPostProcess('forgeax.taa-resolve', {
@@ -1555,7 +1571,11 @@ async function makeWebGPURenderer(
1555
1571
  : getShaderModuleAdapter(),
1556
1572
  pipelineLayout,
1557
1573
  vertexBuffers,
1558
- ...(layoutKind === 'pbr-skin' || layoutKind === 'gpu-driven-skin' ? { layoutKind } : {}),
1574
+ ...(layoutKind === 'pbr-skin' ||
1575
+ layoutKind === 'gpu-driven-skin' ||
1576
+ layoutKind === 'gpu-driven-cluster-skin'
1577
+ ? { layoutKind }
1578
+ : {}),
1559
1579
  };
1560
1580
  };
1561
1581
  /**
@@ -1622,7 +1642,10 @@ async function makeWebGPURenderer(
1622
1642
  particleInputLanes?: number,
1623
1643
  coverageOnly = false,
1624
1644
  ): RenderPipeline | null => {
1625
- const declaredGroup2Contract = resolvePipelineGroup2Contract(entry.source);
1645
+ const declaredGroup2Contract = resolveMaterialPipelineGroup2Contract(
1646
+ entry.source,
1647
+ layoutKindOverride,
1648
+ );
1626
1649
  const group2Contract =
1627
1650
  declaredGroup2Contract === 'mesh' &&
1628
1651
  (materialShaderId === 'forgeax::vfx-render.particles.mesh' ||
@@ -2051,6 +2074,10 @@ async function makeWebGPURenderer(
2051
2074
  }
2052
2075
  }
2053
2076
  }
2077
+ shaderEntry = prepareLowLimitMaterialShaderEntry(
2078
+ shaderEntry,
2079
+ currentBuildDevice().limits.maxSampledTexturesPerShaderStage,
2080
+ );
2054
2081
  // feat-20260609 M4 / R3-fixup: append `-${passKind}` to the PSO label so
2055
2082
  // GPU debug captures (and the shadow-caster branch in the builder)
2056
2083
  // make the cache variant visible. The fallback path above keeps the
@@ -2118,10 +2145,50 @@ async function makeWebGPURenderer(
2118
2145
  ) => {
2119
2146
  const pipeline = getMaterialShaderPipeline(...args);
2120
2147
  if (pipeline === null) return null;
2148
+ const materialShaderId = args[0];
2149
+ const variantSet = args[5];
2150
+ const passKind = args[6] ?? 'forward';
2151
+ const vertexLayoutProjection = args[13];
2152
+ const layoutKind = args[15];
2153
+ const sceneIndexAddress =
2154
+ layoutKind === 'gpu-driven-pbr' ||
2155
+ layoutKind === 'gpu-driven-skin' ||
2156
+ layoutKind === 'gpu-driven-cluster-pbr' ||
2157
+ layoutKind === 'gpu-driven-cluster-skin';
2158
+ const artifact = resolveRendererMaterialShaderArtifact(
2159
+ materialShaderId,
2160
+ getShader(),
2161
+ pipelineState?.gpuDrivenPbrPrograms,
2162
+ {
2163
+ ...(vertexLayoutProjection === undefined
2164
+ ? {}
2165
+ : {
2166
+ vertexColorAvailable: vertexLayoutProjection.attributes.some(
2167
+ (attribute) => attribute.key === 'color',
2168
+ ),
2169
+ }),
2170
+ ...(layoutKind === 'pbr-skin' ||
2171
+ layoutKind === 'gpu-driven-skin' ||
2172
+ layoutKind === 'gpu-driven-cluster-skin'
2173
+ ? { deformation: 'skin' as const }
2174
+ : {}),
2175
+ ...(variantSet === undefined ? {} : { variantSet }),
2176
+ address: sceneIndexAddress ? 'scene-index' : 'direct',
2177
+ pass: passKind === 'shadow-caster' ? 'shadow' : 'forward',
2178
+ },
2179
+ );
2121
2180
  return {
2122
2181
  pipeline,
2123
2182
  group2Contract:
2124
2183
  materialShaderPipelineGroup2Contracts.get(pipeline as object) ?? ('mesh' as const),
2184
+ ...(artifact?.receipt === undefined
2185
+ ? {}
2186
+ : {
2187
+ receipt: {
2188
+ identity: artifact.receipt.receiptIdentity,
2189
+ generation: artifact.receipt.generation,
2190
+ },
2191
+ }),
2125
2192
  };
2126
2193
  };
2127
2194
  const getParamSchema = (materialShaderId: string) => {
@@ -2175,10 +2242,11 @@ async function makeWebGPURenderer(
2175
2242
  colorFormats: readonly GPUTextureFormat[],
2176
2243
  label: string,
2177
2244
  ): RenderPipeline | null => {
2245
+ const isFxaaPipeline = label.startsWith(`post-process-${FXAA_POST_PROCESS_ID}-pso-`);
2178
2246
  const moduleFactory = getShaderModuleAdapter();
2179
2247
  const moduleResult = moduleFactory.createShaderModule({
2180
2248
  code: entry.source,
2181
- label: `${label}-module`,
2249
+ label: postProcessShaderModuleLabel(entry.source),
2182
2250
  });
2183
2251
  if (!moduleResult.ok) {
2184
2252
  // 'rhi-not-available' = async compile in flight: caller falls back one frame.
@@ -2189,7 +2257,7 @@ async function makeWebGPURenderer(
2189
2257
  }
2190
2258
  return null;
2191
2259
  }
2192
- if (currentEmptyPostProcessBgl() === null) {
2260
+ if (!isFxaaPipeline && entry.usesView !== true && currentEmptyPostProcessBgl() === null) {
2193
2261
  const bglRes = currentBuildDevice().createBindGroupLayout({ entries: [] });
2194
2262
  if (!bglRes.ok) {
2195
2263
  internals.errorRegistry.fire(bglRes.error);
@@ -2202,9 +2270,18 @@ async function makeWebGPURenderer(
2202
2270
  emptyPostProcessBgl = bglRes.value;
2203
2271
  }
2204
2272
  }
2273
+ const viewLayout =
2274
+ entry.usesView === true ? currentPipelineState()?.viewBindGroupLayout : undefined;
2275
+ const group0Layout = viewLayout ?? currentEmptyPostProcessBgl();
2276
+ if (group0Layout === null || group0Layout === undefined) {
2277
+ internals.errorRegistry.fire(
2278
+ new Error('fullscreen post-process View layout is unavailable') as never,
2279
+ );
2280
+ return null;
2281
+ }
2205
2282
  const layoutRes = currentBuildDevice().createPipelineLayout({
2206
2283
  label: `${label}-layout`,
2207
- bindGroupLayouts: [currentEmptyPostProcessBgl() as BindGroupLayout, bgl],
2284
+ bindGroupLayouts: isFxaaPipeline ? [bgl] : [group0Layout as BindGroupLayout, bgl],
2208
2285
  });
2209
2286
  if (!layoutRes.ok) {
2210
2287
  internals.errorRegistry.fire(layoutRes.error);
@@ -2442,6 +2519,22 @@ async function makeWebGPURenderer(
2442
2519
  });
2443
2520
  attachGpuPassTimingSession(internals, gpuPassTimingSession);
2444
2521
  renderSystemForTargetPromotion = renderSystem;
2522
+ renderSystem.registerBuiltinPostProcess(SINGLE_LAYER_MEDIUM_RAW_DEPTH_POST_PROCESS_ID, {
2523
+ source: SINGLE_LAYER_MEDIUM_RAW_DEPTH_WGSL,
2524
+ reads: ['input', { key: 'scene-depth', sampleType: 'depth' }],
2525
+ });
2526
+ const pairedMsaaReads = [
2527
+ { key: 'input', sampleType: 'multisampled-float' as const },
2528
+ { key: 'scene-depth', sampleType: 'depth' as const },
2529
+ ];
2530
+ renderSystem.registerBuiltinPostProcess(SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_POST_PROCESS_ID, {
2531
+ source: SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_WGSL,
2532
+ reads: pairedMsaaReads,
2533
+ });
2534
+ renderSystem.registerBuiltinPostProcess(SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_POST_PROCESS_ID, {
2535
+ source: SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_WGSL,
2536
+ reads: pairedMsaaReads,
2537
+ });
2445
2538
  if (
2446
2539
  internals.device.caps.backendKind === 'null' &&
2447
2540
  Array.from(getShader().entries()).length === 0
@@ -2478,183 +2571,33 @@ async function makeWebGPURenderer(
2478
2571
  const receiptTimings = new WeakMap<FrameReceipt, Promise<VolumeTimingObservation>>();
2479
2572
  let latestReceipt: FrameReceipt | undefined;
2480
2573
  let pendingObservationDomains: readonly FrameObservationDomain[] | undefined;
2481
- let observationAllocationCount = 0;
2482
- let observationLiveCount = 0;
2483
- let observationPeakLiveCount = 0;
2484
- let observationMapCount = 0;
2485
- let observationReadbackCount = 0;
2486
- let observationLiveByteLength = 0;
2487
- const observationCaptureOwner = (() => {
2488
- const capturesByFrame = new Map<number, TypedFrameObservationCapture[]>();
2489
- return {
2490
- register(capture: TypedFrameObservationCapture): void {
2491
- const captures = capturesByFrame.get(capture.frameNumber) ?? [];
2492
- captures.push(capture);
2493
- capturesByFrame.set(capture.frameNumber, captures);
2494
- observationAllocationCount += 1;
2495
- observationLiveCount += 1;
2496
- observationPeakLiveCount = Math.max(observationPeakLiveCount, observationLiveCount);
2497
- observationLiveByteLength += capture.bytesPerRow * capture.height;
2498
- },
2499
- consume(frameNumber: number): readonly TypedFrameObservationCapture[] {
2500
- const captures = capturesByFrame.get(frameNumber) ?? [];
2501
- capturesByFrame.delete(frameNumber);
2502
- return Object.freeze(captures);
2503
- },
2504
- drain(): readonly TypedFrameObservationCapture[] {
2505
- const captures = [...capturesByFrame.values()].flat();
2506
- capturesByFrame.clear();
2507
- return Object.freeze(captures);
2508
- },
2509
- };
2510
- })();
2574
+ const observationOwner = createRendererObservationCaptureOwner((error) => {
2575
+ internals.errorRegistry.fire(error);
2576
+ });
2577
+ const {
2578
+ observationCaptureOwner,
2579
+ stats: observationStats,
2580
+ receiptObservationCaptures,
2581
+ receiptObservationBuffers,
2582
+ destroyedObservationBuffers,
2583
+ disposeObservationCaptures,
2584
+ disposeOwnedObservationCaptures,
2585
+ readObservationCapture,
2586
+ disposeReceiptObservationCaptures,
2587
+ } = observationOwner;
2511
2588
  Object.assign(internals, { observationCaptureOwner });
2512
- let expectedObservationGraphGeneration: number | undefined;
2513
2589
  Object.defineProperty(internals, 'observationGraphGeneration', {
2514
2590
  configurable: true,
2515
- get: () => expectedObservationGraphGeneration,
2591
+ get: () => observationOwner.expectedGraphGeneration,
2516
2592
  set: (generation: number | undefined) => {
2517
- expectedObservationGraphGeneration = generation;
2593
+ observationOwner.expectedGraphGeneration = generation;
2518
2594
  },
2519
2595
  });
2520
- type ObservationCaptureRead = () => Promise<
2521
- RenderResult<
2522
- readonly {
2523
- readonly capture: TypedFrameObservationCapture;
2524
- readonly bytes: Uint8Array;
2525
- }[],
2526
- RenderError
2527
- >
2528
- >;
2529
- const receiptObservationCaptures = new Map<FrameReceipt, ObservationCaptureRead>();
2530
- const receiptObservationBuffers = new Map<
2531
- FrameReceipt,
2532
- readonly TypedFrameObservationCapture[]
2533
- >();
2534
- const destroyedObservationBuffers = new WeakSet<Buffer>();
2535
- const observationBufferCleanupFailures = new WeakMap<Buffer, RendererContractFailureError>();
2536
- const failedObservationCaptures = new Map<Buffer, TypedFrameObservationCapture>();
2537
- const disposeObservationCaptures = (
2538
- captures: readonly TypedFrameObservationCapture[],
2539
- ): RendererContractFailureError | undefined => {
2540
- const wasDestroyed = new Set(
2541
- captures
2542
- .filter((capture) => destroyedObservationBuffers.has(capture.buffer))
2543
- .map((capture) => capture.buffer),
2544
- );
2545
- const result = disposeObservationCaptureSet(
2546
- captures,
2547
- destroyedObservationBuffers,
2548
- observationBufferCleanupFailures,
2549
- (failure) => internals.errorRegistry.fire(failure),
2550
- );
2551
- for (const capture of captures) {
2552
- if (!wasDestroyed.has(capture.buffer) && destroyedObservationBuffers.has(capture.buffer)) {
2553
- observationLiveCount = Math.max(0, observationLiveCount - 1);
2554
- observationLiveByteLength = Math.max(
2555
- 0,
2556
- observationLiveByteLength - capture.bytesPerRow * capture.height,
2557
- );
2558
- }
2559
- }
2560
- return result;
2561
- };
2562
- const disposeOwnedObservationCaptures = (
2563
- captures: readonly TypedFrameObservationCapture[],
2564
- ): RendererContractFailureError | undefined => {
2565
- const failure = disposeObservationCaptures(captures);
2566
- if (failure !== undefined) {
2567
- for (const capture of captures) {
2568
- if (!destroyedObservationBuffers.has(capture.buffer)) {
2569
- failedObservationCaptures.set(capture.buffer, capture);
2570
- }
2571
- }
2572
- }
2573
- return failure;
2574
- };
2575
- const readObservationCapture = async (
2576
- capture: TypedFrameObservationCapture,
2577
- ): Promise<RenderResult<Uint8Array, RenderError>> => {
2578
- try {
2579
- if (typeof capture.buffer.mapAsync !== 'function') {
2580
- const cleanupFailure = disposeObservationCaptures([capture]);
2581
- return err(
2582
- cleanupFailure ??
2583
- new RendererContractFailureError(
2584
- 'observe',
2585
- `the ${capture.domain} receipt-bound readback backend has no mapAsync capability`,
2586
- ),
2587
- );
2588
- }
2589
- observationMapCount += 1;
2590
- const mapped = await capture.buffer.mapAsync(1);
2591
- if (!mapped.ok) {
2592
- const cleanupFailure = disposeObservationCaptures([capture]);
2593
- return err(
2594
- cleanupFailure ??
2595
- new RendererContractFailureError(
2596
- 'observe',
2597
- `mapping ${capture.domain} receipt-bound readback failed: ${mapped.error.code}`,
2598
- ),
2599
- );
2600
- }
2601
- const range = mapped.value.getMappedRange();
2602
- if (!range.ok) {
2603
- mapped.value.unmap();
2604
- const cleanupFailure = disposeObservationCaptures([capture]);
2605
- return err(
2606
- cleanupFailure ??
2607
- new RendererContractFailureError(
2608
- 'observe',
2609
- `reading ${capture.domain} receipt-bound readback failed: ${range.error.code}`,
2610
- ),
2611
- );
2612
- }
2613
- const bytes = new Uint8Array(range.value.slice(0));
2614
- mapped.value.unmap();
2615
- observationReadbackCount += 1;
2616
- const cleanupFailure = disposeObservationCaptures([capture]);
2617
- if (cleanupFailure !== undefined) return err(cleanupFailure);
2618
- return ok(bytes);
2619
- } catch (cause) {
2620
- const cleanupFailure = disposeObservationCaptures([capture]);
2621
- return err(
2622
- cleanupFailure ??
2623
- new RendererContractFailureError(
2624
- 'observe',
2625
- `reading ${capture.domain} receipt-bound readback threw: ${
2626
- cause instanceof Error ? cause.message : String(cause)
2627
- }`,
2628
- ),
2629
- );
2630
- }
2631
- };
2632
-
2633
- const disposeReceiptObservationCaptures = (): RendererContractFailureError | undefined => {
2634
- let firstFailure: RendererContractFailureError | undefined;
2635
- for (const [receipt, captures] of receiptObservationBuffers) {
2636
- const failure = disposeObservationCaptures(captures);
2637
- firstFailure ??= failure;
2638
- if (captures.every((capture) => destroyedObservationBuffers.has(capture.buffer))) {
2639
- receiptObservationBuffers.delete(receipt);
2640
- }
2641
- }
2642
- receiptObservationCaptures.clear();
2643
- const retryCaptures = [...failedObservationCaptures.values()];
2644
- const retryFailure = disposeObservationCaptures(retryCaptures);
2645
- firstFailure ??= retryFailure;
2646
- for (const capture of retryCaptures) {
2647
- if (destroyedObservationBuffers.has(capture.buffer)) {
2648
- failedObservationCaptures.delete(capture.buffer);
2649
- }
2650
- }
2651
- const ownedFailure = disposeOwnedObservationCaptures(observationCaptureOwner.drain());
2652
- firstFailure ??= ownedFailure;
2653
- return firstFailure;
2654
- };
2655
2596
  let surfaceReleased = false;
2656
2597
  const renderer: RendererAssemblyImplementation = {
2657
- instances: renderSystem.instances,
2598
+ setSurfaceDynamicInput(frame) {
2599
+ renderSystem.setSurfaceDynamicInput(frame);
2600
+ },
2658
2601
  attach(world: World): RenderResult<RenderWorldLease, RenderError> {
2659
2602
  const attached = this.attachScene(world);
2660
2603
  if (!attached.ok) {
@@ -2717,40 +2660,29 @@ async function makeWebGPURenderer(
2717
2660
  ? 'faulted'
2718
2661
  : 'alive';
2719
2662
  const graph = deviceLost ? undefined : renderSystem.perFrameGraphInfo;
2663
+ const graphResourceAllocation = graph?.resourceAllocation;
2664
+ const graphGenerationAllocation = deviceLost
2665
+ ? undefined
2666
+ : renderSystem.renderGraphGenerationAllocation;
2720
2667
  const standardLighting = deviceLost ? undefined : renderSystem.standardLightingInspection;
2721
- const bloom: BloomInspection = deviceLost
2722
- ? {
2723
- graphStatus: 'empty',
2724
- enabled: false,
2725
- targetCount: 0,
2726
- targetBytes: 0,
2727
- resourceCount: 0,
2728
- passCount: 0,
2729
- encodeCount: 0,
2730
- bindGroupCount: 0,
2731
- uploadCount: 0,
2732
- residentChildBytes: 0,
2733
- generation: 0,
2734
- state: 'off',
2735
- }
2736
- : renderSystem.bloom;
2737
- const surfaceStorage = pipelineState?.format ?? 'rgba8unorm';
2738
- const surfaceDisplay = pipelineState?.colorAttachmentFormat ?? 'rgba8unorm';
2668
+ const barrelDistortion = inspectBarrelDistortion(
2669
+ disposed,
2670
+ deviceLost,
2671
+ surfaceReleased,
2672
+ frameId,
2673
+ activeDeviceScope.generation,
2674
+ renderSystem.barrelDistortionInspection,
2675
+ );
2676
+ const bloom: BloomInspection = deviceLost ? emptyBloomInspection() : renderSystem.bloom;
2739
2677
  const observationId = `${STANDARD_OUTPUT_TRANSFORM_FEATURE_ID}:frame-${frameId}`;
2740
- const outputInspection = projectRendererOutputInspection({
2678
+ const outputInspection = projectRendererOutputInspectionFromSurface({
2741
2679
  graph,
2742
- surfaceAvailable: !surfaceReleased && pipelineState !== null,
2743
- surfaceStorage,
2744
- surfaceDisplay,
2745
- ...(pipelineState?.surfaceProfile === undefined
2746
- ? {}
2747
- : { surfaceProfile: pipelineState.surfaceProfile }),
2680
+ surfaceReleased,
2681
+ pipelineState,
2748
2682
  rgba16floatRenderable: internals.device.caps.rgba16floatRenderable,
2749
2683
  autoExposure: renderSystem.autoExposure,
2750
2684
  standardLut: renderSystem.standardLut,
2751
- ...(internals.context?.presentationProof === undefined
2752
- ? {}
2753
- : { presentationProof: internals.context.presentationProof }),
2685
+ presentationProof: internals.context?.presentationProof,
2754
2686
  });
2755
2687
  const volumetricFog = renderSystem.volumetricFog;
2756
2688
  const directionalShadow = renderSystem.directionalShadow;
@@ -2765,6 +2697,7 @@ async function makeWebGPURenderer(
2765
2697
  frameId,
2766
2698
  deviceGeneration: activeDeviceScope.generation,
2767
2699
  }),
2700
+ barrelDistortion,
2768
2701
  ...projectRendererFeatureInspection(internals.featureHost),
2769
2702
  featureGraph: renderSystem.featureGraphInspection,
2770
2703
  materialTextureSources: renderSystem.materialTextureSources,
@@ -2774,9 +2707,6 @@ async function makeWebGPURenderer(
2774
2707
  renderSystem.instanceCollectionsInspection.map((collection) =>
2775
2708
  Object.freeze({
2776
2709
  ...collection,
2777
- dirtyRanges: Object.freeze(
2778
- collection.dirtyRanges.map((range) => Object.freeze({ ...range })),
2779
- ),
2780
2710
  uploadRanges: Object.freeze(
2781
2711
  collection.uploadRanges.map((range) => Object.freeze({ ...range })),
2782
2712
  ),
@@ -2793,6 +2723,12 @@ async function makeWebGPURenderer(
2793
2723
  ),
2794
2724
  dynamicGeometry: dynamicGeometry.inspect(),
2795
2725
  renderScene: renderSystem.renderScene,
2726
+ ...(graphResourceAllocation === undefined
2727
+ ? {}
2728
+ : { renderGraphResourceAllocation: graphResourceAllocation }),
2729
+ ...(graphGenerationAllocation === undefined
2730
+ ? {}
2731
+ : { renderGraphGenerationAllocation: graphGenerationAllocation }),
2796
2732
  ...(renderSystem.iblBinding === undefined ? {} : { iblBinding: renderSystem.iblBinding }),
2797
2733
  reflectionProbes: renderSystem.reflectionProbes,
2798
2734
  ssrDependencies: renderSystem.ssrDependencies,
@@ -2873,12 +2809,12 @@ async function makeWebGPURenderer(
2873
2809
  ? {}
2874
2810
  : { standardOutputColor: Object.freeze({ ...outputInspection.standardOutputColor }) }),
2875
2811
  resourceStats: Object.freeze({
2876
- allocationCount: observationAllocationCount,
2877
- liveCount: observationLiveCount,
2878
- peakLiveCount: observationPeakLiveCount,
2879
- mapCount: observationMapCount,
2880
- readbackCount: observationReadbackCount,
2881
- liveByteLength: observationLiveByteLength,
2812
+ allocationCount: observationStats.allocationCount,
2813
+ liveCount: observationStats.liveCount,
2814
+ peakLiveCount: observationStats.peakLiveCount,
2815
+ mapCount: observationStats.mapCount,
2816
+ readbackCount: observationStats.readbackCount,
2817
+ liveByteLength: observationStats.liveByteLength,
2882
2818
  }),
2883
2819
  }),
2884
2820
  });
@@ -3226,9 +3162,13 @@ async function makeWebGPURenderer(
3226
3162
  ...(frameRequest.camera.entityKey === undefined
3227
3163
  ? {}
3228
3164
  : { cameraEntityKey: frameRequest.camera.entityKey }),
3165
+ ...motionBlurDrawOptions(frameRequest),
3229
3166
  ...(frameRequest.profileFrame === undefined
3230
3167
  ? {}
3231
3168
  : { profileFrame: frameRequest.profileFrame }),
3169
+ ...(frameRequest.geometryLane === undefined
3170
+ ? {}
3171
+ : { geometryLane: frameRequest.geometryLane }),
3232
3172
  }
3233
3173
  : (options ?? { cameraOwner: 0, resourceOwner: 0 });
3234
3174
  // feat-20260612-rhi-destroy-renderer-dispose-gpu-lifecycle / M5 / w21
@@ -3256,6 +3196,8 @@ async function makeWebGPURenderer(
3256
3196
  }),
3257
3197
  );
3258
3198
  }
3199
+ const canvasSizeError = rejectZeroCanvasSize(internals.canvas.width, internals.canvas.height);
3200
+ if (canvasSizeError !== undefined) return err(canvasSizeError);
3259
3201
  // M2 / w9 (A-IN-5): device-lost guard — draw() silently returns err
3260
3202
  // without firing onError each frame. The device-lost channel fires once
3261
3203
  // through the dual-channel fan-out (:750-797); draw() does not repeat it
@@ -3377,6 +3319,8 @@ async function makeWebGPURenderer(
3377
3319
  const cleanupFailure = disposeOwnedObservationCaptures(observationCaptureOwner.drain());
3378
3320
  volumeTimingCapture?.discard();
3379
3321
  if (cleanupFailure !== undefined) return err(cleanupFailure);
3322
+ const invalidMotionBlur = renderSystem.motionBlurInvalidParams;
3323
+ if (invalidMotionBlur !== undefined) return err(invalidMotionBlur);
3380
3324
  return err(
3381
3325
  new RendererContractFailureError(
3382
3326
  'draw',
@@ -3415,34 +3359,30 @@ async function makeWebGPURenderer(
3415
3359
  );
3416
3360
  const continuation = createContinuationTerminator();
3417
3361
  frameContinuations.add(continuation);
3418
- const guardedCompletion = completion.then(
3362
+ const guardedCompletion = guardFrameCompletion(
3363
+ completion,
3364
+ () => continuation.guard('queue-completion'),
3419
3365
  () =>
3420
- continuation.guard('queue-completion')
3421
- ? ok(undefined)
3422
- : err(
3423
- new RendererOperationError('device-operation-failed', {
3424
- operation: 'complete-frame',
3425
- frameId: receiptFrameId,
3426
- deviceGeneration: receiptGeneration,
3427
- cause: structuredRendererCause(
3428
- {
3429
- code: 'stale-generation',
3430
- expected: 'frame completion belongs to its device generation',
3431
- hint: 'discard the stale receipt',
3432
- },
3433
- 'complete-frame',
3434
- ),
3435
- }),
3436
- ),
3366
+ new RendererOperationError('device-operation-failed', {
3367
+ operation: 'complete-frame',
3368
+ frameId: receiptFrameId,
3369
+ deviceGeneration: receiptGeneration,
3370
+ cause: structuredRendererCause(
3371
+ {
3372
+ code: 'stale-generation',
3373
+ expected: 'frame completion belongs to its device generation',
3374
+ hint: 'discard the stale receipt',
3375
+ },
3376
+ 'complete-frame',
3377
+ ),
3378
+ }),
3437
3379
  (cause: unknown) =>
3438
- err(
3439
- new RendererOperationError('device-operation-failed', {
3440
- operation: 'complete-frame',
3441
- frameId: receiptFrameId,
3442
- deviceGeneration: receiptGeneration,
3443
- cause: structuredRendererCause(cause, 'complete-frame'),
3444
- }),
3445
- ),
3380
+ new RendererOperationError('device-operation-failed', {
3381
+ operation: 'complete-frame',
3382
+ frameId: receiptFrameId,
3383
+ deviceGeneration: receiptGeneration,
3384
+ cause: structuredRendererCause(cause, 'complete-frame'),
3385
+ }),
3446
3386
  );
3447
3387
  const terminated = continuation.promise().then((reason) =>
3448
3388
  err(
@@ -3470,12 +3410,17 @@ async function makeWebGPURenderer(
3470
3410
  });
3471
3411
  const captures = observationCaptureOwner.consume(receiptFrameId);
3472
3412
  pendingObservationDomains = undefined;
3473
- const receiptGraphGeneration = timingHost.observationGraphGeneration ?? 0;
3413
+ const receiptGraphGeneration =
3414
+ timingHost.observationGraphGeneration ?? renderSystem.perFrameGraphInfo?.generation ?? 0;
3474
3415
  const receipt = Object.freeze({
3475
3416
  frameId: receiptFrameId,
3476
3417
  deviceGeneration: receiptGeneration,
3418
+ presentation: renderSystem.presentation,
3477
3419
  backendId: internals.device.caps.backendKind,
3478
3420
  graphGeneration: receiptGraphGeneration,
3421
+ ...(renderSystem.lastSuccessfulBarrelDistortion === undefined
3422
+ ? {}
3423
+ : { barrelDistortion: renderSystem.lastSuccessfulBarrelDistortion }),
3479
3424
  completed,
3480
3425
  });
3481
3426
  renderTargetHost.onFrameSubmitted(completed);
@@ -3715,7 +3660,7 @@ async function makeWebGPURenderer(
3715
3660
  receiptObservationBuffers.delete(receipt);
3716
3661
  }
3717
3662
  }
3718
- await renderSystem.observeLodOcclusion();
3663
+ await observeLodOcclusionForReceipt(renderSystem, receipt);
3719
3664
  const targetReadbacks =
3720
3665
  request.targetReadbacks === undefined || request.targetReadbacks.length === 0
3721
3666
  ? undefined
@@ -4070,6 +4015,8 @@ async function makeWebGPURenderer(
4070
4015
  setCandidateEmptyPostProcessBgl(layout) {
4071
4016
  candidateEmptyPostProcessBgl = layout;
4072
4017
  },
4018
+ getShaderModuleAdapter,
4019
+ getImmediateShaderModuleAdapter,
4073
4020
  getShader,
4074
4021
  assets,
4075
4022
  adaptMipmapShaderModuleFactory,