@forgeax/engine-render 0.1.27 → 0.1.29

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 (655) hide show
  1. package/README.md +842 -124
  2. package/dist/assembly/atmosphere-shader-prewarm.d.ts +6 -0
  3. package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -0
  4. package/dist/assembly/dynamic-geometry-host.d.ts +52 -0
  5. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -0
  6. package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
  7. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
  8. package/dist/assembly/factory.d.ts +3 -1
  9. package/dist/assembly/factory.d.ts.map +1 -1
  10. package/dist/assembly/gpu-driven-owner.d.ts +10 -0
  11. package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
  12. package/dist/assembly/host-contract.d.ts +19 -0
  13. package/dist/assembly/host-contract.d.ts.map +1 -1
  14. package/dist/assembly/material/assembly.d.ts +7 -0
  15. package/dist/assembly/material/assembly.d.ts.map +1 -1
  16. package/dist/assembly/material-shader-policy.d.ts +3 -1
  17. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  18. package/dist/assembly/recovery/failure-location.d.ts +12 -0
  19. package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
  20. package/dist/assembly/recovery/renderer-recover.d.ts +6 -4
  21. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  22. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  23. package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
  24. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
  25. package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
  26. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  27. package/dist/assembly/renderer-helpers.d.ts +3 -0
  28. package/dist/assembly/renderer-helpers.d.ts.map +1 -1
  29. package/dist/assembly/renderer-inspection.d.ts +4 -0
  30. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  31. package/dist/assembly/shader-prewarm-policy.d.ts +6 -0
  32. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
  33. package/dist/assembly/skin-palette-owner.d.ts +8 -0
  34. package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
  35. package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
  36. package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
  37. package/dist/assembly/webgpu-device-loss.d.ts +15 -0
  38. package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
  39. package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
  40. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
  41. package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
  42. package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
  43. package/dist/assembly/webgpu-ready.d.ts +7 -3
  44. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  45. package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
  46. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
  47. package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
  48. package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
  49. package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
  50. package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
  51. package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
  52. package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
  53. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
  54. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
  55. package/dist/assembly/webgpu-renderer.d.ts +7 -141
  56. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  57. package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
  58. package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
  59. package/dist/authoring.mjs +3 -3
  60. package/dist/{chunk-ADHHVYLW.mjs → chunk-33XZFTQU.mjs} +245 -39
  61. package/dist/chunk-33XZFTQU.mjs.map +1 -0
  62. package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
  63. package/dist/chunk-BLXGONR2.mjs.map +1 -0
  64. package/dist/{chunk-KM2NOX2I.mjs → chunk-BQVQOQJH.mjs} +958 -254
  65. package/dist/chunk-BQVQOQJH.mjs.map +1 -0
  66. package/dist/{chunk-HKXTW355.mjs → chunk-BTWH7BP4.mjs} +386 -17
  67. package/dist/chunk-BTWH7BP4.mjs.map +1 -0
  68. package/dist/{chunk-TMIASV2N.mjs → chunk-FUODTTIA.mjs} +3934 -676
  69. package/dist/chunk-FUODTTIA.mjs.map +1 -0
  70. package/dist/{chunk-FJ6P52EE.mjs → chunk-ILQ5MEZF.mjs} +3 -17
  71. package/dist/chunk-ILQ5MEZF.mjs.map +1 -0
  72. package/dist/{chunk-E34VL5VI.mjs → chunk-JQTSEI3Z.mjs} +3 -3
  73. package/dist/{chunk-E34VL5VI.mjs.map → chunk-JQTSEI3Z.mjs.map} +1 -1
  74. package/dist/{chunk-GE3SDD72.mjs → chunk-NICXSHAT.mjs} +16 -38
  75. package/dist/chunk-NICXSHAT.mjs.map +1 -0
  76. package/dist/{chunk-ZZ4YQ474.mjs → chunk-NRNXBLIJ.mjs} +577 -7
  77. package/dist/chunk-NRNXBLIJ.mjs.map +1 -0
  78. package/dist/{chunk-JDWARUOI.mjs → chunk-PA5DRJNI.mjs} +17 -3
  79. package/dist/chunk-PA5DRJNI.mjs.map +1 -0
  80. package/dist/{chunk-XDP6XE5V.mjs → chunk-S4DNKQYQ.mjs} +1118 -446
  81. package/dist/chunk-S4DNKQYQ.mjs.map +1 -0
  82. package/dist/components/camera.d.ts +62 -2
  83. package/dist/components/camera.d.ts.map +1 -1
  84. package/dist/components/index.d.ts +1 -0
  85. package/dist/components/index.d.ts.map +1 -1
  86. package/dist/components/instances.d.ts +6 -20
  87. package/dist/components/instances.d.ts.map +1 -1
  88. package/dist/components/scene-instance.d.ts +2 -1
  89. package/dist/components/scene-instance.d.ts.map +1 -1
  90. package/dist/components/screen-space-reflection.d.ts +14 -0
  91. package/dist/components/screen-space-reflection.d.ts.map +1 -0
  92. package/dist/construct-renderer.mjs +13805 -7186
  93. package/dist/construct-renderer.mjs.map +1 -1
  94. package/dist/device/gpu-residency.d.ts +11 -17
  95. package/dist/device/gpu-residency.d.ts.map +1 -1
  96. package/dist/device/mesh-residency-lifetime.d.ts +21 -0
  97. package/dist/device/mesh-residency-lifetime.d.ts.map +1 -0
  98. package/dist/dynamic-geometry.d.ts +125 -0
  99. package/dist/dynamic-geometry.d.ts.map +1 -0
  100. package/dist/environment/background.d.ts +6 -0
  101. package/dist/environment/background.d.ts.map +1 -0
  102. package/dist/errors/gpu-driven.d.ts +6 -3
  103. package/dist/errors/gpu-driven.d.ts.map +1 -1
  104. package/dist/errors/render.d.ts +7 -4
  105. package/dist/errors/render.d.ts.map +1 -1
  106. package/dist/extract/camera.d.ts.map +1 -1
  107. package/dist/extract/gpu-driven.d.ts +33 -3
  108. package/dist/extract/gpu-driven.d.ts.map +1 -1
  109. package/dist/features/host.d.ts +23 -1
  110. package/dist/features/host.d.ts.map +1 -1
  111. package/dist/features/noise-texture.d.ts +17 -0
  112. package/dist/features/noise-texture.d.ts.map +1 -0
  113. package/dist/features/plan.d.ts +83 -2
  114. package/dist/features/plan.d.ts.map +1 -1
  115. package/dist/features/prepared-gpu-work.d.ts +37 -4
  116. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  117. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  118. package/dist/features/prepared-graphics.d.ts +5 -0
  119. package/dist/features/prepared-graphics.d.ts.map +1 -1
  120. package/dist/features/render-graph-compute.d.ts +5 -3
  121. package/dist/features/render-graph-compute.d.ts.map +1 -1
  122. package/dist/features/render-graph-contribution.d.ts +11 -3
  123. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  124. package/dist/features/render-graph-raster.d.ts +19 -3
  125. package/dist/features/render-graph-raster.d.ts.map +1 -1
  126. package/dist/features/types.d.ts +11 -0
  127. package/dist/features/types.d.ts.map +1 -1
  128. package/dist/fullscreen-post-process-pass.d.ts +2 -0
  129. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  130. package/dist/gpu-driven/batch-topology.d.ts +34 -1
  131. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  132. package/dist/gpu-driven/pbr-program.d.ts +10 -0
  133. package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
  134. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  135. package/dist/gpu-driven/production-raster.d.ts +144 -23
  136. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  137. package/dist/gpu-driven/shadow-views.d.ts +126 -0
  138. package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
  139. package/dist/gpu-driven/view-gpu.d.ts +18 -2
  140. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  141. package/dist/gpu-scene-schema.d.ts +2 -8
  142. package/dist/gpu-scene-schema.d.ts.map +1 -1
  143. package/dist/gpu-scene.d.ts +14 -0
  144. package/dist/gpu-scene.d.ts.map +1 -1
  145. package/dist/gpu-texture-usage.d.ts +1 -0
  146. package/dist/gpu-texture-usage.d.ts.map +1 -1
  147. package/dist/hdrp-buffers.d.ts +6 -0
  148. package/dist/hdrp-buffers.d.ts.map +1 -1
  149. package/dist/ibl/frame-resources.d.ts +8 -0
  150. package/dist/ibl/frame-resources.d.ts.map +1 -0
  151. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  152. package/dist/index.d.ts +21 -8
  153. package/dist/index.d.ts.map +1 -1
  154. package/dist/index.mjs +8 -7
  155. package/dist/index.mjs.map +1 -1
  156. package/dist/inspection-types.d.ts +164 -0
  157. package/dist/inspection-types.d.ts.map +1 -1
  158. package/dist/instances-derived-bounds.d.ts +11 -0
  159. package/dist/instances-derived-bounds.d.ts.map +1 -1
  160. package/dist/instances.d.ts +89 -44
  161. package/dist/instances.d.ts.map +1 -1
  162. package/dist/internal.d.ts +3 -0
  163. package/dist/internal.d.ts.map +1 -1
  164. package/dist/internal.mjs +118 -10
  165. package/dist/internal.mjs.map +1 -1
  166. package/dist/lifecycle.d.ts +2 -1
  167. package/dist/lifecycle.d.ts.map +1 -1
  168. package/dist/material-row.d.ts +5 -0
  169. package/dist/material-row.d.ts.map +1 -0
  170. package/dist/materials.d.ts +15 -0
  171. package/dist/materials.d.ts.map +1 -1
  172. package/dist/pbr-pipeline.d.ts +21 -5
  173. package/dist/pbr-pipeline.d.ts.map +1 -1
  174. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  175. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
  176. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
  177. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
  178. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
  179. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
  180. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
  181. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
  182. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
  183. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
  184. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
  185. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
  186. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
  187. package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
  188. package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
  189. package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
  190. package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
  191. package/dist/pipeline/standard-output/graph.d.ts +15 -0
  192. package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
  193. package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
  194. package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
  195. package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
  196. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
  197. package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
  198. package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
  199. package/dist/pipeline/standard-output/resources.d.ts +10 -0
  200. package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
  201. package/dist/pipeline/standard-output/types.d.ts +39 -0
  202. package/dist/pipeline/standard-output/types.d.ts.map +1 -0
  203. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  204. package/dist/pipeline/standard-post.d.ts +2 -2
  205. package/dist/pipeline/standard-post.d.ts.map +1 -1
  206. package/dist/pipeline-builder.d.ts +2 -1
  207. package/dist/pipeline-builder.d.ts.map +1 -1
  208. package/dist/pipeline-spec-types.d.ts +4 -0
  209. package/dist/pipeline-spec-types.d.ts.map +1 -1
  210. package/dist/pipeline-spec.d.ts +1 -9
  211. package/dist/pipeline-spec.d.ts.map +1 -1
  212. package/dist/points-lines/standard-owner.d.ts +1 -1
  213. package/dist/points-lines/standard-owner.d.ts.map +1 -1
  214. package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
  215. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  216. package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
  217. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
  218. package/dist/record/frame-lighting.d.ts +3 -3
  219. package/dist/record/frame-lighting.d.ts.map +1 -1
  220. package/dist/record/frame-snapshot.d.ts +106 -5
  221. package/dist/record/frame-snapshot.d.ts.map +1 -1
  222. package/dist/record/frame-targets.d.ts.map +1 -1
  223. package/dist/record/frame.d.ts +39 -4
  224. package/dist/record/frame.d.ts.map +1 -1
  225. package/dist/record/main-pass-geometry.d.ts +7 -8
  226. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  227. package/dist/record/main-pass-material.d.ts +38 -1
  228. package/dist/record/main-pass-material.d.ts.map +1 -1
  229. package/dist/record/main-pass-sprite-draws.d.ts +2 -10
  230. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  231. package/dist/record/main-pass.d.ts +12 -2
  232. package/dist/record/main-pass.d.ts.map +1 -1
  233. package/dist/record/mesh-ssbo.d.ts +15 -6
  234. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  235. package/dist/record/prepared-material-bindings.d.ts +19 -0
  236. package/dist/record/prepared-material-bindings.d.ts.map +1 -0
  237. package/dist/record/recovery-pipeline.d.ts +2 -9
  238. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  239. package/dist/record/render-context.d.ts +76 -26
  240. package/dist/record/render-context.d.ts.map +1 -1
  241. package/dist/record/shadow-pass.d.ts +62 -7
  242. package/dist/record/shadow-pass.d.ts.map +1 -1
  243. package/dist/record/skybox-post-pass.d.ts +1 -1
  244. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  245. package/dist/record/typed-frame-graph.d.ts +35 -7
  246. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  247. package/dist/record/view-ubo.d.ts +1 -0
  248. package/dist/record/view-ubo.d.ts.map +1 -1
  249. package/dist/recovery/render-system-candidate.d.ts +10 -2
  250. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  251. package/dist/recovery/render-system-roots.d.ts +11 -0
  252. package/dist/recovery/render-system-roots.d.ts.map +1 -0
  253. package/dist/recovery/types.d.ts +76 -0
  254. package/dist/recovery/types.d.ts.map +1 -0
  255. package/dist/reflection/record-owner.d.ts +0 -2
  256. package/dist/reflection/record-owner.d.ts.map +1 -1
  257. package/dist/render-contract.d.ts +185 -30
  258. package/dist/render-contract.d.ts.map +1 -1
  259. package/dist/render-graph-primitives.d.ts +1 -0
  260. package/dist/render-graph-primitives.d.ts.map +1 -1
  261. package/dist/render-pipeline.d.ts +64 -5
  262. package/dist/render-pipeline.d.ts.map +1 -1
  263. package/dist/render-system-extract-tail.d.ts +7 -5
  264. package/dist/render-system-extract-tail.d.ts.map +1 -1
  265. package/dist/render-system-extract.d.ts +101 -41
  266. package/dist/render-system-extract.d.ts.map +1 -1
  267. package/dist/render-system-projections.d.ts +22 -0
  268. package/dist/render-system-projections.d.ts.map +1 -0
  269. package/dist/render-system.d.ts +34 -77
  270. package/dist/render-system.d.ts.map +1 -1
  271. package/dist/scene/render-scene-types.d.ts +14 -7
  272. package/dist/scene/render-scene-types.d.ts.map +1 -1
  273. package/dist/scene/render-scene.d.ts +29 -11
  274. package/dist/scene/render-scene.d.ts.map +1 -1
  275. package/dist/scene/shadow-visibility.d.ts +5 -0
  276. package/dist/scene/shadow-visibility.d.ts.map +1 -0
  277. package/dist/ssr/admission.d.ts +70 -1
  278. package/dist/ssr/admission.d.ts.map +1 -1
  279. package/dist/ssr/compose.d.ts +13 -0
  280. package/dist/ssr/compose.d.ts.map +1 -0
  281. package/dist/ssr/errors.d.ts +35 -0
  282. package/dist/ssr/errors.d.ts.map +1 -1
  283. package/dist/ssr/graph.d.ts +60 -0
  284. package/dist/ssr/graph.d.ts.map +1 -0
  285. package/dist/ssr/history.d.ts +97 -0
  286. package/dist/ssr/history.d.ts.map +1 -0
  287. package/dist/ssr/hiz.d.ts +37 -0
  288. package/dist/ssr/hiz.d.ts.map +1 -0
  289. package/dist/ssr/inspection.d.ts +42 -0
  290. package/dist/ssr/inspection.d.ts.map +1 -0
  291. package/dist/ssr/resources.d.ts +58 -0
  292. package/dist/ssr/resources.d.ts.map +1 -0
  293. package/dist/ssr/temporal.d.ts +38 -0
  294. package/dist/ssr/temporal.d.ts.map +1 -0
  295. package/dist/systems/skin-palette-allocator.d.ts +32 -10
  296. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  297. package/dist/systems/skin-palette-types.d.ts +15 -0
  298. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  299. package/dist/systems/transparent-dispatch.d.ts +9 -0
  300. package/dist/systems/transparent-dispatch.d.ts.map +1 -0
  301. package/dist/targets/material-source.d.ts +7 -0
  302. package/dist/targets/material-source.d.ts.map +1 -1
  303. package/dist/temporal/frame-coordinator.d.ts +7 -0
  304. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  305. package/dist/temporal/gpu.d.ts +8 -0
  306. package/dist/temporal/gpu.d.ts.map +1 -1
  307. package/dist/temporal/history.d.ts.map +1 -1
  308. package/dist/temporal/index.mjs +6 -6
  309. package/dist/temporal/inspection.d.ts.map +1 -1
  310. package/dist/temporal/standard-scene-data.d.ts +2 -1
  311. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  312. package/dist/temporal/temporal-view.d.ts +2 -0
  313. package/dist/temporal/temporal-view.d.ts.map +1 -1
  314. package/dist/typed-render-graph-primitives.d.ts +35 -1
  315. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  316. package/dist/typed-shadow-passes.d.ts +3 -1
  317. package/dist/typed-shadow-passes.d.ts.map +1 -1
  318. package/dist/volume/temporal.d.ts +6 -0
  319. package/dist/volume/temporal.d.ts.map +1 -1
  320. package/package.json +21 -20
  321. package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
  322. package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
  323. package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
  324. package/src/__tests__/auto-exposure.browser.test.ts +33 -0
  325. package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
  326. package/src/__tests__/detached-inspection.integration.test.ts +5 -0
  327. package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
  328. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
  329. package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
  330. package/src/__tests__/dynamic-geometry-host.unit.test.ts +1123 -0
  331. package/src/__tests__/dynamic-geometry.unit.test.ts +233 -0
  332. package/src/__tests__/factory-contract.integration.test.ts +73 -22
  333. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
  334. package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
  335. package/src/__tests__/feature-noise.unit.test.ts +38 -0
  336. package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
  337. package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
  338. package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
  339. package/src/__tests__/frame-targets.unit.test.ts +24 -0
  340. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
  341. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
  342. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +287 -6
  343. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
  344. package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
  345. package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +264 -0
  346. package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +349 -0
  347. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1417 -0
  348. package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
  349. package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
  350. package/src/__tests__/gpu-driven-production.integration.test.ts +1075 -93
  351. package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
  352. package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
  353. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
  354. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
  355. package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
  356. package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
  357. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
  358. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
  359. package/src/__tests__/gpu-driven-view.unit.test.ts +159 -52
  360. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -1
  361. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
  362. package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
  363. package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
  364. package/src/__tests__/gpu-scene.unit.test.ts +559 -33
  365. package/src/__tests__/instances-culling.integration.test.ts +36 -10
  366. package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
  367. package/src/__tests__/instances-store.unit.test.ts +242 -39
  368. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
  369. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
  370. package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
  371. package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
  372. package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
  373. package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
  374. package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
  375. package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
  376. package/src/__tests__/material-texture-source.unit.test.ts +87 -0
  377. package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
  378. package/src/__tests__/materials-standard-contract.unit.test.ts +52 -2
  379. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
  380. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +53 -0
  381. package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
  382. package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
  383. package/src/__tests__/physical-clearcoat.integration.test.ts +37 -3
  384. package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
  385. package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
  386. package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
  387. package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
  388. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +35 -4
  389. package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
  390. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
  391. package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
  392. package/src/__tests__/public-surface.test-d.ts +3 -0
  393. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
  394. package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +104 -0
  395. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +2 -1
  396. package/src/__tests__/render-error-code-owner.test-d.ts +4 -0
  397. package/src/__tests__/render-error-detail-ssot.test-d.ts +22 -0
  398. package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
  399. package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
  400. package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
  401. package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
  402. package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
  403. package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
  404. package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
  405. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
  406. package/src/__tests__/render-scene-projection.unit.test.ts +914 -23
  407. package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
  408. package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
  409. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
  410. package/src/__tests__/render-target-material-source.test-d.ts +27 -3
  411. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +61 -1
  412. package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
  413. package/src/__tests__/shader-manifest-fixture.ts +39 -0
  414. package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
  415. package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
  416. package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
  417. package/src/__tests__/skinned-shadow-caster.test.ts +118 -14
  418. package/src/__tests__/specular-environment-scale.dawn.test.ts +156 -0
  419. package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
  420. package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
  421. package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
  422. package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
  423. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +91 -0
  424. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +112 -0
  425. package/src/__tests__/ssr-gpu-dispatch.ts +946 -0
  426. package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
  427. package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
  428. package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
  429. package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
  430. package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
  431. package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
  432. package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
  433. package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
  434. package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
  435. package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
  436. package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
  437. package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
  438. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
  439. package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
  440. package/src/__tests__/ssr-reprojection-probe.ts +90 -0
  441. package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
  442. package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
  443. package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
  444. package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
  445. package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
  446. package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
  447. package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
  448. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +44 -12
  449. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
  450. package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
  451. package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
  452. package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
  453. package/src/__tests__/standard-output.browser.test.ts +15 -0
  454. package/src/__tests__/standard-output.dawn.test.ts +15 -0
  455. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +38 -0
  456. package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
  457. package/src/__tests__/standard-profile-oracle.unit.test.ts +22 -0
  458. package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
  459. package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
  460. package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
  461. package/src/__tests__/taa-coverage-edge.dawn.test.ts +193 -0
  462. package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
  463. package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +778 -0
  464. package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
  465. package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
  466. package/src/__tests__/taa-stability-feedback.ts +341 -0
  467. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
  468. package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
  469. package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
  470. package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
  471. package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
  472. package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
  473. package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
  474. package/src/__tests__/visibility-extract.perf.test.ts +20 -8
  475. package/src/__tests__/visibility-instances.integration.test.ts +19 -7
  476. package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
  477. package/src/assembly/atmosphere-shader-prewarm.ts +38 -0
  478. package/src/assembly/dynamic-geometry-host.ts +887 -0
  479. package/src/assembly/dynamic-geometry-runtime.ts +71 -0
  480. package/src/assembly/factory.ts +4 -0
  481. package/src/assembly/gpu-driven-owner.ts +29 -0
  482. package/src/assembly/host-contract.ts +36 -0
  483. package/src/assembly/material/assembly.ts +38 -0
  484. package/src/assembly/material-shader-policy.ts +71 -28
  485. package/src/assembly/recovery/failure-location.ts +62 -0
  486. package/src/assembly/recovery/renderer-recover.ts +19 -17
  487. package/src/assembly/renderer-facade.ts +29 -0
  488. package/src/assembly/renderer-feature-inspection.ts +13 -0
  489. package/src/assembly/renderer-frame-transaction.ts +63 -0
  490. package/src/assembly/renderer-helpers.ts +26 -0
  491. package/src/assembly/renderer-inspection.ts +6 -0
  492. package/src/assembly/shader-prewarm-policy.ts +32 -0
  493. package/src/assembly/skin-palette-owner.ts +21 -0
  494. package/src/assembly/ssr-shader-prewarm.ts +41 -0
  495. package/src/assembly/webgpu-device-loss.ts +75 -0
  496. package/src/assembly/webgpu-pbr-ready.ts +232 -0
  497. package/src/assembly/webgpu-ready-mipmap.ts +26 -0
  498. package/src/assembly/webgpu-ready.ts +142 -121
  499. package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
  500. package/src/assembly/webgpu-renderer-contract.ts +69 -0
  501. package/src/assembly/webgpu-renderer-guards.ts +32 -0
  502. package/src/assembly/webgpu-renderer-observation.ts +43 -0
  503. package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
  504. package/src/assembly/webgpu-renderer.ts +675 -614
  505. package/src/assembly/webgpu-vertex-layouts.ts +233 -87
  506. package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
  507. package/src/components/camera.ts +287 -7
  508. package/src/components/index.ts +1 -0
  509. package/src/components/instances.ts +45 -18
  510. package/src/components/scene-instance.ts +2 -1
  511. package/src/components/screen-space-reflection.ts +21 -0
  512. package/src/components/sprite-animation.ts +3 -3
  513. package/src/components/sprite-instances.ts +1 -1
  514. package/src/device/gpu-residency.ts +96 -93
  515. package/src/device/mesh-residency-lifetime.ts +73 -0
  516. package/src/dynamic-geometry.ts +736 -0
  517. package/src/environment/background.ts +263 -0
  518. package/src/errors/gpu-driven.ts +39 -5
  519. package/src/errors/render.ts +27 -3
  520. package/src/extract/camera.ts +26 -1
  521. package/src/extract/gpu-driven.ts +185 -10
  522. package/src/features/host.ts +237 -19
  523. package/src/features/noise-texture.ts +91 -0
  524. package/src/features/plan.ts +553 -24
  525. package/src/features/prepared-gpu-work.ts +631 -49
  526. package/src/features/prepared-graphics-store.ts +31 -0
  527. package/src/features/prepared-graphics.ts +5 -0
  528. package/src/features/render-graph-compute.ts +41 -8
  529. package/src/features/render-graph-contribution.ts +141 -3
  530. package/src/features/render-graph-raster.ts +143 -30
  531. package/src/features/types.ts +11 -0
  532. package/src/fullscreen-post-process-pass.ts +3 -0
  533. package/src/gpu-driven/batch-topology.ts +424 -102
  534. package/src/gpu-driven/pbr-program.ts +31 -0
  535. package/src/gpu-driven/prepared-draw.ts +29 -4
  536. package/src/gpu-driven/production-raster.ts +2267 -694
  537. package/src/gpu-driven/shadow-views.ts +539 -0
  538. package/src/gpu-driven/view-gpu.ts +188 -41
  539. package/src/gpu-scene-schema.ts +52 -11
  540. package/src/gpu-scene.ts +186 -99
  541. package/src/gpu-texture-usage.ts +1 -0
  542. package/src/hdrp-buffers.ts +72 -36
  543. package/src/ibl/frame-resources.ts +38 -0
  544. package/src/ibl/skylight-bind-group.ts +5 -4
  545. package/src/index.ts +125 -1
  546. package/src/inspection-types.ts +191 -0
  547. package/src/instances-derived-bounds.ts +258 -34
  548. package/src/instances.ts +459 -150
  549. package/src/internal.ts +22 -0
  550. package/src/lifecycle.ts +2 -0
  551. package/src/material-row.ts +145 -0
  552. package/src/materials.ts +44 -8
  553. package/src/pbr-pipeline.ts +159 -17
  554. package/src/pipeline/standard-forward-lane.ts +52 -24
  555. package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
  556. package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
  557. package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
  558. package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
  559. package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
  560. package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
  561. package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
  562. package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
  563. package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
  564. package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
  565. package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
  566. package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
  567. package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
  568. package/src/pipeline/standard-output/color-transform.ts +124 -0
  569. package/src/pipeline/standard-output/graph.ts +139 -0
  570. package/src/pipeline/standard-output/lut-admission.ts +121 -0
  571. package/src/pipeline/standard-output/lut-gpu.ts +399 -0
  572. package/src/pipeline/standard-output/lut-state.ts +176 -0
  573. package/src/pipeline/standard-output/resources.ts +121 -0
  574. package/src/pipeline/standard-output/types.ts +58 -0
  575. package/src/pipeline/standard-pipeline.ts +192 -59
  576. package/src/pipeline/standard-post.ts +186 -27
  577. package/src/pipeline-builder.ts +16 -6
  578. package/src/pipeline-spec-types.ts +4 -0
  579. package/src/pipeline-spec.ts +37 -29
  580. package/src/points-lines/standard-owner.ts +6 -14
  581. package/src/prepare/prepared-graphics-resolver.ts +9 -2
  582. package/src/record/__tests__/material-slot-plan.unit.test.ts +48 -0
  583. package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
  584. package/src/record/__tests__/recovery-pipeline.unit.test.ts +2 -29
  585. package/src/record/__tests__/sprite-material-abi.unit.test.ts +36 -5
  586. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
  587. package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
  588. package/src/record/dynamic-geometry-consumption.ts +59 -0
  589. package/src/record/frame-lighting.ts +12 -11
  590. package/src/record/frame-snapshot.ts +133 -23
  591. package/src/record/frame-targets.ts +9 -0
  592. package/src/record/frame.ts +727 -133
  593. package/src/record/main-pass-geometry.ts +162 -98
  594. package/src/record/main-pass-material.ts +115 -26
  595. package/src/record/main-pass-sprite-draws.ts +18 -107
  596. package/src/record/main-pass.ts +78 -8
  597. package/src/record/material-uniforms.ts +1 -1
  598. package/src/record/mesh-ssbo.ts +59 -15
  599. package/src/record/prepared-material-bindings.ts +234 -0
  600. package/src/record/recovery-pipeline.ts +59 -136
  601. package/src/record/render-context.ts +92 -22
  602. package/src/record/shadow-pass.ts +1231 -209
  603. package/src/record/skybox-post-pass.ts +14 -3
  604. package/src/record/typed-frame-graph.ts +1006 -53
  605. package/src/record/view-ubo.ts +11 -0
  606. package/src/recovery/render-system-candidate.ts +90 -66
  607. package/src/recovery/render-system-roots.ts +113 -0
  608. package/src/recovery/types.ts +77 -0
  609. package/src/reflection/record-owner.ts +26 -54
  610. package/src/render-contract.ts +219 -25
  611. package/src/render-graph-primitives.ts +6 -2
  612. package/src/render-pipeline.ts +70 -1
  613. package/src/render-system-extract-tail.ts +409 -160
  614. package/src/render-system-extract.ts +376 -102
  615. package/src/render-system-projections.ts +241 -0
  616. package/src/render-system.ts +692 -791
  617. package/src/scene/render-scene-types.ts +13 -4
  618. package/src/scene/render-scene.ts +569 -355
  619. package/src/scene/shadow-visibility.ts +21 -0
  620. package/src/ssr/admission.ts +380 -14
  621. package/src/ssr/compose.ts +144 -0
  622. package/src/ssr/errors.ts +48 -0
  623. package/src/ssr/graph.ts +777 -0
  624. package/src/ssr/history.ts +436 -0
  625. package/src/ssr/hiz.ts +124 -0
  626. package/src/ssr/inspection.ts +124 -0
  627. package/src/ssr/resources.ts +202 -0
  628. package/src/ssr/temporal.ts +164 -0
  629. package/src/systems/skin-palette-allocator.ts +495 -148
  630. package/src/systems/skin-palette-types.ts +17 -0
  631. package/src/systems/transparent-dispatch.ts +90 -0
  632. package/src/targets/material-source.ts +34 -0
  633. package/src/temporal/coverage.ts +1 -1
  634. package/src/temporal/frame-coordinator.ts +23 -2
  635. package/src/temporal/gpu.ts +74 -12
  636. package/src/temporal/history.ts +3 -1
  637. package/src/temporal/inspection.ts +2 -1
  638. package/src/temporal/standard-scene-data.ts +3 -1
  639. package/src/temporal/temporal-view.ts +3 -0
  640. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +204 -139
  641. package/src/typed-render-graph-primitives.ts +266 -74
  642. package/src/typed-shadow-passes.ts +122 -12
  643. package/src/volume/temporal.ts +10 -0
  644. package/dist/chunk-ADHHVYLW.mjs.map +0 -1
  645. package/dist/chunk-FJ6P52EE.mjs.map +0 -1
  646. package/dist/chunk-GE3SDD72.mjs.map +0 -1
  647. package/dist/chunk-GF523LHF.mjs.map +0 -1
  648. package/dist/chunk-HKXTW355.mjs.map +0 -1
  649. package/dist/chunk-JDWARUOI.mjs.map +0 -1
  650. package/dist/chunk-KM2NOX2I.mjs.map +0 -1
  651. package/dist/chunk-TMIASV2N.mjs.map +0 -1
  652. package/dist/chunk-XDP6XE5V.mjs.map +0 -1
  653. package/dist/chunk-ZZ4YQ474.mjs.map +0 -1
  654. package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
  655. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
