@forgeax/engine-render 0.1.33 → 0.1.35

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 +1062 -127
  2. package/dist/assembly/backend-contract.d.ts +2 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
  5. package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
  6. package/dist/assembly/canvas-draw-guard.d.ts +3 -0
  7. package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
  8. package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
  9. package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
  10. package/dist/assembly/device-feature-admission.d.ts +2 -2
  11. package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
  12. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  13. package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
  14. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
  15. package/dist/assembly/factory.d.ts +1 -1
  16. package/dist/assembly/factory.d.ts.map +1 -1
  17. package/dist/assembly/host-contract.d.ts +6 -5
  18. package/dist/assembly/host-contract.d.ts.map +1 -1
  19. package/dist/assembly/material/assembly.d.ts.map +1 -1
  20. package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
  21. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
  22. package/dist/assembly/material-shader-policy.d.ts +16 -2
  23. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  24. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
  25. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  26. package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
  27. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  28. package/dist/assembly/render-feature-post-processes.d.ts +6 -0
  29. package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
  30. package/dist/assembly/render-target-host.d.ts +5 -0
  31. package/dist/assembly/render-target-host.d.ts.map +1 -1
  32. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  33. package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
  34. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
  35. package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
  36. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  37. package/dist/assembly/renderer-inspection.d.ts +11 -0
  38. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  39. package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
  40. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
  41. package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
  42. package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
  43. package/dist/assembly/webgpu-ready.d.ts +1 -1
  44. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  45. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
  46. package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
  47. package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
  48. package/dist/assembly/webgpu-renderer.d.ts +2 -1
  49. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  50. package/dist/authoring.mjs +2 -4
  51. package/dist/authoring.mjs.map +1 -1
  52. package/dist/barrel-distortion.d.ts +47 -0
  53. package/dist/barrel-distortion.d.ts.map +1 -0
  54. package/dist/chunk-3XUBWRY2.mjs +1842 -0
  55. package/dist/chunk-3XUBWRY2.mjs.map +1 -0
  56. package/dist/{chunk-OO3DRYK7.mjs → chunk-G6HDNGY7.mjs} +2400 -1767
  57. package/dist/chunk-G6HDNGY7.mjs.map +1 -0
  58. package/dist/{chunk-ZDQWGQW7.mjs → chunk-LM5IE7GF.mjs} +4 -4
  59. package/dist/{chunk-ZDQWGQW7.mjs.map → chunk-LM5IE7GF.mjs.map} +1 -1
  60. package/dist/{chunk-VOZWDM3L.mjs → chunk-LNIUIKQ7.mjs} +1514 -498
  61. package/dist/chunk-LNIUIKQ7.mjs.map +1 -0
  62. package/dist/chunk-MXTWKZO4.mjs +3268 -0
  63. package/dist/chunk-MXTWKZO4.mjs.map +1 -0
  64. package/dist/chunk-MZ4C7EHF.mjs +6942 -0
  65. package/dist/chunk-MZ4C7EHF.mjs.map +1 -0
  66. package/dist/chunk-RIPAEGI6.mjs +48 -0
  67. package/dist/chunk-RIPAEGI6.mjs.map +1 -0
  68. package/dist/{chunk-LEAXOMYJ.mjs → chunk-SGPUJW3F.mjs} +117 -5
  69. package/dist/chunk-SGPUJW3F.mjs.map +1 -0
  70. package/dist/{chunk-PA5DRJNI.mjs → chunk-X2KA6WHM.mjs} +29 -4
  71. package/dist/chunk-X2KA6WHM.mjs.map +1 -0
  72. package/dist/{chunk-BLXGONR2.mjs → chunk-XSFB7XXQ.mjs} +51 -4
  73. package/dist/chunk-XSFB7XXQ.mjs.map +1 -0
  74. package/dist/cloud/density.d.ts +55 -0
  75. package/dist/cloud/density.d.ts.map +1 -0
  76. package/dist/cloud/extract.d.ts +25 -0
  77. package/dist/cloud/extract.d.ts.map +1 -0
  78. package/dist/cloud/feature.d.ts +57 -0
  79. package/dist/cloud/feature.d.ts.map +1 -0
  80. package/dist/cloud/frame-context.d.ts +8 -0
  81. package/dist/cloud/frame-context.d.ts.map +1 -0
  82. package/dist/cloud/inspection.d.ts +59 -0
  83. package/dist/cloud/inspection.d.ts.map +1 -0
  84. package/dist/cloud/optics.d.ts +56 -0
  85. package/dist/cloud/optics.d.ts.map +1 -0
  86. package/dist/cloud/parameters.d.ts +73 -0
  87. package/dist/cloud/parameters.d.ts.map +1 -0
  88. package/dist/cloud/resources.d.ts +60 -0
  89. package/dist/cloud/resources.d.ts.map +1 -0
  90. package/dist/cloud/shadow.d.ts +42 -0
  91. package/dist/cloud/shadow.d.ts.map +1 -0
  92. package/dist/cloud/temporal.d.ts +74 -0
  93. package/dist/cloud/temporal.d.ts.map +1 -0
  94. package/dist/components/barrel-distortion.d.ts +13 -0
  95. package/dist/components/barrel-distortion.d.ts.map +1 -0
  96. package/dist/components/cloud-layer.d.ts +29 -0
  97. package/dist/components/cloud-layer.d.ts.map +1 -0
  98. package/dist/components/index.d.ts +2 -0
  99. package/dist/components/index.d.ts.map +1 -1
  100. package/dist/components/instances.d.ts +20 -6
  101. package/dist/components/instances.d.ts.map +1 -1
  102. package/dist/construct-renderer.d.ts +1 -1
  103. package/dist/construct-renderer.d.ts.map +1 -1
  104. package/dist/construct-renderer.mjs +8406 -5785
  105. package/dist/construct-renderer.mjs.map +1 -1
  106. package/dist/device/gpu-residency.d.ts +19 -19
  107. package/dist/device/gpu-residency.d.ts.map +1 -1
  108. package/dist/dynamic-geometry.d.ts +5 -1
  109. package/dist/dynamic-geometry.d.ts.map +1 -1
  110. package/dist/errors/cloud.d.ts +59 -0
  111. package/dist/errors/cloud.d.ts.map +1 -0
  112. package/dist/errors/render.d.ts +20 -5
  113. package/dist/errors/render.d.ts.map +1 -1
  114. package/dist/examples/single-layer-medium-surface.d.ts +47 -0
  115. package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
  116. package/dist/extract/camera.d.ts.map +1 -1
  117. package/dist/extract/contracts.d.ts +5 -1
  118. package/dist/extract/contracts.d.ts.map +1 -1
  119. package/dist/extract/material-context.d.ts +7 -0
  120. package/dist/extract/material-context.d.ts.map +1 -0
  121. package/dist/features/barrel-distortion.d.ts +29 -0
  122. package/dist/features/barrel-distortion.d.ts.map +1 -0
  123. package/dist/features/error-reporting.d.ts +6 -2
  124. package/dist/features/error-reporting.d.ts.map +1 -1
  125. package/dist/features/host.d.ts +15 -0
  126. package/dist/features/host.d.ts.map +1 -1
  127. package/dist/features/plan.d.ts +10 -0
  128. package/dist/features/plan.d.ts.map +1 -1
  129. package/dist/features/render-graph-contribution.d.ts +5 -0
  130. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  131. package/dist/features/render-graph-raster.d.ts +1 -0
  132. package/dist/features/render-graph-raster.d.ts.map +1 -1
  133. package/dist/features/targets.d.ts +2 -0
  134. package/dist/features/targets.d.ts.map +1 -1
  135. package/dist/features/types.d.ts +48 -0
  136. package/dist/features/types.d.ts.map +1 -1
  137. package/dist/fullscreen-post-process-pass.d.ts +15 -7
  138. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  139. package/dist/glyph-text-layout-system.d.ts +1 -1
  140. package/dist/glyph-text-layout-system.d.ts.map +1 -1
  141. package/dist/gpu-dirty-ranges.d.ts +11 -0
  142. package/dist/gpu-dirty-ranges.d.ts.map +1 -0
  143. package/dist/gpu-driven/batch-topology.d.ts +17 -0
  144. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  145. package/dist/gpu-driven/material-artifacts.d.ts +6 -0
  146. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  147. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  148. package/dist/gpu-driven/production-raster-material.d.ts +178 -0
  149. package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
  150. package/dist/gpu-driven/production-raster.d.ts +47 -3
  151. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  152. package/dist/gpu-driven/resource-allocation.d.ts +31 -0
  153. package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
  154. package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
  155. package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
  156. package/dist/gpu-driven/view-gpu.d.ts +26 -2
  157. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  158. package/dist/gpu-scene.d.ts +5 -0
  159. package/dist/gpu-scene.d.ts.map +1 -1
  160. package/dist/hdrp-buffers.d.ts +2 -2
  161. package/dist/hdrp-buffers.d.ts.map +1 -1
  162. package/dist/ibl/frame-resources.d.ts.map +1 -1
  163. package/dist/ibl/skylight-bind-group.d.ts +14 -5
  164. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  165. package/dist/index.d.ts +30 -7
  166. package/dist/index.d.ts.map +1 -1
  167. package/dist/index.mjs +780 -9
  168. package/dist/index.mjs.map +1 -1
  169. package/dist/inspection-types.d.ts +135 -1
  170. package/dist/inspection-types.d.ts.map +1 -1
  171. package/dist/instance-buffer-cache.d.ts +4 -4
  172. package/dist/instance-buffer-cache.d.ts.map +1 -1
  173. package/dist/instances.d.ts +47 -100
  174. package/dist/instances.d.ts.map +1 -1
  175. package/dist/internal.mjs +7 -8
  176. package/dist/internal.mjs.map +1 -1
  177. package/dist/pbr-pipeline.d.ts +22 -4
  178. package/dist/pbr-pipeline.d.ts.map +1 -1
  179. package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
  180. package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
  181. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  182. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  183. package/dist/pipeline/standard-output/lut-gpu.d.ts +2 -2
  184. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -1
  185. package/dist/pipeline/standard-output/resources.d.ts +2 -2
  186. package/dist/pipeline/standard-output/resources.d.ts.map +1 -1
  187. package/dist/pipeline/standard-output/types.d.ts +4 -2
  188. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  189. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  190. package/dist/pipeline/standard-post.d.ts.map +1 -1
  191. package/dist/pipeline-builder.d.ts +1 -1
  192. package/dist/pipeline-builder.d.ts.map +1 -1
  193. package/dist/plugin.d.ts.map +1 -1
  194. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
  195. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  196. package/dist/publication/contract.d.ts +77 -0
  197. package/dist/publication/contract.d.ts.map +1 -0
  198. package/dist/publication/dependencies.d.ts +7 -0
  199. package/dist/publication/dependencies.d.ts.map +1 -0
  200. package/dist/publication/prepare-geometry.d.ts +9 -0
  201. package/dist/publication/prepare-geometry.d.ts.map +1 -0
  202. package/dist/publication/programs.d.ts +5 -0
  203. package/dist/publication/programs.d.ts.map +1 -0
  204. package/dist/publication/publisher.d.ts +33 -0
  205. package/dist/publication/publisher.d.ts.map +1 -0
  206. package/dist/publication/receiver.d.ts +29 -0
  207. package/dist/publication/receiver.d.ts.map +1 -0
  208. package/dist/publication/resource-scope.d.ts +18 -0
  209. package/dist/publication/resource-scope.d.ts.map +1 -0
  210. package/dist/publication/targets.d.ts +33 -0
  211. package/dist/publication/targets.d.ts.map +1 -0
  212. package/dist/publication/video.d.ts +5 -0
  213. package/dist/publication/video.d.ts.map +1 -0
  214. package/dist/record/barrel-distortion-frame.d.ts +15 -0
  215. package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
  216. package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
  217. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
  218. package/dist/record/fold-buckets.d.ts +95 -0
  219. package/dist/record/fold-buckets.d.ts.map +1 -0
  220. package/dist/record/fold-instance-buffer.d.ts +6 -0
  221. package/dist/record/fold-instance-buffer.d.ts.map +1 -0
  222. package/dist/record/frame-lighting.d.ts +1 -0
  223. package/dist/record/frame-lighting.d.ts.map +1 -1
  224. package/dist/record/frame-snapshot.d.ts +43 -9
  225. package/dist/record/frame-snapshot.d.ts.map +1 -1
  226. package/dist/record/frame.d.ts +15 -65
  227. package/dist/record/frame.d.ts.map +1 -1
  228. package/dist/record/gpu-draw-receipts.d.ts +11 -0
  229. package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
  230. package/dist/record/gpu-timing.d.ts +8 -0
  231. package/dist/record/gpu-timing.d.ts.map +1 -1
  232. package/dist/record/helpers.d.ts +2 -2
  233. package/dist/record/helpers.d.ts.map +1 -1
  234. package/dist/record/main-pass-geometry.d.ts +22 -6
  235. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  236. package/dist/record/main-pass-material.d.ts +14 -10
  237. package/dist/record/main-pass-material.d.ts.map +1 -1
  238. package/dist/record/main-pass-sprite-draws.d.ts +3 -16
  239. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  240. package/dist/record/main-pass.d.ts +13 -2
  241. package/dist/record/main-pass.d.ts.map +1 -1
  242. package/dist/record/motion-blur-receipt.d.ts +11 -0
  243. package/dist/record/motion-blur-receipt.d.ts.map +1 -0
  244. package/dist/record/prepared-material-bindings.d.ts +3 -3
  245. package/dist/record/prepared-material-bindings.d.ts.map +1 -1
  246. package/dist/record/probe-blend-buffer.d.ts +16 -0
  247. package/dist/record/probe-blend-buffer.d.ts.map +1 -0
  248. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  249. package/dist/record/render-context.d.ts +24 -5
  250. package/dist/record/render-context.d.ts.map +1 -1
  251. package/dist/record/shadow-pass.d.ts +2 -0
  252. package/dist/record/shadow-pass.d.ts.map +1 -1
  253. package/dist/record/skybox-post-pass.d.ts +1 -1
  254. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  255. package/dist/record/sprite-instance-buffer.d.ts +31 -0
  256. package/dist/record/sprite-instance-buffer.d.ts.map +1 -0
  257. package/dist/record/target-capture-graph.d.ts +19 -0
  258. package/dist/record/target-capture-graph.d.ts.map +1 -0
  259. package/dist/record/typed-frame-graph.d.ts +24 -15
  260. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  261. package/dist/record/view-ubo.d.ts +11 -3
  262. package/dist/record/view-ubo.d.ts.map +1 -1
  263. package/dist/record/volume-params.d.ts +9 -0
  264. package/dist/record/volume-params.d.ts.map +1 -0
  265. package/dist/recovery/render-system-candidate.d.ts +14 -4
  266. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  267. package/dist/reflection/record-owner.d.ts.map +1 -1
  268. package/dist/render-contract.d.ts +46 -5
  269. package/dist/render-contract.d.ts.map +1 -1
  270. package/dist/render-graph-primitives.d.ts.map +1 -1
  271. package/dist/render-pipeline.d.ts +103 -2
  272. package/dist/render-pipeline.d.ts.map +1 -1
  273. package/dist/render-system-extract-tail.d.ts +3 -2
  274. package/dist/render-system-extract-tail.d.ts.map +1 -1
  275. package/dist/render-system-extract.d.ts +18 -9
  276. package/dist/render-system-extract.d.ts.map +1 -1
  277. package/dist/render-system-presentation.d.ts +23 -0
  278. package/dist/render-system-presentation.d.ts.map +1 -0
  279. package/dist/render-system-producer-roots.d.ts +10 -0
  280. package/dist/render-system-producer-roots.d.ts.map +1 -0
  281. package/dist/render-system-projections.d.ts +3 -2
  282. package/dist/render-system-projections.d.ts.map +1 -1
  283. package/dist/render-system-residency.d.ts +12 -0
  284. package/dist/render-system-residency.d.ts.map +1 -0
  285. package/dist/render-system.d.ts +22 -21
  286. package/dist/render-system.d.ts.map +1 -1
  287. package/dist/scene/probe-blend.d.ts +27 -0
  288. package/dist/scene/probe-blend.d.ts.map +1 -1
  289. package/dist/scene/render-scene.d.ts +18 -7
  290. package/dist/scene/render-scene.d.ts.map +1 -1
  291. package/dist/scene/render-source.d.ts +42 -0
  292. package/dist/scene/render-source.d.ts.map +1 -0
  293. package/dist/scene/source-systems.d.ts +6 -0
  294. package/dist/scene/source-systems.d.ts.map +1 -0
  295. package/dist/ssao-buffers.d.ts +9 -0
  296. package/dist/ssao-buffers.d.ts.map +1 -1
  297. package/dist/surface/dynamic-input.d.ts +133 -0
  298. package/dist/surface/dynamic-input.d.ts.map +1 -0
  299. package/dist/surface/gpu-driven.d.ts +41 -0
  300. package/dist/surface/gpu-driven.d.ts.map +1 -0
  301. package/dist/surface/submission-observation.d.ts +136 -0
  302. package/dist/surface/submission-observation.d.ts.map +1 -0
  303. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  304. package/dist/systems/skin-palette-types.d.ts +10 -0
  305. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  306. package/dist/systems/transparent-dispatch.d.ts +2 -2
  307. package/dist/systems/transparent-dispatch.d.ts.map +1 -1
  308. package/dist/systems/transparent-sort-config.d.ts +2 -1
  309. package/dist/systems/transparent-sort-config.d.ts.map +1 -1
  310. package/dist/temporal/gpu.d.ts +13 -1
  311. package/dist/temporal/gpu.d.ts.map +1 -1
  312. package/dist/temporal/index.mjs +6 -7
  313. package/dist/temporal/inspection.d.ts.map +1 -1
  314. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  315. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
  316. package/dist/transmission/single-layer-medium.d.ts +89 -0
  317. package/dist/transmission/single-layer-medium.d.ts.map +1 -0
  318. package/dist/typed-render-graph-primitives.d.ts +14 -2
  319. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  320. package/dist/volume/component.d.ts +9 -4
  321. package/dist/volume/component.d.ts.map +1 -1
  322. package/dist/volume/extract.d.ts +1 -1
  323. package/dist/volume/extract.d.ts.map +1 -1
  324. package/dist/volume/inspection.d.ts +2 -0
  325. package/dist/volume/inspection.d.ts.map +1 -1
  326. package/dist/volume/passes.d.ts +4 -1
  327. package/dist/volume/passes.d.ts.map +1 -1
  328. package/dist/volume/resources.d.ts.map +1 -1
  329. package/package.json +22 -21
  330. package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
  331. package/src/__tests__/auto-exposure-transaction.integration.test.ts +4 -9
  332. package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
  333. package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
  334. package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
  335. package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
  336. package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
  337. package/src/__tests__/device-feature-admission.unit.test.ts +3 -2
  338. package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
  339. package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
  340. package/src/__tests__/factory-contract.integration.test.ts +295 -45
  341. package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
  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-material-artifacts.unit.test.ts +143 -0
  347. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +5 -6
  348. package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
  349. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +6 -5
  350. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +94 -6
  351. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
  352. package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
  353. package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
  354. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
  355. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
  356. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
  357. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
  358. package/src/__tests__/gpu-scene.unit.test.ts +119 -9
  359. package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
  360. package/src/__tests__/instances-culling.integration.test.ts +10 -36
  361. package/src/__tests__/instances-store.unit.test.ts +97 -305
  362. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  363. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +4 -1
  364. package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +145 -0
  365. package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
  366. package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
  367. package/src/__tests__/materials-standard-contract.unit.test.ts +0 -1
  368. package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
  369. package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
  370. package/src/__tests__/motion-blur-compute.dawn.test.ts +13 -7
  371. package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
  372. package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
  373. package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
  374. package/src/__tests__/physical-clearcoat.integration.test.ts +66 -8
  375. package/src/__tests__/physical-material-budget.unit.test.ts +40 -0
  376. package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
  377. package/src/__tests__/probe-bindings.unit.test.ts +582 -1
  378. package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
  379. package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
  380. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
  381. package/src/__tests__/render-error-code-owner.test-d.ts +8 -0
  382. package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
  383. package/src/__tests__/render-feature-error-reporting.unit.test.ts +21 -1
  384. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
  385. package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
  386. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
  387. package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
  388. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +20 -20
  389. package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
  390. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
  391. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
  392. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +42 -8
  393. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
  394. package/src/__tests__/renderer-frame-transaction.integration.test.ts +26 -10
  395. package/src/__tests__/resource-allocation.unit.test.ts +123 -0
  396. package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
  397. package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
  398. package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
  399. package/src/__tests__/skinned-shadow-caster.test.ts +15 -0
  400. package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
  401. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
  402. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
  403. package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
  404. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
  405. package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
  406. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
  407. package/src/__tests__/standard-pipeline.integration.test.ts +182 -1
  408. package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
  409. package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
  410. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
  411. package/src/__tests__/temporal-performance.integration.test.ts +3 -3
  412. package/src/__tests__/visibility-instances.integration.test.ts +7 -19
  413. package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
  414. package/src/__tests__/volume-optics-oracle.unit.test.ts +4 -2
  415. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +30 -20
  416. package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
  417. package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
  418. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
  419. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +113 -9
  420. package/src/__tests__/volumetric-fog-topology.unit.test.ts +5 -3
  421. package/src/assembly/backend-contract.ts +30 -0
  422. package/src/assembly/barrel-distortion-inspection.ts +22 -0
  423. package/src/assembly/canvas-draw-guard.ts +11 -0
  424. package/src/assembly/cloud-shadow-entry.ts +22 -0
  425. package/src/assembly/device-feature-admission.ts +2 -2
  426. package/src/assembly/dynamic-geometry-host.ts +65 -37
  427. package/src/assembly/dynamic-geometry-runtime.ts +7 -1
  428. package/src/assembly/factory.ts +2 -30
  429. package/src/assembly/host-contract.ts +8 -5
  430. package/src/assembly/material/assembly.ts +25 -13
  431. package/src/assembly/material/pipeline-helpers.ts +53 -12
  432. package/src/assembly/material-shader-policy.ts +55 -0
  433. package/src/assembly/material-shader-prewarm.ts +21 -10
  434. package/src/assembly/recovery/device-loss-fanout.ts +13 -0
  435. package/src/assembly/recovery/renderer-recover.ts +50 -18
  436. package/src/assembly/render-feature-post-processes.ts +54 -0
  437. package/src/assembly/render-target-host.ts +57 -47
  438. package/src/assembly/renderer-facade.ts +7 -2
  439. package/src/assembly/renderer-feature-inspection.ts +8 -2
  440. package/src/assembly/renderer-frame-transaction.ts +23 -0
  441. package/src/assembly/renderer-inspection.ts +28 -0
  442. package/src/assembly/skin-palette-owner.ts +1 -1
  443. package/src/assembly/temporal-post-process-prewarm.ts +3 -3
  444. package/src/assembly/webgpu-pbr-ready.ts +9 -1
  445. package/src/assembly/webgpu-ready-per-pass.ts +104 -0
  446. package/src/assembly/webgpu-ready.ts +116 -62
  447. package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
  448. package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
  449. package/src/assembly/webgpu-renderer.ts +303 -313
  450. package/src/assembly/webgpu-vertex-layouts.ts +1 -1
  451. package/src/barrel-distortion.ts +247 -0
  452. package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
  453. package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
  454. package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
  455. package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
  456. package/src/cloud/density.ts +600 -0
  457. package/src/cloud/extract.ts +110 -0
  458. package/src/cloud/feature.ts +1810 -0
  459. package/src/cloud/frame-context.ts +42 -0
  460. package/src/cloud/inspection.ts +130 -0
  461. package/src/cloud/optics.ts +285 -0
  462. package/src/cloud/parameters.ts +255 -0
  463. package/src/cloud/resources.ts +122 -0
  464. package/src/cloud/shadow.ts +167 -0
  465. package/src/cloud/temporal.ts +226 -0
  466. package/src/components/barrel-distortion.ts +46 -0
  467. package/src/components/cloud-layer.ts +47 -0
  468. package/src/components/index.ts +2 -0
  469. package/src/components/instances.ts +18 -45
  470. package/src/components/sprite-instances.ts +1 -1
  471. package/src/construct-renderer.ts +1 -1
  472. package/src/device/gpu-residency.ts +26 -25
  473. package/src/dynamic-geometry.ts +12 -1
  474. package/src/errors/cloud.ts +103 -0
  475. package/src/errors/render.ts +47 -8
  476. package/src/examples/single-layer-medium-surface.ts +59 -0
  477. package/src/extract/camera.ts +15 -1
  478. package/src/extract/contracts.ts +5 -0
  479. package/src/extract/material-context.ts +21 -0
  480. package/src/features/barrel-distortion.ts +172 -0
  481. package/src/features/error-reporting.ts +26 -6
  482. package/src/features/host.ts +128 -19
  483. package/src/features/plan.ts +10 -0
  484. package/src/features/render-graph-contribution.ts +9 -0
  485. package/src/features/render-graph-raster.ts +45 -3
  486. package/src/features/targets.ts +66 -0
  487. package/src/features/types.ts +51 -0
  488. package/src/fullscreen-post-process-pass.ts +41 -9
  489. package/src/glyph-text-layout-system.ts +2 -2
  490. package/src/gpu-dirty-ranges.ts +48 -0
  491. package/src/gpu-driven/batch-topology.ts +53 -0
  492. package/src/gpu-driven/material-artifacts.ts +33 -25
  493. package/src/gpu-driven/prepared-draw.ts +12 -4
  494. package/src/gpu-driven/production-raster-material.ts +1894 -0
  495. package/src/gpu-driven/production-raster.ts +825 -784
  496. package/src/gpu-driven/resource-allocation.ts +142 -0
  497. package/src/gpu-driven/shadow-ownership.ts +71 -0
  498. package/src/gpu-driven/view-gpu.ts +164 -10
  499. package/src/gpu-scene.ts +75 -84
  500. package/src/hdrp-buffers.ts +4 -3
  501. package/src/ibl/frame-resources.ts +0 -1
  502. package/src/ibl/skylight-bind-group.ts +62 -32
  503. package/src/index.ts +205 -9
  504. package/src/inspection-types.ts +162 -0
  505. package/src/instance-buffer-cache.ts +4 -4
  506. package/src/instances.ts +152 -569
  507. package/src/pbr-pipeline.ts +230 -30
  508. package/src/pipeline/single-layer-medium-passes.ts +267 -0
  509. package/src/pipeline/standard-forward-lane.ts +313 -57
  510. package/src/pipeline/standard-output/graph.ts +8 -2
  511. package/src/pipeline/standard-output/lut-gpu.ts +3 -3
  512. package/src/pipeline/standard-output/resources.ts +2 -2
  513. package/src/pipeline/standard-output/types.ts +12 -1
  514. package/src/pipeline/standard-pipeline.ts +291 -18
  515. package/src/pipeline/standard-post.ts +90 -24
  516. package/src/pipeline-builder.ts +1 -1
  517. package/src/plugin.ts +4 -0
  518. package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
  519. package/src/prepare/prepared-graphics-resolver.ts +2 -0
  520. package/src/publication/__tests__/derived-geometry.integration.test.ts +177 -0
  521. package/src/publication/__tests__/features.integration.test.ts +122 -0
  522. package/src/publication/__tests__/programs.unit.test.ts +25 -0
  523. package/src/publication/__tests__/publication.integration.test.ts +370 -0
  524. package/src/publication/__tests__/targets.integration.test.ts +120 -0
  525. package/src/publication/__tests__/video.browser.test.ts +50 -0
  526. package/src/publication/contract.ts +104 -0
  527. package/src/publication/dependencies.ts +54 -0
  528. package/src/publication/prepare-geometry.ts +94 -0
  529. package/src/publication/programs.ts +45 -0
  530. package/src/publication/publisher.ts +618 -0
  531. package/src/publication/receiver.ts +297 -0
  532. package/src/publication/resource-scope.ts +31 -0
  533. package/src/publication/targets.ts +182 -0
  534. package/src/publication/video.ts +33 -0
  535. package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
  536. package/src/record/__tests__/material-bg-cache.unit.test.ts +15 -1
  537. package/src/record/__tests__/sprite-material-abi.unit.test.ts +9 -11
  538. package/src/record/__tests__/temporal-payload.unit.test.ts +1 -1
  539. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
  540. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
  541. package/src/record/__tests__/video-texture-view.unit.test.ts +9 -9
  542. package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
  543. package/src/record/barrel-distortion-frame.ts +110 -0
  544. package/src/record/dynamic-geometry-consumption.ts +39 -9
  545. package/src/record/fold-buckets.ts +855 -0
  546. package/src/record/fold-instance-buffer.ts +51 -0
  547. package/src/record/frame-lighting.ts +36 -2
  548. package/src/record/frame-snapshot.ts +45 -9
  549. package/src/record/frame.ts +258 -1105
  550. package/src/record/gpu-draw-receipts.ts +38 -0
  551. package/src/record/gpu-timing.ts +48 -5
  552. package/src/record/helpers.ts +2 -2
  553. package/src/record/main-pass-geometry.ts +272 -84
  554. package/src/record/main-pass-material.ts +102 -36
  555. package/src/record/main-pass-sprite-draws.ts +13 -217
  556. package/src/record/main-pass.ts +164 -27
  557. package/src/record/motion-blur-receipt.ts +91 -0
  558. package/src/record/prepared-material-bindings.ts +11 -6
  559. package/src/record/probe-blend-buffer.ts +180 -0
  560. package/src/record/recovery-pipeline.ts +35 -3
  561. package/src/record/render-context.ts +41 -5
  562. package/src/record/shadow-pass.ts +30 -4
  563. package/src/record/skybox-post-pass.ts +28 -4
  564. package/src/record/sprite-instance-buffer.ts +155 -0
  565. package/src/record/target-capture-graph.ts +258 -0
  566. package/src/record/typed-frame-graph.ts +776 -340
  567. package/src/record/view-ubo.ts +27 -4
  568. package/src/record/volume-params.ts +225 -0
  569. package/src/recovery/render-system-candidate.ts +243 -50
  570. package/src/reflection/record-owner.ts +7 -3
  571. package/src/render-contract.ts +54 -5
  572. package/src/render-graph-primitives.ts +7 -1
  573. package/src/render-pipeline.ts +130 -0
  574. package/src/render-system-extract-tail.ts +90 -78
  575. package/src/render-system-extract.ts +76 -76
  576. package/src/render-system-presentation.ts +56 -0
  577. package/src/render-system-producer-roots.ts +96 -0
  578. package/src/render-system-projections.ts +3 -2
  579. package/src/render-system-residency.ts +159 -0
  580. package/src/render-system.ts +421 -408
  581. package/src/scene/probe-blend.ts +96 -4
  582. package/src/scene/render-scene.ts +416 -337
  583. package/src/scene/render-source.ts +90 -0
  584. package/src/scene/source-systems.ts +33 -0
  585. package/src/ssao-buffers.ts +95 -2
  586. package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
  587. package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
  588. package/src/surface/dynamic-input.ts +658 -0
  589. package/src/surface/gpu-driven.ts +147 -0
  590. package/src/surface/submission-observation.ts +517 -0
  591. package/src/systems/skin-palette-allocator.ts +5 -1
  592. package/src/systems/skin-palette-types.ts +11 -0
  593. package/src/systems/transparent-dispatch.ts +2 -2
  594. package/src/systems/transparent-sort-config.ts +3 -1
  595. package/src/temporal/gpu.ts +101 -17
  596. package/src/temporal/inspection.ts +7 -1
  597. package/src/temporal/standard-scene-data.ts +5 -0
  598. package/src/temporal/target-coverage-attachment.ts +4 -0
  599. package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
  600. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
  601. package/src/transmission/single-layer-medium.ts +322 -0
  602. package/src/typed-render-graph-primitives.ts +70 -2
  603. package/src/volume/component.ts +10 -9
  604. package/src/volume/extract.ts +11 -5
  605. package/src/volume/inspection.ts +3 -0
  606. package/src/volume/passes.ts +87 -4
  607. package/src/volume/resources.ts +2 -1
  608. package/dist/chunk-3RTCJTH4.mjs +0 -1610
  609. package/dist/chunk-3RTCJTH4.mjs.map +0 -1
  610. package/dist/chunk-BLXGONR2.mjs.map +0 -1
  611. package/dist/chunk-ILQ5MEZF.mjs +0 -32
  612. package/dist/chunk-ILQ5MEZF.mjs.map +0 -1
  613. package/dist/chunk-LEAXOMYJ.mjs.map +0 -1
  614. package/dist/chunk-NB2S7ZRX.mjs +0 -1783
  615. package/dist/chunk-NB2S7ZRX.mjs.map +0 -1
  616. package/dist/chunk-NNQL7CB3.mjs +0 -1713
  617. package/dist/chunk-NNQL7CB3.mjs.map +0 -1
  618. package/dist/chunk-OO3DRYK7.mjs.map +0 -1
  619. package/dist/chunk-PA5DRJNI.mjs.map +0 -1
  620. package/dist/chunk-PLAXOOX5.mjs +0 -1907
  621. package/dist/chunk-PLAXOOX5.mjs.map +0 -1
  622. package/dist/chunk-RXZ3RGOU.mjs +0 -53
  623. package/dist/chunk-RXZ3RGOU.mjs.map +0 -1
  624. package/dist/chunk-VOZWDM3L.mjs.map +0 -1
