@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
@@ -43,11 +43,9 @@ import type { PointsLinesRecordPlan } from '../points-lines/record';
43
43
  import { POINTS_LINES_MATERIAL_SHADER_ID } from '../points-lines/record';
44
44
  import type { RenderRecordPhase } from '../render-contract';
45
45
  import type { DispatchEntry, MaterialSnapshot, RenderableSnapshot } from '../render-system-extract';
46
- import {
47
- PROBE_BLEND_RECORD_BYTE_SIZE,
48
- PROBE_BLEND_RECORD_STRIDE,
49
- probeBlendRecordOffset,
50
- } from '../scene/probe-blend-record';
46
+ import { PROBE_BLEND_RECORD_BYTE_SIZE, probeBlendRecordOffset } from '../scene/probe-blend-record';
47
+ import type { SurfacePassName } from '../surface/submission-observation';
48
+ import { resolveFoldInstanceBuffer } from './fold-instance-buffer';
51
49
  import {
52
50
  getOpaqueResourceIdentity,
53
51
  instanceCollectionCacheKey,
@@ -69,6 +67,7 @@ import {
69
67
  MESH_UBO_FULL_ARRAY_BYTES,
70
68
  packInstanceStorageBuffer,
71
69
  } from './mesh-ssbo';
70
+ import { ensureProbeBlendRecordBuffer } from './probe-blend-buffer';
72
71
  import type { _InternalRenderPipelineContext, MaterialShaderPipelineEntry } from './render-context';
73
72
  import { MATERIAL_PER_ENTITY_STRIDE } from './render-context';
74
73
  import { POINTS_LINES_VIEW_SLOT_STRIDE, writePointsLinesViewUbo } from './view-ubo';
@@ -93,11 +92,19 @@ export function sameOpaqueTemporalDraw(a: DispatchEntry, b: DispatchEntry): bool
93
92
  type GeometryInstanceDraw = {
94
93
  readonly instanceBuffer: Buffer;
95
94
  readonly instanceBindGroup: BindGroup;
95
+ /** Producer-owned Probe buffer paired with probeOffset, when present. */
96
+ readonly probeBuffer?: Buffer;
96
97
  /** -1 means the no-probe layout and therefore no dynamic offset. */
97
98
  readonly probeOffset: number;
99
+ readonly dynamicOffsets?: readonly number[];
98
100
  readonly instanceCount: number;
101
+ readonly firstInstanceOrdinal?: number;
102
+ readonly surfaceFrameBase?: number;
103
+ readonly surfaceMemberIds?: readonly string[];
99
104
  };
100
105
 
106
+ type DirectSurfaceLayoutKind = 'surface-direct-pbr' | 'surface-direct-cluster-pbr';
107
+
101
108
  type InstanceUploadResult =
102
109
  | {
103
110
  readonly ok: true;
@@ -113,6 +120,7 @@ type InstanceUploadResult =
113
120
  type GeometryBindingState = {
114
121
  pipeline: RenderPipeline | null;
115
122
  instancesBuffer: Buffer | null;
123
+ instanceBindGroup: BindGroup | null;
116
124
  probeOffset: number;
117
125
  };
118
126
 
@@ -143,6 +151,7 @@ type MaterialPipelineLookup = {
143
151
  readonly colorFormatOverride: GPUTextureFormat | undefined;
144
152
  readonly additionalColorFormats: readonly GPUTextureFormat[] | undefined;
145
153
  readonly textureMask: number | undefined;
154
+ readonly layoutKind: DirectSurfaceLayoutKind | undefined;
146
155
  readonly handle: MaterialShaderPipelineEntry | null;
147
156
  };
148
157
 
@@ -219,10 +228,11 @@ function isGpuDrivenMainClaimedSubmesh(
219
228
  if (drawItemIndex === undefined || draw === undefined) return false;
220
229
  const material = source.materials[draw.materialSlot] ?? source.material;
221
230
  const sourceDrawItemIndex = gpuDrivenSourceDrawItemIndex(draw, drawItemIndex);
231
+ const stableWorld = c.gpuDrivenWorldKeys?.[source.worldId] ?? source.worldId;
222
232
  return (
223
233
  c.gpuDrivenDrawKeys?.has(
224
234
  gpuDrivenDrawKey(
225
- worldEntityKey(source.worldId, source.entityKey),
235
+ worldEntityKey(stableWorld, source.entityKey),
226
236
  material.materialHandle ?? -1,
227
237
  sourceDrawItemIndex,
228
238
  ),
@@ -365,6 +375,22 @@ export function geometryRenderStateForPass(
365
375
  };
366
376
  }
367
377
 
378
+ /**
379
+ * Transparent depth is an authored medium policy. A transparent pass with no
380
+ * explicit depth-write bit remains read-only, which keeps alpha smoke and
381
+ * ordinary blending from becoming an opaque occluder; water or a cutout-like
382
+ * medium can opt in by setting the bit on its own pass state.
383
+ */
384
+ export function authoredTransparentDepthWrite(
385
+ transparent: boolean | undefined,
386
+ renderState: MaterialSnapshot['renderState'],
387
+ ): boolean {
388
+ return (
389
+ (transparent === true || renderState?.blend !== undefined) &&
390
+ renderState?.depthWriteEnabled === true
391
+ );
392
+ }
393
+
368
394
  function geometryRecordPhase(
369
395
  passKind: PassKind,
370
396
  segment: GeometryRecordProfileSegment,
@@ -394,7 +420,7 @@ function submitSubmeshDraws(
394
420
  indexCount: number,
395
421
  vertexCount: number,
396
422
  indexOffset: number,
397
- onDraw?: () => void,
423
+ onDraw?: (draw: GeometryInstanceDraw, command: 'draw' | 'draw-indexed') => void,
398
424
  ): void {
399
425
  if (state.pipeline !== pipeline) {
400
426
  pass.setPipeline(pipeline);
@@ -403,14 +429,18 @@ function submitSubmeshDraws(
403
429
  for (const instanceDraw of instanceDraws) {
404
430
  if (
405
431
  instanceDraw.instanceBuffer !== state.instancesBuffer ||
432
+ instanceDraw.instanceBindGroup !== state.instanceBindGroup ||
406
433
  instanceDraw.probeOffset !== state.probeOffset
407
434
  ) {
408
- if (instanceDraw.probeOffset < 0) {
435
+ if (instanceDraw.dynamicOffsets !== undefined) {
436
+ pass.setBindGroup(3, instanceDraw.instanceBindGroup, instanceDraw.dynamicOffsets);
437
+ } else if (instanceDraw.probeOffset < 0) {
409
438
  pass.setBindGroup(3, instanceDraw.instanceBindGroup);
410
439
  } else {
411
440
  pass.setBindGroup(3, instanceDraw.instanceBindGroup, [instanceDraw.probeOffset]);
412
441
  }
413
442
  state.instancesBuffer = instanceDraw.instanceBuffer;
443
+ state.instanceBindGroup = instanceDraw.instanceBindGroup;
414
444
  state.probeOffset = instanceDraw.probeOffset;
415
445
  }
416
446
  if (indexed) {
@@ -418,7 +448,7 @@ function submitSubmeshDraws(
418
448
  } else {
419
449
  pass.draw(vertexCount, instanceDraw.instanceCount, 0, 0);
420
450
  }
421
- onDraw?.();
451
+ onDraw?.(instanceDraw, indexed ? 'draw-indexed' : 'draw');
422
452
  }
423
453
  }
424
454
 
@@ -472,6 +502,9 @@ export function recordGeometryDraws(
472
502
  selectedDispatch?: readonly DispatchEntry[],
473
503
  colorFormats: readonly GPUTextureFormat[] = [],
474
504
  coverageOnly = false,
505
+ fragmentEntryPoint?: string,
506
+ surfacePass?: SurfacePassName,
507
+ transparentDepthWrite = false,
475
508
  ): void {
476
509
  const {
477
510
  runtime,
@@ -520,6 +553,7 @@ export function recordGeometryDraws(
520
553
  const bindingState: GeometryBindingState = {
521
554
  pipeline: null,
522
555
  instancesBuffer: null,
556
+ instanceBindGroup: null,
523
557
  probeOffset: -1,
524
558
  };
525
559
  const identityInstanceBuffer = pipelineState.identityInstanceBuffer;
@@ -563,6 +597,7 @@ export function recordGeometryDraws(
563
597
  vertexEntry?: string,
564
598
  fragmentEntry?: string,
565
599
  textureMask?: number,
600
+ layoutKind?: DirectSurfaceLayoutKind,
566
601
  ): MaterialShaderPipelineEntry | null => {
567
602
  const pipelineVariantSet = withCoverageVariant(variantSet);
568
603
  // The fallback MRT is an extension of the built-in Standard PBR output
@@ -594,6 +629,7 @@ export function recordGeometryDraws(
594
629
  cached.vertexEntry === vertexEntry &&
595
630
  cached.fragmentEntry === fragmentEntry &&
596
631
  cached.textureMask === textureMask &&
632
+ cached.layoutKind === layoutKind &&
597
633
  cached.passKind === passKind &&
598
634
  cached.layoutProjection.digest === layoutProjection.digest &&
599
635
  cached.sampleCount === sampleCount &&
@@ -604,8 +640,13 @@ export function recordGeometryDraws(
604
640
  }
605
641
  }
606
642
  }
643
+ // Published Surface artifacts carry both direct and scene-index modules.
644
+ // The boot artifact may be the scene-index specialization selected by the
645
+ // retained producer, so a direct slot-3 layout must still resolve the
646
+ // explicit capability key. This keeps the module source, entry point and
647
+ // pipeline layout on the same GPU_DRIVEN_SCENE_INDEX_AVAILABLE=false ABI.
607
648
  const resolvedVariantSetResult =
608
- runtime.getMaterialArtifact?.(materialShaderId) !== undefined
649
+ runtime.getMaterialArtifact?.(materialShaderId) !== undefined && layoutKind === undefined
609
650
  ? ({ ok: true, value: undefined } as const)
610
651
  : pipelineVariantSet === undefined &&
611
652
  (materialShaderId === 'forgeax::sprite' || materialShaderId === 'forgeax::sprite-lit')
@@ -639,7 +680,7 @@ export function recordGeometryDraws(
639
680
  undefined,
640
681
  layoutProjection,
641
682
  undefined,
642
- undefined,
683
+ layoutKind,
643
684
  undefined,
644
685
  reflectionFallbackFormats,
645
686
  vertexEntry,
@@ -674,6 +715,7 @@ export function recordGeometryDraws(
674
715
  colorFormatOverride: colorFormat,
675
716
  additionalColorFormats: reflectionFallbackFormats,
676
717
  textureMask,
718
+ layoutKind,
677
719
  handle,
678
720
  };
679
721
  if (shaderLookupCache === undefined) {
@@ -693,6 +735,9 @@ export function recordGeometryDraws(
693
735
  for (let i = 0; i < validatedOrdered.length; i++) {
694
736
  const entry = validatedOrdered[i];
695
737
  if (entry === undefined) continue;
738
+ // The typed transparent pass uses this common draw owner. Consume the
739
+ // same fold plan as the legacy sprite pass, including coverage/depth draws.
740
+ if (c.foldDispatchPlan?.skipIndices.has(i) === true) continue;
696
741
  // Points/Lines share the Standard geometry pass. Their retained source
697
742
  // is prepared once by the renderer owner, while this loop remains the
698
743
  // sole pass/draw submission owner and preserves the authored topology.
@@ -822,8 +867,22 @@ export function recordGeometryDraws(
822
867
  // length instead.
823
868
  if (pipelineTag === 'unlit') dispatchCounts.unlit += 1;
824
869
 
825
- const instanceDraws = resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws, false);
826
- if (instanceDraws === null) continue;
870
+ const fold = c.foldDispatchPlan?.headBuckets.get(i);
871
+ const foldBuffer = fold === undefined ? null : resolveFoldInstanceBuffer(c, fold, i);
872
+ const baseInstanceDraws =
873
+ fold === undefined
874
+ ? resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws, false)
875
+ : foldBuffer === null
876
+ ? null
877
+ : [
878
+ {
879
+ instanceBuffer: foldBuffer,
880
+ instanceBindGroup: resolveGeometryInstancesBindGroup(c, foldBuffer, undefined),
881
+ probeOffset: -1,
882
+ instanceCount: fold.bucketSize,
883
+ },
884
+ ];
885
+ if (baseInstanceDraws === null) continue;
827
886
 
828
887
  // feat-20260611 R2 / M8 / w28 (IS-14): skin entries need a 3-binding
829
888
  // group(2) BG matching `pbr-skin-pl` (binding 0 mesh-array UBO +
@@ -1114,16 +1173,22 @@ export function recordGeometryDraws(
1114
1173
  ) {
1115
1174
  continue;
1116
1175
  }
1176
+ const selectedMaterialPasses = materialPasses
1177
+ .get(entry.renderableIndex)
1178
+ ?.get(submeshMaterial.materialHandle ?? 0);
1117
1179
  const draws: readonly (DispatchEntry | undefined)[] =
1118
- selectedDispatch === undefined
1180
+ selectedDispatch === undefined ||
1181
+ (selectedMaterialPasses === undefined &&
1182
+ submeshMaterial.surfaceModel === 'single-layer-medium' &&
1183
+ matchedMaterials?.get(entry.renderableIndex)?.has(submeshMaterial.materialHandle ?? 0))
1119
1184
  ? [undefined]
1120
- : (materialPasses.get(entry.renderableIndex)?.get(submeshMaterial.materialHandle ?? 0) ??
1121
- []);
1185
+ : (selectedMaterialPasses ?? []);
1122
1186
  for (const selectedPass of draws) {
1123
1187
  // Temporal projects the selected material's alpha/motion contract,
1124
1188
  // not its authored Forward entry points or color outputs.
1125
1189
  const vertexEntry = passKind === 'temporal' ? undefined : selectedPass?.vertexEntry;
1126
- const fragmentEntry = passKind === 'temporal' ? undefined : selectedPass?.fragmentEntry;
1190
+ const fragmentEntry =
1191
+ passKind === 'temporal' ? undefined : (fragmentEntryPoint ?? selectedPass?.fragmentEntry);
1127
1192
  const selectedShaderId =
1128
1193
  selectedPass === undefined
1129
1194
  ? submeshMaterial.materialShaderId
@@ -1228,7 +1293,9 @@ export function recordGeometryDraws(
1228
1293
  : SKIN_MATERIAL_SHADER_ID
1229
1294
  : submeshMaterial.materialShaderId;
1230
1295
  const probeBlendAvailable =
1231
- probeBlendRecordAvailable && isStandardPbrMaterialShader(smMaterialShaderId);
1296
+ probeBlendRecordAvailable &&
1297
+ (isStandardPbrMaterialShader(smMaterialShaderId) ||
1298
+ submeshMaterial.surfaceModel === 'single-layer-medium');
1232
1299
  const isSpriteShader =
1233
1300
  smMaterialShaderId === 'forgeax::sprite' || smMaterialShaderId === 'forgeax::sprite-lit';
1234
1301
  // Preserve the dedicated sprite-pass state when the linear-LDR graph
@@ -1243,11 +1310,25 @@ export function recordGeometryDraws(
1243
1310
  blend: selectedRenderState?.blend ?? SPRITE_PREMULTIPLIED_ALPHA_BLEND,
1244
1311
  }
1245
1312
  : geometryRenderStateForTopology(smTopology, selectedRenderState);
1246
- const pipelineRenderState = geometryRenderStateForPass(
1313
+ let pipelineRenderState = geometryRenderStateForPass(
1247
1314
  basePipelineRenderState,
1248
1315
  passKind,
1249
1316
  coverageOnly,
1250
1317
  );
1318
+ if (
1319
+ transparentDepthWrite &&
1320
+ passKind === 'forward' &&
1321
+ (submeshMaterial.transparent === true || selectedRenderState?.blend !== undefined)
1322
+ ) {
1323
+ pipelineRenderState = {
1324
+ ...pipelineRenderState,
1325
+ depthWriteEnabled: authoredTransparentDepthWrite(
1326
+ submeshMaterial.transparent,
1327
+ selectedRenderState,
1328
+ ),
1329
+ depthCompare: 'less-equal',
1330
+ };
1331
+ }
1251
1332
  let smPipelineHandle: typeof pipelineState.unlitPipeline;
1252
1333
  let materialGroup2Contract: 'mesh' | 'skin' | 'cluster' | 'skin-cluster' | undefined;
1253
1334
  let materialPipelineEntry: MaterialShaderPipelineEntry | null = null;
@@ -1319,15 +1400,17 @@ export function recordGeometryDraws(
1319
1400
  transmissionAvailable && !capabilityVariantSet.includes('TRANSMISSION_AVAILABLE=')
1320
1401
  ? `${capabilityVariantSet}+TRANSMISSION_AVAILABLE=true`
1321
1402
  : capabilityVariantSet;
1322
- // Sprite's base request must retain the boot-selected artifact. Only
1323
- // SpriteInstances uses the explicit empty key for the
1324
- // PER_INSTANCE_REGION=true variant; synthesizing the generic PBR
1325
- // capability axes for a base sprite would invent a lazy module label
1326
- // that has no boot seed and skip the first HDR draw.
1403
+ // Regular sprite keeps the boot-selected artifact; SpriteInstances
1404
+ // uses the explicit empty key for PER_INSTANCE_REGION=true. Sprite-lit
1405
+ // is different: the typed Standard transparent lane records it here,
1406
+ // so its shader must follow the frame-owned cluster topology or local
1407
+ // lights disappear while the ordinary sprite path remains direct.
1327
1408
  const variantSet = isSpriteShader
1328
- ? smMaterialShaderId === 'forgeax::sprite' && entry.source.spriteInstances !== undefined
1329
- ? ''
1330
- : undefined
1409
+ ? smMaterialShaderId === 'forgeax::sprite-lit'
1410
+ ? materialCapabilityVariantSet
1411
+ : entry.source.spriteInstances !== undefined
1412
+ ? ''
1413
+ : undefined
1331
1414
  : entry.variantSet === undefined
1332
1415
  ? materialCapabilityVariantSet
1333
1416
  : `${materialCapabilityVariantSet}+${entry.variantSet}`;
@@ -1342,6 +1425,11 @@ export function recordGeometryDraws(
1342
1425
  vertexEntry,
1343
1426
  fragmentEntry,
1344
1427
  submeshMaterial.standardTextureMask,
1428
+ submeshMaterial.surfaceModel === 'single-layer-medium' && passKind === 'forward'
1429
+ ? capabilityVariantSet.includes('CLUSTER_FORWARD_AVAILABLE=true')
1430
+ ? 'surface-direct-cluster-pbr'
1431
+ : 'surface-direct-pbr'
1432
+ : undefined,
1345
1433
  );
1346
1434
  // feat-20260615-pipeline-spec-ssot M6-T1: cache miss resolves to
1347
1435
  // null uniformly across URP / HDRP / skin shaders. Charter P3
@@ -1380,12 +1468,28 @@ export function recordGeometryDraws(
1380
1468
  // renderable, but unlit/custom shaders still use the one-binding
1381
1469
  // instances BGL and must never receive the probe bind group. Resolve
1382
1470
  // this per submesh so mixed-material meshes cannot cross the layouts.
1383
- const instanceDraws = resolveGeometryInstanceBuffer(
1384
- c,
1385
- entry,
1386
- identityInstanceDraws,
1387
- probeBlendAvailable,
1388
- );
1471
+ const resolvedInstanceDraws = probeBlendAvailable
1472
+ ? resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws, true)
1473
+ : baseInstanceDraws;
1474
+ if (resolvedInstanceDraws === null) continue;
1475
+ const compactDrawIndex = gpuDrivenDrawIndices.get(smIdx);
1476
+ const compactDraw =
1477
+ compactDrawIndex === undefined
1478
+ ? undefined
1479
+ : entry.source.gpuDrivenDraws?.[compactDrawIndex];
1480
+ const sourceDrawItemIndex =
1481
+ compactDrawIndex === undefined || compactDraw === undefined
1482
+ ? smIdx
1483
+ : gpuDrivenSourceDrawItemIndex(compactDraw, compactDrawIndex);
1484
+ const instanceDraws =
1485
+ submeshMaterial.surfaceModel === 'single-layer-medium' && passKind === 'forward'
1486
+ ? resolveSurfaceDirectInstanceDraws(
1487
+ c,
1488
+ entry,
1489
+ sourceDrawItemIndex,
1490
+ resolvedInstanceDraws,
1491
+ )
1492
+ : resolvedInstanceDraws;
1389
1493
  if (instanceDraws === null) continue;
1390
1494
  // Standard clustered PBR variants declare the unified cluster/SSAO
1391
1495
  // group(2) layout. Unlit and other URP-layout materials must bind the
@@ -1441,7 +1545,26 @@ export function recordGeometryDraws(
1441
1545
  sm.indexCount,
1442
1546
  sm.vertexCount,
1443
1547
  sm.indexOffset,
1444
- () => c.onRenderableDraw?.(entry),
1548
+ (draw, command) => {
1549
+ c.onRenderableDraw?.(entry, smIdx);
1550
+ if (surfacePass === undefined || draw.surfaceFrameBase === undefined) return;
1551
+ c.frameState.surfaceSubmissionObservation?.record(surfacePass, {
1552
+ kind: command,
1553
+ count: entry.mesh.indexed ? sm.indexCount : sm.vertexCount,
1554
+ first: entry.mesh.indexed ? sm.indexOffset : 0,
1555
+ instanceCount: draw.instanceCount,
1556
+ firstInstance: 0,
1557
+ surfaceFrameBase: draw.surfaceFrameBase,
1558
+ memberIds: draw.surfaceMemberIds ?? [],
1559
+ pipelineIdentity: getOpaqueResourceIdentity(smPipelineHandle as object),
1560
+ ...(materialPipelineEntry?.receipt === undefined
1561
+ ? {}
1562
+ : {
1563
+ receiptIdentity: materialPipelineEntry.receipt.identity,
1564
+ receiptGeneration: materialPipelineEntry.receipt.generation,
1565
+ }),
1566
+ });
1567
+ },
1445
1568
  ),
1446
1569
  );
1447
1570
  } else {
@@ -1456,7 +1579,26 @@ export function recordGeometryDraws(
1456
1579
  sm.indexCount,
1457
1580
  sm.vertexCount,
1458
1581
  sm.indexOffset,
1459
- () => c.onRenderableDraw?.(entry),
1582
+ (draw, command) => {
1583
+ c.onRenderableDraw?.(entry, smIdx);
1584
+ if (surfacePass === undefined || draw.surfaceFrameBase === undefined) return;
1585
+ c.frameState.surfaceSubmissionObservation?.record(surfacePass, {
1586
+ kind: command,
1587
+ count: entry.mesh.indexed ? sm.indexCount : sm.vertexCount,
1588
+ first: entry.mesh.indexed ? sm.indexOffset : 0,
1589
+ instanceCount: draw.instanceCount,
1590
+ firstInstance: 0,
1591
+ surfaceFrameBase: draw.surfaceFrameBase,
1592
+ memberIds: draw.surfaceMemberIds ?? [],
1593
+ pipelineIdentity: getOpaqueResourceIdentity(smPipelineHandle as object),
1594
+ ...(materialPipelineEntry?.receipt === undefined
1595
+ ? {}
1596
+ : {
1597
+ receiptIdentity: materialPipelineEntry.receipt.identity,
1598
+ receiptGeneration: materialPipelineEntry.receipt.generation,
1599
+ }),
1600
+ });
1601
+ },
1460
1602
  ),
1461
1603
  ),
1462
1604
  );
@@ -1475,12 +1617,13 @@ export function recordGeometryDraws(
1475
1617
  * @internal
1476
1618
  */
1477
1619
  function uploadInstanceRanges(
1478
- c: _InternalRenderPipelineContext,
1620
+ c: InstanceBufferContext,
1479
1621
  inst: NonNullable<RenderableSnapshot['instances']>,
1480
1622
  buffer: Buffer,
1481
1623
  ranges: readonly { readonly start: number; readonly end: number }[],
1482
1624
  storageBacked: boolean,
1483
1625
  sourceOffsetInstances = 0,
1626
+ previousInst: NonNullable<RenderableSnapshot['temporal']>['previousInstances'] = undefined,
1484
1627
  ): InstanceUploadResult {
1485
1628
  const strideBytes =
1486
1629
  (storageBacked ? INSTANCE_STORAGE_STRIDE_FLOATS : 16) * Float32Array.BYTES_PER_ELEMENT;
@@ -1494,7 +1637,31 @@ function uploadInstanceRanges(
1494
1637
  (sourceOffsetInstances + start) * 16,
1495
1638
  (sourceOffsetInstances + end) * 16,
1496
1639
  );
1497
- const payload = storageBacked ? packInstanceStorageBuffer(source) : source;
1640
+ // A generation-bearing previous collection is kept whole so a compacted
1641
+ // or reordered current range can resolve its real prior ordinal. Without
1642
+ // identity proof, keep the old range-local shape and let the packer seed
1643
+ // on count mismatch rather than pairing an unrelated slot.
1644
+ const hasIdentityProof =
1645
+ inst.generations !== undefined && previousInst?.generations !== undefined;
1646
+ const previousSource = hasIdentityProof
1647
+ ? previousInst?.transforms
1648
+ : previousInst?.transforms.subarray(
1649
+ (sourceOffsetInstances + start) * 16,
1650
+ (sourceOffsetInstances + end) * 16,
1651
+ );
1652
+ const currentGenerations = inst.generations?.subarray(
1653
+ sourceOffsetInstances + start,
1654
+ sourceOffsetInstances + end,
1655
+ );
1656
+ const previousGenerations = hasIdentityProof
1657
+ ? previousInst?.generations
1658
+ : previousInst?.generations?.subarray(
1659
+ sourceOffsetInstances + start,
1660
+ sourceOffsetInstances + end,
1661
+ );
1662
+ const payload = storageBacked
1663
+ ? packInstanceStorageBuffer(source, previousSource, currentGenerations, previousGenerations)
1664
+ : source;
1498
1665
  const written = c.runtime.device.queue.writeBuffer(buffer, start * strideBytes, payload);
1499
1666
  if (!written.ok) {
1500
1667
  c.runtime.errorRegistry.fire(written.error);
@@ -1507,7 +1674,7 @@ function uploadInstanceRanges(
1507
1674
  }
1508
1675
 
1509
1676
  export function reportInstanceResidency(
1510
- c: _InternalRenderPipelineContext,
1677
+ c: InstanceBufferContext,
1511
1678
  inst: NonNullable<RenderableSnapshot['instances']>,
1512
1679
  input: {
1513
1680
  readonly lane: 'direct-storage' | 'chunked-storage' | 'direct-uniform' | 'chunked-uniform';
@@ -1532,7 +1699,7 @@ export function reportInstanceResidency(
1532
1699
  }
1533
1700
 
1534
1701
  function reportInstanceFailure(
1535
- c: _InternalRenderPipelineContext,
1702
+ c: InstanceBufferContext,
1536
1703
  inst: NonNullable<RenderableSnapshot['instances']>,
1537
1704
  error: {
1538
1705
  readonly code: InstanceCollectionFailureCode;
@@ -1559,7 +1726,7 @@ function reportInstanceFailure(
1559
1726
  });
1560
1727
  }
1561
1728
 
1562
- function clearInstanceChunksForOwner(c: _InternalRenderPipelineContext, ownerKey: number): void {
1729
+ function clearInstanceChunksForOwner(c: InstanceBufferContext, ownerKey: number): void {
1563
1730
  const chunks = c.frameState.instanceBufferChunks;
1564
1731
  if (chunks === undefined) return;
1565
1732
  const prefix = `${ownerKey}:`;
@@ -1574,7 +1741,7 @@ function clearInstanceChunksForOwner(c: _InternalRenderPipelineContext, ownerKey
1574
1741
  }
1575
1742
 
1576
1743
  export function resolveStorageInstanceChunks(
1577
- c: _InternalRenderPipelineContext,
1744
+ c: InstanceBufferContext,
1578
1745
  entry: _InternalRenderPipelineContext['validatedOrdered'][number],
1579
1746
  inst: NonNullable<RenderableSnapshot['instances']>,
1580
1747
  cap: number,
@@ -1673,6 +1840,7 @@ export function resolveStorageInstanceChunks(
1673
1840
  rangesToUpload,
1674
1841
  true,
1675
1842
  start,
1843
+ entry.source.temporal?.previousInstances,
1676
1844
  );
1677
1845
  for (const range of upload.ranges) {
1678
1846
  uploadedRanges.push({ start: range.start + start, end: range.end + start });
@@ -1708,8 +1876,10 @@ export function resolveStorageInstanceChunks(
1708
1876
  activeBuffer.buffer.handle,
1709
1877
  probeBuffer,
1710
1878
  ),
1879
+ ...(probeBuffer === undefined ? {} : { probeBuffer }),
1711
1880
  probeOffset,
1712
1881
  instanceCount: count,
1882
+ firstInstanceOrdinal: start,
1713
1883
  });
1714
1884
  }
1715
1885
  if (chunks !== undefined) {
@@ -1733,8 +1903,13 @@ export function resolveStorageInstanceChunks(
1733
1903
  return draws;
1734
1904
  }
1735
1905
 
1736
- function resolveGeometryInstanceBuffer(
1737
- c: _InternalRenderPipelineContext,
1906
+ type InstanceBufferContext = Pick<
1907
+ _InternalRenderPipelineContext,
1908
+ 'runtime' | 'pipelineState' | 'frameState' | 'bindGroupCounts'
1909
+ >;
1910
+
1911
+ export function resolveGeometryInstanceBuffer(
1912
+ c: InstanceBufferContext,
1738
1913
  entry: _InternalRenderPipelineContext['validatedOrdered'][number],
1739
1914
  identityInstanceDraws: readonly GeometryInstanceDraw[],
1740
1915
  useProbeBlend: boolean,
@@ -1762,6 +1937,7 @@ function resolveGeometryInstanceBuffer(
1762
1937
  pipelineState.identityInstanceBuffer,
1763
1938
  probeBinding?.buffer,
1764
1939
  ),
1940
+ ...(probeBinding?.buffer === undefined ? {} : { probeBuffer: probeBinding.buffer }),
1765
1941
  probeOffset: probeBinding?.offset ?? -1,
1766
1942
  },
1767
1943
  ];
@@ -1858,6 +2034,7 @@ function resolveGeometryInstanceBuffer(
1858
2034
  rangesToUpload,
1859
2035
  false,
1860
2036
  start,
2037
+ entry.source.temporal?.previousInstances,
1861
2038
  );
1862
2039
  for (const range of upload.ranges) {
1863
2040
  uploadedRanges.push({ start: range.start + start, end: range.end + start });
@@ -1891,8 +2068,10 @@ function resolveGeometryInstanceBuffer(
1891
2068
  active.buffer.handle,
1892
2069
  probeBinding?.buffer,
1893
2070
  ),
2071
+ ...(probeBinding?.buffer === undefined ? {} : { probeBuffer: probeBinding.buffer }),
1894
2072
  probeOffset: probeBinding?.offset ?? -1,
1895
2073
  instanceCount: count,
2074
+ firstInstanceOrdinal: start,
1896
2075
  });
1897
2076
  }
1898
2077
  if (chunks !== undefined) {
@@ -1961,6 +2140,7 @@ function resolveGeometryInstanceBuffer(
1961
2140
  if (!bufRes.ok) {
1962
2141
  runtime.errorRegistry.fire(bufRes.error);
1963
2142
  reportInstanceFailure(c, inst, bufRes.error, requestedBytes, cap);
2143
+ return null;
1964
2144
  } else {
1965
2145
  // feat-20260619 M4 / F12: destroy the old cached buffer
1966
2146
  // before replacing it with the new one (D-6).
@@ -1997,6 +2177,8 @@ function resolveGeometryInstanceBuffer(
1997
2177
  active.buffer.handle,
1998
2178
  ranges,
1999
2179
  !uniformFallback,
2180
+ 0,
2181
+ entry.source.temporal?.previousInstances,
2000
2182
  );
2001
2183
  uploadRanges = upload.ranges;
2002
2184
  uploadedBytes = upload.bytes;
@@ -2049,62 +2231,78 @@ function resolveGeometryInstanceBuffer(
2049
2231
  {
2050
2232
  instanceBuffer,
2051
2233
  instanceBindGroup: resolveGeometryInstancesBindGroup(c, instanceBuffer, probeBinding?.buffer),
2234
+ ...(probeBinding?.buffer === undefined ? {} : { probeBuffer: probeBinding.buffer }),
2052
2235
  probeOffset: probeBinding?.offset ?? -1,
2053
2236
  instanceCount,
2054
2237
  },
2055
2238
  ];
2056
2239
  }
2057
2240
 
2058
- export function resolveProbeBlendBuffer(
2241
+ function resolveSurfaceDirectInstanceDraws(
2059
2242
  c: _InternalRenderPipelineContext,
2243
+ entry: _InternalRenderPipelineContext['validatedOrdered'][number],
2244
+ drawItemIndex: number,
2245
+ draws: readonly GeometryInstanceDraw[],
2246
+ ): readonly GeometryInstanceDraw[] | null {
2247
+ const resolve = c.gpuDrivenStandardPbrFrameResources?.surfaceDirectInstances;
2248
+ if (resolve === undefined) {
2249
+ c.runtime.errorRegistry.fire(
2250
+ new RhiError({
2251
+ code: 'rhi-not-available',
2252
+ expected: 'the prepared Surface producer publishes the direct slot-3 resource closure',
2253
+ hint: 'prepare the retained Surface frame before recording direct medium draws',
2254
+ }),
2255
+ );
2256
+ return null;
2257
+ }
2258
+ const resolved: GeometryInstanceDraw[] = [];
2259
+ for (const draw of draws) {
2260
+ const direct = resolve({
2261
+ worldId: entry.source.worldId,
2262
+ entityKey: entry.source.entityKey,
2263
+ drawItemIndex,
2264
+ instanceCount: draw.instanceCount,
2265
+ firstInstanceOrdinal: draw.firstInstanceOrdinal ?? 0,
2266
+ instanceBuffer: draw.instanceBuffer,
2267
+ ...(draw.probeBuffer === undefined ? {} : { probeBuffer: draw.probeBuffer }),
2268
+ ...(draw.probeOffset < 0
2269
+ ? {}
2270
+ : {
2271
+ probeOffset: draw.probeOffset,
2272
+ }),
2273
+ });
2274
+ if (!direct.ok) {
2275
+ c.runtime.errorRegistry.fire(direct.error);
2276
+ return null;
2277
+ }
2278
+ resolved.push({
2279
+ ...draw,
2280
+ instanceBindGroup: direct.value.bindGroup,
2281
+ dynamicOffsets: direct.value.dynamicOffsets,
2282
+ surfaceFrameBase: direct.value.frameBase,
2283
+ surfaceMemberIds: direct.value.memberIds,
2284
+ });
2285
+ }
2286
+ return resolved;
2287
+ }
2288
+
2289
+ export function resolveProbeBlendBuffer(
2290
+ c: InstanceBufferContext,
2060
2291
  record: import('../scene/probe-blend-record').ProbeBlendRecord | undefined,
2061
2292
  entityKey?: number,
2062
2293
  ): { readonly buffer: Buffer; readonly offset: number } {
2063
2294
  const { runtime, frameState } = c;
2064
- const usage = runtime.device.caps.storageBuffer
2065
- ? GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST
2066
- : GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST;
2067
2295
  if (record === undefined) throw new Error('probe blend record is required for probe allocation');
2068
2296
  if (entityKey === undefined) throw new Error('probe blend record requires an entity key');
2069
- const offset = probeBlendRecordOffset(record.objectKey);
2070
- const requiredCapacity = record.objectKey + 2;
2071
- let buffer = frameState.probeBlendRecordBuffer;
2072
- if (buffer === undefined || frameState.probeBlendRecordBufferCapacity < requiredCapacity) {
2073
- const created = runtime.device.createBuffer({
2074
- label: 'probe-blend-records',
2075
- size: requiredCapacity * PROBE_BLEND_RECORD_STRIDE,
2076
- usage,
2077
- mappedAtCreation: false,
2078
- });
2079
- if (!created.ok) throw created.error;
2080
- buffer = new GpuBuffer(runtime.device, created.value);
2081
- frameState.probeBlendRecordBuffer = buffer;
2082
- frameState.probeBlendRecordBufferCapacity = requiredCapacity;
2083
- // The cache is tied to the previous backing allocation. A new buffer has
2084
- // no valid record contents, so every later object must upload its full
2085
- // 160B payload even when generation/bytes match the old allocation.
2086
- frameState.probeBlendBuffers.clear();
2087
- }
2088
- const cached = frameState.probeBlendBuffers.get(entityKey);
2089
- const unchanged =
2090
- cached !== undefined &&
2091
- cached.generation === record.generation &&
2092
- cached.bytes.length === record.bytes.length &&
2093
- cached.bytes.every((value, index) => value === record.bytes[index]);
2094
- if (!unchanged) {
2095
- const uploaded = runtime.device.queue.writeBuffer(buffer.handle, offset, record.bytes);
2096
- if (!uploaded.ok) throw uploaded.error;
2097
- // Publish the generation only after the complete 160B queue write succeeds.
2098
- frameState.probeBlendBuffers.set(entityKey, {
2099
- generation: record.generation,
2100
- bytes: new Uint8Array(record.bytes),
2101
- });
2102
- }
2103
- return { buffer: buffer.handle, offset };
2297
+ const buffer = ensureProbeBlendRecordBuffer(runtime.device, frameState, [
2298
+ { cacheKey: entityKey, record },
2299
+ ]);
2300
+ if (buffer === undefined) throw new Error('probe blend record buffer allocation failed');
2301
+ return { buffer, offset: probeBlendRecordOffset(record.objectKey) };
2104
2302
  }
2105
2303
 
2106
2304
  export function resolveGeometryInstancesBindGroup(
2107
- c: _InternalRenderPipelineContext,
2305
+ c: InstanceBufferContext,
2108
2306
  instanceBuffer: Buffer,
2109
2307
  probeBuffer?: Buffer,
2110
2308
  ): BindGroup {