@forgeax/engine-render 0.1.28 → 0.1.30

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 (768) hide show
  1. package/README.md +856 -126
  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/device-feature-admission.d.ts +4 -3
  5. package/dist/assembly/device-feature-admission.d.ts.map +1 -1
  6. package/dist/assembly/dynamic-geometry-host.d.ts +27 -0
  7. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  8. package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
  9. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
  10. package/dist/assembly/factory.d.ts +3 -1
  11. package/dist/assembly/factory.d.ts.map +1 -1
  12. package/dist/assembly/gpu-driven-owner.d.ts +10 -0
  13. package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
  14. package/dist/assembly/host-contract.d.ts +14 -0
  15. package/dist/assembly/host-contract.d.ts.map +1 -1
  16. package/dist/assembly/material/assembly.d.ts +31 -1
  17. package/dist/assembly/material/assembly.d.ts.map +1 -1
  18. package/dist/assembly/material/pipeline-helpers.d.ts +24 -0
  19. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -0
  20. package/dist/assembly/material-shader-policy.d.ts +3 -1
  21. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  22. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  23. package/dist/assembly/recovery/failure-location.d.ts +12 -0
  24. package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
  25. package/dist/assembly/recovery/recovery-attempt.d.ts +1 -6
  26. package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -1
  27. package/dist/assembly/recovery/renderer-recover.d.ts +7 -4
  28. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  29. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  30. package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
  31. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
  32. package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
  33. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  34. package/dist/assembly/renderer-helpers.d.ts +3 -0
  35. package/dist/assembly/renderer-helpers.d.ts.map +1 -1
  36. package/dist/assembly/renderer-inspection.d.ts +4 -0
  37. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  38. package/dist/assembly/shader-prewarm-policy.d.ts +7 -1
  39. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
  40. package/dist/assembly/skin-palette-owner.d.ts +8 -0
  41. package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
  42. package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
  43. package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
  44. package/dist/assembly/webgpu-device-loss.d.ts +15 -0
  45. package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
  47. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
  48. package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
  49. package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
  50. package/dist/assembly/webgpu-ready.d.ts +7 -3
  51. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  52. package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
  53. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
  54. package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
  55. package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
  56. package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
  57. package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
  58. package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
  59. package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
  60. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
  61. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
  62. package/dist/assembly/webgpu-renderer.d.ts +7 -141
  63. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  64. package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
  65. package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
  66. package/dist/authoring.mjs +2 -2
  67. package/dist/capture/scene-projection.d.ts +41 -0
  68. package/dist/capture/scene-projection.d.ts.map +1 -0
  69. package/dist/{chunk-J52NMQKR.mjs → chunk-7MQ3XBSP.mjs} +1098 -844
  70. package/dist/chunk-7MQ3XBSP.mjs.map +1 -0
  71. package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
  72. package/dist/chunk-BLXGONR2.mjs.map +1 -0
  73. package/dist/{chunk-VSL23LZE.mjs → chunk-C3DDSXYK.mjs} +1188 -463
  74. package/dist/chunk-C3DDSXYK.mjs.map +1 -0
  75. package/dist/{chunk-IQMKJLNU.mjs → chunk-FUUO4UND.mjs} +443 -30
  76. package/dist/chunk-FUUO4UND.mjs.map +1 -0
  77. package/dist/{chunk-J6KACNOH.mjs → chunk-JRBDO2KB.mjs} +617 -7
  78. package/dist/chunk-JRBDO2KB.mjs.map +1 -0
  79. package/dist/{chunk-GE3SDD72.mjs → chunk-MDQJPY3T.mjs} +20 -40
  80. package/dist/chunk-MDQJPY3T.mjs.map +1 -0
  81. package/dist/{chunk-MYJ5RPJO.mjs → chunk-NO4WZCAH.mjs} +3 -3
  82. package/dist/chunk-NO4WZCAH.mjs.map +1 -0
  83. package/dist/{chunk-RBDBZ5R7.mjs → chunk-PA5DRJNI.mjs} +2 -2
  84. package/dist/chunk-PA5DRJNI.mjs.map +1 -0
  85. package/dist/{chunk-MBU4ZVE7.mjs → chunk-PSEQ6QPH.mjs} +4655 -892
  86. package/dist/chunk-PSEQ6QPH.mjs.map +1 -0
  87. package/dist/{chunk-JAASCMXA.mjs → chunk-S5UE2T5P.mjs} +289 -41
  88. package/dist/chunk-S5UE2T5P.mjs.map +1 -0
  89. package/dist/components/camera.d.ts +62 -2
  90. package/dist/components/camera.d.ts.map +1 -1
  91. package/dist/components/directional-light.d.ts +2 -2
  92. package/dist/components/dynamic-resolution.d.ts +15 -0
  93. package/dist/components/dynamic-resolution.d.ts.map +1 -0
  94. package/dist/components/index.d.ts +2 -0
  95. package/dist/components/index.d.ts.map +1 -1
  96. package/dist/components/instances.d.ts +6 -20
  97. package/dist/components/instances.d.ts.map +1 -1
  98. package/dist/components/light-helpers.d.ts.map +1 -1
  99. package/dist/components/reflection-probe.d.ts +1 -0
  100. package/dist/components/reflection-probe.d.ts.map +1 -1
  101. package/dist/components/scene-instance.d.ts +2 -1
  102. package/dist/components/scene-instance.d.ts.map +1 -1
  103. package/dist/components/screen-space-reflection.d.ts +14 -0
  104. package/dist/components/screen-space-reflection.d.ts.map +1 -0
  105. package/dist/components/skylight.d.ts +4 -1
  106. package/dist/components/skylight.d.ts.map +1 -1
  107. package/dist/construct-renderer.mjs +14809 -7570
  108. package/dist/construct-renderer.mjs.map +1 -1
  109. package/dist/device/device-scope.d.ts +2 -0
  110. package/dist/device/device-scope.d.ts.map +1 -1
  111. package/dist/device/gpu-residency.d.ts +3 -14
  112. package/dist/device/gpu-residency.d.ts.map +1 -1
  113. package/dist/dynamic-geometry.d.ts.map +1 -1
  114. package/dist/environment/background.d.ts +7 -0
  115. package/dist/environment/background.d.ts.map +1 -0
  116. package/dist/environment/ibl.d.ts +11 -0
  117. package/dist/environment/ibl.d.ts.map +1 -0
  118. package/dist/environment/storage.d.ts +14 -0
  119. package/dist/environment/storage.d.ts.map +1 -0
  120. package/dist/errors/gpu-driven.d.ts +6 -3
  121. package/dist/errors/gpu-driven.d.ts.map +1 -1
  122. package/dist/errors/render.d.ts +41 -4
  123. package/dist/errors/render.d.ts.map +1 -1
  124. package/dist/extract/camera.d.ts.map +1 -1
  125. package/dist/extract/contracts.d.ts +7 -0
  126. package/dist/extract/contracts.d.ts.map +1 -1
  127. package/dist/extract/gpu-driven.d.ts +50 -3
  128. package/dist/extract/gpu-driven.d.ts.map +1 -1
  129. package/dist/features/host.d.ts +23 -1
  130. package/dist/features/host.d.ts.map +1 -1
  131. package/dist/features/noise-texture.d.ts +17 -0
  132. package/dist/features/noise-texture.d.ts.map +1 -0
  133. package/dist/features/plan.d.ts +83 -2
  134. package/dist/features/plan.d.ts.map +1 -1
  135. package/dist/features/prepared-gpu-work.d.ts +37 -4
  136. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  137. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  138. package/dist/features/prepared-graphics.d.ts +5 -0
  139. package/dist/features/prepared-graphics.d.ts.map +1 -1
  140. package/dist/features/render-graph-compute.d.ts +5 -3
  141. package/dist/features/render-graph-compute.d.ts.map +1 -1
  142. package/dist/features/render-graph-contribution.d.ts +11 -3
  143. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  144. package/dist/features/render-graph-raster.d.ts +19 -3
  145. package/dist/features/render-graph-raster.d.ts.map +1 -1
  146. package/dist/features/types.d.ts +11 -0
  147. package/dist/features/types.d.ts.map +1 -1
  148. package/dist/fullscreen-post-process-pass.d.ts +2 -0
  149. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  150. package/dist/gpu-driven/batch-topology.d.ts +34 -1
  151. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  152. package/dist/gpu-driven/material-artifacts.d.ts +24 -0
  153. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -0
  154. package/dist/gpu-driven/material-bindings.d.ts +7 -0
  155. package/dist/gpu-driven/material-bindings.d.ts.map +1 -0
  156. package/dist/gpu-driven/pbr-program.d.ts +10 -0
  157. package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
  158. package/dist/gpu-driven/prepared-draw.d.ts +2 -0
  159. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  160. package/dist/gpu-driven/production-raster.d.ts +169 -27
  161. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  162. package/dist/gpu-driven/shadow-views.d.ts +126 -0
  163. package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
  164. package/dist/gpu-driven/view-gpu.d.ts +18 -2
  165. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  166. package/dist/gpu-resource.d.ts +5 -2
  167. package/dist/gpu-resource.d.ts.map +1 -1
  168. package/dist/gpu-scene-schema.d.ts +2 -8
  169. package/dist/gpu-scene-schema.d.ts.map +1 -1
  170. package/dist/gpu-scene.d.ts +14 -0
  171. package/dist/gpu-scene.d.ts.map +1 -1
  172. package/dist/gpu-texture-usage.d.ts +1 -0
  173. package/dist/gpu-texture-usage.d.ts.map +1 -1
  174. package/dist/hdrp-buffers.d.ts +9 -0
  175. package/dist/hdrp-buffers.d.ts.map +1 -1
  176. package/dist/ibl/IblPipelineCache.d.ts +2 -0
  177. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  178. package/dist/ibl/frame-resources.d.ts +8 -0
  179. package/dist/ibl/frame-resources.d.ts.map +1 -0
  180. package/dist/ibl/skylight-bind-group.d.ts +3 -1
  181. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  182. package/dist/index.d.ts +87 -75
  183. package/dist/index.d.ts.map +1 -1
  184. package/dist/index.mjs +10 -8
  185. package/dist/index.mjs.map +1 -1
  186. package/dist/inspection-types.d.ts +180 -1
  187. package/dist/inspection-types.d.ts.map +1 -1
  188. package/dist/instances-derived-bounds.d.ts +11 -0
  189. package/dist/instances-derived-bounds.d.ts.map +1 -1
  190. package/dist/instances.d.ts +89 -44
  191. package/dist/instances.d.ts.map +1 -1
  192. package/dist/internal.d.ts +3 -0
  193. package/dist/internal.d.ts.map +1 -1
  194. package/dist/internal.mjs +117 -9
  195. package/dist/internal.mjs.map +1 -1
  196. package/dist/lifecycle.d.ts +2 -1
  197. package/dist/lifecycle.d.ts.map +1 -1
  198. package/dist/material-row.d.ts +15 -0
  199. package/dist/material-row.d.ts.map +1 -0
  200. package/dist/materials.d.ts +15 -0
  201. package/dist/materials.d.ts.map +1 -1
  202. package/dist/pbr-pipeline.d.ts +23 -5
  203. package/dist/pbr-pipeline.d.ts.map +1 -1
  204. package/dist/pipeline/render-extent.d.ts +51 -0
  205. package/dist/pipeline/render-extent.d.ts.map +1 -0
  206. package/dist/pipeline/standard-build-context.d.ts +7 -0
  207. package/dist/pipeline/standard-build-context.d.ts.map +1 -0
  208. package/dist/pipeline/standard-forward-lane.d.ts +3 -2
  209. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  210. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
  211. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
  212. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
  213. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
  214. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
  215. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
  216. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
  217. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
  218. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
  219. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
  220. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
  221. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
  222. package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
  223. package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
  224. package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
  225. package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
  226. package/dist/pipeline/standard-output/graph.d.ts +15 -0
  227. package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
  228. package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
  229. package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
  230. package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
  231. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
  232. package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
  233. package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
  234. package/dist/pipeline/standard-output/resources.d.ts +10 -0
  235. package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
  236. package/dist/pipeline/standard-output/types.d.ts +39 -0
  237. package/dist/pipeline/standard-output/types.d.ts.map +1 -0
  238. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  239. package/dist/pipeline/standard-post.d.ts +2 -2
  240. package/dist/pipeline/standard-post.d.ts.map +1 -1
  241. package/dist/pipeline/standard-profile.d.ts +2 -1
  242. package/dist/pipeline/standard-profile.d.ts.map +1 -1
  243. package/dist/pipeline-builder.d.ts +5 -2
  244. package/dist/pipeline-builder.d.ts.map +1 -1
  245. package/dist/pipeline-spec-types.d.ts +4 -0
  246. package/dist/pipeline-spec-types.d.ts.map +1 -1
  247. package/dist/pipeline-spec.d.ts +1 -9
  248. package/dist/pipeline-spec.d.ts.map +1 -1
  249. package/dist/plugin.d.ts.map +1 -1
  250. package/dist/points-lines/standard-owner.d.ts +1 -1
  251. package/dist/points-lines/standard-owner.d.ts.map +1 -1
  252. package/dist/post-process-errors.d.ts +9 -2
  253. package/dist/post-process-errors.d.ts.map +1 -1
  254. package/dist/prepare/extended-lighting/resources.d.ts +3 -3
  255. package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
  256. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  257. package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
  258. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
  259. package/dist/record/frame-lighting.d.ts +3 -3
  260. package/dist/record/frame-lighting.d.ts.map +1 -1
  261. package/dist/record/frame-snapshot.d.ts +109 -13
  262. package/dist/record/frame-snapshot.d.ts.map +1 -1
  263. package/dist/record/frame-targets.d.ts.map +1 -1
  264. package/dist/record/frame.d.ts +41 -5
  265. package/dist/record/frame.d.ts.map +1 -1
  266. package/dist/record/main-pass-geometry.d.ts +13 -9
  267. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  268. package/dist/record/main-pass-material.d.ts +43 -3
  269. package/dist/record/main-pass-material.d.ts.map +1 -1
  270. package/dist/record/main-pass-sprite-draws.d.ts +2 -10
  271. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  272. package/dist/record/main-pass.d.ts +14 -2
  273. package/dist/record/main-pass.d.ts.map +1 -1
  274. package/dist/record/mesh-ssbo.d.ts +15 -6
  275. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  276. package/dist/record/prepared-material-bindings.d.ts +19 -0
  277. package/dist/record/prepared-material-bindings.d.ts.map +1 -0
  278. package/dist/record/recovery-pipeline.d.ts +1 -0
  279. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  280. package/dist/record/render-context.d.ts +101 -22
  281. package/dist/record/render-context.d.ts.map +1 -1
  282. package/dist/record/shadow-pass.d.ts +62 -7
  283. package/dist/record/shadow-pass.d.ts.map +1 -1
  284. package/dist/record/skybox-post-pass.d.ts +1 -1
  285. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  286. package/dist/record/typed-frame-graph.d.ts +39 -8
  287. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  288. package/dist/record/view-ubo.d.ts +1 -0
  289. package/dist/record/view-ubo.d.ts.map +1 -1
  290. package/dist/recovery/render-system-candidate.d.ts +10 -2
  291. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  292. package/dist/recovery/render-system-roots.d.ts +11 -0
  293. package/dist/recovery/render-system-roots.d.ts.map +1 -0
  294. package/dist/recovery/types.d.ts +76 -0
  295. package/dist/recovery/types.d.ts.map +1 -0
  296. package/dist/reflection/background.d.ts +14 -0
  297. package/dist/reflection/background.d.ts.map +1 -0
  298. package/dist/reflection/filter.d.ts.map +1 -1
  299. package/dist/reflection/projection.d.ts +1 -0
  300. package/dist/reflection/projection.d.ts.map +1 -1
  301. package/dist/reflection/record-owner.d.ts +4 -4
  302. package/dist/reflection/record-owner.d.ts.map +1 -1
  303. package/dist/render-contract.d.ts +211 -53
  304. package/dist/render-contract.d.ts.map +1 -1
  305. package/dist/render-graph-primitives.d.ts +1 -0
  306. package/dist/render-graph-primitives.d.ts.map +1 -1
  307. package/dist/render-pipeline.d.ts +81 -6
  308. package/dist/render-pipeline.d.ts.map +1 -1
  309. package/dist/render-system-extract-tail.d.ts +15 -6
  310. package/dist/render-system-extract-tail.d.ts.map +1 -1
  311. package/dist/render-system-extract.d.ts +128 -41
  312. package/dist/render-system-extract.d.ts.map +1 -1
  313. package/dist/render-system-projections.d.ts +22 -0
  314. package/dist/render-system-projections.d.ts.map +1 -0
  315. package/dist/render-system.d.ts +27 -77
  316. package/dist/render-system.d.ts.map +1 -1
  317. package/dist/scene/render-scene-types.d.ts +14 -7
  318. package/dist/scene/render-scene-types.d.ts.map +1 -1
  319. package/dist/scene/render-scene.d.ts +31 -11
  320. package/dist/scene/render-scene.d.ts.map +1 -1
  321. package/dist/scene/shadow-visibility.d.ts +5 -0
  322. package/dist/scene/shadow-visibility.d.ts.map +1 -0
  323. package/dist/ssao-config.d.ts +8 -6
  324. package/dist/ssao-config.d.ts.map +1 -1
  325. package/dist/ssr/admission.d.ts +70 -1
  326. package/dist/ssr/admission.d.ts.map +1 -1
  327. package/dist/ssr/compose.d.ts +13 -0
  328. package/dist/ssr/compose.d.ts.map +1 -0
  329. package/dist/ssr/errors.d.ts +35 -0
  330. package/dist/ssr/errors.d.ts.map +1 -1
  331. package/dist/ssr/graph.d.ts +60 -0
  332. package/dist/ssr/graph.d.ts.map +1 -0
  333. package/dist/ssr/history.d.ts +97 -0
  334. package/dist/ssr/history.d.ts.map +1 -0
  335. package/dist/ssr/hiz.d.ts +37 -0
  336. package/dist/ssr/hiz.d.ts.map +1 -0
  337. package/dist/ssr/inspection.d.ts +42 -0
  338. package/dist/ssr/inspection.d.ts.map +1 -0
  339. package/dist/ssr/resources.d.ts +58 -0
  340. package/dist/ssr/resources.d.ts.map +1 -0
  341. package/dist/ssr/temporal.d.ts +38 -0
  342. package/dist/ssr/temporal.d.ts.map +1 -0
  343. package/dist/systems/skin-palette-allocator.d.ts +32 -10
  344. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  345. package/dist/systems/skin-palette-types.d.ts +15 -0
  346. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  347. package/dist/systems/transparent-dispatch.d.ts +9 -0
  348. package/dist/systems/transparent-dispatch.d.ts.map +1 -0
  349. package/dist/targets/material-source.d.ts +7 -0
  350. package/dist/targets/material-source.d.ts.map +1 -1
  351. package/dist/temporal/frame-coordinator.d.ts +7 -0
  352. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  353. package/dist/temporal/gpu.d.ts +8 -0
  354. package/dist/temporal/gpu.d.ts.map +1 -1
  355. package/dist/temporal/history.d.ts.map +1 -1
  356. package/dist/temporal/index.mjs +6 -6
  357. package/dist/temporal/inspection.d.ts.map +1 -1
  358. package/dist/temporal/standard-scene-data.d.ts +4 -2
  359. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  360. package/dist/temporal/target-coverage-attachment.d.ts +15 -0
  361. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -0
  362. package/dist/temporal/temporal-view.d.ts +6 -0
  363. package/dist/temporal/temporal-view.d.ts.map +1 -1
  364. package/dist/temporal/view.d.ts +6 -0
  365. package/dist/temporal/view.d.ts.map +1 -1
  366. package/dist/typed-render-graph-primitives.d.ts +41 -1
  367. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  368. package/dist/typed-shadow-passes.d.ts +3 -1
  369. package/dist/typed-shadow-passes.d.ts.map +1 -1
  370. package/dist/volume/component.d.ts +1 -0
  371. package/dist/volume/component.d.ts.map +1 -1
  372. package/dist/volume/temporal.d.ts +6 -0
  373. package/dist/volume/temporal.d.ts.map +1 -1
  374. package/package.json +21 -20
  375. package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
  376. package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
  377. package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
  378. package/src/__tests__/auto-exposure.browser.test.ts +33 -0
  379. package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
  380. package/src/__tests__/capture-scene-projection.unit.test.ts +24 -0
  381. package/src/__tests__/detached-inspection.integration.test.ts +5 -0
  382. package/src/__tests__/device-feature-admission.unit.test.ts +15 -24
  383. package/src/__tests__/device-loss-fanout.unit.test.ts +43 -0
  384. package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
  385. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
  386. package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
  387. package/src/__tests__/dynamic-geometry-batch.unit.test.ts +157 -0
  388. package/src/__tests__/dynamic-geometry.unit.test.ts +36 -0
  389. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +81 -0
  390. package/src/__tests__/factory-contract.integration.test.ts +231 -9
  391. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
  392. package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
  393. package/src/__tests__/feature-noise.unit.test.ts +38 -0
  394. package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
  395. package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
  396. package/src/__tests__/frame-observation.contract.test.ts +21 -0
  397. package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
  398. package/src/__tests__/frame-targets.unit.test.ts +24 -0
  399. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
  400. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
  401. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +307 -7
  402. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
  403. package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
  404. package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +261 -0
  405. package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +346 -0
  406. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1422 -0
  407. package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
  408. package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
  409. package/src/__tests__/gpu-driven-production.integration.test.ts +1076 -106
  410. package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
  411. package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
  412. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
  413. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
  414. package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
  415. package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
  416. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
  417. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
  418. package/src/__tests__/gpu-driven-view.unit.test.ts +160 -52
  419. package/src/__tests__/gpu-pass-timing-browser-runner.ts +15 -0
  420. package/src/__tests__/gpu-pass-timing.browser.test.ts +20 -2
  421. package/src/__tests__/gpu-resource-scope.unit.test.ts +71 -0
  422. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
  423. package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
  424. package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
  425. package/src/__tests__/gpu-scene.unit.test.ts +613 -33
  426. package/src/__tests__/instances-culling.integration.test.ts +36 -10
  427. package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
  428. package/src/__tests__/instances-store.unit.test.ts +242 -39
  429. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
  430. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
  431. package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
  432. package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
  433. package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
  434. package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
  435. package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
  436. package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
  437. package/src/__tests__/material-texture-source.unit.test.ts +87 -0
  438. package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
  439. package/src/__tests__/materials-standard-contract.unit.test.ts +57 -3
  440. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
  441. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +8 -0
  442. package/src/__tests__/morph-neutral-admission.unit.test.ts +19 -0
  443. package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
  444. package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
  445. package/src/__tests__/physical-clearcoat.integration.test.ts +42 -3
  446. package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
  447. package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
  448. package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -5
  449. package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
  450. package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
  451. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +251 -9
  452. package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
  453. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
  454. package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
  455. package/src/__tests__/public-surface.test-d.ts +3 -0
  456. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
  457. package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +171 -0
  458. package/src/__tests__/reflection-probe-authoring.unit.test.ts +12 -10
  459. package/src/__tests__/reflection-probe-box.dawn.test.ts +71 -0
  460. package/src/__tests__/reflection-probe-filter.unit.test.ts +9 -0
  461. package/src/__tests__/reflection-probe-orientation.dawn.test.ts +294 -0
  462. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +5 -14
  463. package/src/__tests__/reflection-probe-updates.unit.test.ts +129 -0
  464. package/src/__tests__/render-error-code-owner.test-d.ts +7 -0
  465. package/src/__tests__/render-error-detail-ssot.test-d.ts +27 -1
  466. package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
  467. package/src/__tests__/render-extent.unit.test.ts +63 -0
  468. package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
  469. package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
  470. package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
  471. package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
  472. package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
  473. package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
  474. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
  475. package/src/__tests__/render-scene-projection.unit.test.ts +915 -23
  476. package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
  477. package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
  478. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
  479. package/src/__tests__/render-target-material-source.test-d.ts +27 -3
  480. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +233 -9
  481. package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
  482. package/src/__tests__/shader-manifest-fixture.ts +45 -0
  483. package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
  484. package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
  485. package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
  486. package/src/__tests__/skinned-shadow-caster.test.ts +125 -14
  487. package/src/__tests__/specular-environment-scale.dawn.test.ts +158 -0
  488. package/src/__tests__/ssao-config.unit.test.ts +7 -0
  489. package/src/__tests__/ssao-surface.dawn.test.ts +252 -0
  490. package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
  491. package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
  492. package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
  493. package/src/__tests__/ssr-cube-silhouette.dawn.test.ts +270 -0
  494. package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
  495. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +99 -0
  496. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +116 -0
  497. package/src/__tests__/ssr-gpu-dispatch.ts +951 -0
  498. package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
  499. package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
  500. package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
  501. package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
  502. package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
  503. package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
  504. package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
  505. package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
  506. package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
  507. package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
  508. package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
  509. package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
  510. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
  511. package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
  512. package/src/__tests__/ssr-reprojection-probe.ts +90 -0
  513. package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
  514. package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
  515. package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
  516. package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
  517. package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
  518. package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
  519. package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
  520. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +84 -12
  521. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
  522. package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
  523. package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
  524. package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
  525. package/src/__tests__/standard-output.browser.test.ts +15 -0
  526. package/src/__tests__/standard-output.dawn.test.ts +15 -0
  527. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +275 -0
  528. package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
  529. package/src/__tests__/standard-profile-oracle.unit.test.ts +49 -0
  530. package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
  531. package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
  532. package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
  533. package/src/__tests__/taa-coverage-edge.dawn.test.ts +199 -0
  534. package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
  535. package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +782 -0
  536. package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
  537. package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
  538. package/src/__tests__/taa-stability-feedback.ts +342 -0
  539. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
  540. package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
  541. package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
  542. package/src/__tests__/temporal-view.unit.test.ts +17 -0
  543. package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
  544. package/src/__tests__/transmission-prewarm.unit.test.ts +57 -0
  545. package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
  546. package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
  547. package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
  548. package/src/__tests__/visibility-extract.perf.test.ts +20 -8
  549. package/src/__tests__/visibility-instances.integration.test.ts +19 -7
  550. package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
  551. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +62 -13
  552. package/src/__tests__/volumetric-fog-topology.unit.test.ts +7 -7
  553. package/src/assembly/atmosphere-shader-prewarm.ts +39 -0
  554. package/src/assembly/device-feature-admission.ts +9 -4
  555. package/src/assembly/dynamic-geometry-host.ts +284 -163
  556. package/src/assembly/dynamic-geometry-runtime.ts +71 -0
  557. package/src/assembly/factory.ts +4 -0
  558. package/src/assembly/gpu-driven-owner.ts +29 -0
  559. package/src/assembly/host-contract.ts +19 -0
  560. package/src/assembly/material/assembly.ts +383 -1
  561. package/src/assembly/material/pipeline-helpers.ts +100 -0
  562. package/src/assembly/material-shader-policy.ts +110 -46
  563. package/src/assembly/recovery/device-loss-fanout.ts +5 -0
  564. package/src/assembly/recovery/failure-location.ts +62 -0
  565. package/src/assembly/recovery/recovery-attempt.ts +2 -29
  566. package/src/assembly/recovery/renderer-recover.ts +16 -17
  567. package/src/assembly/renderer-facade.ts +34 -1
  568. package/src/assembly/renderer-feature-inspection.ts +13 -0
  569. package/src/assembly/renderer-frame-transaction.ts +63 -0
  570. package/src/assembly/renderer-helpers.ts +26 -0
  571. package/src/assembly/renderer-inspection.ts +6 -0
  572. package/src/assembly/shader-prewarm-policy.ts +46 -1
  573. package/src/assembly/skin-palette-owner.ts +21 -0
  574. package/src/assembly/ssr-shader-prewarm.ts +41 -0
  575. package/src/assembly/webgpu-device-loss.ts +75 -0
  576. package/src/assembly/webgpu-pbr-ready.ts +232 -0
  577. package/src/assembly/webgpu-ready-mipmap.ts +26 -0
  578. package/src/assembly/webgpu-ready.ts +161 -131
  579. package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
  580. package/src/assembly/webgpu-renderer-contract.ts +69 -0
  581. package/src/assembly/webgpu-renderer-guards.ts +32 -0
  582. package/src/assembly/webgpu-renderer-observation.ts +43 -0
  583. package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
  584. package/src/assembly/webgpu-renderer.ts +744 -730
  585. package/src/assembly/webgpu-vertex-layouts.ts +233 -87
  586. package/src/capture/scene-projection.ts +37 -0
  587. package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
  588. package/src/components/__tests__/dynamic-resolution-schema.unit.test.ts +65 -0
  589. package/src/components/__tests__/light-radius.integration.test.ts +59 -0
  590. package/src/components/camera.ts +287 -7
  591. package/src/components/directional-light.ts +3 -3
  592. package/src/components/dynamic-resolution.ts +67 -0
  593. package/src/components/index.ts +2 -0
  594. package/src/components/instances.ts +45 -18
  595. package/src/components/light-helpers.ts +6 -1
  596. package/src/components/reflection-probe.ts +1 -0
  597. package/src/components/scene-instance.ts +2 -1
  598. package/src/components/screen-space-reflection.ts +21 -0
  599. package/src/components/skylight.ts +4 -1
  600. package/src/components/sprite-animation.ts +2 -2
  601. package/src/components/sprite-instances.ts +1 -1
  602. package/src/device/device-scope.ts +13 -7
  603. package/src/device/gpu-residency.ts +45 -42
  604. package/src/dynamic-geometry.ts +13 -8
  605. package/src/environment/background.ts +281 -0
  606. package/src/environment/ibl.ts +211 -0
  607. package/src/environment/storage.ts +63 -0
  608. package/src/errors/gpu-driven.ts +49 -8
  609. package/src/errors/render.ts +91 -3
  610. package/src/extract/camera.ts +37 -1
  611. package/src/extract/contracts.ts +10 -0
  612. package/src/extract/gpu-driven.ts +240 -10
  613. package/src/features/host.ts +237 -19
  614. package/src/features/noise-texture.ts +91 -0
  615. package/src/features/plan.ts +553 -24
  616. package/src/features/prepared-gpu-work.ts +631 -49
  617. package/src/features/prepared-graphics-store.ts +31 -0
  618. package/src/features/prepared-graphics.ts +5 -0
  619. package/src/features/render-graph-compute.ts +41 -8
  620. package/src/features/render-graph-contribution.ts +141 -3
  621. package/src/features/render-graph-raster.ts +143 -30
  622. package/src/features/types.ts +11 -0
  623. package/src/fullscreen-post-process-pass.ts +3 -0
  624. package/src/gpu-driven/batch-topology.ts +452 -108
  625. package/src/gpu-driven/material-artifacts.ts +179 -0
  626. package/src/gpu-driven/material-bindings.ts +41 -0
  627. package/src/gpu-driven/pbr-program.ts +31 -0
  628. package/src/gpu-driven/prepared-draw.ts +42 -6
  629. package/src/gpu-driven/production-raster.ts +2806 -716
  630. package/src/gpu-driven/shadow-views.ts +539 -0
  631. package/src/gpu-driven/view-gpu.ts +188 -41
  632. package/src/gpu-resource.ts +21 -2
  633. package/src/gpu-scene-schema.ts +61 -11
  634. package/src/gpu-scene.ts +197 -99
  635. package/src/gpu-texture-usage.ts +1 -0
  636. package/src/hdrp-buffers.ts +141 -36
  637. package/src/ibl/IblPipelineCache.ts +5 -0
  638. package/src/ibl/frame-resources.ts +38 -0
  639. package/src/ibl/skylight-bind-group.ts +32 -21
  640. package/src/index.ts +194 -75
  641. package/src/inspection-types.ts +207 -1
  642. package/src/instances-derived-bounds.ts +258 -34
  643. package/src/instances.ts +459 -150
  644. package/src/internal.ts +22 -0
  645. package/src/lifecycle.ts +2 -0
  646. package/src/material-row.ts +194 -0
  647. package/src/materials.ts +44 -8
  648. package/src/pbr-pipeline.ts +172 -19
  649. package/src/pipeline/render-extent.ts +111 -0
  650. package/src/pipeline/standard-build-context.ts +7 -0
  651. package/src/pipeline/standard-forward-lane.ts +74 -29
  652. package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
  653. package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
  654. package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
  655. package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
  656. package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
  657. package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
  658. package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
  659. package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
  660. package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
  661. package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
  662. package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
  663. package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
  664. package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
  665. package/src/pipeline/standard-output/color-transform.ts +124 -0
  666. package/src/pipeline/standard-output/graph.ts +139 -0
  667. package/src/pipeline/standard-output/lut-admission.ts +121 -0
  668. package/src/pipeline/standard-output/lut-gpu.ts +399 -0
  669. package/src/pipeline/standard-output/lut-state.ts +176 -0
  670. package/src/pipeline/standard-output/resources.ts +121 -0
  671. package/src/pipeline/standard-output/types.ts +58 -0
  672. package/src/pipeline/standard-pipeline.ts +232 -70
  673. package/src/pipeline/standard-post.ts +190 -27
  674. package/src/pipeline/standard-profile.ts +2 -1
  675. package/src/pipeline-builder.ts +28 -9
  676. package/src/pipeline-spec-types.ts +4 -0
  677. package/src/pipeline-spec.ts +37 -29
  678. package/src/plugin.ts +4 -0
  679. package/src/points-lines/standard-owner.ts +6 -14
  680. package/src/post-process-errors.ts +26 -18
  681. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +2 -2
  682. package/src/prepare/extended-lighting/resources.ts +3 -3
  683. package/src/prepare/prepared-graphics-resolver.ts +9 -2
  684. package/src/record/__tests__/main-pass-geometry.unit.test.ts +68 -0
  685. package/src/record/__tests__/material-bg-cache.unit.test.ts +45 -0
  686. package/src/record/__tests__/material-slot-plan.unit.test.ts +57 -0
  687. package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
  688. package/src/record/__tests__/recovery-pipeline.unit.test.ts +20 -1
  689. package/src/record/__tests__/sprite-material-abi.unit.test.ts +41 -6
  690. package/src/record/__tests__/temporal-payload.unit.test.ts +2 -0
  691. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
  692. package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
  693. package/src/record/dynamic-geometry-consumption.ts +59 -0
  694. package/src/record/frame-lighting.ts +15 -12
  695. package/src/record/frame-snapshot.ts +146 -34
  696. package/src/record/frame-targets.ts +9 -0
  697. package/src/record/frame.ts +838 -170
  698. package/src/record/main-pass-geometry.ts +209 -103
  699. package/src/record/main-pass-material.ts +157 -40
  700. package/src/record/main-pass-sprite-draws.ts +16 -107
  701. package/src/record/main-pass.ts +141 -12
  702. package/src/record/material-uniforms.ts +1 -1
  703. package/src/record/mesh-ssbo.ts +59 -15
  704. package/src/record/prepared-material-bindings.ts +238 -0
  705. package/src/record/recovery-pipeline.ts +69 -90
  706. package/src/record/render-context.ts +123 -24
  707. package/src/record/shadow-pass.ts +1389 -230
  708. package/src/record/skybox-post-pass.ts +14 -3
  709. package/src/record/typed-frame-graph.ts +1064 -47
  710. package/src/record/view-ubo.ts +12 -1
  711. package/src/recovery/render-system-candidate.ts +135 -68
  712. package/src/recovery/render-system-roots.ts +113 -0
  713. package/src/recovery/types.ts +77 -0
  714. package/src/reflection/background.ts +151 -0
  715. package/src/reflection/filter.ts +3 -0
  716. package/src/reflection/projection.ts +16 -6
  717. package/src/reflection/record-owner.ts +308 -140
  718. package/src/render-contract.ts +237 -49
  719. package/src/render-graph-primitives.ts +34 -5
  720. package/src/render-pipeline.ts +90 -2
  721. package/src/render-system-extract-tail.ts +431 -162
  722. package/src/render-system-extract.ts +478 -119
  723. package/src/render-system-projections.ts +241 -0
  724. package/src/render-system.ts +715 -828
  725. package/src/scene/render-scene-types.ts +13 -4
  726. package/src/scene/render-scene.ts +577 -355
  727. package/src/scene/shadow-visibility.ts +21 -0
  728. package/src/ssao-config.ts +25 -8
  729. package/src/ssr/admission.ts +380 -14
  730. package/src/ssr/compose.ts +144 -0
  731. package/src/ssr/errors.ts +48 -0
  732. package/src/ssr/graph.ts +797 -0
  733. package/src/ssr/history.ts +436 -0
  734. package/src/ssr/hiz.ts +124 -0
  735. package/src/ssr/inspection.ts +124 -0
  736. package/src/ssr/resources.ts +202 -0
  737. package/src/ssr/temporal.ts +164 -0
  738. package/src/systems/skin-palette-allocator.ts +495 -148
  739. package/src/systems/skin-palette-types.ts +17 -0
  740. package/src/systems/transparent-dispatch.ts +90 -0
  741. package/src/targets/material-source.ts +34 -0
  742. package/src/temporal/coverage.ts +1 -1
  743. package/src/temporal/frame-coordinator.ts +23 -2
  744. package/src/temporal/gpu.ts +79 -12
  745. package/src/temporal/history.ts +3 -1
  746. package/src/temporal/inspection.ts +2 -1
  747. package/src/temporal/standard-scene-data.ts +10 -2
  748. package/src/temporal/target-coverage-attachment.ts +72 -0
  749. package/src/temporal/temporal-view.ts +11 -2
  750. package/src/temporal/view.ts +12 -2
  751. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +219 -139
  752. package/src/typed-render-graph-primitives.ts +304 -74
  753. package/src/typed-shadow-passes.ts +122 -12
  754. package/src/volume/component.ts +1 -0
  755. package/src/volume/passes.ts +3 -3
  756. package/src/volume/temporal.ts +10 -0
  757. package/dist/chunk-GE3SDD72.mjs.map +0 -1
  758. package/dist/chunk-GF523LHF.mjs.map +0 -1
  759. package/dist/chunk-IQMKJLNU.mjs.map +0 -1
  760. package/dist/chunk-J52NMQKR.mjs.map +0 -1
  761. package/dist/chunk-J6KACNOH.mjs.map +0 -1
  762. package/dist/chunk-JAASCMXA.mjs.map +0 -1
  763. package/dist/chunk-MBU4ZVE7.mjs.map +0 -1
  764. package/dist/chunk-MYJ5RPJO.mjs.map +0 -1
  765. package/dist/chunk-RBDBZ5R7.mjs.map +0 -1
  766. package/dist/chunk-VSL23LZE.mjs.map +0 -1
  767. package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
  768. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