@@ -1,8 +1,9 @@
1
+ import type { RenderResourceScope } from '../publication/resource-scope';
2
+ import { resolveSpriteInstancesBuffer } from './sprite-instance-buffer';
1
3
  // @forgeax/engine-runtime - RenderSystem record stage: main-pass geometry draws.
2
4
  // feat-20260704 M5/w31: further-split from main-pass.ts (AC-05 <=1500 lines/file).
3
5
  // recordGeometryDraws + resolveGeometryInstanceBuffer, moved verbatim.
4
6
 
5
- import type { World } from '@forgeax/engine-ecs';
6
7
  import {
7
8
  type BindGroup,
8
9
  type Buffer,
@@ -43,11 +44,9 @@ import type { PointsLinesRecordPlan } from '../points-lines/record';
43
44
  import { POINTS_LINES_MATERIAL_SHADER_ID } from '../points-lines/record';
44
45
  import type { RenderRecordPhase } from '../render-contract';
45
46
  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';
47
+ import { PROBE_BLEND_RECORD_BYTE_SIZE, probeBlendRecordOffset } from '../scene/probe-blend-record';
48
+ import type { SurfacePassName } from '../surface/submission-observation';
49
+ import { resolveFoldInstanceBuffer } from './fold-instance-buffer';
51
50
  import {
52
51
  getOpaqueResourceIdentity,
53
52
  instanceCollectionCacheKey,
@@ -69,6 +68,7 @@ import {
69
68
  MESH_UBO_FULL_ARRAY_BYTES,
70
69
  packInstanceStorageBuffer,
71
70
  } from './mesh-ssbo';
71
+ import { ensureProbeBlendRecordBuffer } from './probe-blend-buffer';
72
72
  import type { _InternalRenderPipelineContext, MaterialShaderPipelineEntry } from './render-context';
73
73
  import { MATERIAL_PER_ENTITY_STRIDE } from './render-context';
74
74
  import { POINTS_LINES_VIEW_SLOT_STRIDE, writePointsLinesViewUbo } from './view-ubo';
@@ -93,11 +93,19 @@ export function sameOpaqueTemporalDraw(a: DispatchEntry, b: DispatchEntry): bool
93
93
  type GeometryInstanceDraw = {
94
94
  readonly instanceBuffer: Buffer;
95
95
  readonly instanceBindGroup: BindGroup;
96
+ /** Producer-owned Probe buffer paired with probeOffset, when present. */
97
+ readonly probeBuffer?: Buffer;
96
98
  /** -1 means the no-probe layout and therefore no dynamic offset. */
97
99
  readonly probeOffset: number;
100
+ readonly dynamicOffsets?: readonly number[];
98
101
  readonly instanceCount: number;
102
+ readonly firstInstanceOrdinal?: number;
103
+ readonly surfaceFrameBase?: number;
104
+ readonly surfaceMemberIds?: readonly string[];
99
105
  };
100
106
 
107
+ type DirectSurfaceLayoutKind = 'surface-direct-pbr' | 'surface-direct-cluster-pbr';
108
+
101
109
  type InstanceUploadResult =
102
110
  | {
103
111
  readonly ok: true;
@@ -113,6 +121,7 @@ type InstanceUploadResult =
113
121
  type GeometryBindingState = {
114
122
  pipeline: RenderPipeline | null;
115
123
  instancesBuffer: Buffer | null;
124
+ instanceBindGroup: BindGroup | null;
116
125
  probeOffset: number;
117
126
  };
118
127
 
@@ -143,6 +152,7 @@ type MaterialPipelineLookup = {
143
152
  readonly colorFormatOverride: GPUTextureFormat | undefined;
144
153
  readonly additionalColorFormats: readonly GPUTextureFormat[] | undefined;
145
154
  readonly textureMask: number | undefined;
155
+ readonly layoutKind: DirectSurfaceLayoutKind | undefined;
146
156
  readonly handle: MaterialShaderPipelineEntry | null;
147
157
  };
148
158
 
@@ -219,10 +229,11 @@ function isGpuDrivenMainClaimedSubmesh(
219
229
  if (drawItemIndex === undefined || draw === undefined) return false;
220
230
  const material = source.materials[draw.materialSlot] ?? source.material;
221
231
  const sourceDrawItemIndex = gpuDrivenSourceDrawItemIndex(draw, drawItemIndex);
232
+ const stableWorld = c.gpuDrivenWorldKeys?.[source.worldId] ?? source.worldId;
222
233
  return (
223
234
  c.gpuDrivenDrawKeys?.has(
224
235
  gpuDrivenDrawKey(
225
- worldEntityKey(source.worldId, source.entityKey),
236
+ worldEntityKey(stableWorld, source.entityKey),
226
237
  material.materialHandle ?? -1,
227
238
  sourceDrawItemIndex,
228
239
  ),
@@ -365,6 +376,22 @@ export function geometryRenderStateForPass(
365
376
  };
366
377
  }
367
378
 
379
+ /**
380
+ * Transparent depth is an authored medium policy. A transparent pass with no
381
+ * explicit depth-write bit remains read-only, which keeps alpha smoke and
382
+ * ordinary blending from becoming an opaque occluder; water or a cutout-like
383
+ * medium can opt in by setting the bit on its own pass state.
384
+ */
385
+ export function authoredTransparentDepthWrite(
386
+ transparent: boolean | undefined,
387
+ renderState: MaterialSnapshot['renderState'],
388
+ ): boolean {
389
+ return (
390
+ (transparent === true || renderState?.blend !== undefined) &&
391
+ renderState?.depthWriteEnabled === true
392
+ );
393
+ }
394
+
368
395
  function geometryRecordPhase(
369
396
  passKind: PassKind,
370
397
  segment: GeometryRecordProfileSegment,
@@ -394,7 +421,7 @@ function submitSubmeshDraws(
394
421
  indexCount: number,
395
422
  vertexCount: number,
396
423
  indexOffset: number,
397
- onDraw?: () => void,
424
+ onDraw?: (draw: GeometryInstanceDraw, command: 'draw' | 'draw-indexed') => void,
398
425
  ): void {
399
426
  if (state.pipeline !== pipeline) {
400
427
  pass.setPipeline(pipeline);
@@ -403,14 +430,18 @@ function submitSubmeshDraws(
403
430
  for (const instanceDraw of instanceDraws) {
404
431
  if (
405
432
  instanceDraw.instanceBuffer !== state.instancesBuffer ||
433
+ instanceDraw.instanceBindGroup !== state.instanceBindGroup ||
406
434
  instanceDraw.probeOffset !== state.probeOffset
407
435
  ) {
408
- if (instanceDraw.probeOffset < 0) {
436
+ if (instanceDraw.dynamicOffsets !== undefined) {
437
+ pass.setBindGroup(3, instanceDraw.instanceBindGroup, instanceDraw.dynamicOffsets);
438
+ } else if (instanceDraw.probeOffset < 0) {
409
439
  pass.setBindGroup(3, instanceDraw.instanceBindGroup);
410
440
  } else {
411
441
  pass.setBindGroup(3, instanceDraw.instanceBindGroup, [instanceDraw.probeOffset]);
412
442
  }
413
443
  state.instancesBuffer = instanceDraw.instanceBuffer;
444
+ state.instanceBindGroup = instanceDraw.instanceBindGroup;
414
445
  state.probeOffset = instanceDraw.probeOffset;
415
446
  }
416
447
  if (indexed) {
@@ -418,7 +449,7 @@ function submitSubmeshDraws(
418
449
  } else {
419
450
  pass.draw(vertexCount, instanceDraw.instanceCount, 0, 0);
420
451
  }
421
- onDraw?.();
452
+ onDraw?.(instanceDraw, indexed ? 'draw-indexed' : 'draw');
422
453
  }
423
454
  }
424
455
 
@@ -465,13 +496,16 @@ export function recordGeometryDraws(
465
496
  materialSlot: number,
466
497
  submeshMaterial: MaterialSnapshot,
467
498
  entityKey: number,
468
- materialWorld: World,
499
+ materialWorld: RenderResourceScope,
469
500
  materialShaderId?: string,
470
501
  ) => BindGroup,
471
502
  passKind: PassKind = 'forward',
472
503
  selectedDispatch?: readonly DispatchEntry[],
473
504
  colorFormats: readonly GPUTextureFormat[] = [],
474
505
  coverageOnly = false,
506
+ fragmentEntryPoint?: string,
507
+ surfacePass?: SurfacePassName,
508
+ transparentDepthWrite = false,
475
509
  ): void {
476
510
  const {
477
511
  runtime,
@@ -520,6 +554,7 @@ export function recordGeometryDraws(
520
554
  const bindingState: GeometryBindingState = {
521
555
  pipeline: null,
522
556
  instancesBuffer: null,
557
+ instanceBindGroup: null,
523
558
  probeOffset: -1,
524
559
  };
525
560
  const identityInstanceBuffer = pipelineState.identityInstanceBuffer;
@@ -563,6 +598,7 @@ export function recordGeometryDraws(
563
598
  vertexEntry?: string,
564
599
  fragmentEntry?: string,
565
600
  textureMask?: number,
601
+ layoutKind?: DirectSurfaceLayoutKind,
566
602
  ): MaterialShaderPipelineEntry | null => {
567
603
  const pipelineVariantSet = withCoverageVariant(variantSet);
568
604
  // The fallback MRT is an extension of the built-in Standard PBR output
@@ -594,6 +630,7 @@ export function recordGeometryDraws(
594
630
  cached.vertexEntry === vertexEntry &&
595
631
  cached.fragmentEntry === fragmentEntry &&
596
632
  cached.textureMask === textureMask &&
633
+ cached.layoutKind === layoutKind &&
597
634
  cached.passKind === passKind &&
598
635
  cached.layoutProjection.digest === layoutProjection.digest &&
599
636
  cached.sampleCount === sampleCount &&
@@ -604,8 +641,13 @@ export function recordGeometryDraws(
604
641
  }
605
642
  }
606
643
  }
644
+ // Published Surface artifacts carry both direct and scene-index modules.
645
+ // The boot artifact may be the scene-index specialization selected by the
646
+ // retained producer, so a direct slot-3 layout must still resolve the
647
+ // explicit capability key. This keeps the module source, entry point and
648
+ // pipeline layout on the same GPU_DRIVEN_SCENE_INDEX_AVAILABLE=false ABI.
607
649
  const resolvedVariantSetResult =
608
- runtime.getMaterialArtifact?.(materialShaderId) !== undefined
650
+ runtime.getMaterialArtifact?.(materialShaderId) !== undefined && layoutKind === undefined
609
651
  ? ({ ok: true, value: undefined } as const)
610
652
  : pipelineVariantSet === undefined &&
611
653
  (materialShaderId === 'forgeax::sprite' || materialShaderId === 'forgeax::sprite-lit')
@@ -639,7 +681,7 @@ export function recordGeometryDraws(
639
681
  undefined,
640
682
  layoutProjection,
641
683
  undefined,
642
- undefined,
684
+ layoutKind,
643
685
  undefined,
644
686
  reflectionFallbackFormats,
645
687
  vertexEntry,
@@ -674,6 +716,7 @@ export function recordGeometryDraws(
674
716
  colorFormatOverride: colorFormat,
675
717
  additionalColorFormats: reflectionFallbackFormats,
676
718
  textureMask,
719
+ layoutKind,
677
720
  handle,
678
721
  };
679
722
  if (shaderLookupCache === undefined) {
@@ -693,6 +736,9 @@ export function recordGeometryDraws(
693
736
  for (let i = 0; i < validatedOrdered.length; i++) {
694
737
  const entry = validatedOrdered[i];
695
738
  if (entry === undefined) continue;
739
+ // The typed transparent pass uses this common draw owner. Consume the
740
+ // same fold plan as the legacy sprite pass, including coverage/depth draws.
741
+ if (c.foldDispatchPlan?.skipIndices.has(i) === true) continue;
696
742
  // Points/Lines share the Standard geometry pass. Their retained source
697
743
  // is prepared once by the renderer owner, while this loop remains the
698
744
  // sole pass/draw submission owner and preserves the authored topology.
@@ -822,8 +868,22 @@ export function recordGeometryDraws(
822
868
  // length instead.
823
869
  if (pipelineTag === 'unlit') dispatchCounts.unlit += 1;
824
870
 
825
- const instanceDraws = resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws, false);
826
- if (instanceDraws === null) continue;
871
+ const fold = c.foldDispatchPlan?.headBuckets.get(i);
872
+ const foldBuffer = fold === undefined ? null : resolveFoldInstanceBuffer(c, fold, i);
873
+ const baseInstanceDraws =
874
+ fold === undefined
875
+ ? resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws, false)
876
+ : foldBuffer === null
877
+ ? null
878
+ : [
879
+ {
880
+ instanceBuffer: foldBuffer,
881
+ instanceBindGroup: resolveGeometryInstancesBindGroup(c, foldBuffer, undefined),
882
+ probeOffset: -1,
883
+ instanceCount: fold.bucketSize,
884
+ },
885
+ ];
886
+ if (baseInstanceDraws === null) continue;
827
887
 
828
888
  // feat-20260611 R2 / M8 / w28 (IS-14): skin entries need a 3-binding
829
889
  // group(2) BG matching `pbr-skin-pl` (binding 0 mesh-array UBO +
@@ -1114,16 +1174,22 @@ export function recordGeometryDraws(
1114
1174
  ) {
1115
1175
  continue;
1116
1176
  }
1177
+ const selectedMaterialPasses = materialPasses
1178
+ .get(entry.renderableIndex)
1179
+ ?.get(submeshMaterial.materialHandle ?? 0);
1117
1180
  const draws: readonly (DispatchEntry | undefined)[] =
1118
- selectedDispatch === undefined
1181
+ selectedDispatch === undefined ||
1182
+ (selectedMaterialPasses === undefined &&
1183
+ submeshMaterial.surfaceModel === 'single-layer-medium' &&
1184
+ matchedMaterials?.get(entry.renderableIndex)?.has(submeshMaterial.materialHandle ?? 0))
1119
1185
  ? [undefined]
1120
- : (materialPasses.get(entry.renderableIndex)?.get(submeshMaterial.materialHandle ?? 0) ??
1121
- []);
1186
+ : (selectedMaterialPasses ?? []);
1122
1187
  for (const selectedPass of draws) {
1123
1188
  // Temporal projects the selected material's alpha/motion contract,
1124
1189
  // not its authored Forward entry points or color outputs.
1125
1190
  const vertexEntry = passKind === 'temporal' ? undefined : selectedPass?.vertexEntry;
1126
- const fragmentEntry = passKind === 'temporal' ? undefined : selectedPass?.fragmentEntry;
1191
+ const fragmentEntry =
1192
+ passKind === 'temporal' ? undefined : (fragmentEntryPoint ?? selectedPass?.fragmentEntry);
1127
1193
  const selectedShaderId =
1128
1194
  selectedPass === undefined
1129
1195
  ? submeshMaterial.materialShaderId
@@ -1228,7 +1294,9 @@ export function recordGeometryDraws(
1228
1294
  : SKIN_MATERIAL_SHADER_ID
1229
1295
  : submeshMaterial.materialShaderId;
1230
1296
  const probeBlendAvailable =
1231
- probeBlendRecordAvailable && isStandardPbrMaterialShader(smMaterialShaderId);
1297
+ probeBlendRecordAvailable &&
1298
+ (isStandardPbrMaterialShader(smMaterialShaderId) ||
1299
+ submeshMaterial.surfaceModel === 'single-layer-medium');
1232
1300
  const isSpriteShader =
1233
1301
  smMaterialShaderId === 'forgeax::sprite' || smMaterialShaderId === 'forgeax::sprite-lit';
1234
1302
  // Preserve the dedicated sprite-pass state when the linear-LDR graph
@@ -1243,11 +1311,25 @@ export function recordGeometryDraws(
1243
1311
  blend: selectedRenderState?.blend ?? SPRITE_PREMULTIPLIED_ALPHA_BLEND,
1244
1312
  }
1245
1313
  : geometryRenderStateForTopology(smTopology, selectedRenderState);
1246
- const pipelineRenderState = geometryRenderStateForPass(
1314
+ let pipelineRenderState = geometryRenderStateForPass(
1247
1315
  basePipelineRenderState,
1248
1316
  passKind,
1249
1317
  coverageOnly,
1250
1318
  );
1319
+ if (
1320
+ transparentDepthWrite &&
1321
+ passKind === 'forward' &&
1322
+ (submeshMaterial.transparent === true || selectedRenderState?.blend !== undefined)
1323
+ ) {
1324
+ pipelineRenderState = {
1325
+ ...pipelineRenderState,
1326
+ depthWriteEnabled: authoredTransparentDepthWrite(
1327
+ submeshMaterial.transparent,
1328
+ selectedRenderState,
1329
+ ),
1330
+ depthCompare: 'less-equal',
1331
+ };
1332
+ }
1251
1333
  let smPipelineHandle: typeof pipelineState.unlitPipeline;
1252
1334
  let materialGroup2Contract: 'mesh' | 'skin' | 'cluster' | 'skin-cluster' | undefined;
1253
1335
  let materialPipelineEntry: MaterialShaderPipelineEntry | null = null;
@@ -1319,15 +1401,17 @@ export function recordGeometryDraws(
1319
1401
  transmissionAvailable && !capabilityVariantSet.includes('TRANSMISSION_AVAILABLE=')
1320
1402
  ? `${capabilityVariantSet}+TRANSMISSION_AVAILABLE=true`
1321
1403
  : 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.
1404
+ // Regular sprite keeps the boot-selected artifact; SpriteInstances
1405
+ // uses the explicit empty key for PER_INSTANCE_REGION=true. Sprite-lit
1406
+ // is different: the typed Standard transparent lane records it here,
1407
+ // so its shader must follow the frame-owned cluster topology or local
1408
+ // lights disappear while the ordinary sprite path remains direct.
1327
1409
  const variantSet = isSpriteShader
1328
- ? smMaterialShaderId === 'forgeax::sprite' && entry.source.spriteInstances !== undefined
1329
- ? ''
1330
- : undefined
1410
+ ? smMaterialShaderId === 'forgeax::sprite-lit'
1411
+ ? materialCapabilityVariantSet
1412
+ : entry.source.spriteInstances !== undefined
1413
+ ? ''
1414
+ : undefined
1331
1415
  : entry.variantSet === undefined
1332
1416
  ? materialCapabilityVariantSet
1333
1417
  : `${materialCapabilityVariantSet}+${entry.variantSet}`;
@@ -1342,6 +1426,11 @@ export function recordGeometryDraws(
1342
1426
  vertexEntry,
1343
1427
  fragmentEntry,
1344
1428
  submeshMaterial.standardTextureMask,
1429
+ submeshMaterial.surfaceModel === 'single-layer-medium' && passKind === 'forward'
1430
+ ? capabilityVariantSet.includes('CLUSTER_FORWARD_AVAILABLE=true')
1431
+ ? 'surface-direct-cluster-pbr'
1432
+ : 'surface-direct-pbr'
1433
+ : undefined,
1345
1434
  );
1346
1435
  // feat-20260615-pipeline-spec-ssot M6-T1: cache miss resolves to
1347
1436
  // null uniformly across URP / HDRP / skin shaders. Charter P3
@@ -1380,12 +1469,28 @@ export function recordGeometryDraws(
1380
1469
  // renderable, but unlit/custom shaders still use the one-binding
1381
1470
  // instances BGL and must never receive the probe bind group. Resolve
1382
1471
  // this per submesh so mixed-material meshes cannot cross the layouts.
1383
- const instanceDraws = resolveGeometryInstanceBuffer(
1384
- c,
1385
- entry,
1386
- identityInstanceDraws,
1387
- probeBlendAvailable,
1388
- );
1472
+ const resolvedInstanceDraws = probeBlendAvailable
1473
+ ? resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws, true)
1474
+ : baseInstanceDraws;
1475
+ if (resolvedInstanceDraws === null) continue;
1476
+ const compactDrawIndex = gpuDrivenDrawIndices.get(smIdx);
1477
+ const compactDraw =
1478
+ compactDrawIndex === undefined
1479
+ ? undefined
1480
+ : entry.source.gpuDrivenDraws?.[compactDrawIndex];
1481
+ const sourceDrawItemIndex =
1482
+ compactDrawIndex === undefined || compactDraw === undefined
1483
+ ? smIdx
1484
+ : gpuDrivenSourceDrawItemIndex(compactDraw, compactDrawIndex);
1485
+ const instanceDraws =
1486
+ submeshMaterial.surfaceModel === 'single-layer-medium' && passKind === 'forward'
1487
+ ? resolveSurfaceDirectInstanceDraws(
1488
+ c,
1489
+ entry,
1490
+ sourceDrawItemIndex,
1491
+ resolvedInstanceDraws,
1492
+ )
1493
+ : resolvedInstanceDraws;
1389
1494
  if (instanceDraws === null) continue;
1390
1495
  // Standard clustered PBR variants declare the unified cluster/SSAO
1391
1496
  // group(2) layout. Unlit and other URP-layout materials must bind the
@@ -1441,7 +1546,26 @@ export function recordGeometryDraws(
1441
1546
  sm.indexCount,
1442
1547
  sm.vertexCount,
1443
1548
  sm.indexOffset,
1444
- () => c.onRenderableDraw?.(entry),
1549
+ (draw, command) => {
1550
+ c.onRenderableDraw?.(entry, smIdx);
1551
+ if (surfacePass === undefined || draw.surfaceFrameBase === undefined) return;
1552
+ c.frameState.surfaceSubmissionObservation?.record(surfacePass, {
1553
+ kind: command,
1554
+ count: entry.mesh.indexed ? sm.indexCount : sm.vertexCount,
1555
+ first: entry.mesh.indexed ? sm.indexOffset : 0,
1556
+ instanceCount: draw.instanceCount,
1557
+ firstInstance: 0,
1558
+ surfaceFrameBase: draw.surfaceFrameBase,
1559
+ memberIds: draw.surfaceMemberIds ?? [],
1560
+ pipelineIdentity: getOpaqueResourceIdentity(smPipelineHandle as object),
1561
+ ...(materialPipelineEntry?.receipt === undefined
1562
+ ? {}
1563
+ : {
1564
+ receiptIdentity: materialPipelineEntry.receipt.identity,
1565
+ receiptGeneration: materialPipelineEntry.receipt.generation,
1566
+ }),
1567
+ });
1568
+ },
1445
1569
  ),
1446
1570
  );
1447
1571
  } else {
@@ -1456,7 +1580,26 @@ export function recordGeometryDraws(
1456
1580
  sm.indexCount,
1457
1581
  sm.vertexCount,
1458
1582
  sm.indexOffset,
1459
- () => c.onRenderableDraw?.(entry),
1583
+ (draw, command) => {
1584
+ c.onRenderableDraw?.(entry, smIdx);
1585
+ if (surfacePass === undefined || draw.surfaceFrameBase === undefined) return;
1586
+ c.frameState.surfaceSubmissionObservation?.record(surfacePass, {
1587
+ kind: command,
1588
+ count: entry.mesh.indexed ? sm.indexCount : sm.vertexCount,
1589
+ first: entry.mesh.indexed ? sm.indexOffset : 0,
1590
+ instanceCount: draw.instanceCount,
1591
+ firstInstance: 0,
1592
+ surfaceFrameBase: draw.surfaceFrameBase,
1593
+ memberIds: draw.surfaceMemberIds ?? [],
1594
+ pipelineIdentity: getOpaqueResourceIdentity(smPipelineHandle as object),
1595
+ ...(materialPipelineEntry?.receipt === undefined
1596
+ ? {}
1597
+ : {
1598
+ receiptIdentity: materialPipelineEntry.receipt.identity,
1599
+ receiptGeneration: materialPipelineEntry.receipt.generation,
1600
+ }),
1601
+ });
1602
+ },
1460
1603
  ),
1461
1604
  ),
1462
1605
  );
@@ -1475,7 +1618,7 @@ export function recordGeometryDraws(
1475
1618
  * @internal
1476
1619
  */
1477
1620
  function uploadInstanceRanges(
1478
- c: _InternalRenderPipelineContext,
1621
+ c: InstanceBufferContext,
1479
1622
  inst: NonNullable<RenderableSnapshot['instances']>,
1480
1623
  buffer: Buffer,
1481
1624
  ranges: readonly { readonly start: number; readonly end: number }[],
@@ -1532,7 +1675,7 @@ function uploadInstanceRanges(
1532
1675
  }
1533
1676
 
1534
1677
  export function reportInstanceResidency(
1535
- c: _InternalRenderPipelineContext,
1678
+ c: InstanceBufferContext,
1536
1679
  inst: NonNullable<RenderableSnapshot['instances']>,
1537
1680
  input: {
1538
1681
  readonly lane: 'direct-storage' | 'chunked-storage' | 'direct-uniform' | 'chunked-uniform';
@@ -1557,7 +1700,7 @@ export function reportInstanceResidency(
1557
1700
  }
1558
1701
 
1559
1702
  function reportInstanceFailure(
1560
- c: _InternalRenderPipelineContext,
1703
+ c: InstanceBufferContext,
1561
1704
  inst: NonNullable<RenderableSnapshot['instances']>,
1562
1705
  error: {
1563
1706
  readonly code: InstanceCollectionFailureCode;
@@ -1584,7 +1727,7 @@ function reportInstanceFailure(
1584
1727
  });
1585
1728
  }
1586
1729
 
1587
- function clearInstanceChunksForOwner(c: _InternalRenderPipelineContext, ownerKey: number): void {
1730
+ function clearInstanceChunksForOwner(c: InstanceBufferContext, ownerKey: number): void {
1588
1731
  const chunks = c.frameState.instanceBufferChunks;
1589
1732
  if (chunks === undefined) return;
1590
1733
  const prefix = `${ownerKey}:`;
@@ -1599,7 +1742,7 @@ function clearInstanceChunksForOwner(c: _InternalRenderPipelineContext, ownerKey
1599
1742
  }
1600
1743
 
1601
1744
  export function resolveStorageInstanceChunks(
1602
- c: _InternalRenderPipelineContext,
1745
+ c: InstanceBufferContext,
1603
1746
  entry: _InternalRenderPipelineContext['validatedOrdered'][number],
1604
1747
  inst: NonNullable<RenderableSnapshot['instances']>,
1605
1748
  cap: number,
@@ -1734,8 +1877,10 @@ export function resolveStorageInstanceChunks(
1734
1877
  activeBuffer.buffer.handle,
1735
1878
  probeBuffer,
1736
1879
  ),
1880
+ ...(probeBuffer === undefined ? {} : { probeBuffer }),
1737
1881
  probeOffset,
1738
1882
  instanceCount: count,
1883
+ firstInstanceOrdinal: start,
1739
1884
  });
1740
1885
  }
1741
1886
  if (chunks !== undefined) {
@@ -1759,14 +1904,37 @@ export function resolveStorageInstanceChunks(
1759
1904
  return draws;
1760
1905
  }
1761
1906
 
1762
- function resolveGeometryInstanceBuffer(
1763
- c: _InternalRenderPipelineContext,
1907
+ type InstanceBufferContext = Pick<
1908
+ _InternalRenderPipelineContext,
1909
+ 'runtime' | 'pipelineState' | 'frameState' | 'bindGroupCounts'
1910
+ >;
1911
+
1912
+ export function resolveGeometryInstanceBuffer(
1913
+ c: InstanceBufferContext,
1764
1914
  entry: _InternalRenderPipelineContext['validatedOrdered'][number],
1765
1915
  identityInstanceDraws: readonly GeometryInstanceDraw[],
1766
1916
  useProbeBlend: boolean,
1767
1917
  ): readonly GeometryInstanceDraw[] | null {
1768
1918
  const { runtime, pipelineState, frameState } = c;
1769
1919
  const inst = entry.source.instances;
1920
+ if (entry.source.spriteInstances !== undefined) {
1921
+ const { buffer, count } = resolveSpriteInstancesBuffer(
1922
+ c,
1923
+ entry,
1924
+ pipelineState.identityInstanceBuffer,
1925
+ 0,
1926
+ );
1927
+ return count === 0
1928
+ ? []
1929
+ : [
1930
+ {
1931
+ instanceBuffer: buffer,
1932
+ instanceBindGroup: resolveGeometryInstancesBindGroup(c, buffer, undefined),
1933
+ probeOffset: -1,
1934
+ instanceCount: count,
1935
+ },
1936
+ ];
1937
+ }
1770
1938
  const probeBinding =
1771
1939
  !useProbeBlend ||
1772
1940
  !runtime.device.caps.storageBuffer ||
@@ -1788,6 +1956,7 @@ function resolveGeometryInstanceBuffer(
1788
1956
  pipelineState.identityInstanceBuffer,
1789
1957
  probeBinding?.buffer,
1790
1958
  ),
1959
+ ...(probeBinding?.buffer === undefined ? {} : { probeBuffer: probeBinding.buffer }),
1791
1960
  probeOffset: probeBinding?.offset ?? -1,
1792
1961
  },
1793
1962
  ];
@@ -1918,8 +2087,10 @@ function resolveGeometryInstanceBuffer(
1918
2087
  active.buffer.handle,
1919
2088
  probeBinding?.buffer,
1920
2089
  ),
2090
+ ...(probeBinding?.buffer === undefined ? {} : { probeBuffer: probeBinding.buffer }),
1921
2091
  probeOffset: probeBinding?.offset ?? -1,
1922
2092
  instanceCount: count,
2093
+ firstInstanceOrdinal: start,
1923
2094
  });
1924
2095
  }
1925
2096
  if (chunks !== undefined) {
@@ -1988,6 +2159,7 @@ function resolveGeometryInstanceBuffer(
1988
2159
  if (!bufRes.ok) {
1989
2160
  runtime.errorRegistry.fire(bufRes.error);
1990
2161
  reportInstanceFailure(c, inst, bufRes.error, requestedBytes, cap);
2162
+ return null;
1991
2163
  } else {
1992
2164
  // feat-20260619 M4 / F12: destroy the old cached buffer
1993
2165
  // before replacing it with the new one (D-6).
@@ -2078,62 +2250,78 @@ function resolveGeometryInstanceBuffer(
2078
2250
  {
2079
2251
  instanceBuffer,
2080
2252
  instanceBindGroup: resolveGeometryInstancesBindGroup(c, instanceBuffer, probeBinding?.buffer),
2253
+ ...(probeBinding?.buffer === undefined ? {} : { probeBuffer: probeBinding.buffer }),
2081
2254
  probeOffset: probeBinding?.offset ?? -1,
2082
2255
  instanceCount,
2083
2256
  },
2084
2257
  ];
2085
2258
  }
2086
2259
 
2087
- export function resolveProbeBlendBuffer(
2260
+ function resolveSurfaceDirectInstanceDraws(
2088
2261
  c: _InternalRenderPipelineContext,
2262
+ entry: _InternalRenderPipelineContext['validatedOrdered'][number],
2263
+ drawItemIndex: number,
2264
+ draws: readonly GeometryInstanceDraw[],
2265
+ ): readonly GeometryInstanceDraw[] | null {
2266
+ const resolve = c.gpuDrivenStandardPbrFrameResources?.surfaceDirectInstances;
2267
+ if (resolve === undefined) {
2268
+ c.runtime.errorRegistry.fire(
2269
+ new RhiError({
2270
+ code: 'rhi-not-available',
2271
+ expected: 'the prepared Surface producer publishes the direct slot-3 resource closure',
2272
+ hint: 'prepare the retained Surface frame before recording direct medium draws',
2273
+ }),
2274
+ );
2275
+ return null;
2276
+ }
2277
+ const resolved: GeometryInstanceDraw[] = [];
2278
+ for (const draw of draws) {
2279
+ const direct = resolve({
2280
+ worldId: entry.source.worldId,
2281
+ entityKey: entry.source.entityKey,
2282
+ drawItemIndex,
2283
+ instanceCount: draw.instanceCount,
2284
+ firstInstanceOrdinal: draw.firstInstanceOrdinal ?? 0,
2285
+ instanceBuffer: draw.instanceBuffer,
2286
+ ...(draw.probeBuffer === undefined ? {} : { probeBuffer: draw.probeBuffer }),
2287
+ ...(draw.probeOffset < 0
2288
+ ? {}
2289
+ : {
2290
+ probeOffset: draw.probeOffset,
2291
+ }),
2292
+ });
2293
+ if (!direct.ok) {
2294
+ c.runtime.errorRegistry.fire(direct.error);
2295
+ return null;
2296
+ }
2297
+ resolved.push({
2298
+ ...draw,
2299
+ instanceBindGroup: direct.value.bindGroup,
2300
+ dynamicOffsets: direct.value.dynamicOffsets,
2301
+ surfaceFrameBase: direct.value.frameBase,
2302
+ surfaceMemberIds: direct.value.memberIds,
2303
+ });
2304
+ }
2305
+ return resolved;
2306
+ }
2307
+
2308
+ export function resolveProbeBlendBuffer(
2309
+ c: InstanceBufferContext,
2089
2310
  record: import('../scene/probe-blend-record').ProbeBlendRecord | undefined,
2090
2311
  entityKey?: number,
2091
2312
  ): { readonly buffer: Buffer; readonly offset: number } {
2092
2313
  const { runtime, frameState } = c;
2093
- const usage = runtime.device.caps.storageBuffer
2094
- ? GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST
2095
- : GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST;
2096
2314
  if (record === undefined) throw new Error('probe blend record is required for probe allocation');
2097
2315
  if (entityKey === undefined) throw new Error('probe blend record requires an entity key');
2098
- const offset = probeBlendRecordOffset(record.objectKey);
2099
- const requiredCapacity = record.objectKey + 2;
2100
- let buffer = frameState.probeBlendRecordBuffer;
2101
- if (buffer === undefined || frameState.probeBlendRecordBufferCapacity < requiredCapacity) {
2102
- const created = runtime.device.createBuffer({
2103
- label: 'probe-blend-records',
2104
- size: requiredCapacity * PROBE_BLEND_RECORD_STRIDE,
2105
- usage,
2106
- mappedAtCreation: false,
2107
- });
2108
- if (!created.ok) throw created.error;
2109
- buffer = new GpuBuffer(runtime.device, created.value);
2110
- frameState.probeBlendRecordBuffer = buffer;
2111
- frameState.probeBlendRecordBufferCapacity = requiredCapacity;
2112
- // The cache is tied to the previous backing allocation. A new buffer has
2113
- // no valid record contents, so every later object must upload its full
2114
- // 160B payload even when generation/bytes match the old allocation.
2115
- frameState.probeBlendBuffers.clear();
2116
- }
2117
- const cached = frameState.probeBlendBuffers.get(entityKey);
2118
- const unchanged =
2119
- cached !== undefined &&
2120
- cached.generation === record.generation &&
2121
- cached.bytes.length === record.bytes.length &&
2122
- cached.bytes.every((value, index) => value === record.bytes[index]);
2123
- if (!unchanged) {
2124
- const uploaded = runtime.device.queue.writeBuffer(buffer.handle, offset, record.bytes);
2125
- if (!uploaded.ok) throw uploaded.error;
2126
- // Publish the generation only after the complete 160B queue write succeeds.
2127
- frameState.probeBlendBuffers.set(entityKey, {
2128
- generation: record.generation,
2129
- bytes: new Uint8Array(record.bytes),
2130
- });
2131
- }
2132
- return { buffer: buffer.handle, offset };
2316
+ const buffer = ensureProbeBlendRecordBuffer(runtime.device, frameState, [
2317
+ { cacheKey: entityKey, record },
2318
+ ]);
2319
+ if (buffer === undefined) throw new Error('probe blend record buffer allocation failed');
2320
+ return { buffer, offset: probeBlendRecordOffset(record.objectKey) };
2133
2321
  }
2134
2322
 
2135
2323
  export function resolveGeometryInstancesBindGroup(
2136
- c: _InternalRenderPipelineContext,
2324
+ c: InstanceBufferContext,
2137
2325
  instanceBuffer: Buffer,
2138
2326
  probeBuffer?: Buffer,
2139
2327
  ): BindGroup {