@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
@@ -0,0 +1,91 @@
1
+ import { getRenderFeaturePlanExecutionProjection } from '../features/host';
2
+ import type { RenderFeaturePlannedFrame } from '../features/plan';
3
+ import type { MotionBlurExecutionPass, MotionBlurExecutionReceipt } from '../inspection-types';
4
+ import type { RenderFrameState } from './frame-snapshot';
5
+ import type { RenderSystemInternals } from './render-context';
6
+
7
+ /**
8
+ * Project one accepted Motion Blur compute execution from the same graph and
9
+ * resolved dispatch objects used by the encoder. A plan/capability candidate
10
+ * without both executed passes deliberately returns no receipt.
11
+ */
12
+ export function deriveMotionBlurExecutionReceipt(
13
+ internals: RenderSystemInternals,
14
+ frameState: RenderFrameState,
15
+ plans: readonly RenderFeaturePlannedFrame[],
16
+ ): MotionBlurExecutionReceipt | undefined {
17
+ const graph = frameState.compiledFrameGraph;
18
+ const deviceGeneration = internals.deviceScope?.generation;
19
+ if (graph === null || deviceGeneration === undefined) return undefined;
20
+ const info = graph.inspect();
21
+ const graphPasses = new Map(info.passes.map((pass) => [pass.name, pass]));
22
+ const summaryGraphPass = graphPasses.get('motion-blur-tile-summary');
23
+ const reconstructGraphPass = graphPasses.get('motion-blur');
24
+ if (summaryGraphPass?.kind !== 'compute' || reconstructGraphPass?.kind !== 'compute') {
25
+ return undefined;
26
+ }
27
+ const planned = plans.find((candidate) => candidate.featureIdentity === 'forgeax.motion-blur');
28
+ const execution =
29
+ planned === undefined ? undefined : getRenderFeaturePlanExecutionProjection(planned);
30
+ if (execution === undefined || execution.featureIdentity !== 'forgeax.motion-blur') {
31
+ return undefined;
32
+ }
33
+ const executionPass = (name: 'motion-blur-tile-summary' | 'motion-blur') =>
34
+ execution.passes.find((pass) => pass.name === name);
35
+ const summary = executionPass('motion-blur-tile-summary');
36
+ const reconstruct = executionPass('motion-blur');
37
+ if (
38
+ summary?.gpuCompute === undefined ||
39
+ reconstruct?.gpuCompute === undefined ||
40
+ summary.resolvedGpuCompute === undefined ||
41
+ reconstruct.resolvedGpuCompute === undefined
42
+ ) {
43
+ return undefined;
44
+ }
45
+ const directWorkgroups = (
46
+ pass: NonNullable<typeof summary.resolvedGpuCompute>,
47
+ ): readonly [number, number, number] | undefined => {
48
+ const dispatch = pass.dispatches[0];
49
+ if (dispatch === undefined || !('workgroups' in dispatch)) return undefined;
50
+ return dispatch.workgroups;
51
+ };
52
+ const summaryWorkgroups = directWorkgroups(summary.resolvedGpuCompute);
53
+ const reconstructWorkgroups = directWorkgroups(reconstruct.resolvedGpuCompute);
54
+ if (summaryWorkgroups === undefined || reconstructWorkgroups === undefined) return undefined;
55
+ const outputResource = info.resources.find(
56
+ (resource) =>
57
+ resource.label === 'motion-blurred-color' ||
58
+ reconstructGraphPass.accesses.some(
59
+ (access) => access.resource === resource.label && access.usage === 'storage-write',
60
+ ),
61
+ );
62
+ if (
63
+ outputResource?.descriptor.kind !== 'texture' ||
64
+ outputResource.descriptor.format !== 'rgba16float'
65
+ ) {
66
+ return undefined;
67
+ }
68
+ const summaryReceipt: MotionBlurExecutionPass = {
69
+ name: 'motion-blur-tile-summary',
70
+ kind: 'compute',
71
+ entryPoint: 'tile_summary',
72
+ workgroups: summaryWorkgroups,
73
+ };
74
+ const reconstructReceipt: MotionBlurExecutionPass = {
75
+ name: 'motion-blur',
76
+ kind: 'compute',
77
+ entryPoint: 'reconstruct',
78
+ workgroups: reconstructWorkgroups,
79
+ };
80
+ return Object.freeze({
81
+ frameId: frameState.frameNumber,
82
+ deviceGeneration,
83
+ // RenderGraphBuilder generations are process-global. The renderer's
84
+ // frame-state generation is the identity used by inspection and by the
85
+ // same-frame admission check below, so retain that owner-scoped value.
86
+ graphGeneration: frameState.graphGeneration,
87
+ program: 'motion-blur-compute' as const,
88
+ outputFormat: 'rgba16float' as const,
89
+ passes: [summaryReceipt, reconstructReceipt] as const,
90
+ });
91
+ }
@@ -0,0 +1,180 @@
1
+ import type { Buffer, RhiDevice } from '@forgeax/engine-rhi';
2
+ import { GpuBuffer } from '../gpu-resource';
3
+ import {
4
+ GPU_BUFFER_USAGE_COPY_DST,
5
+ GPU_BUFFER_USAGE_STORAGE,
6
+ GPU_BUFFER_USAGE_UNIFORM,
7
+ } from '../gpu-usage';
8
+ import type { ProbeBlendBufferProjection } from '../scene/probe-blend';
9
+ import {
10
+ PROBE_BLEND_RECORD_STRIDE,
11
+ type ProbeBlendRecord,
12
+ probeBlendRecordOffset,
13
+ } from '../scene/probe-blend-record';
14
+ import type { RenderFrameState } from './frame-snapshot';
15
+
16
+ export interface ProbeBlendBufferRecord {
17
+ readonly cacheKey: number;
18
+ readonly record: ProbeBlendRecord;
19
+ }
20
+
21
+ function isProbeBlendProjection(
22
+ input: ProbeBlendBufferProjection | readonly ProbeBlendBufferRecord[],
23
+ ): input is ProbeBlendBufferProjection {
24
+ return !Array.isArray(input);
25
+ }
26
+
27
+ function retireProbeBlendRecordBuffer(buffer: GpuBuffer): void {
28
+ const destroy = (): void => {
29
+ if (!buffer.isDestroyed) void buffer.destroy();
30
+ };
31
+ void buffer.device.queue.onSubmittedWorkDone().then(destroy, destroy);
32
+ }
33
+
34
+ function createCompleteProbeBlendBuffer(
35
+ device: RhiDevice,
36
+ requiredCapacity: number,
37
+ records: readonly ProbeBlendBufferRecord[],
38
+ ): {
39
+ readonly buffer: GpuBuffer;
40
+ readonly cache: ReadonlyMap<number, { readonly generation: number; readonly bytes: Uint8Array }>;
41
+ } {
42
+ const created = device.createBuffer({
43
+ label: 'probe-blend-records',
44
+ size: requiredCapacity * PROBE_BLEND_RECORD_STRIDE,
45
+ usage:
46
+ (device.caps.storageBuffer ? GPU_BUFFER_USAGE_STORAGE : GPU_BUFFER_USAGE_UNIFORM) |
47
+ GPU_BUFFER_USAGE_COPY_DST,
48
+ mappedAtCreation: false,
49
+ });
50
+ if (!created.ok) throw created.error;
51
+ const candidate = new GpuBuffer(device, created.value);
52
+ const cache = new Map<number, { readonly generation: number; readonly bytes: Uint8Array }>();
53
+ try {
54
+ for (const { cacheKey, record } of records) {
55
+ const uploaded = device.queue.writeBuffer(
56
+ candidate.handle,
57
+ probeBlendRecordOffset(record.objectKey),
58
+ record.bytes,
59
+ );
60
+ if (!uploaded.ok) throw uploaded.error;
61
+ cache.set(cacheKey, {
62
+ generation: record.generation,
63
+ bytes: new Uint8Array(record.bytes),
64
+ });
65
+ }
66
+ } catch (cause) {
67
+ void candidate.destroy();
68
+ throw cause;
69
+ }
70
+ return { buffer: candidate, cache };
71
+ }
72
+
73
+ /**
74
+ * Retain one device buffer for direct and scene-index ProbeBlend consumers.
75
+ * Capacity is settled before any upload so a growth cannot erase records
76
+ * written earlier in the same frame. Slot zero remains the producer sentinel;
77
+ * RenderScene object slot N occupies aligned record N+1.
78
+ */
79
+ export function ensureProbeBlendRecordBuffer(
80
+ device: RhiDevice,
81
+ frameState: Pick<
82
+ RenderFrameState,
83
+ | 'probeBlendRecordBuffer'
84
+ | 'probeBlendRecordBufferCapacity'
85
+ | 'probeBlendBuffers'
86
+ | 'probeBlendRecordProjection'
87
+ >,
88
+ input: ProbeBlendBufferProjection | readonly ProbeBlendBufferRecord[] | undefined,
89
+ ): Buffer | undefined {
90
+ const projection = input !== undefined && isProbeBlendProjection(input) ? input : undefined;
91
+ const records: readonly ProbeBlendBufferRecord[] =
92
+ input === undefined
93
+ ? []
94
+ : (projection?.records ?? (input as readonly ProbeBlendBufferRecord[]));
95
+ let buffer = frameState.probeBlendRecordBuffer;
96
+ const accepted = frameState.probeBlendRecordProjection;
97
+ if (
98
+ projection !== undefined &&
99
+ accepted?.projection === projection &&
100
+ accepted.device === device
101
+ ) {
102
+ if (records.length === 0) return undefined;
103
+ if (accepted.buffer === buffer && buffer !== undefined && !buffer.isDestroyed) {
104
+ return buffer.handle;
105
+ }
106
+ }
107
+ if (records.length === 0) {
108
+ if (projection !== undefined) {
109
+ frameState.probeBlendBuffers.clear();
110
+ frameState.probeBlendRecordProjection = {
111
+ projection,
112
+ device,
113
+ buffer: undefined,
114
+ };
115
+ }
116
+ return undefined;
117
+ }
118
+ const requiredCapacity =
119
+ projection?.capacity ??
120
+ records.reduce((capacity, { record }) => Math.max(capacity, record.objectKey + 2), 1);
121
+ const grows =
122
+ buffer === undefined ||
123
+ buffer.isDestroyed ||
124
+ buffer.device !== device ||
125
+ frameState.probeBlendRecordBufferCapacity < requiredCapacity;
126
+ const hasAcceptedBaseline =
127
+ projection !== undefined &&
128
+ accepted !== undefined &&
129
+ accepted.device === device &&
130
+ accepted.buffer === buffer &&
131
+ buffer !== undefined &&
132
+ !buffer.isDestroyed &&
133
+ accepted.projection.sourceIdentity === projection.sourceIdentity &&
134
+ accepted.projection.revision === projection.baseRevision;
135
+ const requiresCompletePublish =
136
+ grows ||
137
+ (projection !== undefined && (!hasAcceptedBaseline || projection.dirtyRecords.length > 1));
138
+ if (requiresCompletePublish) {
139
+ const candidate = createCompleteProbeBlendBuffer(device, requiredCapacity, records);
140
+ const previous = buffer;
141
+ buffer = candidate.buffer;
142
+ frameState.probeBlendRecordBuffer = candidate.buffer;
143
+ frameState.probeBlendRecordBufferCapacity = requiredCapacity;
144
+ frameState.probeBlendBuffers.clear();
145
+ for (const [key, value] of candidate.cache) frameState.probeBlendBuffers.set(key, value);
146
+ if (projection === undefined) delete frameState.probeBlendRecordProjection;
147
+ else frameState.probeBlendRecordProjection = { projection, device, buffer: candidate.buffer };
148
+ if (previous !== undefined) retireProbeBlendRecordBuffer(previous);
149
+ return candidate.buffer.handle;
150
+ }
151
+ if (buffer === undefined) return undefined;
152
+ const changed = projection?.dirtyRecords ?? records;
153
+ const cacheUpdates: [number, { readonly generation: number; readonly bytes: Uint8Array }][] = [];
154
+ for (const { cacheKey, record } of changed) {
155
+ const cached = frameState.probeBlendBuffers.get(cacheKey);
156
+ const unchanged =
157
+ cached !== undefined &&
158
+ cached.generation === record.generation &&
159
+ cached.bytes.length === record.bytes.length &&
160
+ cached.bytes.every((value, index) => value === record.bytes[index]);
161
+ if (unchanged) continue;
162
+ const uploaded = device.queue.writeBuffer(
163
+ buffer.handle,
164
+ probeBlendRecordOffset(record.objectKey),
165
+ record.bytes,
166
+ );
167
+ if (!uploaded.ok) throw uploaded.error;
168
+ cacheUpdates.push([
169
+ cacheKey,
170
+ { generation: record.generation, bytes: new Uint8Array(record.bytes) },
171
+ ]);
172
+ }
173
+ for (const [cacheKey, value] of cacheUpdates) frameState.probeBlendBuffers.set(cacheKey, value);
174
+ for (const cacheKey of projection?.removedCacheKeys ?? []) {
175
+ frameState.probeBlendBuffers.delete(cacheKey);
176
+ }
177
+ if (projection === undefined) delete frameState.probeBlendRecordProjection;
178
+ else frameState.probeBlendRecordProjection = { projection, device, buffer };
179
+ return buffer.handle;
180
+ }
@@ -173,7 +173,11 @@ function addRequest(input: {
173
173
  readonly vertexLayoutProjection?: VertexLayoutProjection;
174
174
  readonly vertexEntry?: string;
175
175
  readonly fragmentEntry?: string;
176
- readonly layoutKindOverride?: 'pbr' | 'pbr-skin';
176
+ readonly layoutKindOverride?:
177
+ | 'pbr'
178
+ | 'pbr-skin'
179
+ | 'surface-direct-pbr'
180
+ | 'surface-direct-cluster-pbr';
177
181
  readonly preserveUndefinedVariant?: boolean;
178
182
  readonly variantAlreadyResolved?: boolean;
179
183
  }): void {
@@ -244,7 +248,7 @@ function addRequest(input: {
244
248
  undefined,
245
249
  undefined,
246
250
  projection,
247
- undefined,
251
+ 'immediate',
248
252
  input.layoutKindOverride,
249
253
  undefined,
250
254
  input.additionalColorFormats,
@@ -260,6 +264,7 @@ function addStandardMaterialRequests(input: {
260
264
  readonly internals: RenderSystemInternals;
261
265
  readonly pipelineState: PipelineState;
262
266
  readonly validated: readonly ValidatedRenderable[];
267
+ readonly dispatch: readonly DispatchEntry[];
263
268
  readonly standardLighting: StandardTopologyInputValue | undefined;
264
269
  readonly sampleCount: number;
265
270
  readonly isHdrTarget: boolean;
@@ -267,6 +272,13 @@ function addStandardMaterialRequests(input: {
267
272
  readonly reflectionFallbackAvailable: boolean;
268
273
  }): void {
269
274
  const pointsLinesProjection = deriveVertexLayoutProjection(DEFAULT_VERTEX_ATTRIBUTE_MAP);
275
+ const forwardPrograms = new Map<string, DispatchEntry>();
276
+ for (const candidate of input.dispatch) {
277
+ if (candidate.tags.LightMode !== 'Forward' || candidate.materialShaderId === undefined)
278
+ continue;
279
+ const key = `${candidate.renderableIndex}:${candidate.materialHandle}`;
280
+ if (!forwardPrograms.has(key)) forwardPrograms.set(key, candidate);
281
+ }
270
282
  for (const entry of input.validated) {
271
283
  if (entry.source.pointsLines !== undefined) {
272
284
  const pointsLinesMaterial = entry.source.material;
@@ -312,9 +324,14 @@ function addStandardMaterialRequests(input: {
312
324
  const unlitHasColor = unlitProjection === 'VERTEX_COLOR_AVAILABLE=true';
313
325
  for (const submesh of entry.mesh.submeshes) {
314
326
  const material = entry.source.materials[submesh.materialSlot] ?? entry.source.material;
327
+ const forwardProgram = forwardPrograms.get(
328
+ `${entry.renderableIndex}:${material.materialHandle ?? -1}`,
329
+ );
315
330
  const materialShaderId =
316
331
  entry.source.skin === undefined
317
- ? (material.materialShaderId ?? 'forgeax::default-unlit')
332
+ ? (forwardProgram?.materialShaderId ??
333
+ material.materialShaderId ??
334
+ 'forgeax::default-unlit')
318
335
  : SKIN_MATERIAL_SHADER_ID;
319
336
  const renderState = geometryRenderStateForPass(
320
337
  recoveryRenderState(materialShaderId, material, submesh.topology) as ReturnType<
@@ -370,6 +387,13 @@ function addStandardMaterialRequests(input: {
370
387
  const materialCapabilityVariantSet = isStandardPbrMaterialShader(materialShaderId)
371
388
  ? standardPbrCapabilityVariantSet
372
389
  : capabilityVariantSet;
390
+ const surfaceLayoutKind =
391
+ material.surfaceModel === 'single-layer-medium'
392
+ ? input.standardLighting?.kind === 'clustered' &&
393
+ input.internals.device.caps.storageBuffer
394
+ ? ('surface-direct-cluster-pbr' as const)
395
+ : ('surface-direct-pbr' as const)
396
+ : undefined;
373
397
  const requestedVariant = isSprite
374
398
  ? materialShaderId === 'forgeax::sprite' && entry.source.spriteInstances !== undefined
375
399
  ? SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET
@@ -398,6 +422,12 @@ function addStandardMaterialRequests(input: {
398
422
  indexFormat: entry.mesh.indexFormat,
399
423
  ...optionalVariant(reflectionFallbackVariant),
400
424
  passKind: 'forward',
425
+ ...(forwardProgram?.vertexEntry === undefined
426
+ ? {}
427
+ : { vertexEntry: forwardProgram.vertexEntry }),
428
+ ...(forwardProgram?.fragmentEntry === undefined
429
+ ? {}
430
+ : { fragmentEntry: forwardProgram.fragmentEntry }),
401
431
  sampleCount: input.sampleCount,
402
432
  ...optionalColorFormat(input.colorFormatOverride),
403
433
  ...(input.reflectionFallbackAvailable &&
@@ -405,6 +435,7 @@ function addStandardMaterialRequests(input: {
405
435
  ? { additionalColorFormats: ['rgba16float'] as const }
406
436
  : {}),
407
437
  vertexLayoutProjection: meshProjection,
438
+ ...(surfaceLayoutKind === undefined ? {} : { layoutKindOverride: surfaceLayoutKind }),
408
439
  preserveUndefinedVariant: isSprite && requestedVariant === undefined,
409
440
  variantAlreadyResolved:
410
441
  isSprite ||
@@ -610,6 +641,7 @@ export function prepareRecoveryPipelineReadiness(input: {
610
641
  internals: input.internals,
611
642
  pipelineState: input.pipelineState,
612
643
  validated: input.validated,
644
+ dispatch: input.dispatch,
613
645
  standardLighting: input.standardLighting,
614
646
  sampleCount,
615
647
  isHdrTarget,
@@ -113,6 +113,11 @@ export interface ReflectionProbeRecordState {
113
113
  export interface MaterialShaderPipelineEntry {
114
114
  readonly pipeline: RhiRenderPipeline;
115
115
  readonly group2Contract: PipelineGroup2Contract;
116
+ /** Producer receipt for the exact artifact selected with this pipeline. */
117
+ readonly receipt?: {
118
+ readonly identity: string;
119
+ readonly generation: number;
120
+ };
116
121
  }
117
122
 
118
123
  import type {
@@ -198,6 +203,7 @@ export interface RenderSystemRuntime {
198
203
  | {
199
204
  readonly vertexColorAvailable?: boolean;
200
205
  readonly deformation?: 'rigid' | 'skin';
206
+ readonly variantSet?: string;
201
207
  readonly clustered?: boolean;
202
208
  readonly reflectionFallback?: boolean;
203
209
  readonly pass?: 'forward' | 'shadow' | 'depth';
@@ -221,7 +227,15 @@ export interface RenderSystemRuntime {
221
227
  vertexLayout?: string,
222
228
  vertexLayoutProjection?: VertexLayoutProjection,
223
229
  shaderModuleMode?: RenderFeatureShaderModuleMode,
224
- layoutKindOverride?: 'pbr' | 'pbr-skin' | 'gpu-driven-pbr' | 'gpu-driven-skin',
230
+ layoutKindOverride?:
231
+ | 'pbr'
232
+ | 'pbr-skin'
233
+ | 'gpu-driven-pbr'
234
+ | 'gpu-driven-skin'
235
+ | 'gpu-driven-cluster-pbr'
236
+ | 'gpu-driven-cluster-skin'
237
+ | 'surface-direct-pbr'
238
+ | 'surface-direct-cluster-pbr',
225
239
  /** Optional vertex entry override for receipt-owned scene-index passes. */
226
240
  vertexEntryPoint?: string,
227
241
  additionalColorFormats?: readonly GPUTextureFormat[],
@@ -246,7 +260,15 @@ export interface RenderSystemRuntime {
246
260
  vertexLayout?: string,
247
261
  vertexLayoutProjection?: VertexLayoutProjection,
248
262
  shaderModuleMode?: RenderFeatureShaderModuleMode,
249
- layoutKindOverride?: 'pbr' | 'pbr-skin' | 'gpu-driven-pbr' | 'gpu-driven-skin',
263
+ layoutKindOverride?:
264
+ | 'pbr'
265
+ | 'pbr-skin'
266
+ | 'gpu-driven-pbr'
267
+ | 'gpu-driven-skin'
268
+ | 'gpu-driven-cluster-pbr'
269
+ | 'gpu-driven-cluster-skin'
270
+ | 'surface-direct-pbr'
271
+ | 'surface-direct-cluster-pbr',
250
272
  /** Optional vertex entry override for receipt-owned scene-index passes. */
251
273
  vertexEntryPoint?: string,
252
274
  additionalColorFormats?: readonly GPUTextureFormat[],
@@ -337,17 +359,15 @@ export interface PerPassResources {
337
359
  readonly skyboxBindGroupLayout: BindGroupLayout | null;
338
360
  readonly skyboxSampler: Sampler | null;
339
361
  readonly skyboxRotationBuffer: Buffer | null;
340
- bloomBrightPipeline: RhiRenderPipeline | null;
341
- bloomBlurHPipeline: RhiRenderPipeline | null;
342
- bloomBlurVPipeline: RhiRenderPipeline | null;
362
+ bloomDownsamplePipeline: RhiRenderPipeline | null;
363
+ bloomUpsamplePipeline: RhiRenderPipeline | null;
343
364
  bloomCompositePipeline: RhiRenderPipeline | null;
344
- bloomBrightBindGroupLayout: BindGroupLayout | null;
345
- bloomBlurBindGroupLayout: BindGroupLayout | null;
365
+ bloomDownsampleBindGroupLayout: BindGroupLayout | null;
366
+ bloomUpsampleBindGroupLayout: BindGroupLayout | null;
346
367
  bloomCompositeBindGroupLayout: BindGroupLayout | null;
347
368
  bloomSampler: Sampler | null;
348
- bloomBrightParamsBuffer: Buffer | null;
349
- bloomBlurHParamsBuffer: Buffer | null;
350
- bloomBlurVParamsBuffer: Buffer | null;
369
+ bloomDownsampleParamsBuffer: Buffer | null;
370
+ bloomUpsampleParamsBuffer: Buffer | null;
351
371
  bloomCompositeParamsBuffer: Buffer | null;
352
372
  ensureBloomResources?: () => void;
353
373
  getBloomResources?: () => BloomPersistentBundle | null;
@@ -358,18 +378,6 @@ export interface PerPassResources {
358
378
  /** Drain candidate, active, and fence-retiring Bloom generations. */
359
379
  drainBloomResources?: () => void;
360
380
  inspectBloomResources?: (graph?: CompiledRenderGraphInfo) => BloomInspection;
361
- bloomBrightTexture: Texture | null;
362
- bloomBrightView: TextureView | null;
363
- bloomBrightWidth: number;
364
- bloomBrightHeight: number;
365
- bloomBlurHTexture: Texture | null;
366
- bloomBlurHView: TextureView | null;
367
- bloomBlurHWidth: number;
368
- bloomBlurHHeight: number;
369
- bloomBlurVTexture: Texture | null;
370
- bloomBlurVView: TextureView | null;
371
- bloomBlurVWidth: number;
372
- bloomBlurVHeight: number;
373
381
  ssaoCalcPipeline: RhiRenderPipeline | null;
374
382
  ssaoBlurPipeline: RhiRenderPipeline | null;
375
383
  ssaoBgl: BindGroupLayout | null;
@@ -392,17 +400,15 @@ export interface PerPassResources {
392
400
  export interface BloomPersistentBundle {
393
401
  readonly scope: DeviceScope;
394
402
  readonly generation: number;
395
- readonly bloomBrightPipeline: RhiRenderPipeline | null;
396
- readonly bloomBlurHPipeline: RhiRenderPipeline | null;
397
- readonly bloomBlurVPipeline: RhiRenderPipeline | null;
403
+ readonly bloomDownsamplePipeline: RhiRenderPipeline | null;
404
+ readonly bloomUpsamplePipeline: RhiRenderPipeline | null;
398
405
  readonly bloomCompositePipeline: RhiRenderPipeline | null;
399
- readonly bloomBrightBindGroupLayout: BindGroupLayout | null;
400
- readonly bloomBlurBindGroupLayout: BindGroupLayout | null;
406
+ readonly bloomDownsampleBindGroupLayout: BindGroupLayout | null;
407
+ readonly bloomUpsampleBindGroupLayout: BindGroupLayout | null;
401
408
  readonly bloomCompositeBindGroupLayout: BindGroupLayout | null;
402
409
  readonly bloomSampler: Sampler | null;
403
- readonly bloomBrightParamsBuffer: Buffer | null;
404
- readonly bloomBlurHParamsBuffer: Buffer | null;
405
- readonly bloomBlurVParamsBuffer: Buffer | null;
410
+ readonly bloomDownsampleParamsBuffer: Buffer | null;
411
+ readonly bloomUpsampleParamsBuffer: Buffer | null;
406
412
  readonly bloomCompositeParamsBuffer: Buffer | null;
407
413
  }
408
414
 
@@ -429,6 +435,8 @@ export interface PipelineState {
429
435
  readonly probeInstancesBindGroupLayout?: BindGroupLayout;
430
436
  readonly identityInstanceBuffer: Buffer;
431
437
  readonly defaultSampler: Sampler;
438
+ /** Nearest/clamp sampler required by r32float Surface depth input. */
439
+ readonly surfaceMediumDepthSampler?: Sampler;
432
440
  readonly fallbackTextureView: TextureView;
433
441
  readonly unlitPipeline: RhiRenderPipeline | null;
434
442
  readonly standardPipeline: RhiRenderPipeline | null;
@@ -443,10 +451,16 @@ export interface PipelineState {
443
451
  readonly pbrPipelineLayout: PipelineLayout | null;
444
452
  /** Dedicated slot-3 layout for scene-index GPU-driven Standard PBR draws. */
445
453
  readonly gpuDrivenInstancesBindGroupLayout?: BindGroupLayout | null;
454
+ /** Direct Surface slot-3 ABI: instances + retained medium frame resources. */
455
+ readonly surfaceDirectInstancesBindGroupLayout?: BindGroupLayout | null;
446
456
  readonly gpuDrivenPbrPipelineLayout?: PipelineLayout | null;
447
457
  /** Device-owned shader modules paired with their exact Standard PBR receipts. */
448
458
  readonly gpuDrivenPbrPrograms?: ReadonlyMap<string, GpuDrivenPbrProgram>;
449
459
  readonly gpuDrivenPbrSkinPipelineLayout?: PipelineLayout | null;
460
+ /** Clustered group(2) layouts paired with the scene-index slot(3). */
461
+ readonly gpuDrivenClusterPbrPipelineLayout?: PipelineLayout | null;
462
+ readonly gpuDrivenClusterPbrSkinPipelineLayout?: PipelineLayout | null;
463
+ readonly gpuDrivenClusterMeshBindGroupLayout?: BindGroupLayout | null;
450
464
  readonly pbrProbePipelineLayout?: PipelineLayout | null;
451
465
  readonly hdrpPbrPipelineLayout: PipelineLayout | null;
452
466
  readonly hdrpMeshBindGroupLayout?: BindGroupLayout | null;
@@ -595,6 +609,8 @@ export interface _StandardForwardSceneView {
595
609
  readonly gpuDrivenSceneMaterialBuffer?: Buffer;
596
610
  /** Concrete main-pass draw identities already claimed by the capable GPU lane. */
597
611
  readonly gpuDrivenDrawKeys?: ReadonlySet<string>;
612
+ /** Stable world identities used to construct the claimed draw keys. */
613
+ readonly gpuDrivenWorldKeys?: readonly number[];
598
614
  readonly gpuDrivenShadowViews?: ShadowViewStatePool;
599
615
  readonly gpuDrivenShadowBatchProjections?: ReadonlyMap<
600
616
  string,
@@ -617,7 +633,11 @@ export interface _StandardForwardSceneView {
617
633
  readonly pointsLines: PointsLinesRecordOwner | undefined;
618
634
  readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;
619
635
  /** Record-stage proof callback; invoked only after a real draw command is encoded. */
620
- readonly onRenderableDraw?: (entry: ValidatedRenderable) => void;
636
+ readonly onRenderableDraw?: (
637
+ entry: ValidatedRenderable,
638
+ submeshIndex?: number,
639
+ receipt?: { readonly lane: 'cpu' | 'gpu'; readonly ready: boolean },
640
+ ) => void;
621
641
  readonly reflectionProbes?: ReflectionProbeRecordState;
622
642
  materialUboPayloadCache?: {
623
643
  readonly materialSlots: readonly MaterialSnapshot[];
@@ -82,6 +82,8 @@ export interface GpuDrivenShadowBatch {
82
82
  readonly deformation: 'rigid' | 'skin';
83
83
  /** Complete binding for this batch, including opaque batches after custom casters. */
84
84
  readonly materialGroup: BindGroup;
85
+ /** Receipt-derived material BG for alpha-mask batches; opaque uses the pass singleton. */
86
+ readonly alphaMaskMaterialGroup?: BindGroup | undefined;
85
87
  readonly vertexBuffer: Buffer;
86
88
  readonly indexBuffer?: Buffer | undefined;
87
89
  readonly indexFormat?: 'uint16' | 'uint32' | undefined;
@@ -192,6 +194,7 @@ function ensureTypedShadowViewBg(
192
194
  );
193
195
  }
194
196
  const projectorAvailable = pipelineState.projectorAvailable !== false;
197
+ const lowLimitCloudBindings = !extendedLighting && !projectorAvailable;
195
198
  try {
196
199
  return getOrCreateFromChain(
197
200
  frameState.viewBindGroupCache,
@@ -209,6 +212,9 @@ function ensureTypedShadowViewBg(
209
212
  ? [pipelineState.defaultWhiteTextureView, pipelineState.defaultSampler]
210
213
  : []),
211
214
  pipelineState.pointsLinesViewBuffer ?? pipelineState.viewUniformBuffer,
215
+ ...(lowLimitCloudBindings
216
+ ? []
217
+ : [pipelineState.defaultWhiteTextureView, pipelineState.defaultSampler]),
212
218
  ],
213
219
  variant,
214
220
  () => {
@@ -287,6 +293,24 @@ function ensureTypedShadowViewBg(
287
293
  },
288
294
  ]
289
295
  : []),
296
+ ...(lowLimitCloudBindings
297
+ ? []
298
+ : [
299
+ {
300
+ binding: 16,
301
+ resource: {
302
+ kind: 'textureView' as const,
303
+ value: pipelineState.defaultWhiteTextureView,
304
+ },
305
+ },
306
+ {
307
+ binding: 17,
308
+ resource: {
309
+ kind: 'sampler' as const,
310
+ value: pipelineState.defaultSampler,
311
+ },
312
+ },
313
+ ]),
290
314
  ],
291
315
  });
292
316
  if (!created.ok) throw created.error;
@@ -786,6 +810,7 @@ function recordGpuDrivenShadowIfPublished(
786
810
  visibleBindGroup: projection.visibleBindGroup,
787
811
  deformation: projection.deformation,
788
812
  materialGroup,
813
+ ...(batch.key.admission === 'alpha-mask' ? { alphaMaskMaterialGroup: materialGroup } : {}),
789
814
  vertexBuffer: projection.mesh.vertexBuffer.handle,
790
815
  ...(batch.key.drawKind === 'indexed' && projection.mesh.indexBuffer !== null
791
816
  ? {
@@ -1503,7 +1528,12 @@ export function recordShadowCasterDraws(
1503
1528
  : GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;
1504
1529
  const instancePayload = uniformFallback
1505
1530
  ? shadowInst.transforms
1506
- : packInstanceStorageBuffer(shadowInst.transforms);
1531
+ : packInstanceStorageBuffer(
1532
+ shadowInst.transforms,
1533
+ entry.source.temporal?.previousInstances?.transforms,
1534
+ shadowInst.generations,
1535
+ entry.source.temporal?.previousInstances?.generations,
1536
+ );
1507
1537
  const requestedBytes = instancePayload.byteLength;
1508
1538
  const cap = runtime.device.limits.maxStorageBufferBindingSize;
1509
1539
  if (!uniformFallback && typeof cap === 'number' && cap > 0 && requestedBytes > cap) {
@@ -1965,7 +1995,11 @@ function ensureGpuDrivenCustomShadowMaterialBg(
1965
1995
  c: _InternalRenderPipelineContext,
1966
1996
  projection: GpuDrivenShadowBatchProjection,
1967
1997
  ): BindGroup {
1968
- const shaderId = projection.shadowArtifact.material;
1998
+ const shaderId =
1999
+ projection.shadowArtifact.specializationKey ?? projection.shadowArtifact.material;
2000
+ const materialKey = `shadow-material-custom:${shaderId}:${projection.materialEntityKey}:${projection.material.materialHandle ?? -1}:${c.store.materialResourceEpoch}`;
2001
+ const cached = c.materialBgAssemblyCache.get(materialKey);
2002
+ if (cached !== undefined) return cached.bindGroup;
1969
2003
  const fallback = c.pipelineState.skylightFallback;
1970
2004
  if (fallback === null) {
1971
2005
  throw new RhiError({