package/src/internal.ts CHANGED
@@ -49,4 +49,26 @@ export {
49
49
  type OcclusionRuntimeTestHooks,
50
50
  setOcclusionRuntimeTestHooks,
51
51
  } from './scene/visibility/occlusion-runtime';
52
+ export {
53
+ createSsrHistoryOwner,
54
+ SSR_HISTORY_FORMAT,
55
+ type SsrHistoryCandidate,
56
+ type SsrHistoryError,
57
+ type SsrHistoryFailureStage,
58
+ type SsrHistoryInspection,
59
+ SsrHistoryOwner,
60
+ type SsrHistoryResetReason,
61
+ type SsrHistoryResources,
62
+ type SsrHistorySlot,
63
+ type SsrHistoryState,
64
+ } from './ssr/history';
65
+ export { estimateSsrSpatialMemory } from './ssr/resources';
66
+ export {
67
+ createSsrTemporalConsumer,
68
+ type SsrTemporalCandidate,
69
+ SsrTemporalConsumer,
70
+ type SsrTemporalError,
71
+ type SsrTemporalExecutionError,
72
+ type SsrTemporalInspection,
73
+ } from './ssr/temporal';
52
74
  export { TemporalFrameCoordinator } from './temporal/frame-coordinator';
package/src/lifecycle.ts CHANGED
@@ -3,6 +3,7 @@ import type { RenderGraphError } from '@forgeax/engine-render-graph';
3
3
  import type { RhiError } from '@forgeax/engine-rhi';
