@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,14 +1,16 @@
1
1
  import { transmissionBackdropAvailable } from '../assembly/device-feature-admission';
2
2
  import { getOrCreateIblCache } from '../ibl/IblPipelineCache';
3
+ import type { RenderResourceScope } from '../publication/resource-scope';
3
4
  import type { _InternalRenderPipelineContext } from './render-context';
4
5
  // @forgeax/engine-runtime - RenderSystem record stage: main-pass-material.
5
6
  // Extracted from render-system-record.ts (feat-20260704 M3/w17, pure move).
6
7
 
7
8
  import { resolveAssetHandle } from '@forgeax/engine-assets-runtime';
8
- import type { EntityHandle, World } from '@forgeax/engine-ecs';
9
+ import type { EntityHandle } from '@forgeax/engine-ecs';
9
10
  import {
10
- VIDEO_ELEMENT_PROVIDER_KEY,
11
- type VideoElementProvider,
11
+ VIDEO_SOURCE_PROVIDER_KEY,
12
+ type VideoSourceProvider,
13
+ videoSourceExtent,
12
14
  } from '@forgeax/engine-graphics-extras';
13
15
  import {
14
16
  type BindGroup,
@@ -42,6 +44,7 @@ import { VideoUploadUnsupportedError } from '../errors/render';
42
44
  import {
43
45
  assembleMaterialWithSkylightEntries,
44
46
  type SkylightBindGroupResources,
47
+ type SurfaceMediumBindGroupResources,
45
48
  type TextureInjectionResource,
46
49
  type TransmissionBindGroupResources,
47
50
  } from '../ibl/skylight-bind-group';
@@ -260,11 +263,11 @@ function materialDiagnosticsEnabled(): boolean {
260
263
  }
261
264
 
262
265
  export function residentTextureView(
263
- world: World,
266
+ world: RenderResourceScope,
264
267
  store: GpuResidencyCache,
265
268
  runtime: RenderSystemRuntime,
266
269
  handle: Handle<'TextureAsset', 'shared'>,
267
- worldId: World | number = world,
270
+ worldId: RenderResourceScope | number = world,
268
271
  ): TextureView | undefined {
269
272
  const podRes = resolveAssetHandle<TextureAsset>(world, handle);
270
273
  const diagnosticsEnabled = materialDiagnosticsEnabled();
@@ -322,11 +325,11 @@ export function residentTextureView(
322
325
  }
323
326
 
324
327
  function residentSampler(
325
- world: World,
328
+ world: RenderResourceScope,
326
329
  store: GpuResidencyCache,
327
330
  runtime: RenderSystemRuntime,
328
331
  handle: Handle<'SamplerAsset', 'shared'>,
329
- worldId: World | number = world,
332
+ worldId: RenderResourceScope | number = world,
330
333
  ): Sampler | undefined {
331
334
  const podRes = resolveAssetHandle<SamplerAsset>(world, handle);
332
335
  if (!podRes.ok) return undefined;
@@ -343,7 +346,7 @@ function residentSampler(
343
346
  // transient DynamicTextureStore, NOT the static `residentTextureView` /
344
347
  // `ensureResident` cache (video never enters that switch; AC-08).
345
348
  //
346
- // Per frame: ask the host-registered VideoElementProvider (World Resource,
349
+ // Per frame: ask the host-registered VideoSourceProvider (RenderResourceScope Resource,
347
350
  // D-1) for this entity's HTMLVideoElement, upload its current frame via
348
351
  // `store.uploadFrame` (copyExternalImageToTexture), and return the resulting
349
352
  // view. When the provider is absent / returns no element / the element has no
@@ -403,7 +406,7 @@ function clearVideoUploadFailureEpisode(
403
406
  }
404
407
 
405
408
  export function videoTextureView(
406
- world: World,
409
+ world: RenderResourceScope,
407
410
  store: DynamicTextureStore | undefined,
408
411
  runtime: RenderSystemRuntime,
409
412
  entityKey: number,
@@ -411,10 +414,14 @@ export function videoTextureView(
411
414
  highPerfAvailable: boolean,
412
415
  ): TextureView | undefined {
413
416
  if (store === undefined) return undefined;
414
- const provider = world.hasResource(VIDEO_ELEMENT_PROVIDER_KEY)
415
- ? world.getResource<VideoElementProvider>(VIDEO_ELEMENT_PROVIDER_KEY)
416
- : undefined;
417
- const element = provider?.getElement(entityKey as EntityHandle, clip);
417
+ const provider =
418
+ !('resolveAsset' in world) && world.hasResource(VIDEO_SOURCE_PROVIDER_KEY)
419
+ ? world.getResource<VideoSourceProvider>(VIDEO_SOURCE_PROVIDER_KEY)
420
+ : undefined;
421
+ const element =
422
+ 'resolveAsset' in world
423
+ ? world.videoFrame(entityKey, clip)
424
+ : provider?.getSource(entityKey as EntityHandle, clip);
418
425
  // AC-10 double-miss: a VideoPlayer entity can reach NEITHER upload path this
419
426
  // frame — no host HTMLVideoElement (general copyExternalImageToTexture path)
420
427
  // AND no high-perf GPUExternalTexture path. This is the genuine "this backend
@@ -440,13 +447,9 @@ export function videoTextureView(
440
447
  clearVideoUploadFailureEpisode(store, entityKey, clip);
441
448
  return store.getView(clip);
442
449
  }
443
- const width = element.videoWidth;
444
- const height = element.videoHeight;
445
- // Metadata dimensions can be non-zero before the decoder has produced a
446
- // current frame. WebGPU rejects copyExternalImageToTexture in that window
447
- // because the video element has no back resource yet; keep the previous
448
- // frame/default view until HAVE_CURRENT_DATA (2) is reached.
449
- if (width <= 0 || height <= 0 || element.readyState < 2) return store.getView(clip);
450
+ const extent = videoSourceExtent(element);
451
+ if (extent === undefined) return store.getView(clip);
452
+ const { width, height } = extent;
450
453
  const uploaded = store.uploadFrame(clip, element, width, height);
451
454
  if (uploaded === undefined) return store.getView(clip);
452
455
  if (!uploaded.ok) {
@@ -591,7 +594,7 @@ function writeNumericParamValue(
591
594
  export function applyMaterialTextureUvScales(
592
595
  payload: MaterialUboPayload,
593
596
  material: MaterialSnapshot,
594
- world: World,
597
+ world: RenderResourceScope,
595
598
  ): void {
596
599
  const f32 = materialUboFloatView(payload);
597
600
  const coordinateSchema = materialCoordinateSchema(material);
@@ -939,14 +942,14 @@ export function applyParamSchemaDefaultsToUbo(
939
942
  export interface PerSubmeshMaterialBgDeps {
940
943
  readonly runtime: RenderSystemRuntime;
941
944
  readonly pipelineState: PipelineState;
942
- readonly world: World;
945
+ readonly world: RenderResourceScope;
943
946
  readonly store: GpuResidencyCache;
944
947
  readonly materialSlice: number;
945
948
  readonly videoHighPerfAvailable: boolean;
946
949
  readonly skylightResources: SkylightBindGroupResources;
947
950
  readonly resolveRenderTargetTextureSource?: RenderSystemRuntime['resolveRenderTargetTextureSource'];
948
951
  readonly resolveReflectionProbeResources?: (
949
- materialWorld: World,
952
+ materialWorld: RenderResourceScope,
950
953
  entityKey: number,
951
954
  ) => { readonly resources: SkylightBindGroupResources; readonly probeIndex: number } | undefined;
952
955
  readonly materialBgShared: Map<string, WeakMap<object, unknown>>;
@@ -956,6 +959,12 @@ export interface PerSubmeshMaterialBgDeps {
956
959
  readonly sceneMaterialBuffer?: Buffer;
957
960
  /** Active transmission backdrop; undefined/null means layout placeholder. */
958
961
  readonly transmissionBackdropView?: TextureView | null;
962
+ /** Independent sampled raw depth for the active medium graph pass. */
963
+ readonly surfaceRawDepthView?: TextureView | null;
964
+ /** Nearest-layer color from the preceding medium graph pass. */
965
+ readonly surfaceNearestLayerView?: TextureView | null;
966
+ /** Nearest-layer depth from the preceding medium graph pass. */
967
+ readonly surfaceNearestDepthView?: TextureView | null;
959
968
  readonly bindGroupCounts: BindGroupCounts;
960
969
  readonly frameState: RenderFrameState;
961
970
  }
@@ -972,7 +981,7 @@ function recordIblMaterialBinding(
972
981
  if (receipt === undefined) return;
973
982
  const skylightBindingStart = entries.findIndex((entry) => entry.binding === iblStart);
974
983
  if (skylightBindingStart < 0) return;
975
- const iblEntries = entries.slice(skylightBindingStart, skylightBindingStart + 7);
984
+ const iblEntries = entries.slice(skylightBindingStart, skylightBindingStart + 6);
976
985
  const projected: IblBindingEntryInspection[] = [];
977
986
  for (const entry of iblEntries) {
978
987
  if (entry.resource.kind === 'externalTexture') continue;
@@ -1009,8 +1018,17 @@ export function isMaterialBgAssemblyCacheHit(
1009
1018
  materialResourceEpoch: number,
1010
1019
  transmissionBackdropView?: TextureView | null,
1011
1020
  sceneMaterialBuffer?: Buffer,
1021
+ surfaceRawDepthView?: TextureView | null,
1012
1022
  ): cached is MaterialBgAssemblyCacheEntry {
1013
- if (transmissionBackdropView != null) return false;
1023
+ // Logical target sources keep their identity when a resize promotes a new
1024
+ // physical view. Resolve those views each frame; the lower binding cache is
1025
+ // keyed by the actual GPU resources and still reuses unchanged bindings.
1026
+ if (
1027
+ transmissionBackdropView != null ||
1028
+ surfaceRawDepthView != null ||
1029
+ (material.textureSources?.size ?? 0) > 0
1030
+ )
1031
+ return false;
1014
1032
  return (
1015
1033
  cached?.material === material &&
1016
1034
  cached.materialResourceEpoch === materialResourceEpoch &&
@@ -1023,7 +1041,6 @@ export function isMaterialBgAssemblyCacheHit(
1023
1041
  cached.skylightResources.skylightPrefilterView === skylightResources.skylightPrefilterView &&
1024
1042
  cached.skylightResources.prefilterSampler === skylightResources.prefilterSampler &&
1025
1043
  cached.skylightResources.brdfLutView === skylightResources.brdfLutView &&
1026
- cached.skylightResources.brdfLutSampler === skylightResources.brdfLutSampler &&
1027
1044
  cached.skylightResources.intensityBuffer === skylightResources.intensityBuffer
1028
1045
  );
1029
1046
  }
@@ -1032,7 +1049,7 @@ export function buildPerSubmeshMaterialBg(
1032
1049
  deps: PerSubmeshMaterialBgDeps,
1033
1050
  submeshMaterial: MaterialSnapshot,
1034
1051
  entityKey: number,
1035
- materialWorld: World = deps.world,
1052
+ materialWorld: RenderResourceScope = deps.world,
1036
1053
  materialShaderId: string | undefined = submeshMaterial.materialShaderId,
1037
1054
  ): BindGroup {
1038
1055
  const {
@@ -1047,6 +1064,9 @@ export function buildPerSubmeshMaterialBg(
1047
1064
  materialBgShared,
1048
1065
  materialBgAssemblyCache,
1049
1066
  transmissionBackdropView,
1067
+ surfaceRawDepthView,
1068
+ surfaceNearestLayerView,
1069
+ surfaceNearestDepthView,
1050
1070
  bindGroupCounts,
1051
1071
  frameState,
1052
1072
  } = deps;
@@ -1059,6 +1079,39 @@ export function buildPerSubmeshMaterialBg(
1059
1079
  : `${materialWorld.identity}:${smMaterialHandle}:${materialShaderId ?? ''}:${selectedProbe?.probeIndex ?? 'sky'}`;
1060
1080
  const smHasVideoFields = (submeshMaterial.videoTextureFields?.size ?? 0) > 0;
1061
1081
  const smShaderId = materialShaderId;
1082
+ const selectedMaterialShaderArtifact =
1083
+ smShaderId === undefined ? undefined : runtime.getMaterialShaderArtifact?.(smShaderId);
1084
+ const selectedMediumShader =
1085
+ smShaderId === 'forgeax::single-layer-medium' ||
1086
+ selectedMaterialShaderArtifact?.receipt?.surface?.model === 'single-layer-medium';
1087
+ let surfaceMediumResources: SurfaceMediumBindGroupResources | undefined;
1088
+ if (selectedMediumShader) {
1089
+ if (surfaceRawDepthView == null) {
1090
+ throw new RhiError({
1091
+ code: 'rhi-descriptor-invalid',
1092
+ expected: 'single-layer medium material bind group has producer-owned raw depth',
1093
+ hint: 'admit the Surface material only from a graph pass with an available raw-depth pair',
1094
+ });
1095
+ }
1096
+ const nearestLayerView = surfaceNearestLayerView ?? transmissionBackdropView;
1097
+ const nearestDepthView = surfaceNearestDepthView ?? pipelineState.shadowFallbackTextureView;
1098
+ if (nearestLayerView == null || pipelineState.surfaceMediumDepthSampler === undefined) {
1099
+ throw new RhiError({
1100
+ code: 'rhi-descriptor-invalid',
1101
+ expected:
1102
+ 'single-layer medium material bind group has paired nearest resources and depth sampler',
1103
+ hint: 'publish the nearest-layer target and the non-filtering raw-depth sampler before recording the Surface pass',
1104
+ });
1105
+ }
1106
+ surfaceMediumResources = {
1107
+ rawDepthSampler: pipelineState.surfaceMediumDepthSampler,
1108
+ rawDepthView: surfaceRawDepthView,
1109
+ nearestLayerSampler: effectiveSkylightResources.prefilterSampler,
1110
+ nearestLayerView,
1111
+ nearestDepthSampler: pipelineState.surfaceMediumDepthSampler,
1112
+ nearestDepthView,
1113
+ };
1114
+ }
1062
1115
  // The cooked shader schema owns the resource ABI. A material snapshot may
1063
1116
  // carry only the authored values (for example a clearcoat-only root omits
1064
1117
  // the standard emissive/occlusion maps), while the Standard template still
@@ -1100,6 +1153,7 @@ export function buildPerSubmeshMaterialBg(
1100
1153
  store.materialResourceEpoch,
1101
1154
  transmissionBackdropView,
1102
1155
  sceneMaterialBuffer,
1156
+ surfaceRawDepthView,
1103
1157
  )
1104
1158
  ) {
1105
1159
  if (diagnosticsEnabled) {
@@ -1130,10 +1184,6 @@ export function buildPerSubmeshMaterialBg(
1130
1184
  },
1131
1185
  {
1132
1186
  binding: 6 + smUserRegionFields.length * 2,
1133
- resource: { kind: 'sampler', value: effectiveSkylightResources.brdfLutSampler },
1134
- },
1135
- {
1136
- binding: 7 + smUserRegionFields.length * 2,
1137
1187
  resource: {
1138
1188
  kind: 'buffer',
1139
1189
  value: { buffer: effectiveSkylightResources.intensityBuffer },
@@ -1232,7 +1282,7 @@ export function buildPerSubmeshMaterialBg(
1232
1282
  // Physical Standard maps are deliberately appended after the stable IBL /
1233
1283
  // transmission tail. Keep their resource projection separate from the
1234
1284
  // user-region loop so the slot order is the same as
1235
- // `appendTextureInjection(afterTransmission, physicalFields)` in the
1285
+ // `appendTextureInjection(afterSurfaceMedium, physicalFields)` in the
1236
1286
  // layout owner.
1237
1287
  const physicalTextureInjections: TextureInjectionResource[] = [];
1238
1288
  for (let slot = 0; slot < physicalFields.length; slot += 1) {
@@ -1271,18 +1321,27 @@ export function buildPerSubmeshMaterialBg(
1271
1321
  transmissionBackdropView != null
1272
1322
  ? effectiveSkylightResources.prefilterSampler
1273
1323
  : pipelineState.defaultSampler;
1324
+ // The medium shader keeps the transmission backdrop pair in its fixed
1325
+ // group(1) ABI even on a device that cannot admit the ordinary Standard
1326
+ // transmission topology. Its Surface resources start at binding 10, so
1327
+ // retain a real backdrop pair here whenever the medium resources exist;
1328
+ // otherwise the raw-depth view would slide into binding 9 and Dawn would
1329
+ // reject the unfilterable r32float view as a filtering float texture.
1330
+ const keepMediumBackdropSlots = surfaceMediumResources !== undefined;
1274
1331
  const smMergedEntries = assembleMaterialWithSkylightEntries(
1275
1332
  smBaseEntries,
1276
1333
  effectiveSkylightResources,
1277
- transmissionBackdropAvailable(runtime.device.limits.maxSampledTexturesPerShaderStage)
1334
+ transmissionBackdropAvailable(runtime.device.limits.maxSampledTexturesPerShaderStage) ||
1335
+ keepMediumBackdropSlots
1278
1336
  ? ({
1279
1337
  sampler: transmissionSampler,
1280
1338
  ...(transmissionBackdropView === undefined
1281
- ? {}
1339
+ ? { backdropView: pipelineState.defaultWhiteTextureView }
1282
1340
  : { backdropView: transmissionBackdropView }),
1283
1341
  } satisfies TransmissionBindGroupResources)
1284
1342
  : null,
1285
1343
  physicalTextureInjections,
1344
+ surfaceMediumResources,
1286
1345
  );
1287
1346
  // Storage-capable devices share one Standard material BGL with the
1288
1347
  // scene-index GPU lane. Even direct draws need a complete entry for
@@ -1321,6 +1380,14 @@ export function buildPerSubmeshMaterialBg(
1321
1380
  entityKey,
1322
1381
  materialHandle: smMaterialHandle,
1323
1382
  shader: smShaderId,
1383
+ surfaceModel: submeshMaterial.surfaceModel,
1384
+ layoutIdentity: getOpaqueResourceIdentity(smMaterialBgl as object),
1385
+ bindings: smMergedEntries.map((entry) => entry.binding),
1386
+ graphResources: {
1387
+ rawDepth: surfaceRawDepthView != null,
1388
+ nearestLayer: surfaceNearestLayerView != null,
1389
+ nearestDepth: surfaceNearestDepthView != null,
1390
+ },
1324
1391
  paramSnapshot: submeshMaterial.paramSnapshot,
1325
1392
  handleTypes: materialCacheHandles.map((handle) => typeof handle),
1326
1393
  })}`,
@@ -1367,6 +1434,7 @@ export function buildPerSubmeshMaterialBg(
1367
1434
  if (
1368
1435
  smMaterialHandle !== undefined &&
1369
1436
  !smHasVideoFields &&
1437
+ (submeshMaterial.textureSources?.size ?? 0) === 0 &&
1370
1438
  materialResourcesResident &&
1371
1439
  !hasActiveTransmissionBackdrop
1372
1440
  ) {
@@ -1470,7 +1538,6 @@ export function resolveMaterialSkylight(
1470
1538
  prefilterView: activeViews.pref,
1471
1539
  prefilterSampler: skylightFallback.sampler,
1472
1540
  brdfLutView: activeViews.brdf,
1473
- brdfLutSampler: skylightFallback.sampler,
1474
1541
  intensityBuffer: skylightFallback.intensityBuffer,
1475
1542
  }
1476
1543
  : {
@@ -1479,7 +1546,6 @@ export function resolveMaterialSkylight(
1479
1546
  prefilterView: skylightFallback.prefilterView,
1480
1547
  prefilterSampler: skylightFallback.sampler,
1481
1548
  brdfLutView: skylightFallback.brdfLutView,
1482
- brdfLutSampler: skylightFallback.sampler,
1483
1549
  intensityBuffer: skylightFallback.intensityBuffer,
1484
1550
  };
1485
1551
  return { skylightResources, activeViews };
@@ -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 sprite draws.
2
4
  // feat-20260704 M5/w31: further-split from main-pass.ts (AC-05 <=1500 lines/file).
3
5
  // recordSpritePass + sprite entity/transparent/instance-buffer helpers, moved verbatim.
4
6
 
5
- import type { World } from '@forgeax/engine-ecs';
6
7
  import {
7
8
  type BindGroup,
8
9
  type Buffer,
@@ -21,11 +22,8 @@ import type { InstanceBufferCacheEntry } from '../instance-buffer-cache';
21
22
  import { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';
22
23
  import { SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET } from '../pbr-pipeline';
23
24
  import { buildBeginRenderPassDescriptor, standardTopologyVariantSet } from '../pipeline-spec';
24
- import type {
25
- DispatchEntry,
26
- MaterialSnapshot,
27
- SpriteInstancesSnapshot,
28
- } from '../render-system-extract';
25
+ import type { DispatchEntry, MaterialSnapshot } from '../render-system-extract';
26
+ import { resolveFoldInstanceBuffer } from './fold-instance-buffer';
29
27
  import { worldEntityKey } from './frame-snapshot';
30
28
  import { recordGeometryDraws, resolveGeometryInstancesBindGroup } from './main-pass-geometry';
31
29
  import {
@@ -36,55 +34,6 @@ import {
36
34
  import type { _InternalRenderPipelineContext } from './render-context';
37
35
  import { MATERIAL_PER_ENTITY_STRIDE } from './render-context';
38
36
 
39
- export type { SpriteInstancesSnapshot };
40
-
41
- /**
42
- * Build the interleaved sprite instance payload consumed by this record owner.
43
- * The extract stage validates the two packed arrays before they reach this
44
- * function, so the record path has one source of count-mismatch errors.
45
- */
46
- export function interleaveSpriteInstanceBuffer(
47
- transforms: Float32Array,
48
- regions: Float32Array,
49
- includePrevious = false,
50
- ): Float32Array {
51
- const count = transforms.length / 16;
52
- const stride = includePrevious ? 36 : 20;
53
- const regionOffset = includePrevious ? 32 : 16;
54
- const out = new Float32Array(count * stride);
55
- for (let i = 0; i < count; i++) {
56
- const dstBase = i * stride;
57
- const transformBase = i * 16;
58
- const regionBase = i * 4;
59
- for (let k = 0; k < 16; k++) out[dstBase + k] = transforms[transformBase + k] ?? 0;
60
- if (includePrevious) {
61
- for (let k = 0; k < 16; k++) {
62
- out[dstBase + 16 + k] = transforms[transformBase + k] ?? 0;
63
- }
64
- }
65
- for (let k = 0; k < 4; k++) {
66
- out[dstBase + regionOffset + k] = regions[regionBase + k] ?? 0;
67
- }
68
- }
69
- return out;
70
- }
71
-
72
- /**
73
- * Check whether the existing per-entity sprite buffer still matches the
74
- * extract snapshot and interleaved byte count.
75
- */
76
- export function spriteInstancesCacheHit(
77
- entry: InstanceBufferCacheEntry | undefined,
78
- snapshot: SpriteInstancesSnapshot,
79
- requestedBytes: number,
80
- ): boolean {
81
- return (
82
- entry !== undefined &&
83
- entry.uploadedArchVersion === snapshot.archVersion &&
84
- entry.uploadedByteLength === requestedBytes
85
- );
86
- }
87
-
88
37
  /**
89
38
  * Decide whether the LDR record needs the transparent sprite sub-pass. This
90
39
  * remains beside the sprite record owner so the frame stage and draw stage
@@ -143,7 +92,7 @@ export function recordSpritePass(
143
92
  materialSlot: number,
144
93
  submeshMaterial: MaterialSnapshot,
145
94
  entityKey: number,
146
- materialWorld: World,
95
+ materialWorld: RenderResourceScope,
147
96
  materialShaderId?: string,
148
97
  ) => BindGroup,
149
98
  graphPass?: RhiRenderPassEncoder,
@@ -381,7 +330,7 @@ function recordSpriteTransparentPbrDraws(
381
330
  slot: number,
382
331
  material: MaterialSnapshot,
383
332
  entityKey: number,
384
- world: World,
333
+ world: RenderResourceScope,
385
334
  shader?: string,
386
335
  ) => BindGroup,
387
336
  meshGroup2: BindGroup | null,
@@ -454,7 +403,7 @@ function recordSpriteEntityDraws(
454
403
  materialSlot: number,
455
404
  material: MaterialSnapshot,
456
405
  entityKey: number,
457
- materialWorld: World,
406
+ materialWorld: RenderResourceScope,
458
407
  ) => BindGroup,
459
408
  spritePH: RenderPipeline | null,
460
409
  spritePH_withRegion: RenderPipeline | null,
@@ -589,69 +538,10 @@ function recordSpriteEntityDraws(
589
538
  const spriteInst = spriteEntry.source.instances;
590
539
  const useFold = foldHeadBucket !== undefined && spriteInst === undefined;
591
540
  if (useFold && foldHeadBucket !== undefined) {
592
- // w6 (D-8): bucket transient buffer reuse composite cacheKey from
593
- // (materialHandle, layer, validatedOrdered head index) so the
594
- // existing `frameState.instanceBuffers` byteLength/archVersion path
595
- // covers static steady-state upload-skip. Numeric Map<number,…> key
596
- // requires a 32-bit-safe fold; we use a negative number-space prefix
597
- // (-1, -2, ...) by `((materialHandle << 16) | i)` shifted into the
598
- // negative half so it never collides with positive entity-Instances
599
- // cacheKeys (which are extracted from Instances component cacheKey
600
- // numeric ids, always non-negative). The `archVersion` proxy is
601
- // bucketSize (a structural-shape signal) so static frames hit the
602
- // cache.
603
- const bucketCacheKey = -1 - (((foldHeadBucket.materialHandle & 0xffff) << 16) | (i & 0xffff));
604
- const uniformFallback = runtime.device.caps.storageBuffer === false;
605
- const bucketPayload = uniformFallback
606
- ? foldHeadBucket.transforms
607
- : packInstanceStorageBuffer(foldHeadBucket.transforms);
608
- const bucketBytes = bucketPayload.byteLength;
609
- const bucketBufUsage = uniformFallback
610
- ? GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST
611
- : GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;
612
- const cachedBucket = frameState.instanceBuffers.get(bucketCacheKey);
613
- let activeBucket: InstanceBufferCacheEntry | null = null;
614
- if (
615
- cachedBucket !== undefined &&
616
- cachedBucket.uploadedArchVersion === foldHeadBucket.bucketSize &&
617
- cachedBucket.uploadedByteLength === bucketBytes
618
- ) {
619
- activeBucket = cachedBucket;
620
- } else if (bucketBytes > 0) {
621
- const bufRes = runtime.device.createBuffer({
622
- size: bucketBytes,
623
- usage: bucketBufUsage,
624
- mappedAtCreation: false,
625
- });
626
- if (!bufRes.ok) {
627
- runtime.errorRegistry.fire(bufRes.error);
628
- } else {
629
- if (cachedBucket !== undefined && !cachedBucket.buffer.isDestroyed) {
630
- const r = cachedBucket.buffer.destroy();
631
- if (!r.ok) runtime.errorRegistry.fire(r.error);
632
- }
633
- const newBuf = new GpuBuffer(runtime.device, bufRes.value);
634
- activeBucket = {
635
- buffer: newBuf,
636
- uploadedArchVersion: foldHeadBucket.bucketSize,
637
- uploadedByteLength: bucketBytes,
638
- };
639
- frameState.instanceBuffers.set(bucketCacheKey, activeBucket);
640
- }
641
- }
642
- if (activeBucket !== null) {
643
- const writeRes = runtime.device.queue.writeBuffer(
644
- activeBucket.buffer.handle,
645
- 0,
646
- bucketPayload,
647
- );
648
- if (!writeRes.ok) {
649
- runtime.errorRegistry.fire(writeRes.error);
650
- } else {
651
- spriteInstanceBuffer = activeBucket.buffer.handle;
652
- spriteInstanceCount = foldHeadBucket.bucketSize;
653
- }
654
- }
541
+ const buffer = resolveFoldInstanceBuffer(c, foldHeadBucket, i);
542
+ if (buffer === null) continue;
543
+ spriteInstanceBuffer = buffer;
544
+ spriteInstanceCount = foldHeadBucket.bucketSize;
655
545
  } else if (spriteInst !== undefined) {
656
546
  const uniformFallback = runtime.device.caps.storageBuffer === false;
657
547
  let spriteBufUsage = GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;
@@ -681,7 +571,7 @@ function recordSpriteEntityDraws(
681
571
  );
682
572
  spritePass.setBindGroup(3, spriteInstBg);
683
573
  spritePass.drawIndexed(spriteEntry.mesh.indexCount, spriteInstanceCount, 0, 0, 0);
684
- c.onRenderableDraw?.(spriteEntry);
574
+ c.onRenderableDraw?.(spriteEntry, 0);
685
575
  continue;
686
576
  }
687
577
  spriteBufUsage = GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST;
@@ -814,102 +704,8 @@ function recordSpriteEntityDraws(
814
704
  spritePass.setBindGroup(1, spritePassBg, [materialSlot * MATERIAL_PER_ENTITY_STRIDE]);
815
705
  spritePass.setBindGroup(3, spriteInstancesBg);
816
706
  spritePass.drawIndexed(spriteEntry.mesh.indexCount, spriteInstanceCount, 0, 0, 0);
817
- c.onRenderableDraw?.(spriteEntry);
818
- }
819
- }
820
-
821
- /**
822
- * feat-20260704 M3/w19: resolve the interleaved SpriteInstances (@group(3))
823
- * buffer + instanceCount for a sprite entity in the LDR blend sub-pass,
824
- * extracted verbatim from recordSpriteEntityDraws. Uploads the interleaved
825
- * mat4 + per-instance UV region transforms (cache-keyed on the snapshot); on
826
- * over-cap fires the structured limit-exceeded error and leaves the passed-in
827
- * fallback buffer/count. Returns the resolved (or unchanged) buffer + count.
828
- *
829
- * @internal
830
- */
831
- function resolveSpriteInstancesBuffer(
832
- c: _InternalRenderPipelineContext,
833
- spriteEntry: _InternalRenderPipelineContext['validatedOrdered'][number],
834
- fallbackBuffer: Buffer,
835
- fallbackCount: number,
836
- ): { buffer: Buffer; count: number } {
837
- const { runtime, frameState } = c;
838
- let buffer = fallbackBuffer;
839
- let count = fallbackCount;
840
- const spriteInstancesSnap: SpriteInstancesSnapshot | undefined =
841
- spriteEntry.source.spriteInstances;
842
- if (spriteInstancesSnap !== undefined) {
843
- const uniformFallback = runtime.device.caps.storageBuffer === false;
844
- const interleaved = interleaveSpriteInstanceBuffer(
845
- spriteInstancesSnap.transforms,
846
- spriteInstancesSnap.regions,
847
- !uniformFallback,
848
- );
849
- const requestedBytes = interleaved.byteLength;
850
- const cap = runtime.device.limits.maxStorageBufferBindingSize;
851
- if (typeof cap === 'number' && requestedBytes > cap) {
852
- runtime.errorRegistry.fire(
853
- new RhiError({
854
- code: 'limit-exceeded',
855
- expected: `requestedBytes (${requestedBytes}) <= maxStorageBufferBindingSize (${cap})`,
856
- hint: 'reduce SpriteInstances instance count to fit within device.limits.maxStorageBufferBindingSize (144 bytes per instance: current mat4 64B + previous mat4 64B + region 16B)',
857
- detail: {
858
- maxStorageBufferBindingSize: cap,
859
- requestedBytes,
860
- },
861
- }),
862
- );
863
- } else {
864
- const cachedSpriteInst = frameState.instanceBuffers.get(
865
- worldEntityKey(spriteEntry.source.worldId, spriteInstancesSnap.cacheKey),
866
- );
867
- let activeSpriteInst: InstanceBufferCacheEntry | null = null;
868
- if (spriteInstancesCacheHit(cachedSpriteInst, spriteInstancesSnap, requestedBytes)) {
869
- activeSpriteInst = cachedSpriteInst ?? null;
870
- } else if (requestedBytes > 0) {
871
- const bufRes = runtime.device.createBuffer({
872
- size: requestedBytes,
873
- usage:
874
- (uniformFallback ? GPU_BUFFER_USAGE_UNIFORM : GPU_BUFFER_USAGE_STORAGE) |
875
- GPU_BUFFER_USAGE_COPY_DST,
876
- mappedAtCreation: false,
877
- });
878
- if (!bufRes.ok) {
879
- runtime.errorRegistry.fire(bufRes.error);
880
- } else {
881
- if (cachedSpriteInst !== undefined && !cachedSpriteInst.buffer.isDestroyed) {
882
- const r = cachedSpriteInst.buffer.destroy();
883
- if (!r.ok) runtime.errorRegistry.fire(r.error);
884
- }
885
- const newBuf = new GpuBuffer(runtime.device, bufRes.value);
886
- activeSpriteInst = {
887
- buffer: newBuf,
888
- uploadedArchVersion: spriteInstancesSnap.archVersion,
889
- uploadedByteLength: requestedBytes,
890
- };
891
- frameState.instanceBuffers.set(
892
- worldEntityKey(spriteEntry.source.worldId, spriteInstancesSnap.cacheKey),
893
- activeSpriteInst,
894
- );
895
- }
896
- }
897
- if (activeSpriteInst !== null && requestedBytes > 0) {
898
- const writeRes = runtime.device.queue.writeBuffer(
899
- activeSpriteInst.buffer.handle,
900
- 0,
901
- interleaved,
902
- );
903
- if (!writeRes.ok) {
904
- runtime.errorRegistry.fire(writeRes.error);
905
- } else {
906
- buffer = activeSpriteInst.buffer.handle;
907
- count = spriteInstancesSnap.instanceCount;
908
- }
909
- }
910
- }
707
+ c.onRenderableDraw?.(spriteEntry, 0);
911
708
  }
912
- return { buffer, count };
913
709
  }
914
710
 
915
711
  function transparentPassColorFormat(