@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
@@ -13,8 +13,8 @@ import type { RecoverFailure } from '../errors/recover';
13
13
  import type { ObservationUnavailableError, RenderError } from '../errors/render';
14
14
  import type { RenderFeature, RenderFeatureDiagnostics } from '../features/types';
15
15
  import type { GpuDrivenProductionInspection, LodOcclusionInspection } from '../inspection-types';
16
- import type { InstanceCollectionStore } from '../instances';
17
16
  import type { MeshMaterialBindingObservation } from '../mesh-material-bindings';
17
+ import type { PublishedRenderFrameInput } from '../publication/contract';
18
18
  import type { FrameObservation, FrameObservationOptions } from '../record/frame';
19
19
  import type { CurrentGraphTarget, GraphTargetCaptureRequest } from '../record/frame-snapshot';
20
20
  import type {
@@ -35,6 +35,7 @@ import type {
35
35
  } from '../render-contract';
36
36
  import type { RenderSceneInspection } from '../render-system';
37
37
  import type { RenderSceneBounds } from '../scene/render-scene-types';
38
+ import type { SurfaceDynamicInputFrame } from '../surface/dynamic-input';
38
39
  import type {
39
40
  RenderTarget,
40
41
  RenderTargetDescriptor,
@@ -62,8 +63,8 @@ export type RendererHostEventListener = (event: RendererHostEvent) => void;
62
63
  * the public Renderer type.
63
64
  */
64
65
  export interface RendererHostImplementation {
65
- /** Renderer-owned authoring and update path for large instance collections. */
66
- readonly instances: InstanceCollectionStore;
66
+ /** Publish one renderer-owned read-only Surface dynamic page for the next frame. */
67
+ setSurfaceDynamicInput(frame: SurfaceDynamicInputFrame | undefined): void;
67
68
  attach(world: World): RenderResult<RenderWorldLease, RenderError>;
68
69
  prepareDynamicGeometry(
69
70
  input: DynamicGeometryPrepareInput,
@@ -120,7 +121,9 @@ export interface RendererHostImplementation {
120
121
  readonly lodOcclusion: LodOcclusionInspection | undefined;
121
122
  readonly gpuDriven: GpuDrivenProductionInspection;
122
123
  };
123
- drawFrame(request: RenderFrameInput): RenderResult<FrameReceipt, RhiError | RenderError>;
124
+ drawFrame(
125
+ request: RenderFrameInput | PublishedRenderFrameInput,
126
+ ): RenderResult<FrameReceipt, RhiError | RenderError>;
124
127
  /** Arm one upcoming frame for receipt-bound color observations. */
125
128
  requestObservation?: (
126
129
  domains: readonly import('../render-contract').FrameObservationDomain[],
@@ -154,7 +157,7 @@ export interface RendererLegacyHostAdapter {
154
157
  attachScene(world: World): RenderResult<void, RhiError>;
155
158
  detachScene(world: World): void;
156
159
  draw(
157
- worldsOrRequest: readonly World[] | RenderFrameInput,
160
+ worldsOrRequest: readonly World[] | RenderFrameInput | PublishedRenderFrameInput,
158
161
  options?: DrawOwnerOptions,
159
162
  ): RenderResult<void | FrameReceipt, RhiError | RenderError>;
160
163
  observeCurrentFrame(
@@ -245,7 +245,17 @@ function selectPublishedVariant(
245
245
  withColor = withColor.filter((variant) => variant.defines.COVERAGE_ONLY !== true);
246
246
  }
247
247
  if (options.variantSet !== undefined) {
248
- return withColor.find((variant) => variant.definesKey === options.variantSet);
248
+ const requestedAxes = new Map(
249
+ options.variantSet.length === 0
250
+ ? []
251
+ : options.variantSet.split('+').map((entry) => {
252
+ const [name, value] = entry.split('=');
253
+ return [name ?? '', value === 'true'] as const;
254
+ }),
255
+ );
256
+ withColor = withColor.filter((variant) =>
257
+ [...requestedAxes].every(([name, value]) => variant.defines[name] === value),
258
+ );
249
259
  }
250
260
  // GPU-driven Standard owns the storage-backed scene-index variant. Prefer that exact family, then fall back to the closest variant
251
261
  // carrying the requested COLOR_0 fact. This keeps the selection deterministic
@@ -296,12 +306,13 @@ export function resolveStandardPbrArtifact(
296
306
  for (const lookupId of lookupIds) {
297
307
  const lookup = shader.findMaterialArtifact(lookupId);
298
308
  if (!lookup.ok) continue;
299
- const manifestEntry =
300
- shader.materialShaderManifestEntries === undefined
301
- ? undefined
302
- : Array.from(shader.materialShaderManifestEntries()).find(
303
- (entry) => entry.identifier === lookupId,
304
- );
309
+ let manifestEntry: MaterialShaderManifestEntry | undefined;
310
+ for (const entry of shader.materialShaderManifestEntries?.() ?? []) {
311
+ if (entry.identifier === lookupId) {
312
+ manifestEntry = entry;
313
+ break;
314
+ }
315
+ }
305
316
  const selected =
306
317
  manifestEntry === undefined || manifestEntry.variants.length === 0
307
318
  ? undefined
@@ -356,12 +367,13 @@ export function resolveMaterialShaderArtifact(
356
367
  for (const lookupId of lookupIds) {
357
368
  const lookup = shader.findMaterialArtifact(lookupId);
358
369
  if (!lookup.ok) continue;
359
- const manifestEntry =
360
- shader.materialShaderManifestEntries === undefined
361
- ? undefined
362
- : Array.from(shader.materialShaderManifestEntries()).find(
363
- (entry) => entry.identifier === lookupId,
364
- );
370
+ let manifestEntry: MaterialShaderManifestEntry | undefined;
371
+ for (const entry of shader.materialShaderManifestEntries?.() ?? []) {
372
+ if (entry.identifier === lookupId) {
373
+ manifestEntry = entry;
374
+ break;
375
+ }
376
+ }
365
377
  let cache = publishedArtifacts.get(lookup.value);
366
378
  if (cache === undefined || cache.manifest !== manifestEntry) {
367
379
  cache = { manifest: manifestEntry, requests: new Map() };
@@ -1,6 +1,7 @@
1
1
  import type { BindGroupLayout } from '@forgeax/engine-rhi';
2
2
  import type { MaterialShaderArtifact, ShaderRegistry } from '@forgeax/engine-shader';
3
3
  import { type GpuDrivenPbrProgram, resolveStandardPbrProgram } from '../../gpu-driven/pbr-program';
4
+ import { type PipelineGroup2Contract, resolvePipelineGroup2Contract } from '../../pbr-pipeline';
4
5
  import type { LayoutKind } from '../material-shader-policy';
5
6
  import { type MaterialShaderArtifactRequest, resolveMaterialShaderArtifact } from './assembly';
6
7
 
@@ -42,7 +43,11 @@ export function resolveMaterialPipelineVertexEntry(
42
43
  vertexEntryPoint: string | undefined,
43
44
  authoredVertexEntry: string | undefined,
44
45
  ): string | undefined {
45
- const sceneIndex = layoutKind === 'gpu-driven-pbr' || layoutKind === 'gpu-driven-skin';
46
+ const sceneIndex =
47
+ layoutKind === 'gpu-driven-pbr' ||
48
+ layoutKind === 'gpu-driven-skin' ||
49
+ layoutKind === 'gpu-driven-cluster-pbr' ||
50
+ layoutKind === 'gpu-driven-cluster-skin';
46
51
  // Scene-index is a renderer submission ABI. An authored/direct entry may
47
52
  // accompany the artifact for diagnostics, but it must not replace the
48
53
  // receipt entry when the GPU-driven layout is selected.
@@ -51,6 +56,33 @@ export function resolveMaterialPipelineVertexEntry(
51
56
  : (authoredVertexEntry ?? vertexEntryPoint);
52
57
  }
53
58
 
59
+ /** Keep the recorded group(2) receipt identical to the selected pipeline layout. */
60
+ export function resolveMaterialPipelineGroup2Contract(
61
+ source: string,
62
+ layoutKind: LayoutKind | undefined,
63
+ ): PipelineGroup2Contract {
64
+ switch (layoutKind) {
65
+ case 'hdrp-pbr':
66
+ case 'gpu-driven-cluster-pbr':
67
+ case 'surface-direct-cluster-pbr':
68
+ return 'cluster';
69
+ case 'hdrp-skin':
70
+ case 'gpu-driven-cluster-skin':
71
+ return 'skin-cluster';
72
+ case 'pbr-skin':
73
+ case 'gpu-driven-skin':
74
+ return 'skin';
75
+ case 'pbr':
76
+ case 'gpu-driven-pbr':
77
+ case 'surface-direct-pbr':
78
+ case 'sprite-urp':
79
+ case 'unlit-urp':
80
+ return 'mesh';
81
+ case undefined:
82
+ return resolvePipelineGroup2Contract(source);
83
+ }
84
+ }
85
+
54
86
  export interface MaterialPipelineBindGroupState {
55
87
  readonly meshBindGroupLayout: BindGroupLayout;
56
88
  readonly pbrSkinMeshBindGroupLayout: BindGroupLayout | null;
@@ -58,6 +90,8 @@ export interface MaterialPipelineBindGroupState {
58
90
  readonly hdrpMeshBindGroupLayout?: BindGroupLayout | null;
59
91
  readonly instancesBindGroupLayout: BindGroupLayout;
60
92
  readonly gpuDrivenInstancesBindGroupLayout?: BindGroupLayout | null;
93
+ readonly surfaceDirectInstancesBindGroupLayout?: BindGroupLayout | null;
94
+ readonly gpuDrivenClusterMeshBindGroupLayout?: BindGroupLayout | null;
61
95
  }
62
96
 
63
97
  export function resolveMaterialPipelineBindGroups(
@@ -66,20 +100,27 @@ export function resolveMaterialPipelineBindGroups(
66
100
  clustered = false,
67
101
  ): { readonly meshLayout: BindGroupLayout; readonly instancesLayout: BindGroupLayout } | null {
68
102
  const meshLayout =
69
- clustered && layoutKind === 'gpu-driven-pbr'
70
- ? state.hdrpMeshBindGroupLayout
71
- : clustered && layoutKind === 'gpu-driven-skin'
72
- ? state.hdrpSkinMeshBindGroupLayout
73
- : layoutKind === 'pbr-skin' || layoutKind === 'gpu-driven-skin'
74
- ? state.pbrSkinMeshBindGroupLayout
75
- : layoutKind === 'hdrp-skin'
103
+ layoutKind === 'gpu-driven-cluster-pbr' || layoutKind === 'surface-direct-cluster-pbr'
104
+ ? state.gpuDrivenClusterMeshBindGroupLayout
105
+ : clustered && layoutKind === 'gpu-driven-pbr'
106
+ ? state.hdrpMeshBindGroupLayout
107
+ : clustered && layoutKind === 'gpu-driven-skin'
108
+ ? state.hdrpSkinMeshBindGroupLayout
109
+ : layoutKind === 'gpu-driven-cluster-skin' || layoutKind === 'hdrp-skin'
76
110
  ? state.hdrpSkinMeshBindGroupLayout
77
- : state.meshBindGroupLayout;
111
+ : layoutKind === 'pbr-skin' || layoutKind === 'gpu-driven-skin'
112
+ ? state.pbrSkinMeshBindGroupLayout
113
+ : state.meshBindGroupLayout;
78
114
  if (meshLayout == null) return null;
79
115
  const instancesLayout =
80
- layoutKind === 'gpu-driven-pbr' || layoutKind === 'gpu-driven-skin'
81
- ? state.gpuDrivenInstancesBindGroupLayout
82
- : state.instancesBindGroupLayout;
116
+ layoutKind === 'surface-direct-pbr' || layoutKind === 'surface-direct-cluster-pbr'
117
+ ? state.surfaceDirectInstancesBindGroupLayout
118
+ : layoutKind === 'gpu-driven-pbr' ||
119
+ layoutKind === 'gpu-driven-skin' ||
120
+ layoutKind === 'gpu-driven-cluster-pbr' ||
121
+ layoutKind === 'gpu-driven-cluster-skin'
122
+ ? state.gpuDrivenInstancesBindGroupLayout
123
+ : state.instancesBindGroupLayout;
83
124
  return instancesLayout === null || instancesLayout === undefined
84
125
  ? null
85
126
  : { meshLayout, instancesLayout };
@@ -9,6 +9,7 @@ import { err, ok, RhiError } from '@forgeax/engine-rhi';
9
9
  import {
10
10
  DEFAULT_STANDARD_PBR_PARAM_SCHEMA,
11
11
  findVariantByKey,
12
+ type MaterialShaderEntry,
12
13
  type MaterialShaderManifestEntry,
13
14
  type ShaderCatalog,
14
15
  type ShaderCatalogDevice,
@@ -543,6 +544,10 @@ export type LayoutKind =
543
544
  | 'pbr-skin'
544
545
  | 'gpu-driven-pbr'
545
546
  | 'gpu-driven-skin'
547
+ | 'gpu-driven-cluster-pbr'
548
+ | 'gpu-driven-cluster-skin'
549
+ | 'surface-direct-pbr'
550
+ | 'surface-direct-cluster-pbr'
546
551
  | 'hdrp-pbr'
547
552
  | 'hdrp-skin'
548
553
  | 'sprite-urp'
@@ -781,6 +786,48 @@ export function resolveMaterialShaderBackendArtifactKey(
781
786
  return fallback?.specializationKey ?? materialShaderId;
782
787
  }
783
788
 
789
+ /**
790
+ * Remove the optional cloud-shadow sampler pair from a cooked material when
791
+ * the active device has no spare sampled-texture lanes. Pack-cooked material
792
+ * programs are immutable artifacts and therefore do not carry the engine
793
+ * manifest's capability Cartesian product. The low-limit renderer contract is
794
+ * still explicit: direct solar remains fully lit, while the view BGL stays at
795
+ * its 16-texture limit. Only the cloud sampler declarations and their sample
796
+ * are rewritten; the material's surface, parameters, and lighting remain
797
+ * unchanged.
798
+ */
799
+ export function stripCloudShadowBindingsForLowLimit(source: string): string {
800
+ const textureDeclaration =
801
+ /@group\s*\(\s*0\s*\)\s*@binding\s*\(\s*16\s*\)\s*var\s+(\w+)\s*:\s*texture_2d<f32>\s*;\s*/u;
802
+ const samplerDeclaration =
803
+ /@group\s*\(\s*0\s*\)\s*@binding\s*\(\s*17\s*\)\s*var\s+(\w+)\s*:\s*sampler\s*;\s*/u;
804
+ const textureMatch = textureDeclaration.exec(source);
805
+ const samplerMatch = samplerDeclaration.exec(source);
806
+ if (textureMatch === null || samplerMatch === null) return source;
807
+ const textureName = textureMatch[1];
808
+ const samplerName = samplerMatch[1];
809
+ if (textureName === undefined || samplerName === undefined) return source;
810
+
811
+ let rewritten = source.replace(textureDeclaration, '').replace(samplerDeclaration, '');
812
+ const escapedTexture = textureName.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
813
+ const escapedSampler = samplerName.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
814
+ const cloudSample = new RegExp(
815
+ `textureSampleLevel\\(\\s*${escapedTexture}\\s*,\\s*${escapedSampler}\\s*,[^;\\n]*\\)`,
816
+ 'gu',
817
+ );
818
+ rewritten = rewritten.replace(cloudSample, 'vec4<f32>(1.0)');
819
+ return rewritten;
820
+ }
821
+
822
+ export function prepareLowLimitMaterialShaderEntry<T extends MaterialShaderEntry>(
823
+ entry: T,
824
+ sampledTextureLimit: number | undefined,
825
+ ): T {
826
+ if ((sampledTextureLimit ?? 0) >= STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES) return entry;
827
+ const source = stripCloudShadowBindingsForLowLimit(entry.source);
828
+ return source === entry.source ? entry : ({ ...entry, source } as T);
829
+ }
830
+
784
831
  export function allowsUnlitPreparedFallback(
785
832
  depthFormatOverride: GPUTextureFormat | null | undefined,
786
833
  vertexLayout: string | undefined,
@@ -822,6 +869,8 @@ export function selectPipelineLayoutForVariant(
822
869
  readonly pbrSkinProbePipelineLayout?: PipelineLayout | null;
823
870
  readonly gpuDrivenPbrPipelineLayout?: PipelineLayout | null;
824
871
  readonly gpuDrivenPbrSkinPipelineLayout?: PipelineLayout | null;
872
+ readonly gpuDrivenClusterPbrPipelineLayout?: PipelineLayout | null;
873
+ readonly gpuDrivenClusterPbrSkinPipelineLayout?: PipelineLayout | null;
825
874
  readonly hdrpSkinPipelineLayout?: PipelineLayout | null;
826
875
  } | null,
827
876
  variantSet: string | undefined,
@@ -835,6 +884,12 @@ export function selectPipelineLayoutForVariant(
835
884
  if (layoutKind === 'gpu-driven-skin') {
836
885
  return state.gpuDrivenPbrSkinPipelineLayout ?? null;
837
886
  }
887
+ if (layoutKind === 'gpu-driven-cluster-pbr') {
888
+ return state.gpuDrivenClusterPbrPipelineLayout ?? null;
889
+ }
890
+ if (layoutKind === 'gpu-driven-cluster-skin') {
891
+ return state.gpuDrivenClusterPbrSkinPipelineLayout ?? null;
892
+ }
838
893
  // bug-20260611: skin layout selection takes precedence over HDRP variant
839
894
  // resolution. HDRP × skin is OOS-1 (plan-strategy R-2 — left for a
840
895
  // dedicated feat); when an HDRP-variant skin call ever lands, we fail
@@ -2,7 +2,10 @@ import type { Result, RhiDevice, ShaderModule } from '@forgeax/engine-rhi';
2
2
  import { RhiError } from '@forgeax/engine-rhi';
3
3
  import type { ShaderCatalog } from '@forgeax/engine-shader';
4
4
 
5
- import { invokeDeviceCreateShaderModule } from './material-shader-policy';
5
+ import {
6
+ invokeDeviceCreateShaderModule,
7
+ prepareLowLimitMaterialShaderEntry,
8
+ } from './material-shader-policy';
6
9
  import { runShimStep } from './renderer-helpers';
7
10
 
8
11
  type AsyncCreateShaderModule = (
@@ -37,12 +40,18 @@ export async function prewarmRequiredMaterialShaders({
37
40
  hint: `add material shader '${materialShaderId}' to the shader manifest or remove it from the feature declaration`,
38
41
  });
39
42
  }
43
+ // Prewarm and lazy pipelines share a module label, so they must compile
44
+ // the same capability-adjusted source on the replacement device.
45
+ const entry = prepareLowLimitMaterialShaderEntry(
46
+ lookup.value,
47
+ rhiDevice.limits.maxSampledTexturesPerShaderStage,
48
+ );
40
49
  const label = `module-${materialShaderId}`;
41
50
  const shaderResult = await runShimStep(
42
51
  () =>
43
52
  asyncCreateShaderModule
44
- ? asyncCreateShaderModule(rhiDevice, { code: lookup.value.source, label })
45
- : invokeDeviceCreateShaderModule(rhiDevice, { code: lookup.value.source, label }),
53
+ ? asyncCreateShaderModule(rhiDevice, { code: entry.source, label })
54
+ : invokeDeviceCreateShaderModule(rhiDevice, { code: entry.source, label }),
46
55
  'shader-compile-failed',
47
56
  `declared render feature material shader '${materialShaderId}' compiled`,
48
57
  `inspect the composed WGSL for '${materialShaderId}' and check device.features`,
@@ -50,28 +59,30 @@ export async function prewarmRequiredMaterialShaders({
50
59
  if (!shaderResult.ok) throw shaderResult.error;
51
60
  seedShaderModule(label, shaderResult.value);
52
61
 
53
- const prewarmedSources = new Map<string, ShaderModule>([
54
- [lookup.value.source, shaderResult.value],
55
- ]);
62
+ const prewarmedSources = new Map<string, ShaderModule>([[entry.source, shaderResult.value]]);
56
63
  const manifestEntry = [...registry.materialShaderManifestEntries()].find(
57
64
  (candidate) => candidate.identifier === materialShaderId,
58
65
  );
59
66
  if (manifestEntry === undefined) continue;
60
67
 
61
68
  for (const variant of manifestEntry.variants) {
69
+ const variantSource = prepareLowLimitMaterialShaderEntry(
70
+ { ...entry, source: variant.composedWgsl },
71
+ rhiDevice.limits.maxSampledTexturesPerShaderStage,
72
+ ).source;
62
73
  const variantLabel = `module-${materialShaderId}#${variant.definesKey}`;
63
74
  if (variantLabel === label) continue;
64
- let variantModule = prewarmedSources.get(variant.composedWgsl);
75
+ let variantModule = prewarmedSources.get(variantSource);
65
76
  if (variantModule === undefined) {
66
77
  const variantResult = await runShimStep(
67
78
  () =>
68
79
  asyncCreateShaderModule
69
80
  ? asyncCreateShaderModule(rhiDevice, {
70
- code: variant.composedWgsl,
81
+ code: variantSource,
71
82
  label: variantLabel,
72
83
  })
73
84
  : invokeDeviceCreateShaderModule(rhiDevice, {
74
- code: variant.composedWgsl,
85
+ code: variantSource,
75
86
  label: variantLabel,
76
87
  }),
77
88
  'shader-compile-failed',
@@ -80,7 +91,7 @@ export async function prewarmRequiredMaterialShaders({
80
91
  );
81
92
  if (!variantResult.ok) throw variantResult.error;
82
93
  variantModule = variantResult.value;
83
- prewarmedSources.set(variant.composedWgsl, variantModule);
94
+ prewarmedSources.set(variantSource, variantModule);
84
95
  }
85
96
  seedShaderModule(variantLabel, variantModule);
86
97
  }
@@ -30,6 +30,19 @@ export function attachDeviceLostFanout(
30
30
  onStaleLoss,
31
31
  onDeviceLost,
32
32
  } = registries;
33
+ if (pack._internal_getRawDevice && pack.translateErrorEventToRhiError) {
34
+ const backendDevice = pack._internal_getRawDevice(device);
35
+ if (backendDevice && typeof backendDevice === 'object') {
36
+ const target = backendDevice as {
37
+ onuncapturederror?: ((event: unknown) => void) | null;
38
+ };
39
+ target.onuncapturederror = (event: unknown): void => {
40
+ if (generation !== currentGeneration()) return;
41
+ const translated = pack.translateErrorEventToRhiError?.(event);
42
+ if (translated && !translated.ok) errorRegistry.fire(translated.error);
43
+ };
44
+ }
45
+ }
33
46
  const dispatch = (safe: {
34
47
  readonly reason: 'destroyed' | 'unknown';
35
48
  readonly message: string;
@@ -10,6 +10,7 @@ import type {
10
10
  import { err, ok, type Result, RhiError } from '@forgeax/engine-rhi';
11
11
  import type { MaterialShaderManifestEntry, ShaderCatalog } from '@forgeax/engine-shader';
12
12
  import type { Handle, ParamSchemaEntry } from '@forgeax/engine-types';
13
+ import { AssetError } from '@forgeax/engine-types';
13
14
  import { DeviceScope } from '../../device/device-scope';
14
15
  import { GpuResidencyCache } from '../../device/gpu-residency';
15
16
  import { RecoverError, type RecoverFailure } from '../../errors/recover';
@@ -126,6 +127,8 @@ export interface RendererRecoveryDependencies {
126
127
  readonly getCandidateMaterialShaderUvSetCounts: () => Map<string, number> | undefined;
127
128
  readonly setCandidateMaterialShaderUvSetCounts: (state: Map<string, number> | undefined) => void;
128
129
  readonly setCandidateEmptyPostProcessBgl: (layout: BindGroupLayout | null | undefined) => void;
130
+ readonly getShaderModuleAdapter: () => ShaderDeviceAdapterInternal;
131
+ readonly getImmediateShaderModuleAdapter: () => ShaderDeviceAdapterInternal;
129
132
  readonly getShader: () => ShaderCatalog;
130
133
  readonly assets: AssetRegistry;
131
134
  readonly adaptMipmapShaderModuleFactory: (
@@ -197,6 +200,8 @@ export function createRendererRecovery(deps: RendererRecoveryDependencies): Rend
197
200
  getCandidateMaterialShaderUvSetCounts,
198
201
  setCandidateMaterialShaderUvSetCounts,
199
202
  setCandidateEmptyPostProcessBgl,
203
+ getShaderModuleAdapter,
204
+ getImmediateShaderModuleAdapter,
200
205
  getShader,
201
206
  assets,
202
207
  adaptMipmapShaderModuleFactory,
@@ -319,24 +324,8 @@ export function createRendererRecovery(deps: RendererRecoveryDependencies): Rend
319
324
  setCandidatePipelineCacheState(candidateState.pipelineCacheState);
320
325
  setCandidateMaterialShaderUvSetCounts(candidateState.materialShaderUvSetCounts);
321
326
  setCandidateEmptyPostProcessBgl(candidateState.emptyPostProcessBgl);
322
- // Copy only the active catalog's CPU declarations into the candidate.
323
- // Its manifest/module cache remains candidate-owned, so no lost-device
324
- // ShaderModule can cross the recovery boundary while late-installed
325
- // material shaders remain available to the normal builder.
326
- const activeShaderCatalog = getActiveShaderState().shaderInstance;
327
- if (activeShaderCatalog !== null) {
328
- const candidateShaderCatalog = getShader();
329
- for (const identifier of activeShaderCatalog.materialShaderIdentifiers()) {
330
- const entry = activeShaderCatalog.findMaterialArtifact(identifier);
331
- if (entry.ok && !candidateShaderCatalog.findMaterialArtifact(identifier).ok) {
332
- candidateShaderCatalog.installMaterialArtifact(identifier, {
333
- source: entry.value.source,
334
- paramSchema: entry.value.paramSchema,
335
- ...(entry.value.receipt === undefined ? {} : { receipt: entry.value.receipt }),
336
- });
337
- }
338
- }
339
- }
327
+ // getShader forks the admitted CPU catalog into the candidate on first
328
+ // access. Shader modules and all device-bound caches start empty.
340
329
  let candidatePostProcessResources: RecoveryPostProcessResources | undefined;
341
330
  let recoveryGraphCandidate: RecoveryGraphCandidate | undefined;
342
331
  let recoveryRootBundle: RecoveryRootBundle | undefined;
@@ -411,6 +400,14 @@ export function createRendererRecovery(deps: RendererRecoveryDependencies): Rend
411
400
  device,
412
401
  adaptMipmapShaderModuleFactory(internals.pack.createShaderModule),
413
402
  (world, pod) => {
403
+ if ('resolveAsset' in world)
404
+ return err(
405
+ new AssetError({
406
+ code: 'asset-not-found',
407
+ expected: 'source-owned environment asset allocation',
408
+ hint: 'publish the environment asset from its source owner before GPU preparation',
409
+ }),
410
+ );
414
411
  const handle: Handle<'EquirectAsset', 'shared'> = world.allocSharedRef(
415
412
  'EquirectAsset',
416
413
  pod,
@@ -486,6 +483,27 @@ export function createRendererRecovery(deps: RendererRecoveryDependencies): Rend
486
483
  if (preparation.kind === 'error') throw preparation.error;
487
484
  const abortedAfterShaders = abortDisposedRecovery('rehydrate');
488
485
  if (abortedAfterShaders !== undefined) return abortedAfterShaders;
486
+ // Rehydrate manifest-selected builtins before carrying over late-
487
+ // installed user declarations. Builtin material sources are capability
488
+ // variants: copying the active generation first can retain a shader that
489
+ // declares cloud bindings 16/17 while the replacement device only
490
+ // admits the low-limit view layout. The candidate catalog owns fresh CPU
491
+ // declarations and modules; only identifiers still absent after
492
+ // preparation cross the generation boundary.
493
+ const activeShaderCatalog = getActiveShaderState().shaderInstance;
494
+ if (activeShaderCatalog !== null) {
495
+ const candidateShaderCatalog = getShader();
496
+ for (const identifier of activeShaderCatalog.materialShaderIdentifiers()) {
497
+ const entry = activeShaderCatalog.findMaterialArtifact(identifier);
498
+ if (entry.ok && !candidateShaderCatalog.findMaterialArtifact(identifier).ok) {
499
+ candidateShaderCatalog.installMaterialArtifact(identifier, {
500
+ source: entry.value.source,
501
+ paramSchema: entry.value.paramSchema,
502
+ ...(entry.value.receipt === undefined ? {} : { receipt: entry.value.receipt }),
503
+ });
504
+ }
505
+ }
506
+ }
489
507
  setRecoveryPhase('compile-graph');
490
508
  const pipeline = await runRecoveryStep(
491
509
  async (attemptToken) => {
@@ -580,6 +598,20 @@ export function createRendererRecovery(deps: RendererRecoveryDependencies): Rend
580
598
  getParamSchema: { value: getParamSchema },
581
599
  getMaterialBindGroupLayout: { value: getMaterialBindGroupLayout },
582
600
  metrics: { value: metrics },
601
+ shaderModuleFactory: {
602
+ value: {
603
+ createShaderModule: (
604
+ descriptor: Parameters<ShaderDeviceAdapterInternal['createShaderModule']>[0],
605
+ ) => getShaderModuleAdapter().createShaderModule(descriptor),
606
+ },
607
+ },
608
+ immediateShaderModuleFactory: {
609
+ value: {
610
+ createShaderModule: (
611
+ descriptor: Parameters<ShaderDeviceAdapterInternal['createShaderModule']>[0],
612
+ ) => getImmediateShaderModuleAdapter().createShaderModule(descriptor),
613
+ },
614
+ },
583
615
  buildPostProcessPipeline: { value: buildPostProcessPipeline },
584
616
  getPipelineState: { value: () => candidatePipelineState },
585
617
  featureHost: { value: createdCandidateFeatureHost },
@@ -0,0 +1,54 @@
1
+ import { RhiError } from '@forgeax/engine-rhi';
2
+ import {
3
+ SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_WGSL,
4
+ SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_WGSL,
5
+ SINGLE_LAYER_MEDIUM_RAW_DEPTH_WGSL,
6
+ } from '@forgeax/engine-shader';
7
+ import type { RenderFeature } from '../features/types';
8
+ import {
9
+ SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_POST_PROCESS_ID,
10
+ SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_POST_PROCESS_ID,
11
+ SINGLE_LAYER_MEDIUM_RAW_DEPTH_POST_PROCESS_ID,
12
+ } from '../pipeline/single-layer-medium-passes';
13
+
14
+ export function collectRequiredFullscreenPostProcesses(
15
+ features: readonly RenderFeature<unknown>[],
16
+ ): readonly { readonly identity: string; readonly source: string }[] {
17
+ const entries = new Map<string, { readonly identity: string; readonly source: string }>([
18
+ [
19
+ SINGLE_LAYER_MEDIUM_RAW_DEPTH_POST_PROCESS_ID,
20
+ {
21
+ identity: SINGLE_LAYER_MEDIUM_RAW_DEPTH_POST_PROCESS_ID,
22
+ source: SINGLE_LAYER_MEDIUM_RAW_DEPTH_WGSL,
23
+ },
24
+ ],
25
+ [
26
+ SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_POST_PROCESS_ID,
27
+ {
28
+ identity: SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_POST_PROCESS_ID,
29
+ source: SINGLE_LAYER_MEDIUM_MSAA_PAIRED_COLOR_WGSL,
30
+ },
31
+ ],
32
+ [
33
+ SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_POST_PROCESS_ID,
34
+ {
35
+ identity: SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_POST_PROCESS_ID,
36
+ source: SINGLE_LAYER_MEDIUM_MSAA_RAW_DEPTH_WGSL,
37
+ },
38
+ ],
39
+ ]);
40
+ for (const feature of features) {
41
+ for (const entry of feature.requiredFullscreenPostProcesses ?? []) {
42
+ const existing = entries.get(entry.identity);
43
+ if (existing !== undefined && existing.source !== entry.source) {
44
+ throw new RhiError({
45
+ code: 'internal-error',
46
+ expected: `fullscreen identity '${entry.identity}' has one source across render features`,
47
+ hint: 'rename the conflicting fullscreen identity or make its WGSL source identical',
48
+ });
49
+ }
50
+ entries.set(entry.identity, entry);
51
+ }
52
+ }
53
+ return Object.freeze([...entries.values()]);
54
+ }