4
4
  import type { SkinError } from '@forgeax/engine-skinning';
5
5
  import type { ImageError } from '@forgeax/engine-types';
6
+ import type { GpuDrivenPreparationError } from './errors/gpu-driven';
6
7
  import type { RenderError } from './errors/render';
7
8
  import type { PostProcessError } from './post-process-errors';
8
9
 
@@ -18,6 +19,7 @@ export type RendererError =
18
19
  | RenderGraphError
19
20
  | ImageError
20
21
  | RenderError
22
+ | GpuDrivenPreparationError
21
23
  | AssetRuntimeError
22
24
  | SkinError
23
25
  | PostProcessError;
@@ -0,0 +1,145 @@
1
+ import {
2
+ type MaterialShaderArtifactReceipt,
3
+ STANDARD_PIPELINE_PARAM_SCHEMA,
4
+ } from '@forgeax/engine-shader';
5
+ import { derive, type UboFieldLayout } from '@forgeax/engine-types';
6
+ import { GPU_SCENE_LAYOUTS } from './gpu-scene-schema';
7
+ import type { MaterialSnapshot } from './render-system-extract';
8
+
9
+ const ROW = GPU_SCENE_LAYOUTS.material;
10
+ const STANDARD_PIPELINE_DERIVED = derive(STANDARD_PIPELINE_PARAM_SCHEMA);
11
+ const STANDARD_PARAM_ENTRIES = new Map(
12
+ STANDARD_PIPELINE_PARAM_SCHEMA.map((entry) => [entry.name, entry]),
13
+ );
14
+
15
+ function isNumericValue(value: unknown): value is number | readonly number[] {
16
+ return typeof value === 'number' || Array.isArray(value);
17
+ }
18
+
19
+ function numericFallback(
20
+ name: string,
21
+ material: MaterialSnapshot,
22
+ ): number | readonly number[] | undefined {
23
+ switch (name) {
24
+ case 'baseColor':
25
+ return [
26
+ material.baseColor[0] ?? 0,
27
+ material.baseColor[1] ?? 0,
28
+ material.baseColor[2] ?? 0,
29
+ 1,
30
+ ];
31
+ case 'metallic':
32
+ return material.metallic;
33
+ case 'roughness':
34
+ return material.roughness;
35
+ case 'emissive':
36
+ return material.emissive ?? [0, 0, 0];
37
+ case 'emissiveIntensity':
38
+ return material.emissiveIntensity ?? 0;
39
+ case 'occlusionStrength':
40
+ return material.occlusionStrength ?? 1;
41
+ case 'normalScale':
42
+ return material.normalScale ?? 1;
43
+ case 'specularColor':
44
+ return material.specularColor ?? [1, 1, 1];
45
+ default: {
46
+ const defaultValue = STANDARD_PARAM_ENTRIES.get(name)?.default;
47
+ return isNumericValue(defaultValue) ? defaultValue : undefined;
48
+ }
49
+ }
50
+ }
51
+
52
+ function numericValue(
53
+ name: string,
54
+ material: MaterialSnapshot,
55
+ ): number | readonly number[] | undefined {
56
+ const snapshotValue = material.paramSnapshot?.[name];
57
+ return isNumericValue(snapshotValue) ? snapshotValue : numericFallback(name, material);
58
+ }
59
+
60
+ function writeScalar(view: DataView, member: UboFieldLayout, value: number): void {
61
+ switch (member.type) {
62
+ case 'f32':
63
+ case 'vec2':
64
+ case 'vec3':
65
+ case 'vec4':
66
+ case 'color':
67
+ view.setFloat32(member.offset, value, true);
68
+ return;
69
+ case 'i32':
70
+ view.setInt32(member.offset, value, true);
71
+ return;
72
+ case 'u32':
73
+ view.setUint32(member.offset, value, true);
74
+ return;
75
+ }
76
+ }
77
+
78
+ function writeNumeric(
79
+ view: DataView,
80
+ member: UboFieldLayout,
81
+ value: number | readonly number[] | undefined,
82
+ ): void {
83
+ if (member.type === 'f32' || member.type === 'i32' || member.type === 'u32') {
84
+ writeScalar(view, member, typeof value === 'number' ? value : (value?.[0] ?? 0));
85
+ return;
86
+ }
87
+ const values = Array.isArray(value) ? value : [];
88
+ const count = member.type === 'vec2' ? 2 : member.type === 'vec3' ? 3 : 4;
89
+ for (let index = 0; index < count; index += 1) {
90
+ writeScalar(
91
+ view,
92
+ { ...member, offset: member.offset + index * 4, type: 'f32' },
93
+ values[index] ?? 0,
94
+ );
95
+ }
96
+ }
97
+
98
+ function writeVec4(view: DataView, offset: number, values: readonly number[]): void {
99
+ for (let index = 0; index < 4; index += 1) {
100
+ view.setFloat32(offset + index * 4, values[index] ?? 0, true);
101
+ }
102
+ }
103
+
104
+ function validateReceipt(receipt: MaterialShaderArtifactReceipt): void {
105
+ const expectedFields = ROW.fields.map((field) => field.name);
106
+ if (
107
+ receipt.materialRow.byteLength !== ROW.stride ||
108
+ receipt.materialRow.fields.length !== expectedFields.length ||
109
+ receipt.materialRow.fields.some((field, index) => field !== expectedFields[index])
110
+ ) {
111
+ throw new RangeError(
112
+ `Standard PBR material row receipt must match the ${ROW.stride}-byte canonical ABI`,
113
+ );
114
+ }
115
+ }
116
+
117
+ /** Pack the producer receipt's numeric Standard PBR row into the GPU Scene table. */
118
+ export function packStandardPbrMaterialRow(
119
+ receipt: MaterialShaderArtifactReceipt,
120
+ material: MaterialSnapshot,
121
+ ): Uint8Array {
122
+ validateReceipt(receipt);
123
+ const payload = new Uint8Array(ROW.stride);
124
+ const view = new DataView(payload.buffer);
125
+ for (const member of STANDARD_PIPELINE_DERIVED.numericMembers) {
126
+ writeNumeric(view, member, numericValue(member.name, material));
127
+ }
128
+ for (const record of STANDARD_PIPELINE_DERIVED.coordinateRecords) {
129
+ const coordinates = material.textureCoordinates?.get(record.parameter);
130
+ const transform = coordinates?.transform;
131
+ writeVec4(view, record.offset, [
132
+ transform?.offset?.[0] ?? 0,
133
+ transform?.offset?.[1] ?? 0,
134
+ transform?.scale?.[0] ?? 1,
135
+ transform?.scale?.[1] ?? 1,
136
+ ]);
137
+ writeVec4(view, record.offset + 16, [
138
+ coordinates?.set ?? 0,
139
+ transform?.rotation ?? 0,
140
+ coordinates?.physicalUvScale?.[0] ?? 1,
141
+ coordinates?.physicalUvScale?.[1] ?? 1,
142
+ ]);
143
+ }
144
+ return payload;
145
+ }
package/src/materials.ts CHANGED
@@ -21,6 +21,36 @@ export type MaterialTransmissionValidationReason =
21
21
  | 'blend'