@@ -76,9 +76,18 @@ import type { MaterialCookProgramContext } from '@forgeax/engine-pack/material-c
76
76
  // `MeshFilter.assetHandle` dangling path
77
77
  // (charter proposition 5; AC-11).
78
78
  //
79
- // World owns explicit Instances transforms. Extraction makes a detached
80
- // per-renderer projection; GPU residents acknowledge complete snapshots only
81
- // after successful uploads. Reading a snapshot never changes author state.
79
+ // Renderer-owned Large Instances:
80
+ // `Instances { collectionId }` is an ECS association to the renderer's
81
+ // `InstanceCollectionStore`, not an ECS transform-array column. The extract
82
+ // tail resolves the identity against that store and snapshots canonical
83
+ // transforms together with collection revision, capacity, dirty ranges,
84
+ // and residency facts. Invalid or stale associations route the existing
85
+ // typed `InstanceCollectionError` through the World error boundary; the
86
+ // record stage owns GPU residency and upload decisions.
87
+ //
88
+ // `SpriteInstances` remains the separate ECS-owned array-view path. Its
89
+ // snapshot is intentionally independent from renderer-owned Large Instances,
90
+ // so the extract stage does not duplicate collection storage or GPU policy.
82
91
 
83
92
  import type { AssetRegistry } from '@forgeax/engine-assets-runtime';