22
22
  | 'depth-write';
23
23
 
24
+ export type MaterialAuthoringValidationReason = 'non-finite' | 'range';
25
+
26
+ /** Structured authoring failure for a built-in Standard material parameter. */
27
+ export class MaterialAuthoringContractError extends Error {
28
+ readonly code = 'material-authoring-contract-invalid' as const;
29
+ readonly expected =
30
+ 'Standard material authoring values are finite and within their declared ranges';
31
+ readonly hint =
32
+ 'repair the named Standard material parameter alphaCutoff before publishing the material';
33
+ readonly detail: {
34
+ readonly code: 'material-authoring-contract-invalid';
35
+ readonly material: 'Standard';
36
+ readonly parameter: 'alphaCutoff';
37
+ readonly reason: MaterialAuthoringValidationReason;
38
+ readonly actual?: unknown;
39
+ };
40
+
41
+ constructor(reason: MaterialAuthoringValidationReason, actual?: unknown) {
42
+ super(`Materials.standard: alphaCutoff violates the authoring contract (${reason})`);
43
+ this.name = 'MaterialAuthoringContractError';
44
+ this.detail = {
45
+ code: 'material-authoring-contract-invalid',
46
+ material: 'Standard',
47
+ parameter: 'alphaCutoff',
48
+ reason,
49
+ ...(actual === undefined ? {} : { actual }),
50
+ };
51
+ }
52
+ }
53
+
24
54
  /** Structured authoring failure for the Standard transmission contract. */
25
55
  export class MaterialTransmissionContractError extends Error {
26
56
  readonly code = 'material-transmission-contract-invalid' as const;
@@ -195,11 +225,6 @@ function standardParameters(
195
225
  'occlusionStrength',
196
226
  'alphaCutoff',
197
227
  'normalScale',
198
- 'baseColorTexture',
199
- 'metallicRoughnessTexture',
200
- 'normalTexture',
201
- 'emissiveTexture',
202
- 'occlusionTexture',
203
228
  'specular',
204
229
  'specularColor',
205
230
  // IOR is part of the always-present dielectric F0 contract. The
@@ -224,12 +249,20 @@ function standardParameters(
224
249
  'thickness',
225
250
  'attenuationColor',
226
251
  'attenuationDistance',
227
- 'transmissionTexture',
228
- 'thicknessTexture',
229
252
  ]) {
230
253
  baseNames.add(name);
231
254
  }
232
255
  }
256
+ // A texture declaration selects its compiled sampling path. Loading state
257
+ // does not: an authored but not-yet-resident slot still needs its fallback.
258
+ for (const parameter of DEFAULT_STANDARD_PBR_PARAM_SCHEMA) {
259
+ if (
260
+ parameter.type === 'texture2d' &&
261
+ opts[parameter.name as keyof StandardOpts] !== undefined
262
+ ) {
263
+ baseNames.add(parameter.name);
264
+ }
265
+ }
233
266
  // All Standard fields come from one root schema. Physical fields are