84
93
  import {
@@ -94,9 +103,11 @@ import { AssetGuid, type AssetGuid as AssetGuidBytes } from '@forgeax/engine-pac
94
103
  import { RhiError } from '@forgeax/engine-rhi';
95
104
  import { GlobalTransform, Transform } from '@forgeax/engine-scene';
96
105
  import {
106
+ DEFAULT_STANDARD_PBR_PARAM_SCHEMA,
97
107
  DEFAULT_STANDARD_SURFACE_MODULE,
98
108
  type MaterialShaderArtifact,
99
109
  STANDARD_PIPELINE_PARAM_SCHEMA,
110
+ standardTextureMask,
100
111
  } from '@forgeax/engine-shader';
101
112
  import type {
102
113
  Asset,
@@ -110,7 +121,6 @@ import type {
110
121
  MaterialTextureValue,
111
122
  MeshLodLevel,
112
123
  ParamSchemaEntry,
113
- PrimitiveTopology,
114
124
  TextureAsset,
115
125
  } from '@forgeax/engine-types';
116
126
  import {
@@ -119,19 +129,25 @@ import {
119
129
  materialValuesToLinearRuntime,
120
130
  toShared,
121
131
  } from '@forgeax/engine-types';
132
+ import { buildCubeCameraFaceViews } from './capture/cube-views';
122
133
  import {
123
134
  antialiasFromF32,
124
135
  bloomEnabledFromF32,
136
+ CAMERA_EXPOSURE_MODE_MANUAL,
125
137
  Camera,
126
138
  CubeCamera,
139
+ cameraExposureFromColumns,
127
140
  cameraProjectionFromF32,
128
141
  cubeCameraUpdateIntentFromF32,
142
+ DynamicResolution,
129
143
  Fog,
130
144
  MotionBlur,
131
145
  ReflectionProbe,
132
146
  reflectionProbeUpdateIntentFromF32,
147
+ ScreenSpaceReflection,
133
148
  tonemapFromF32,
134
149
  tonemapToU32,
150
+ validateDynamicResolutionCamera,
135
151
  } from './components';
136
152
  import type { DirectionalShadowQuality } from './components/directional-shadow-filter';
137
153
  import type { LightValidationError } from './components/light-helpers';
@@ -147,12 +163,13 @@ import type {
147
163
  FogFrame,
148
164
  FogSelectionFailure,
149
165
  } from './extract/environment';
166
+ import type { GpuDrivenDrawSnapshot } from './extract/gpu-driven';
150
167
  import { resolveVisibility, type VisibilitySnapshot } from './extract/visibility';
151
168
  import type {
152
169
  RenderFeatureHiddenEntityReport,
153
170
  RenderFeatureWorldVisibilitySnapshot,
154
171
  } from './features/types';
155
- import type { InstanceCollectionId, InstanceProjectionStore } from './instances';
172
+ import type { InstanceCollectionId, InstanceCollectionStore } from './instances';
156
173
  import type {
157
174
  MeshMaterialBindingDiagnostic,
158
175
  MeshMaterialBindingSource,
@@ -165,7 +182,7 @@ import { defaultMaterialSnapshot } from './render-system-extract-tail';
165
182
  import { getActiveCamera, selectActiveCameraIndex } from './systems/active-camera';
166
183
  import { selectPasses } from './systems/pass-selector';
167
184
  import type { SkinPaletteAllocator } from './systems/skin-palette-allocator';
168
- import type { SkinPaletteSlice } from './systems/skin-palette-types';
185
+ import type { SkinPaletteReceipt } from './systems/skin-palette-types';
169
186
  import type { RenderTarget, RenderTargetTextureSource } from './targets/contracts';
170
187
  import { resolveRenderTargetMaterialSource } from './targets/material-source';
171
188
  import { resolveSelectedVolumetricLight } from './volume/capability';
@@ -204,6 +221,8 @@ export interface DirectionalLightSnapshot {
204
221
  export interface PointLightSnapshot {
205
222
  readonly kind: 'point';
206
223
  readonly entity?: EntityHandle | number;
224
+ /** World identity stamped by the composited extract owner. */
225
+ readonly worldId?: number;
207
226
  readonly position: Vec3;
208
227
  readonly color: Vec3;
209
228
  readonly intensity: number;
@@ -257,12 +276,16 @@ export interface PointLightSnapshot {
257
276
  export interface PointShadowSnapshot {
258
277
  /** Spawning entity index (joins PointLight + PointLightShadow + Transform). */
259
278
  readonly entity: number;
279
+ /** World identity stamped by the composited extract owner. */
280
+ readonly worldId?: number;
260
281
  /** World-space light position (sourced from companion Transform). */
261
282
  readonly position: Vec3;
262
283
  /** PointLightShadow.mapSize (per-face cube square dimension; 512 default). */
263
284
  readonly mapSize: number;
264
285
  readonly nearPlane: number;
265
286
  readonly farPlane: number;
287
+ readonly depthBias: number;
288
+ readonly normalBias: number;
266
289
  /**
267
290
  * Atlas layer assigned by extract in spawn order while capacity remains.
268
291
  * Sentinel -1 is used for a request that cannot be admitted and is
@@ -298,6 +321,8 @@ export interface SpotLightSnapshot {
298
321
  readonly kind: 'spot';
299
322
  /** Entity identity is branded in extracted frames; numeric fixtures remain compatible. */
300
323
  readonly entity?: EntityHandle | number;
324
+ /** World identity stamped by the composited extract owner. */
325
+ readonly worldId?: number;
301
326
  readonly position: Vec3;
302
327
  readonly direction: Vec3;
303
328
  readonly color: Vec3;
@@ -586,6 +611,8 @@ export interface SkylightSnapshot {
586
611
  /** Local diffuse probe facts; specular remains owned by Skylight/ReflectionProbe. */
587
612
  export interface LightProbeSnapshot {
588
613
  readonly identity: string;
614
+ /** World identity stamped by the composited extract owner. */
615
+ readonly worldId?: number;
589
616
  readonly position: readonly [number, number, number];
590
617
  readonly radius: number;
591
618
  readonly irradiance: Float32Array;
@@ -646,6 +673,8 @@ export interface ExtractedVolumetricFog {
646
673
  }
647
674
 
648
675
  export interface RenderableSnapshot {
676
+ /** Authored hierarchical visibility; retained hidden rows remain addressable. */
677
+ readonly authorVisible?: boolean;
649
678
  readonly assetHandle: number;
650
679
  readonly transform: TransformSnapshot;
651
680
  /** Producer-authored lower-detail references projected from MeshAsset. */
@@ -683,8 +712,6 @@ export interface RenderableSnapshot {
683
712
  readonly materialBindingSources: readonly MeshMaterialBindingSource[];
684
713
  /** Active structured override diagnostics for this renderable. */
685
714
  readonly materialBindingDiagnostics?: readonly MeshMaterialBindingDiagnostic[];
686
- /** Effective authored visibility retained by the persistent scene owner. */
687
- readonly authorVisible?: boolean;
688
715
  /**
689
716
  * feat-20260708-composited-multi-world-rendering M1 / D-1: the worldId
690
717
  * of the world this renderable was extracted from. Defaults to 0 in
@@ -749,9 +776,14 @@ export interface RenderableSnapshot {
749
776
  * draw to `forgeax::pbr-skin` pipeline + set the palette dynamic offset.
750
777
  * Absent (`undefined`) means the entity is not skinned.
751
778
  */
752
- readonly skin?: SkinPaletteSlice;
753
- /** Joint entity identities used by the persistent skin dependency index. */
779
+ readonly skin?: SkinPaletteReceipt;
780
+ /** Joint identities consumed by the retained scene dependency index. */
754
781
  readonly skinJointEntities?: readonly number[];
782
+ /** Source pass ownership retained with the scene record across view changes. */
783
+ readonly shadowCasterPasses?: readonly Omit<
784
+ ShadowCasterMembership,
785
+ 'worldEntity' | 'renderableIndex'
786
+ >[];
755
787
  /**
756
788
  * ECS-owned morph weights. Presence selects the Standard Pipeline CPU
757
789
  * specialized deformation lane; the asset remains the source of target
@@ -782,7 +814,7 @@ export interface RenderableTemporalSnapshot {
782
814
  readonly reactiveReasons: readonly RenderableReactiveReason[];
783
815
  readonly previousTransform: TransformSnapshot;
784
816
  readonly previousInstances: InstancesSnapshot | undefined;
785
- readonly previousSkin: SkinPaletteSlice | undefined;
817
+ readonly previousSkin: SkinPaletteReceipt | undefined;
786
818
  readonly previousMorphWeights: Float32Array | undefined;
787
819
  }
788
820
 
@@ -791,26 +823,7 @@ export interface MorphSnapshot {
791
823
  readonly targetCount: number;
792
824
  }
793
825
 
794
- export interface GpuDrivenDrawSnapshot {
795
- readonly kind: 'indexed' | 'non-indexed';
796
- readonly first: number;
797
- readonly count: number;
798
- readonly baseVertex: number;
799
- readonly materialSlot: number;
800
- readonly topology: PrimitiveTopology;
801
- readonly pipelineClass: string;
802
- readonly materialResourceClass: string;
803
- /** Producer-owned prepared ABI facts used by the Standard PBR GPU lane. */
804
- readonly prepared?: import('./gpu-driven/prepared-draw').PreparedGpuDrivenDraw;
805
- /** Optional projected height supplied by direct GPU-view evidence/tests. */
806
- readonly projectedHeight?: number;
807
- /** Root plus lower-detail index/vertex ranges, in LOD order. */
808
- readonly lodRanges?: readonly {
809
- readonly first: number;
810
- readonly count: number;
811
- readonly baseVertex: number;
812
- }[];
813
- }
826
+ export type { GpuDrivenDrawSnapshot } from './extract/gpu-driven';
814
827
 
815
828
  export interface InstancesSnapshot {
816
829
  /** Renderer-owned collection identity. */
@@ -821,6 +834,13 @@ export interface InstancesSnapshot {
821
834
  readonly instanceCount: number;
822
835
  /** Collection revision captured by this detached frame snapshot. */
823
836
  readonly revision?: number;
837
+ /** Logical collection capacity at snapshot time. */
838
+ readonly capacity?: number;
839
+ /** Coalesced matrix ordinals dirtied since the previous authoring update. */
840
+ readonly dirtyRanges?: readonly {
841
+ readonly start: number;
842
+ readonly end: number;
843
+ }[];
824
844
  /** Stable per-entity GPU buffer cache key (the packed Entity u32). */
825
845
  readonly cacheKey: number;
826
846
  /**
@@ -914,6 +934,10 @@ export interface MaterialSnapshot {
914
934
  */
915
935
  readonly materialShaderId?: string | undefined;
916
936
  readonly materialProgramKeys?: Readonly<Record<string, string>> | undefined;
937
+ /** Producer-selected scene-index program keys, when a cooked publication carries them. */
938
+ readonly materialSceneIndexProgramKeys?:
939
+ | Readonly<Record<string, MaterialSceneIndexProgramKey>>
940
+ | undefined;
917
941
  /**
918
942
  * Stable source handle for the material asset. Record uses this only for
919
943
  * same-frame assembly reuse; GPU bind-group validity still comes from the
@@ -935,6 +959,8 @@ export interface MaterialSnapshot {
935
959
  readonly paramSnapshot?: Readonly<Record<string, number | number[] | string>> | undefined;
936
960
  /** Effective MaterialAsset parameter contract used to lay out this snapshot. */
937
961
  readonly materialParamSchema?: readonly ParamSchemaEntry[] | undefined;
962
+ /** Authored texture presence, separate from the shared GPU layout schema. */
963
+ readonly standardTextureMask?: number | undefined;
938
964
  /** Authored per-slot UV set and KHR texture transform metadata. */
939
965
  readonly textureCoordinates?: ReadonlyMap<string, MaterialTextureCoordinates> | undefined;
940
966
  /**
@@ -954,6 +980,8 @@ export interface MaterialSnapshot {
954
980
  * them in a lightmap injection region.
955
981
  */
956
982
  readonly textureHandles?: ReadonlyMap<string, Handle<'TextureAsset', 'shared'>> | undefined;
983
+ /** Explicitly authored texture fields that must resolve before GPU admission. */
984
+ readonly authoredTextureFields?: ReadonlySet<string> | undefined;
957
985
  /** Renderer-local target sources; never projected as TextureAsset handles. */
958
986
  readonly textureSources?: ReadonlyMap<string, RenderTargetTextureSource> | undefined;
959
987
  /**
@@ -974,6 +1002,8 @@ export interface MaterialSnapshot {
974
1002
  readonly videoTextureFields?: ReadonlyMap<string, Handle<'VideoAsset', 'shared'>> | undefined;
975
1003
  /** Authored sampler handles keyed by their matching texture parameter. */
976
1004
  readonly samplerHandles?: ReadonlyMap<string, Handle<'SamplerAsset', 'shared'>> | undefined;
1005
+ /** Explicitly authored sampler fields that must resolve before GPU admission. */
1006
+ readonly authoredSamplerFields?: ReadonlySet<string> | undefined;
977
1007
  readonly baseColorTexture?: Handle<'TextureAsset', 'shared'> | undefined;
978
1008
  /**
979
1009
  * PBR metallic-roughness texture handle (present for PBR/sprite/skin
@@ -1031,6 +1061,15 @@ export interface MaterialSnapshot {
1031
1061
  readonly transparent?: boolean | undefined;
1032
1062
  }
1033
1063
 
1064
+ /**
1065
+ * One producer-selected scene-index program, retaining the effective Pass
1066
+ * kind so record does not infer shadow/depth semantics from an authored name.
1067
+ */
1068
+ export interface MaterialSceneIndexProgramKey {
1069
+ readonly specializationKey: string;
1070
+ readonly pass: 'forward' | 'shadow' | 'depth';
1071
+ }
1072
+
1034
1073
  export interface MaterialCacheChainIdentity {
1035
1074
  readonly asset: MaterialAsset;
1036
1075
  readonly parentGuid: string | undefined;
@@ -1188,6 +1227,11 @@ export interface ExtractedFrame {
1188
1227
  * three-bucket model per plan-strategy D-3.
1189
1228
  */
1190
1229
  readonly dispatch: DispatchEntry[];
1230
+ readonly shadowCasterEntityKeys: ReadonlySet<number>;
1231
+ /** ShadowCaster ownership keyed by concrete draw item and pass. */
1232
+ readonly shadowCasterDrawKeys: ReadonlySet<string>;
1233
+ /** Structured ShadowCaster ownership facts retained for exact residual routing. */
1234
+ readonly shadowCasterMembership?: readonly ShadowCasterMembership[];
1191
1235
  readonly skylight: SkylightSnapshot | undefined;
1192
1236
  readonly skylightCount: number;
1193
1237
  /** World-local diffuse probe candidates; never a direct-light slot. */
@@ -1207,6 +1251,8 @@ export interface ExtractedFrame {
1207
1251
  readonly frustumStats: { readonly culled: number; readonly total: number };
1208
1252
  /** Candidate entities rejected by author visibility before resource parsing. */
1209
1253
  readonly visibilityStats: { readonly explicitlyHidden: number };
1254
+ /** Detached material-source probe accounting for this extraction. */
1255
+ readonly materialTextureSources?: MaterialTextureSourceStats;
1210
1256
  /**
1211
1257
  * Per-frame post-process params snapshot collected from PostProcessParams
1212
1258
  * entities (D-1: data-driven params channel). Maps shader id to the
@@ -1223,6 +1269,35 @@ export interface ExtractedFrame {
1223
1269
  readonly hiddenEntityReports: readonly RenderFeatureHiddenEntityReport[];
1224
1270
  }
1225
1271
 
1272
+ /** Extracted ownership fact for one concrete ShadowCaster pass. */
1273
+ export interface ShadowCasterMembership {
1274
+ readonly worldEntity: number;
1275
+ readonly renderableIndex: number;
1276
+ readonly drawItemIndex: number;
1277
+ readonly materialHandle: number;
1278
+ readonly passIndex: number;
1279
+ readonly materialShaderId?: string;
1280
+ /** Selected authored ShadowCaster entry points, when published. */
1281
+ readonly vertexEntry?: string;
1282
+ readonly fragmentEntry?: string;
1283
+ readonly renderState?: MaterialRenderState;
1284
+ readonly cpuReason?: ShadowCasterCpuReason;
1285
+ /** Producer-owned result of the complete ShadowCaster admission check. */
1286
+ readonly gpuDrivenEligible?: boolean;
1287
+ }
1288
+
1289
+ /** Producer evidence for a concrete ShadowCaster pass that remains on CPU. */
1290
+ export type ShadowCasterCpuReason =
1291
+ | 'transparent'
1292
+ | 'morph'
1293
+ | 'unsupported-shader'
1294
+ | 'unsupported-render-state'
1295
+ | 'missing-skin-bounds'
1296
+ | 'missing-gpu-draw'
1297
+ | 'unprepared'
1298
+ | 'prepared-contract'
1299
+ | 'multi-pass';
1300
+
1226
1301
  export type CameraTargetUpdate = 'once' | 'on-demand' | 'continuous';
1227
1302
 
1228
1303
  export interface CameraTargetCandidate {
@@ -1376,6 +1451,52 @@ export function materialTextureFields(
1376
1451
  return fields;
1377
1452
  }
1378
1453
 
1454
+ function declaredMaterialTextureFields(
1455
+ shaderId: string | undefined,
1456
+ paramSchema: readonly ParamSchemaEntry[] | undefined,
1457
+ assets: AssetRegistry,
1458
+ ): ReadonlySet<string> | undefined {
1459
+ return materialTextureFields(
1460
+ shaderId,
1461
+ paramSchema !== undefined
1462
+ ? derive(paramSchema).textureFieldNames
1463
+ : shaderId !== undefined
1464
+ ? assets.materialShaderTextureFieldNames(shaderId)
1465
+ : undefined,
1466
+ );
1467
+ }
1468
+
1469
+ /** Preserve authored-vs-default intent for the GPU resource readiness gate. */
1470
+ export function collectAuthoredMaterialTextureFields(
1471
+ values: Readonly<Record<string, unknown>>,
1472
+ shaderId: string | undefined,
1473
+ paramSchema: readonly ParamSchemaEntry[] | undefined,
1474
+ assets: AssetRegistry,
1475
+ ): ReadonlySet<string> | undefined {
1476
+ const fields = declaredMaterialTextureFields(shaderId, paramSchema, assets);
1477
+ if (fields === undefined) return undefined;
1478
+ const authored = new Set<string>();
1479
+ for (const field of fields) {
1480
+ if (Object.hasOwn(values, field)) authored.add(field);
1481
+ }
1482
+ return authored.size === 0 ? undefined : authored;
1483
+ }
1484
+
1485
+ /** Preserve explicit sampler intent; omitted samplers use the default sampler. */
1486
+ export function collectAuthoredMaterialSamplerFields(
1487
+ values: Readonly<Record<string, unknown>>,
1488
+ textureFields: ReadonlySet<string> | undefined,
1489
+ ): ReadonlySet<string> | undefined {
1490
+ const authored = new Set<string>();
1491
+ for (const field of textureFields ?? []) {
1492
+ if (materialTextureValue(values[field])?.sampler !== undefined) authored.add(field);
1493
+ }
1494
+ if (Object.hasOwn(values, 'sampler') && values.sampler !== undefined) {
1495
+ authored.add('baseColorTexture');
1496
+ }
1497
+ return authored.size === 0 ? undefined : authored;
1498
+ }
1499
+
1379
1500
  /**
1380
1501
  * The authored material surface uses the module IDs declared by built-in WGSL
1381
1502
  * sources. Runtime pipeline caches still use the existing engine registration
@@ -1419,28 +1540,85 @@ export function materialProgramKeysForMaterial(
1419
1540
  assets: AssetRegistry,
1420
1541
  context: MaterialCookProgramContext | undefined,
1421
1542
  ): Readonly<Record<string, string>> | undefined {
1543
+ return materialProgramKeysForAddress(material, assets, context, 'direct');
1544
+ }
1545
+
1546
+ /** Resolve the producer's scene-index program key for each cooked Pass. */
1547
+ export function materialSceneIndexProgramKeysForMaterial(
1548
+ material: MaterialAsset,
1549
+ assets: AssetRegistry,
1550
+ context: MaterialCookProgramContext | undefined,
1551
+ ): Readonly<Record<string, MaterialSceneIndexProgramKey>> | undefined {
1422
1552
  const projection = assets.getMaterialProjectionForPayload(material);
1423
1553
  if (projection === undefined) return undefined;
1424
1554
  if (context === undefined)
1425
1555
  throw new Error('Published material selection requires renderer-owned compiler context');
1426
- return Object.fromEntries(
1427
- projection.passes.map((pass) => {
1428
- const mode = String(
1429
- (pass.renderState?.tags as Record<string, unknown> | undefined)?.LightMode ?? pass.name,
1430
- );
1431
- const selectedContext: MaterialCookProgramContext = {
1432
- ...context,
1433
- pass: /shadow/i.test(mode) ? 'shadow' : /depth/i.test(mode) ? 'depth' : 'forward',
1434
- pipeline: /deferred|gbuffer/i.test(mode) ? 'deferred' : context.pipeline,
1435
- };
1436
- return [
1556
+ const entries: Record<string, MaterialSceneIndexProgramKey> = {};
1557
+ for (const pass of projection.passes) {
1558
+ const mode = String(
1559
+ (pass.renderState?.tags as Record<string, unknown> | undefined)?.LightMode ?? pass.name,
1560
+ );
1561
+ const passKind = /shadow/i.test(mode)
1562
+ ? ('shadow' as const)
1563
+ : /depth/i.test(mode)
1564
+ ? ('depth' as const)
1565
+ : ('forward' as const);
1566
+ const selectedContext: MaterialCookProgramContext = {
1567
+ ...context,
1568
+ pass: passKind,
1569
+ pipeline: /deferred|gbuffer/i.test(mode) ? 'deferred' : context.pipeline,
1570
+ };
1571
+ try {
1572
+ const selected = selectMaterialPassProgram(
1573
+ projection,
1437
1574
  pass.name,
1438
- selectMaterialPassProgram(projection, pass.name, selectedContext).specializationKey,
1439
- ];
1440
- }),
1575
+ selectedContext,
1576
+ 'scene-index',
1577
+ );
1578
+ entries[pass.name] = { specializationKey: selected.specializationKey, pass: passKind };
1579
+ } catch (error) {
1580
+ if (!isMissingMaterialProgram(error)) throw error;
1581
+ }
1582
+ }
1583
+ return Object.keys(entries).length === 0 ? undefined : entries;
1584
+ }
1585
+
1586
+ function isMissingMaterialProgram(error: unknown): boolean {
1587
+ return (
1588
+ error !== null &&
1589
+ typeof error === 'object' &&
1590
+ (error as { readonly code?: unknown }).code === 'material-specialization-not-cooked'
1441
1591
  );
1442
1592
  }
1443
1593
 
1594
+ function materialProgramKeysForAddress(
1595
+ material: MaterialAsset,
1596
+ assets: AssetRegistry,
1597
+ context: MaterialCookProgramContext | undefined,
1598
+ address: 'direct' | 'scene-index',
1599
+ ): Readonly<Record<string, string>> | undefined {
1600
+ const projection = assets.getMaterialProjectionForPayload(material);
1601
+ if (projection === undefined) return undefined;
1602
+ if (context === undefined)
1603
+ throw new Error('Published material selection requires renderer-owned compiler context');
1604
+ const entries: [string, string][] = [];
1605
+ for (const pass of projection.passes) {
1606
+ const mode = String(
1607
+ (pass.renderState?.tags as Record<string, unknown> | undefined)?.LightMode ?? pass.name,
1608
+ );
1609
+ const selectedContext: MaterialCookProgramContext = {
1610
+ ...context,
1611
+ pass: /shadow/i.test(mode) ? 'shadow' : /depth/i.test(mode) ? 'depth' : 'forward',
1612
+ pipeline: /deferred|gbuffer/i.test(mode) ? 'deferred' : context.pipeline,
1613
+ };
1614
+ entries.push([
1615
+ pass.name,
1616
+ selectMaterialPassProgram(projection, pass.name, selectedContext, address).specializationKey,
1617
+ ]);
1618
+ }
1619
+ return entries.length === 0 ? undefined : Object.fromEntries(entries);
1620
+ }
1621
+
1444
1622
  export function runtimeMaterialShaderIdForMaterial(
1445
1623
  passes: readonly MaterialPass[],
1446
1624
  programs: Readonly<Record<string, string>> | undefined,
@@ -1507,6 +1685,62 @@ export function pipelineRenderState(
1507
1685
  };
1508
1686
  }
1509
1687
 
1688
+ export function shadowCasterCpuReason(
1689
+ material: MaterialSnapshot,
1690
+ draw: GpuDrivenDrawSnapshot | undefined,
1691
+ shadowEntries: readonly DispatchEntry[],
1692
+ morph: MorphSnapshot | undefined,
1693
+ skin: SkinPaletteReceipt | undefined,
1694
+ ): ShadowCasterCpuReason | undefined {
1695
+ if (shadowEntries.length !== 1) return 'multi-pass';
1696
+ if (material.transparent === true || material.renderState?.blend !== undefined) {
1697
+ return 'transparent';
1698
+ }
1699
+ if (morph !== undefined) return 'morph';
1700
+ const shadowEntry = shadowEntries[0];
1701
+ if (shadowEntry?.renderState !== undefined) return 'unsupported-render-state';
1702
+ if (draw === undefined) return 'missing-gpu-draw';
1703
+ if (draw.prepared === undefined) return 'unprepared';
1704
+ const preparedMaterial = draw.prepared.identity.material;
1705
+ const preparedDeformation = draw.prepared.identity.deformation;
1706
+ const materialContractMatches = preparedMaterial === material.materialShaderId;
1707
+ const deformationContractMatches =
1708
+ (skin === undefined && preparedDeformation === 'rigid') ||
1709
+ (skin !== undefined && preparedDeformation === 'skin');
1710
+ if (!materialContractMatches || !deformationContractMatches) return 'prepared-contract';
1711
+ if (preparedDeformation === 'skin' && !hasFiniteOrderedSkinBounds(skin?.bounds)) {
1712
+ return 'missing-skin-bounds';
1713
+ }
1714
+ return undefined;
1715
+ }
1716
+
1717
+ function hasFiniteOrderedSkinBounds(bounds: Float32Array | undefined): bounds is Float32Array {
1718
+ if (bounds === undefined || bounds.length !== 6) return false;
1719
+ const minX = bounds[0];
1720
+ const minY = bounds[1];
1721
+ const minZ = bounds[2];
1722
+ const maxX = bounds[3];
1723
+ const maxY = bounds[4];
1724
+ const maxZ = bounds[5];
1725
+ return (
1726
+ minX !== undefined &&
1727
+ minY !== undefined &&
1728
+ minZ !== undefined &&
1729
+ maxX !== undefined &&
1730
+ maxY !== undefined &&
1731
+ maxZ !== undefined &&
1732
+ Number.isFinite(minX) &&
1733
+ Number.isFinite(minY) &&
1734
+ Number.isFinite(minZ) &&
1735
+ Number.isFinite(maxX) &&
1736
+ Number.isFinite(maxY) &&
1737
+ Number.isFinite(maxZ) &&
1738
+ minX <= maxX &&
1739
+ minY <= maxY &&
1740
+ minZ <= maxZ
1741
+ );
1742
+ }
1743
+
1510
1744
  /**
1511
1745
  * tweak-20260627-model-loading-smoke-build-perf M4: per-World intern cache for
1512
1746
  * the loadByGuid texture/sampler resolution path. A MaterialAsset's
@@ -1663,20 +1897,82 @@ export function collectMaterialTextureCoordinates(
1663
1897
  return out;
1664
1898
  }
1665
1899
 
1900
+ /**
1901
+ * Return the schema-owned fields that may carry a texture source handle.
1902
+ * Numeric material values are otherwise scalar parameters (roughness,
1903
+ * metallic, custom steps, ...), so probing them through SharedRefStore is
1904
+ * both wasted work and an accidental dependency on slot-number collisions.
1905
+ */
1906
+ export function materialTextureSourceFields(
1907
+ schema: readonly ParamSchemaEntry[] | undefined,
1908
+ ): ReadonlySet<string> | undefined {
1909
+ if (schema === undefined) return undefined;
1910
+ const fields = new Set<string>();
1911
+ for (const entry of schema) {
1912
+ if (entry.type.startsWith('texture')) fields.add(entry.name);
1913
+ }
1914
+ return fields;
1915
+ }
1916
+
1917
+ export interface MaterialTextureSourceStats {
1918
+ sourceFieldsVisited: number;
1919
+ numericSharedRefProbes: number;
1920
+ sourceCacheHits: number;
1921
+ sourceCacheMisses: number;
1922
+ producerRoutes: Record<string, number>;
1923
+ }
1924
+
1925
+ /**
1926
+ * Extract-local cache for numeric shared references. `null` is a deliberate
1927
+ * negative entry: a handle that is not a render-target source must not be
1928
+ * resolved repeatedly for every material field in the same frame.
1929
+ */
1930
+ export type MaterialTextureSourceCache = Map<number, RenderTargetTextureSource | null>;
1931
+
1666
1932
  export function collectMaterialTextureSources(
1667
1933
  values: Readonly<Record<string, unknown>>,
1668
1934
  world: World,
1935
+ textureFields?: ReadonlySet<string>,
1936
+ stats?: MaterialTextureSourceStats,
1937
+ cache?: MaterialTextureSourceCache,
1669
1938
  ): Map<string, RenderTargetTextureSource> {
1670
1939
  const out = new Map<string, RenderTargetTextureSource>();
1671
1940
  for (const [field, value] of Object.entries(values)) {
1672
- const reference = materialTextureRef(value);
1941
+ const structured = materialTextureValue(value);
1942
+ const schemaKnown = textureFields !== undefined;
1943
+ const schemaAdmitted = textureFields?.has(field) === true;
1944
+ // With a known schema, only producer-admitted texture fields may carry a
1945
+ // source handle. Without a schema, retain the historical numeric parse so
1946
+ // an older producer can still publish a direct shared-ref value; its
1947
+ // structured form is accepted on the same conservative path.
1948
+ if (schemaKnown && !schemaAdmitted) continue;
1949
+ const reference = structured?.texture ?? value;
1950
+ if (stats !== undefined) stats.sourceFieldsVisited += 1;
1673
1951
  if (typeof reference !== 'number') continue;
1674
- const resolved = world.sharedRefs.resolve<
1675
- 'RenderTargetTextureSource',
1676
- RenderTargetTextureSource
1677
- >(toShared<'RenderTargetTextureSource'>(reference));
1678
- if (!resolved.ok || resolveRenderTargetMaterialSource(resolved.value) === undefined) continue;
1679
- out.set(field, resolved.value);
1952
+ if (stats !== undefined) stats.numericSharedRefProbes += 1;
1953
+ let source: RenderTargetTextureSource | undefined;
1954
+ if (cache?.has(reference) === true) {
1955
+ if (stats !== undefined) stats.sourceCacheHits += 1;
1956
+ source = cache.get(reference) ?? undefined;
1957
+ } else {
1958
+ if (stats !== undefined) stats.sourceCacheMisses += 1;
1959
+ const resolved = world.sharedRefs.resolve<
1960
+ 'RenderTargetTextureSource',
1961
+ RenderTargetTextureSource
1962
+ >(toShared<'RenderTargetTextureSource'>(reference));
1963
+ if (!resolved.ok) {
1964
+ cache?.set(reference, null);
1965
+ } else {
1966
+ const binding = resolveRenderTargetMaterialSource(resolved.value);
1967
+ cache?.set(reference, binding === undefined ? null : resolved.value);
1968
+ source = binding === undefined ? undefined : resolved.value;
1969
+ }
1970
+ }
1971
+ if (source === undefined) continue;
1972
+ if (stats !== undefined) {
1973
+ stats.producerRoutes.renderTarget = (stats.producerRoutes.renderTarget ?? 0) + 1;
1974
+ }
1975
+ out.set(field, source);
1680
1976
  }
1681
1977
  return out;
1682
1978
  }
@@ -1764,6 +2060,27 @@ export function isEngineInjectedTextureField(
1764
2060
  return isStandardPbrMaterialShader(shaderId) && ENGINE_INJECTED_TEXTURE_FIELDS.has(fieldName);
1765
2061
  }
1766
2062
 
2063
+ export function materialStandardTextureMask(
2064
+ parameters: readonly MaterialParameter[] | undefined,
2065
+ shaderId: string | undefined,
2066
+ values: Readonly<Record<string, unknown>>,
2067
+ ): number | undefined {
2068
+ return isCanonicalStandardPbrMaterialShader(shaderId)
2069
+ ? standardTextureMask(
2070
+ // Canonical materials may provide values without redeclaring the root
2071
+ // schema. Pruning must agree with the texture binder in that route too.
2072
+ DEFAULT_STANDARD_PBR_PARAM_SCHEMA.filter(
2073
+ (entry) =>
2074
+ entry.type === 'texture2d' &&
2075
+ (values[entry.name] !== undefined ||
2076
+ parameters?.some(
2077
+ (parameter) => parameter.name === entry.name && parameter.default !== undefined,
2078
+ )),
2079
+ ),
2080
+ )
2081
+ : undefined;
2082
+ }
2083
+
1767
2084
  /**
1768
2085
  * Project one material's authoring parameters into the runtime ABI.
1769
2086
  *
@@ -1953,6 +2270,8 @@ export function resolveMaterialSnapshot(
1953
2270
  materialSnapshotCache?: MaterialSnapshotCache,
1954
2271
  persistentMaterialSnapshotCache?: MaterialSnapshotCache,
1955
2272
  materialContext?: MaterialCookProgramContext,
2273
+ materialTextureSourceStats?: MaterialTextureSourceStats,
2274
+ materialTextureSourceCache?: MaterialTextureSourceCache,
1956
2275
  ): MaterialSnapshot {
1957
2276
  if (handleRaw === 0) return defaultMaterialSnapshot(handleRaw);
1958
2277
  const cached = materialSnapshotCache?.get(handleRaw);
@@ -1985,6 +2304,11 @@ export function resolveMaterialSnapshot(
1985
2304
  const resolved = resolvedResult.value;
1986
2305
  const allPasses = resolved.passes;
1987
2306
  const materialProgramKeys = materialProgramKeysForMaterial(asset, assetsRef, materialContext);
2307
+ const materialSceneIndexProgramKeys = materialSceneIndexProgramKeysForMaterial(
2308
+ asset,
2309
+ assetsRef,
2310
+ materialContext,
2311
+ );
1988
2312
  const authoredFirstPassShader = runtimeMaterialShaderIdForMaterial(allPasses, undefined);
1989
2313
  const firstPassShader = runtimeMaterialShaderIdForMaterial(allPasses, materialProgramKeys);
1990
2314
  const pv = materialValuesToLinearRuntime(
@@ -2054,7 +2378,13 @@ export function resolveMaterialSnapshot(
2054
2378
  const samplerHandles = collectMaterialTextureSamplers(pv, (value) =>
2055
2379
  resolveTexLike(materialTextureRef(value), 'SamplerAsset'),
2056
2380
  );
2057
- const textureSources = collectMaterialTextureSources(pv, world);
2381
+ const textureSources = collectMaterialTextureSources(
2382
+ pv,
2383
+ world,
2384
+ materialTextureSourceFields(materialParamSchema.length > 0 ? materialParamSchema : undefined),
2385
+ materialTextureSourceStats,
2386
+ materialTextureSourceCache,
2387
+ );
2058
2388
  const emissiveTextureHandle = resolveTexLike(
2059
2389
  materialTextureRef(pv.emissiveTexture),
2060
2390
  'TextureAsset',
@@ -2083,10 +2413,12 @@ export function resolveMaterialSnapshot(
2083
2413
  normalScale: normalScalePv,
2084
2414
  materialShaderId: firstPassShader,
2085
2415
  materialProgramKeys,
2416
+ materialSceneIndexProgramKeys,
2086
2417
  materialHandle: handleRaw,
2087
2418
  renderState: pipelineRenderState(allPasses[0]?.renderState),
2088
2419
  paramSnapshot: paramSnap,
2089
2420
  ...(materialParamSchema.length > 0 && { materialParamSchema }),
2421
+ standardTextureMask: materialStandardTextureMask(resolved.parameters, firstPassShader, pv),
2090
2422
  ...(textureCoordinates.size > 0 && { textureCoordinates }),
2091
2423
  ...(textureHandles.size > 0 && { textureHandles }),
2092
2424
  ...(textureSources.size > 0 && { textureSources }),
@@ -2289,41 +2621,15 @@ export function pssmSplit(
2289
2621
  // requirements §5.3): 6-face view-proj matrix table for one omnidirectional
2290
2622
  // shadow caster.
2291
2623
  //
2292
- // Face order matches WebGPU cube layer convention (also LearnOpenGL 5.3.2):
2293
- // 0 (+X) | look=(+1, 0, 0) | up=(0, -1, 0)
2294
- // 1 (-X) | look=(-1, 0, 0) | up=(0, -1, 0)
2295
- // 2 (+Y) | look=(0, +1, 0) | up=(0, 0, +1)
2296
- // 3 (-Y) | look=(0, -1, 0) | up=(0, 0, -1)
2297
- // 4 (+Z) | look=(0, 0, +1) | up=(0, -1, 0)
2298
- // 5 (-Z) | look=(0, 0, -1) | up=(0, -1, 0)
2299
- //
2300
- // Projection: WebGPU [0, 1] NDC perspective (mat4.perspective short name).
2301
- // fov=90deg, aspect=1, near/far from PointLightShadow component.
2302
- const POINT_SHADOW_FACE_LOOK: readonly Vec3[] = [
2303
- vec3.create(1, 0, 0),
2304
- vec3.create(-1, 0, 0),
2305
- vec3.create(0, 1, 0),
2306
- vec3.create(0, -1, 0),
2307
- vec3.create(0, 0, 1),
2308
- vec3.create(0, 0, -1),
2309
- ];
2310
- const POINT_SHADOW_FACE_UP: readonly Vec3[] = [
2311
- vec3.create(0, -1, 0),
2312
- vec3.create(0, -1, 0),
2313
- vec3.create(0, 0, 1),
2314
- vec3.create(0, 0, -1),
2315
- vec3.create(0, -1, 0),
2316
- vec3.create(0, -1, 0),
2317
- ];
2318
-
2319
2624
  /**
2320
2625
  * Build 6 face view-proj matrices for an omnidirectional shadow caster
2321
2626
  * (point-light cube map). Returns 6 mat4 (column-major 16-float each) in face
2322
- * order [+X, -X, +Y, -Y, +Z, -Z] matching WebGPU cube layer convention.
2627
+ * order [+X, -X, +Y, -Y, +Z, -Z] matching the WebGPU cube-camera layer
2628
+ * convention.
2323
2629
  *
2324
- * Each matrix is `proj * view` where:
2325
- * - `view = lookAt(lightPos, lightPos + faceLook[i], faceUp[i])`
2326
- * - `proj = perspective(PI/2, 1, near, far)` (WebGPU [0, 1] NDC short name)
2630
+ * Derive face directions from the shared CubeCamera owner, then reflect clip X
2631
+ * to match WebGPU cubemap texel orientation. The point-shadow raster lane
2632
+ * mirrors authored front-face winding when it uses these reflected matrices.
2327
2633
  *
2328
2634
  * The returned `Mat4[]` length is always exactly 6. Caller can flatten into a
2329
2635
  * 96-float (6 mat4) Float32Array for UBO upload (T-M1-7).
@@ -2333,29 +2639,10 @@ const POINT_SHADOW_FACE_UP: readonly Vec3[] = [
2333
2639
  * @param far far plane distance (PointLightShadow.farPlane)
2334
2640
  */
2335
2641
  export function buildPointShadowMatrices(lightPos: Vec3, near: number, far: number): Mat4[] {
2336
- const fovY = Math.PI / 2; // 90 deg
2337
- const aspect = 1;
2338
- const proj = mat4.create();
2339
- mat4.perspective(proj, fovY, aspect, near, far);
2340
-
2341
- const out: Mat4[] = [];
2342
- for (let i = 0; i < 6; i++) {
2343
- // biome-ignore lint/style/noNonNullAssertion: i in [0..6) and arrays are length-6 const
2344
- const look = POINT_SHADOW_FACE_LOOK[i]!;
2345
- // biome-ignore lint/style/noNonNullAssertion: i in [0..6) and arrays are length-6 const
2346
- const up = POINT_SHADOW_FACE_UP[i]!;
2347
- const target = vec3.create(
2348
- (lightPos[0] ?? 0) + (look[0] ?? 0),
2349
- (lightPos[1] ?? 0) + (look[1] ?? 0),
2350
- (lightPos[2] ?? 0) + (look[2] ?? 0),
2351
- );
2352
- const view = mat4.create();
2353
- mat4.lookAt(view, lightPos, target, up);
2354
- const vp = mat4.create();
2355
- mat4.multiply(vp, proj, view);
2356
- out.push(vp);
2357
- }
2358
- return out;
2642
+ return buildCubeCameraFaceViews({ position: lightPos, near, far }).map(({ viewProjection }) => {
2643
+ for (const offset of [0, 4, 8, 12]) viewProjection[offset] = -(viewProjection[offset] ?? 0);
2644
+ return viewProjection;
2645
+ });
2359
2646
  }
2360
2647
 
2361
2648
  /**
@@ -2502,7 +2789,11 @@ export function computeDirectionalCsm(
2502
2789
  resultLightViewProjs.push(new Float32Array(16));
2503
2790
  continue;
2504
2791
  }
2505
- const cascadeNear = cIdx === 0 ? sNear : (splits[cIdx - 1] ?? sFar);
2792
+ // The receiver blends into this cascade before the preceding split.
2793
+ // Fit that same overlap instead of sampling outside the next projection.
2794
+ const previousSplit = splits[cIdx - 1] ?? sNear;
2795
+ const cascadeNear =
2796
+ cIdx === 0 ? sNear : Math.max(sNear, previousSplit * (1 - config.cascadeBlend));
2506
2797
  const cascadeFar = splits[cIdx] ?? sFar;
2507
2798
  const corners = computeFrustumCorners(
2508
2799
  cameraVP,
@@ -2544,7 +2835,7 @@ export function computeDirectionalCsm(
2544
2835
  minY,
2545
2836
  maxY,
2546
2837
  minZ,
2547
- maxZ,
2838
+ maxZ: nearZ,
2548
2839
  });
2549
2840
  resultLightViewProjs.push(new Float32Array(mat4.multiply(mat4.create(), orthoProj, lightView)));
2550
2841
  }
@@ -2581,6 +2872,8 @@ export function computeDirectionalCsm(
2581
2872
  export interface ExtractFramesOwner {
2582
2873
  readonly cameraOwner: number;
2583
2874
  readonly resourceOwner: number;
2875
+ /** Explicit display-camera entity selected by the frame owner. */
2876
+ readonly cameraEntityKey?: number;
2584
2877
  }
2585
2878
 
2586
2879
  export interface PreparedExtractContext {
@@ -2593,18 +2886,28 @@ export interface PreparedExtractContext {
2593
2886
  readonly resourceOwnerFog: FogFrame | null | undefined;
2594
2887
  readonly cull: 'self' | 'none' | 'external';
2595
2888
  readonly cullCameras: readonly CameraSnapshot[] | undefined;
2889
+ /** Explicit display-camera entity for this world's camera-owner extract. */
2890
+ readonly cameraEntityKey?: number;
2596
2891
  readonly renderables: 'full' | 'none';
2597
- /** Restrict renderable extraction to these entities while still reading frame resources. */
2598
2892
  readonly renderableEntities: ReadonlySet<number> | undefined;
2599
- /** Keep authored-hidden renderables in the persistent source projection. */
2600
2893
  readonly retainHidden: boolean;
2894
+ /** World identity used to form cross-world producer ownership keys. */
2895
+ readonly worldId: number;
2601
2896
  readonly visibility: VisibilitySnapshot;
2602
2897
  /** Producer-owned artifact lookup; extraction only, never record-time asset reads. */
2603
2898
  readonly getMaterialShaderArtifact:
2604
- | ((materialShaderId: string) => MaterialShaderArtifact | undefined)
2899
+ | ((
2900
+ materialShaderId: string,
2901
+ request?: {
2902
+ readonly vertexColorAvailable?: boolean;
2903
+ readonly deformation?: 'rigid' | 'skin';
2904
+ readonly pass?: 'forward' | 'shadow' | 'depth';
2905
+ readonly address?: 'direct' | 'scene-index';
2906
+ },
2907
+ ) => MaterialShaderArtifact | undefined)
2605
2908
  | undefined;
2606
2909
  /** Renderer-owned canonical source for explicit large instance collections. */
2607
- readonly instanceCollections: InstanceProjectionStore | undefined;
2910
+ readonly instanceCollections: InstanceCollectionStore | undefined;
2608
2911
  }
2609
2912
 
2610
2913
  const ALL_VISIBLE: VisibilitySnapshot = {
@@ -2619,16 +2922,41 @@ function collectCameraSnapshots(world: World): CameraSnapshot[] {
2619
2922
  const worldInternal = createWorldInternalView(world);
2620
2923
  const cameras: CameraSnapshot[] = [];
2621
2924
  const cameraQuery = world
2622
- .query({ read: [Camera], optional: [MotionBlur], with: [Transform, GlobalTransform] })
2925
+ .query({
2926
+ read: [Camera],
2927
+ optional: [MotionBlur, DynamicResolution, ScreenSpaceReflection],
2928
+ with: [Transform, GlobalTransform],
2929
+ })
2623
2930
  .unwrap();
2624
2931
  for (const row of cameraQuery) {
2625
2932
  const cam = row.get(Camera);
2626
2933
  const motionBlur = row.get(MotionBlur);
2934
+ const dynamicResolution = row.get(DynamicResolution);
2935
+ const screenSpaceReflection = row.get(ScreenSpaceReflection);
2627
2936
  const entity = row.entity;
2628
2937
  const view = worldInternal._getArrayView(entity, GlobalTransform, 'world');
2629
2938
  if (view === undefined) continue;
2630
2939
  const worldMat = new Float32Array(view);
2631
2940
  const target = resolveCameraTarget(world, cam.target);
2941
+ const hasNonDefaultOutput =
2942
+ cam.exposureMode !== CAMERA_EXPOSURE_MODE_MANUAL ||
2943
+ cam.exposure !== 1 ||
2944
+ cam.temperature !== 6504 ||
2945
+ cam.tint !== 0 ||
2946
+ cam.colorLut !== 0 ||
2947
+ cam.colorLutStrength !== 0;
2948
+ const output = hasNonDefaultOutput
2949
+ ? {
2950
+ exposure: cameraExposureFromColumns(cam),
2951
+ temperature: cam.temperature,
2952
+ tint: cam.tint,
2953
+ colorLut: cam.colorLut,
2954
+ colorLutStrength: cam.colorLutStrength,
2955
+ }
2956
+ : undefined;
2957
+ const antialias = antialiasFromF32(cam.antialias);
2958
+ const dynamicResolutionResult = validateDynamicResolutionCamera(dynamicResolution, antialias);
2959
+ if (!dynamicResolutionResult.ok) throw dynamicResolutionResult.error;
2632
2960
  cameras.push({
2633
2961
  entityKey: entity as number,
2634
2962
  ...(target === undefined ? {} : { target }),
@@ -2647,7 +2975,11 @@ function collectCameraSnapshots(world: World): CameraSnapshot[] {
2647
2975
  tonemap: tonemapFromF32(cam.tonemap),
2648
2976
  exposure: cam.exposure,
2649
2977
  whitePoint: cam.whitePoint,
2650
- antialias: antialiasFromF32(cam.antialias),
2978
+ ...(output === undefined ? {} : { output }),
2979
+ antialias,
2980
+ ...(dynamicResolutionResult.value === undefined
2981
+ ? {}
2982
+ : { dynamicResolution: dynamicResolutionResult.value }),
2651
2983
  bloom: bloomEnabledFromF32(cam.bloom),
2652
2984
  bloomThreshold: cam.bloomThreshold,
2653
2985
  bloomIntensity: cam.bloomIntensity,
@@ -2667,6 +2999,15 @@ function collectCameraSnapshots(world: World): CameraSnapshot[] {
2667
2999
  sampleCount: motionBlur.sampleCount,
2668
3000
  },
2669
3001
  }),
3002
+ ...(screenSpaceReflection === undefined
3003
+ ? {}
3004
+ : {
3005
+ screenSpaceReflection: {
3006
+ maxDistance: screenSpaceReflection.maxDistance,
3007
+ thickness: screenSpaceReflection.thickness,
3008
+ maxRoughness: screenSpaceReflection.maxRoughness,
3009
+ },
3010
+ }),
2670
3011
  });
2671
3012
  }
2672
3013
  return cameras;
@@ -2720,6 +3061,7 @@ export function collectReflectionProbeFacts(world: World): ReflectionProbeFact[]
2720
3061
  priority: probe.priority,
2721
3062
  intensity: probe.intensity,
2722
3063
  resolution: probe.resolution,
3064
+ boxProjection: probe.boxProjection,
2723
3065
  revision: probe.invalidationVersion,
2724
3066
  updateIntent: reflectionProbeUpdateIntentFromF32(probe.updateIntent),
2725
3067
  invalidationVersion: probe.invalidationVersion,
@@ -2733,16 +3075,23 @@ interface CameraRoleSelection {
2733
3075
  readonly auxiliary: readonly CameraSnapshot[];
2734
3076
  }
2735
3077
 
2736
- export function selectCameraRoles(world: World): CameraRoleSelection {
3078
+ export function selectCameraRoles(world: World, requestedEntityKey?: number): CameraRoleSelection {
2737
3079
  const cameras = collectCameraSnapshots(world);
2738
3080
  const displayEntities = cameras
2739
3081
  .filter((camera) => camera.target === undefined)
2740
3082
  .map((camera) => camera.entityKey ?? 0);
3083
+ const hasExplicitSelection = requestedEntityKey !== undefined;
2741
3084
  const activeCameraIndex = selectActiveCameraIndex(
2742
3085
  displayEntities,
2743
- getActiveCamera(world)?.entity,
3086
+ hasExplicitSelection ? requestedEntityKey : getActiveCamera(world)?.entity,
2744
3087
  );
2745
- const displayEntityKey = displayEntities[activeCameraIndex] ?? displayEntities[0];
3088
+ // An explicit FrameCamera selection is authoritative. If it does not name a
3089
+ // display camera, retain the existing no-camera error path instead of
3090
+ // silently selecting the first camera. ActiveCamera keeps its established
3091
+ // first-hit fallback when no explicit frame selection is supplied.
3092
+ const displayEntityKey = hasExplicitSelection
3093
+ ? displayEntities[activeCameraIndex]
3094
+ : (displayEntities[activeCameraIndex] ?? displayEntities[0]);
2746
3095
  const display =
2747
3096
  displayEntityKey === undefined
2748
3097
  ? []
@@ -2792,13 +3141,21 @@ export function prepareExtractContext(
2792
3141
  readonly resourceOwnerFog?: FogFrame | null;
2793
3142
  readonly cull?: 'self' | 'none' | 'external';
2794
3143
  readonly cullCameras?: readonly CameraSnapshot[];
3144
+ readonly cameraEntityKey?: number;
2795
3145
  readonly renderables?: 'full' | 'none';
2796
3146
  readonly renderableEntities?: ReadonlySet<number>;
2797
3147
  readonly retainHidden?: boolean;
3148
+ readonly worldId?: number;
2798
3149
  readonly getMaterialShaderArtifact?: (
2799
3150
  materialShaderId: string,
3151
+ request?: {
3152
+ readonly vertexColorAvailable?: boolean;
3153
+ readonly deformation?: 'rigid' | 'skin';
3154
+ readonly pass?: 'forward' | 'shadow' | 'depth';
3155
+ readonly address?: 'direct' | 'scene-index';
3156
+ },
2800
3157
  ) => MaterialShaderArtifact | undefined;
2801
- readonly instanceCollections?: InstanceProjectionStore;
3158
+ readonly instanceCollections?: InstanceCollectionStore;
2802
3159
  } = {},
2803
3160
  ): PreparedExtractContext {
2804
3161
  const renderables = options.renderables ?? 'full';
@@ -2810,7 +3167,9 @@ export function prepareExtractContext(
2810
3167
  resourceOwnerFog: options.resourceOwnerFog,
2811
3168
  cull: options.cull ?? 'self',
2812
3169
  cullCameras: options.cullCameras,
3170
+ ...(options.cameraEntityKey === undefined ? {} : { cameraEntityKey: options.cameraEntityKey }),
2813
3171
  renderables,
3172
+ worldId: options.worldId ?? 0,
2814
3173
  renderableEntities: options.renderableEntities,
2815
3174
  retainHidden: options.retainHidden ?? false,
2816
3175
  visibility: renderables === 'none' ? ALL_VISIBLE : resolveVisibility(world),