234
267
  // projected by the authored option membership above; appending a second
235
268
  // physical schema would create a parallel ABI authority.
@@ -487,8 +520,11 @@ function standardDefault(opts: DefaultStandardOptions): MaterialAsset {
487
520
  `Materials.standard: occlusionStrength must be in [0, 1], got ${occlusionStrength}`,
488
521
  );
489
522
  }
523
+ if (opts.alphaCutoff !== undefined && !Number.isFinite(opts.alphaCutoff)) {
524
+ throw new MaterialAuthoringContractError('non-finite', opts.alphaCutoff);
525
+ }
490
526
  if (opts.alphaCutoff !== undefined && (opts.alphaCutoff < 0 || opts.alphaCutoff > 1)) {
491
- throw new Error(`Materials.standard: alphaCutoff must be in [0, 1], got ${opts.alphaCutoff}`);
527
+ throw new MaterialAuthoringContractError('range', opts.alphaCutoff);
492
528
  }
493
529
  validateChannel('metallicChannel', opts.metallicChannel);
494
530
  validateChannel('roughnessChannel', opts.roughnessChannel);
@@ -34,6 +34,7 @@ import type {
34
34
  } from '@forgeax/engine-rhi';
35
35
  import {
36
36
  type ShaderCatalog,
37
+ STANDARD_PHYSICAL_TEXTURE_FIELDS,
37
38
  STANDARD_PIPELINE_PARAM_SCHEMA,
38
39
  standardPhysicalTextureFields,
39
40
  } from '@forgeax/engine-shader';
@@ -154,7 +155,7 @@ export function buildPbrMaterialUserRegionEntries(
154
155
  // Project the engine-owned entry shape into the DOM WebGPU descriptor. Omit
155
156
  // absent optional members so exactOptionalPropertyTypes remains true at the
156
157
  // boundary instead of leaking an `undefined` property into the descriptor.
157
- const entries = derived.bglEntries.map(
158
+ let entries = derived.bglEntries.map(
158
159
  (entry): GPUBindGroupLayoutEntry => ({
159
160
  binding: entry.binding,
160
161
  visibility: entry.visibility,
@@ -164,9 +165,11 @@ export function buildPbrMaterialUserRegionEntries(
164
165
  ...(entry.storageTexture === undefined ? {} : { storageTexture: entry.storageTexture }),
165
166
  }),
166
167
  );
167
- // Patch binding 0 (the material UBO) to the dynamic-offset, vertex-visible
168
- // material-UBO contract. derive() emits binding 0 as the first numeric run's
169
- // merged UBO; an empty schema has no binding-0 UBO and needs no patch.
168
+ // The record path always owns one dynamic material-UBO slot, even when an
169
+ // authored shader declares no numeric parameters (an empty paramSchema).
170
+ // Reserve that slot here so the IBL/transmission injection starts at the
171
+ // same binding used by `buildPerSubmeshMaterialBg`; otherwise binding 0 in
172
+ // the layout is a cube texture while the record path submits a UBO.
170
173
  const ubo = entries[0];
171
174
  if (ubo !== undefined && ubo.binding === 0 && ubo.buffer?.type === 'uniform') {
172
175
  entries[0] = {
@@ -174,6 +177,15 @@ export function buildPbrMaterialUserRegionEntries(
174
177
  visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,
175
178
  buffer: { type: 'uniform', hasDynamicOffset: true },
176
179
  };
180
+ } else {
181
+ entries = [
182
+ {
183
+ binding: 0,
184
+ visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,
185
+ buffer: { type: 'uniform', hasDynamicOffset: true },
186
+ },
187
+ ...entries.map((entry) => ({ ...entry, binding: entry.binding + 1 })),
188
+ ];
177
189
  }
178
190
  return entries;
179
191
  }
@@ -351,16 +363,22 @@ export function physicalTextureFields(paramSchema: readonly ParamSchemaEntry[]):
351
363
  }
352
364
 
353
365
  export function appendTextureInjection(
354
- bgl: readonly GPUBindGroupLayoutEntry[],
366
+ _bgl: readonly GPUBindGroupLayoutEntry[],
355
367
  fields: readonly string[],
356
368
  ): GPUBindGroupLayoutEntry[] {
357
- const start = bgl.length;
358
369
  const fieldSet = new Set(fields);
370
+ // Physical resources use the Standard root's fixed slots (26 + canonical
371
+ // index * 2). Do not compact an authored subset: the shader template and
372
+ // scene-index receipt share these canonical bindings, while gaps simply
373
+ // represent physical axes omitted by the selected root contract.
359
374
  return standardPhysicalTextureFields(
360
- fields.map((name) => ({ name, type: 'texture2d' as const })),
361
- ).flatMap((field, index) => {
375
+ STANDARD_PIPELINE_PARAM_SCHEMA.concat(
376
+ fields.map((name) => ({ name, type: 'texture2d' as const })),
377
+ ),
378
+ ).flatMap((field) => {
362
379
  if (!fieldSet.has(field)) return [];
363
- const binding = start + index * 2;
380
+ const canonicalIndex = STANDARD_PHYSICAL_TEXTURE_FIELDS.indexOf(field);
381
+ const binding = 26 + canonicalIndex * 2;
364
382
  return [
365
383
  {
366
384
  binding,
@@ -441,7 +459,7 @@ export interface PbrCaps {
441
459
  * fragment-only). feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1.
442
460
  * binding 6 = point shadow params UBO (`array<vec4<f32>, 4>`, 64 B;
443
461
  * fragment-only). One lane per shadow-casting point light slot
444
- * (shadowAtlasLayer in [0, 4)) carrying `(near, far, 1/(far-near), 0)`.
462
+ * (shadowAtlasLayer in [0, 4)) carrying `(near, far, depthBias, normalBias)`.
445
463
  * binding 7 = shadowCasterCascade UBO (16 B; vertex + fragment). Per-pass
446
464
  * cascade-index uniform consumed exclusively by `shadow_caster.wgsl` to
447
465
  * pick `view.lightViewProj_X` for the cascade currently being rasterized
@@ -506,7 +524,7 @@ export function buildPbrViewBglEntries(caps: PbrCaps): GPUBindGroupLayoutEntry[]
506
524
  // feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1: point shadow
507
525
  // params UBO. Carries `array<vec4<f32>, 4>` = 64 B with one lane per
508
526
  // shadow-casting point light slot (shadowAtlasLayer in [0, 4)). Each
509
- // lane stores `(near, far, 1/(far-near), 0)` so the fragment-shader
527
+ // lane stores `(near, far, depthBias, normalBias)` so the fragment-shader
510
528
  // depth-ref reconstruction (lighting-punctual.wgsl evalPointShadowed)
511
529
  // can avoid sampling DirectLightSlot for the URP path. The shared
512
530
  // DirectLightSlot metadata remains the identity owner, so binding 6 is
@@ -648,7 +666,10 @@ export function buildPbrPipelineLayouts(
648
666
  // The transmission start binding is computed from the post-Skylight BGL
649
667
  // length (= 22 for the canonical Standard schema) by appendInjection.
650
668
  const materialBglRes = device.createBindGroupLayout(
651
- buildBindGroupLayoutDescriptor(BGL_ONLY_SPEC_STUB, { kind: 'pbr-material-merged' }),
669
+ buildBindGroupLayoutDescriptor(BGL_ONLY_SPEC_STUB, {
670
+ kind: 'pbr-material-merged',
671
+ caps,
672
+ }),
652
673
  );
653
674
  if (!materialBglRes.ok) throw materialBglRes.error;
654
675
 
@@ -751,10 +772,24 @@ export function isStandardPbrSkinMaterialShader(shaderId: string | undefined): b
751
772
  );
752
773
  }
753
774
 
754
- export function shadowCasterVariantSet(storageBuffer: boolean, skinned: boolean): string {
775
+ export function shadowCasterVariantSet(
776
+ storageBuffer: boolean,
777
+ skinned: boolean,
778
+ gpuDrivenSceneIndex = false,
779
+ alphaMask = false,
780
+ ): string {
755
781
  const skinningDisabled = !skinned;
756
- if (storageBuffer && skinningDisabled) return '';
757
- return `SKINNING_DISABLED=${String(skinningDisabled)}+STORAGE_BUFFER_AVAILABLE=${String(storageBuffer)}`;
782
+ const defines: Record<string, boolean> = {
783
+ ALPHA_MASK: alphaMask,
784
+ GPU_DRIVEN_SCENE_INDEX_AVAILABLE: gpuDrivenSceneIndex,
785
+ GPU_DRIVEN_SCENE_INDEX_EXPLICIT: false,
786
+ SKINNING_DISABLED: skinningDisabled,
787
+ STORAGE_BUFFER_AVAILABLE: storageBuffer,
788
+ };
789
+ return Object.entries(defines)
790
+ .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
791
+ .map(([name, value]) => `${name}=${String(value)}`)
792
+ .join('+');
758
793
  }
759
794
 
760
795
  export function isSkinnedShadowCasterVariant(
@@ -894,6 +929,65 @@ export function buildPbrSkinLayouts(
894
929
  };
895
930
  }
896
931
 
932
+ /**
933
+ * Build the dedicated slot-3 layout used by scene-index GPU-driven draws.
934
+ *
935
+ * Direct material draws deliberately keep `pbr-instances-bgl` at binding(0),
936
+ * and ProbeBlend deliberately owns binding(1). The scene-index stream is
937
+ * therefore a separate BGL at binding(2), rather than an optional entry added
938
+ * to the direct layout. This keeps every bind group complete for its shader
939
+ * and prevents a direct draw from having to bind a dummy visible stream.
940
+ */
941
+ export function buildGpuDrivenPbrInstancesBindGroupLayout(
942
+ device: PbrPipelineDevice,
943
+ caps: PbrCaps,
944
+ ): BindGroupLayout {
945
+ if (!caps.storageBuffer) {
946
+ throw new Error('GPU-driven PBR instances layout requires storage-buffer capability');
947
+ }
948
+ const result = device.createBindGroupLayout(
949
+ buildBindGroupLayoutDescriptor(BGL_ONLY_SPEC_STUB, {
950
+ kind: 'pbr-gpu-driven-instances',
951
+ caps,
952
+ }),
953
+ );
954
+ if (!result.ok) throw result.error;
955
+ return result.value;
956
+ }
957
+
958
+ /** Build the four-slot rigid scene-index pipeline layout. */
959
+ export function buildGpuDrivenPbrPipelineLayout(
960
+ device: PbrPipelineDevice,
961
+ pbr: PbrPipelineLayoutBundle,
962
+ gpuDrivenInstancesBgl: BindGroupLayout,
963
+ ): PipelineLayout {
964
+ const result = device.createPipelineLayout({
965
+ label: 'pbr-gpu-driven-pl',
966
+ bindGroupLayouts: [pbr.viewBgl, pbr.materialBgl, pbr.meshArrayBgl, gpuDrivenInstancesBgl],
967
+ });
968
+ if (!result.ok) throw result.error;
969
+ return result.value;
970
+ }
971
+
972
+ /** Build the four-slot skinned scene-index pipeline layout. */
973
+ export function buildGpuDrivenPbrSkinPipelineLayout(
974
+ device: PbrPipelineDevice,
975
+ pbrSkin: PbrPipelineLayoutBundle,
976
+ gpuDrivenInstancesBgl: BindGroupLayout,
977
+ ): PipelineLayout {
978
+ const result = device.createPipelineLayout({
979
+ label: 'pbr-skin-gpu-driven-pl',
980
+ bindGroupLayouts: [
981
+ pbrSkin.viewBgl,
982
+ pbrSkin.materialBgl,
983
+ pbrSkin.meshArrayBgl,
984
+ gpuDrivenInstancesBgl,
985
+ ],
986
+ });
987
+ if (!result.ok) throw result.error;
988
+ return result.value;
989
+ }
990
+
897
991
  /** Project the canonical group(2) resources for a PBR skin draw. */
898
992
  export function createPbrSkinMeshBindGroupEntries(
899
993
  meshBuffer: Buffer,
@@ -1064,7 +1158,9 @@ export const SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET = '';
1064
1158
  * (directional 3/4, point 5/6, cascade 7, spot atlas 8; the former
1065
1159
  * spot lightViewProj matrices moved into the View UBO)
1066
1160
  * - `'pbr-mesh-array'` — 1 entry: per-entity mesh SSBO (dynamic-offset)
1067
- * - `'pbr-instances'` — 1 entry: per-instance SSBO (no dynamic-offset)
1161
+ * - `'pbr-instances'` — 2 entries: per-instance SSBO plus the compact
1162
+ * visible-item index stream (the second entry is used only by the
1163
+ * scene-index vertex entry and shares the frame's instance bind group)
1068
1164
  * - `'pbr-skin-mesh-array'` — 3 entries: meshes + current/previous palette
1069
1165
  * 3. Attachment-driven (fullscreen post-process):
1070
1166
  * - `'fullscreen-post'` — 2 entries: input texture + sampler. The texture
@@ -1084,6 +1180,7 @@ export type BglKind =
1084
1180
  | 'pbr-material-merged'
1085
1181
  | 'pbr-mesh-array'
1086
1182
  | 'pbr-instances'
1183
+ | 'pbr-gpu-driven-instances'
1087
1184
  | 'pbr-skin-mesh-array'
1088
1185
  | 'unlit-material'
1089
1186
  | 'hdrp-7-slot'
@@ -1318,6 +1415,41 @@ export function buildBindGroupLayoutDescriptor(
1318
1415
  ),
1319
1416
  };
1320
1417
  }
1418
+ case 'pbr-gpu-driven-instances': {
1419
+ const caps = options.caps ?? { storageBuffer: true };
1420
+ const meshBufType: GPUBufferBindingType = caps.storageBuffer
1421
+ ? 'read-only-storage'
1422
+ : 'uniform';
1423
+ // GPU-driven scene-index draws use a physically distinct slot-3 layout.
1424
+ // The ordinary instances BGL intentionally stays one-entry for direct
1425
+ // draws, while ProbeBlend owns binding(1). Keep the compact visible
1426
+ // `(meshRow, materialRow)` stream at binding(2) so a future probe-enabled
1427
+ // GPU variant can coexist without colliding with the probe record.
1428
+ return {
1429
+ label: 'pbr-gpu-driven-instances-bgl',
1430
+ entries: [
1431
+ {
1432
+ binding: 0,
1433
+ visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,
1434
+ buffer: { type: meshBufType, hasDynamicOffset: false },
1435
+ },
1436
+ {
1437
+ // ShadowCaster's scene-index entry still reads the visible row
1438
+ // through binding(1). Keep this alias in the dedicated layout so
1439
+ // the shared visible bind group can serve both the Standard PBR
1440
+ // (binding(2)) and depth-only shadow (binding(1)) consumers.
1441
+ binding: 1,
1442
+ visibility: GPU_SHADER_STAGE_VERTEX,
1443
+ buffer: { type: meshBufType, hasDynamicOffset: false },
1444
+ },
1445
+ {
1446
+ binding: 2,
1447
+ visibility: GPU_SHADER_STAGE_VERTEX,
1448
+ buffer: { type: meshBufType, hasDynamicOffset: false },
1449
+ },
1450
+ ],
1451
+ };
1452
+ }
1321
1453
  case 'pbr-skin-mesh-array': {
1322
1454
  const caps = options.caps ?? { storageBuffer: true };
1323
1455
  const meshBufType: GPUBufferBindingType = caps.storageBuffer
@@ -1328,7 +1460,7 @@ export function buildBindGroupLayoutDescriptor(
1328
1460
  entries: [
1329
1461
  {
1330
1462
  binding: 0,
1331
- visibility: GPU_SHADER_STAGE_VERTEX,
1463
+ visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,
1332
1464
  buffer: { type: meshBufType, hasDynamicOffset: true },
1333
1465
  },
1334
1466
  {
@@ -1372,6 +1504,16 @@ export function buildBindGroupLayoutDescriptor(
1372
1504
  ...afterTransmission,
1373
1505
  ...appendTextureInjection(afterTransmission, physicalFields),
1374
1506
  ];
1507
+ // Scene-index Standard variants consume one producer-owned material row
1508
+ // after the complete fixed physical range. Keeping it at binding 46
1509
+ // prevents any authored physical subset from aliasing the row.
1510
+ if (options.caps?.storageBuffer ?? true) {
1511
+ merged.push({
1512
+ binding: 46,
1513
+ visibility: GPU_SHADER_STAGE_VERTEX | GPU_SHADER_STAGE_FRAGMENT,
1514
+ buffer: { type: 'read-only-storage', hasDynamicOffset: false },
1515
+ });
1516
+ }
1375
1517
  return {
1376
1518
  label: 'pbr-material-skylight-bgl',
1377
1519
  entries: merged,
@@ -4,6 +4,7 @@ import type {
4
4
  RenderGraphError,
5
5
  } from '@forgeax/engine-render-graph';
6
6
  import { err, ok, type Result } from '@forgeax/engine-types';
7
+ import { addAtmosphereBackground } from '../environment/background';
7
8
  import { SceneDataUnavailableError } from '../errors/render';
8
9
  import {
9
10
  GPU_TEXTURE_USAGE_COPY_SRC,
@@ -170,7 +171,14 @@ function buildUrp(
170
171
  if (!initialized.ok) return initialized;
171
172
  }
172
173
 
173
- const shadows = addTypedShadowPasses(graph, topology);
174
+ const featureShadows = context.contributeShadowFeatures?.();
175
+ if (featureShadows !== undefined && !featureShadows.ok) return featureShadows;
176
+ const shadows = addTypedShadowPasses(
177
+ graph,
178
+ topology,
179
+ context.projectGpuDrivenShadow,
180
+ featureShadows?.value,
181
+ );
174
182
  if (!shadows.ok) return shadows;
175
183
 
176
184
  const clusterBuffers = clearOnly ? ok(null) : importStandardClusterBuffers(graph, lighting);
@@ -183,12 +191,22 @@ function buildUrp(
183
191
  const clusterReads =
184
192
  clusterBuffers.value === null ? [] : standardClusterReadAccesses(clusterBuffers.value);
185
193
 
186
- const skybox = addTypedSkyboxPass(graph, scene.value);
194
+ const skybox =
195
+ topology.atmosphere === true
196
+ ? addAtmosphereBackground(graph, scene.value)
197
+ : addTypedSkyboxPass(graph, scene.value);
187
198
  if (!skybox.ok) return skybox;
188
- const gpuDriven = context.projectGpuDriven({
189
- format: scene.value.format,
190
- sampleCount: scene.value.sampleCount,
191
- });
199
+ // The GPU-driven Standard PBR raster adapter owns one color target. A
200
+ // reflection fallback adds a second attachment to this pass, so keep that
201
+ // topology on the ordinary producer rather than binding a one-target
202
+ // pipeline into a multi-target render pass.
203
+ const gpuDriven =
204
+ reflectionFallback.value === undefined
205
+ ? context.projectGpuDriven({
206
+ format: scene.value.format,
207
+ sampleCount: scene.value.sampleCount,
208
+ })
209
+ : ok(undefined);
192
210
  if (!gpuDriven.ok) return gpuDriven;
193
211
  const transmissionDemand = transmissionDemandForTopology(topology);
194
212
  const transmissionActive = resolveTransmissionBackdropTopology({
@@ -330,24 +348,34 @@ function buildUrp(
330
348
  if (!volume.ok) return volume;
331
349
  }
332
350
 
333
- const features = context.contributeFeatures([
334
- {
335
- name: 'linear-hdr',
336
- kind: 'scene-color',
337
- texture: scene.value.texture,
338
- view: scene.value.view,
339
- ...(msaa ? { resolveTarget: sceneResolved.value.view } : {}),
340
- format: scene.value.format,
341
- sampleCount: scene.value.sampleCount,
342
- },
343
- {
344
- kind: 'scene-depth',
345
- texture: depth.value.texture,
346
- view: depth.value.view,
347
- format: depth.value.format,
348
- sampleCount: depth.value.sampleCount,
349
- },
350
- ]);
351
+ const features = context.contributeFeatures(
352
+ [
353
+ {
354
+ name: 'linear-hdr',
355
+ kind: 'scene-color',
356
+ texture: scene.value.texture,
357
+ view: scene.value.view,
358
+ ...(msaa ? { resolveTarget: sceneResolved.value.view } : {}),
359
+ format: scene.value.format,
360
+ sampleCount: scene.value.sampleCount,
361
+ },
362
+ {
363
+ kind: 'scene-depth',
364
+ texture: depth.value.texture,
365
+ view: depth.value.view,
366
+ format: depth.value.format,
367
+ sampleCount: depth.value.sampleCount,
368
+ },
369
+ ],
370
+ [],
371
+ {},
372
+ [
373
+ ...clusterReads,
374
+ ...[shadows.value.directional, shadows.value.spot, shadows.value.point].flatMap((target) =>
375
+ target === undefined ? [] : [{ resource: target.view, usage: 'sampled-read' as const }],
376
+ ),
377
+ ],
378
+ );
351
379
  if (!features.ok) return features;
352
380
 
353
381
  if (hdr || linearLdr || rawOnly) {