@forgeax/engine-render 0.1.21 → 0.1.24

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 (584) hide show
  1. package/README.md +281 -38
  2. package/dist/assembly/backend-contract.d.ts +13 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/bundler-contract.d.ts +9 -0
  5. package/dist/assembly/bundler-contract.d.ts.map +1 -0
  6. package/dist/assembly/device-feature-admission.d.ts +8 -0
  7. package/dist/assembly/device-feature-admission.d.ts.map +1 -1
  8. package/dist/assembly/extended-lighting-fallback.d.ts +13 -0
  9. package/dist/assembly/extended-lighting-fallback.d.ts.map +1 -0
  10. package/dist/assembly/factory.d.ts +7 -235
  11. package/dist/assembly/factory.d.ts.map +1 -1
  12. package/dist/assembly/host-contract.d.ts +10 -0
  13. package/dist/assembly/host-contract.d.ts.map +1 -1
  14. package/dist/assembly/material/assembly.d.ts +3 -2
  15. package/dist/assembly/material/assembly.d.ts.map +1 -1
  16. package/dist/assembly/material/standard-layer-projection.d.ts +10 -0
  17. package/dist/assembly/material/standard-layer-projection.d.ts.map +1 -0
  18. package/dist/assembly/material-shader-policy.d.ts +168 -0
  19. package/dist/assembly/material-shader-policy.d.ts.map +1 -0
  20. package/dist/assembly/material-shader-prewarm.d.ts +21 -0
  21. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -0
  22. package/dist/assembly/mesh-ssbo-grow.d.ts +88 -0
  23. package/dist/assembly/mesh-ssbo-grow.d.ts.map +1 -0
  24. package/dist/assembly/recovery/device-loss-fanout.d.ts +14 -0
  25. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -0
  26. package/dist/assembly/recovery/generation.d.ts +46 -0
  27. package/dist/assembly/recovery/generation.d.ts.map +1 -0
  28. package/dist/assembly/recovery/recovery-attempt.d.ts +63 -0
  29. package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -0
  30. package/dist/assembly/recovery/renderer-recover.d.ts +115 -0
  31. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -0
  32. package/dist/assembly/renderer-facade.d.ts +10 -0
  33. package/dist/assembly/renderer-facade.d.ts.map +1 -0
  34. package/dist/assembly/renderer-frame-transaction.d.ts +17 -0
  35. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  36. package/dist/assembly/renderer-helpers.d.ts +19 -0
  37. package/dist/assembly/renderer-helpers.d.ts.map +1 -0
  38. package/dist/assembly/renderer-lifecycle.d.ts +34 -0
  39. package/dist/assembly/renderer-lifecycle.d.ts.map +1 -1
  40. package/dist/assembly/shader-prewarm-policy.d.ts +15 -0
  41. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -0
  42. package/dist/assembly/webgpu-ready-contract.d.ts +9 -0
  43. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -0
  44. package/dist/assembly/webgpu-ready.d.ts +55 -0
  45. package/dist/assembly/webgpu-ready.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-renderer.d.ts +152 -0
  47. package/dist/assembly/webgpu-renderer.d.ts.map +1 -0
  48. package/dist/authoring.mjs +1 -1
  49. package/dist/{chunk-PCHBPYML.mjs → chunk-GE3SDD72.mjs} +37 -5
  50. package/dist/chunk-GE3SDD72.mjs.map +1 -0
  51. package/dist/chunk-KZFTK6DO.mjs +1191 -0
  52. package/dist/chunk-KZFTK6DO.mjs.map +1 -0
  53. package/dist/{chunk-FS2KNUQH.mjs → chunk-Q752SHI5.mjs} +332 -568
  54. package/dist/chunk-Q752SHI5.mjs.map +1 -0
  55. package/dist/{chunk-6OPXDQ2E.mjs → chunk-RR5L4SRS.mjs} +33 -294
  56. package/dist/chunk-RR5L4SRS.mjs.map +1 -0
  57. package/dist/chunk-TFH5I7JJ.mjs +296 -0
  58. package/dist/chunk-TFH5I7JJ.mjs.map +1 -0
  59. package/dist/chunk-UQYS7FRM.mjs +1003 -0
  60. package/dist/chunk-UQYS7FRM.mjs.map +1 -0
  61. package/dist/chunk-YKB5DQV7.mjs +345 -0
  62. package/dist/chunk-YKB5DQV7.mjs.map +1 -0
  63. package/dist/{chunk-5YADUCA7.mjs → chunk-YRUYGA4A.mjs} +1189 -1217
  64. package/dist/chunk-YRUYGA4A.mjs.map +1 -0
  65. package/dist/chunk-Z3YYH2MB.mjs +5082 -0
  66. package/dist/chunk-Z3YYH2MB.mjs.map +1 -0
  67. package/dist/cluster-binner.d.ts +5 -0
  68. package/dist/cluster-binner.d.ts.map +1 -1
  69. package/dist/components/index.d.ts +3 -0
  70. package/dist/components/index.d.ts.map +1 -1
  71. package/dist/components/light-helpers.d.ts +4 -0
  72. package/dist/components/light-helpers.d.ts.map +1 -1
  73. package/dist/components/light-probe.d.ts +9 -0
  74. package/dist/components/light-probe.d.ts.map +1 -0
  75. package/dist/components/rect-area-light.d.ts +12 -0
  76. package/dist/components/rect-area-light.d.ts.map +1 -0
  77. package/dist/components/scene-instance.d.ts +4 -0
  78. package/dist/components/scene-instance.d.ts.map +1 -1
  79. package/dist/components/spot-light.d.ts +3 -0
  80. package/dist/components/spot-light.d.ts.map +1 -1
  81. package/dist/construct-renderer.mjs +27276 -23232
  82. package/dist/construct-renderer.mjs.map +1 -1
  83. package/dist/device/device-scope.d.ts +2 -0
  84. package/dist/device/device-scope.d.ts.map +1 -1
  85. package/dist/device/gpu-residency.d.ts +32 -5
  86. package/dist/device/gpu-residency.d.ts.map +1 -1
  87. package/dist/device/lifecycle-transaction.d.ts +2 -0
  88. package/dist/device/lifecycle-transaction.d.ts.map +1 -0
  89. package/dist/environment/frame.d.ts +5 -0
  90. package/dist/environment/frame.d.ts.map +1 -1
  91. package/dist/environment/inspection.d.ts +7 -0
  92. package/dist/environment/inspection.d.ts.map +1 -1
  93. package/dist/environment/lifecycle.d.ts +20 -2
  94. package/dist/environment/lifecycle.d.ts.map +1 -1
  95. package/dist/errors/gpu-driven.d.ts +26 -0
  96. package/dist/errors/gpu-driven.d.ts.map +1 -0
  97. package/dist/errors/index.d.ts +1 -0
  98. package/dist/errors/index.d.ts.map +1 -1
  99. package/dist/errors/recover.d.ts +67 -3
  100. package/dist/errors/recover.d.ts.map +1 -1
  101. package/dist/errors/render.d.ts +39 -1
  102. package/dist/errors/render.d.ts.map +1 -1
  103. package/dist/extract/contracts.d.ts +899 -0
  104. package/dist/extract/contracts.d.ts.map +1 -0
  105. package/dist/extract/gpu-driven.d.ts +50 -0
  106. package/dist/extract/gpu-driven.d.ts.map +1 -0
  107. package/dist/extract/visibility.d.ts.map +1 -1
  108. package/dist/features/host.d.ts +2 -0
  109. package/dist/features/host.d.ts.map +1 -1
  110. package/dist/features/prepared-gpu-work.d.ts +3 -0
  111. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  112. package/dist/features/prepared-graphics-store.d.ts +2 -0
  113. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  114. package/dist/gpu-driven/batch-topology.d.ts +34 -0
  115. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  116. package/dist/gpu-driven/prepared-draw.d.ts +63 -0
  117. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -0
  118. package/dist/gpu-driven/production-raster.d.ts +126 -2
  119. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  120. package/dist/gpu-driven/view-gpu.d.ts +64 -1
  121. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  122. package/dist/gpu-scene-schema.d.ts +14 -0
  123. package/dist/gpu-scene-schema.d.ts.map +1 -1
  124. package/dist/gpu-scene.d.ts +9 -1
  125. package/dist/gpu-scene.d.ts.map +1 -1
  126. package/dist/gpu-usage.d.ts +0 -1
  127. package/dist/gpu-usage.d.ts.map +1 -1
  128. package/dist/hdrp-buffers.d.ts +3 -3
  129. package/dist/hdrp-buffers.d.ts.map +1 -1
  130. package/dist/ibl/IblPipelineCache.d.ts +7 -6
  131. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  132. package/dist/ibl/skylight-bind-group.d.ts +7 -1
  133. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  134. package/dist/index.d.ts +13 -2
  135. package/dist/index.d.ts.map +1 -1
  136. package/dist/index.mjs +90 -5
  137. package/dist/index.mjs.map +1 -1
  138. package/dist/inspection-types.d.ts +163 -1
  139. package/dist/inspection-types.d.ts.map +1 -1
  140. package/dist/internal.d.ts +9 -0
  141. package/dist/internal.d.ts.map +1 -1
  142. package/dist/internal.mjs +23 -2
  143. package/dist/internal.mjs.map +1 -1
  144. package/dist/light-buffer-layout.d.ts +60 -148
  145. package/dist/light-buffer-layout.d.ts.map +1 -1
  146. package/dist/materials.d.ts +34 -10
  147. package/dist/materials.d.ts.map +1 -1
  148. package/dist/mesh-material-bindings.d.ts +56 -0
  149. package/dist/mesh-material-bindings.d.ts.map +1 -1
  150. package/dist/occlusion-proxy.d.ts +4 -0
  151. package/dist/occlusion-proxy.d.ts.map +1 -0
  152. package/dist/pbr-pipeline.d.ts +58 -21
  153. package/dist/pbr-pipeline.d.ts.map +1 -1
  154. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  155. package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -1
  156. package/dist/pipeline/standard-lighting/light-frame.d.ts +3 -3
  157. package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -1
  158. package/dist/pipeline/standard-lighting/topology.d.ts +1 -1
  159. package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -1
  160. package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -1
  161. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  162. package/dist/pipeline-builder.d.ts +2 -0
  163. package/dist/pipeline-builder.d.ts.map +1 -1
  164. package/dist/pipeline-spec.d.ts +1 -1
  165. package/dist/pipeline-spec.d.ts.map +1 -1
  166. package/dist/plugin.d.ts.map +1 -1
  167. package/dist/points-lines/prepare.d.ts +3 -0
  168. package/dist/points-lines/prepare.d.ts.map +1 -1
  169. package/dist/points-lines/standard-owner.d.ts +33 -0
  170. package/dist/points-lines/standard-owner.d.ts.map +1 -0
  171. package/dist/prepare/extended-lighting/ltc-resources.d.ts +31 -0
  172. package/dist/prepare/extended-lighting/ltc-resources.d.ts.map +1 -0
  173. package/dist/prepare/extended-lighting/resources.d.ts +72 -0
  174. package/dist/prepare/extended-lighting/resources.d.ts.map +1 -0
  175. package/dist/prepare/extended-lighting/spot-modifiers.d.ts +42 -0
  176. package/dist/prepare/extended-lighting/spot-modifiers.d.ts.map +1 -0
  177. package/dist/prepare/extended-lighting/state.d.ts +24 -0
  178. package/dist/prepare/extended-lighting/state.d.ts.map +1 -0
  179. package/dist/record/frame-lighting.d.ts +8 -6
  180. package/dist/record/frame-lighting.d.ts.map +1 -1
  181. package/dist/record/frame-snapshot.d.ts +55 -10
  182. package/dist/record/frame-snapshot.d.ts.map +1 -1
  183. package/dist/record/frame-targets.d.ts.map +1 -1
  184. package/dist/record/frame.d.ts +21 -5
  185. package/dist/record/frame.d.ts.map +1 -1
  186. package/dist/record/gpu-timing.d.ts +19 -7
  187. package/dist/record/gpu-timing.d.ts.map +1 -1
  188. package/dist/record/helpers.d.ts +0 -20
  189. package/dist/record/helpers.d.ts.map +1 -1
  190. package/dist/record/main-pass-geometry.d.ts +20 -2
  191. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  192. package/dist/record/main-pass-material.d.ts +10 -18
  193. package/dist/record/main-pass-material.d.ts.map +1 -1
  194. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  195. package/dist/record/main-pass.d.ts.map +1 -1
  196. package/dist/record/mesh-ssbo.d.ts +11 -3
  197. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  198. package/dist/record/recovery-pipeline.d.ts +30 -0
  199. package/dist/record/recovery-pipeline.d.ts.map +1 -0
  200. package/dist/record/render-context.d.ts +82 -9
  201. package/dist/record/render-context.d.ts.map +1 -1
  202. package/dist/record/shadow-pass.d.ts.map +1 -1
  203. package/dist/record/typed-frame-graph.d.ts +49 -2
  204. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  205. package/dist/record/view-ubo.d.ts +1 -2
  206. package/dist/record/view-ubo.d.ts.map +1 -1
  207. package/dist/recovery/render-system-candidate.d.ts +65 -0
  208. package/dist/recovery/render-system-candidate.d.ts.map +1 -0
  209. package/dist/reflection/inspection.d.ts +10 -0
  210. package/dist/reflection/inspection.d.ts.map +1 -0
  211. package/dist/reflection/projection.d.ts +49 -0
  212. package/dist/reflection/projection.d.ts.map +1 -1
  213. package/dist/reflection/record-owner.d.ts +60 -0
  214. package/dist/reflection/record-owner.d.ts.map +1 -0
  215. package/dist/render-contract.d.ts +78 -15
  216. package/dist/render-contract.d.ts.map +1 -1
  217. package/dist/render-pipeline.d.ts +7 -0
  218. package/dist/render-pipeline.d.ts.map +1 -1
  219. package/dist/render-system-extract-tail.d.ts +12 -0
  220. package/dist/render-system-extract-tail.d.ts.map +1 -0
  221. package/dist/render-system-extract.d.ts +252 -30
  222. package/dist/render-system-extract.d.ts.map +1 -1
  223. package/dist/render-system.d.ts +140 -5
  224. package/dist/render-system.d.ts.map +1 -1
  225. package/dist/scene/probe-blend-record.d.ts +22 -0
  226. package/dist/scene/probe-blend-record.d.ts.map +1 -0
  227. package/dist/scene/probe-blend.d.ts +142 -0
  228. package/dist/scene/probe-blend.d.ts.map +1 -0
  229. package/dist/scene/render-scene-types.d.ts +0 -6
  230. package/dist/scene/render-scene-types.d.ts.map +1 -1
  231. package/dist/scene/render-scene.d.ts +122 -9
  232. package/dist/scene/render-scene.d.ts.map +1 -1
  233. package/dist/scene/visibility/bounds.d.ts +20 -0
  234. package/dist/scene/visibility/bounds.d.ts.map +1 -0
  235. package/dist/scene/visibility/budget.d.ts +16 -0
  236. package/dist/scene/visibility/budget.d.ts.map +1 -0
  237. package/dist/scene/visibility/facet.d.ts +73 -0
  238. package/dist/scene/visibility/facet.d.ts.map +1 -0
  239. package/dist/scene/visibility/gpu-frame-timing.d.ts +41 -0
  240. package/dist/scene/visibility/gpu-frame-timing.d.ts.map +1 -0
  241. package/dist/scene/visibility/gpu-lod.d.ts +46 -0
  242. package/dist/scene/visibility/gpu-lod.d.ts.map +1 -0
  243. package/dist/scene/visibility/inspection.d.ts +132 -0
  244. package/dist/scene/visibility/inspection.d.ts.map +1 -0
  245. package/dist/scene/visibility/lod-selector.d.ts +25 -0
  246. package/dist/scene/visibility/lod-selector.d.ts.map +1 -0
  247. package/dist/scene/visibility/occlusion-confidence.d.ts +81 -0
  248. package/dist/scene/visibility/occlusion-confidence.d.ts.map +1 -0
  249. package/dist/scene/visibility/occlusion-pass.d.ts +57 -0
  250. package/dist/scene/visibility/occlusion-pass.d.ts.map +1 -0
  251. package/dist/scene/visibility/occlusion-query-pool.d.ts +57 -0
  252. package/dist/scene/visibility/occlusion-query-pool.d.ts.map +1 -0
  253. package/dist/scene/visibility/occlusion-runtime.d.ts +96 -0
  254. package/dist/scene/visibility/occlusion-runtime.d.ts.map +1 -0
  255. package/dist/scene/visibility/types.d.ts +34 -0
  256. package/dist/scene/visibility/types.d.ts.map +1 -0
  257. package/dist/ssr/admission.d.ts +122 -0
  258. package/dist/ssr/admission.d.ts.map +1 -0
  259. package/dist/ssr/composition.d.ts +32 -0
  260. package/dist/ssr/composition.d.ts.map +1 -0
  261. package/dist/ssr/errors.d.ts +39 -0
  262. package/dist/ssr/errors.d.ts.map +1 -0
  263. package/dist/ssr/identity.d.ts +13 -0
  264. package/dist/ssr/identity.d.ts.map +1 -0
  265. package/dist/systems/skin-palette-allocator.d.ts +1 -1
  266. package/dist/temporal/frame-coordinator.d.ts +13 -0
  267. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  268. package/dist/temporal/frame.d.ts +2 -0
  269. package/dist/temporal/frame.d.ts.map +1 -1
  270. package/dist/temporal/index.mjs +6 -5
  271. package/dist/temporal/taa-history-store.d.ts +15 -1
  272. package/dist/temporal/taa-history-store.d.ts.map +1 -1
  273. package/dist/temporal/transaction.d.ts +5 -0
  274. package/dist/temporal/transaction.d.ts.map +1 -1
  275. package/dist/temporal/view.d.ts +7 -0
  276. package/dist/temporal/view.d.ts.map +1 -1
  277. package/dist/tilemap-chunk-extract-system.d.ts +1 -1
  278. package/dist/typed-render-graph-primitives.d.ts +4 -0
  279. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  280. package/dist/volume/passes.d.ts +8 -4
  281. package/dist/volume/passes.d.ts.map +1 -1
  282. package/package.json +20 -20
  283. package/src/__tests__/cluster-grid-default-surface.unit.test.ts +5 -0
  284. package/src/__tests__/detached-inspection.integration.test.ts +6 -0
  285. package/src/__tests__/device-feature-admission.unit.test.ts +19 -1
  286. package/src/__tests__/device-loss-fanout.unit.test.ts +107 -0
  287. package/src/__tests__/device-scope-lifecycle.unit.test.ts +21 -0
  288. package/src/__tests__/direct-light-snapshot.unit.test.ts +59 -3
  289. package/src/__tests__/environment-generation.integration.test.ts +39 -0
  290. package/src/__tests__/evidence-identity.ts +13 -0
  291. package/src/__tests__/evidence-identity.unit.test.ts +24 -0
  292. package/src/__tests__/expose-renderer-errors.unit.test.ts +34 -0
  293. package/src/__tests__/extended-lighting-recovery.browser.test.ts +14 -0
  294. package/src/__tests__/extended-lighting-recovery.dawn.test.ts +14 -0
  295. package/src/__tests__/extended-lighting-recovery.integration.test.ts +81 -0
  296. package/src/__tests__/extended-lighting-resources.unit.test.ts +51 -0
  297. package/src/__tests__/extended-lighting-zero-feature.integration.test.ts +52 -0
  298. package/src/__tests__/factory-contract.integration.test.ts +154 -6
  299. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +4 -1
  300. package/src/__tests__/frame-observation.contract.test.ts +15 -0
  301. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
  302. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +1 -0
  303. package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +1 -0
  304. package/src/__tests__/gpu-driven-production.integration.test.ts +572 -9
  305. package/src/__tests__/gpu-driven-scaling.unit.test.ts +66 -2
  306. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +26 -1
  307. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +89 -2
  308. package/src/__tests__/gpu-driven-view.browser.test.ts +3 -3
  309. package/src/__tests__/gpu-driven-view.dawn.test.ts +3 -3
  310. package/src/__tests__/gpu-driven-view.unit.test.ts +50 -0
  311. package/src/__tests__/gpu-lod-evidence.ts +188 -0
  312. package/src/__tests__/gpu-lod-fallback.integration.test.ts +10 -0
  313. package/src/__tests__/gpu-lod-indirect.integration.test.ts +40 -0
  314. package/src/__tests__/gpu-lod-parity.dawn.test.ts +29 -0
  315. package/src/__tests__/gpu-lod-readiness.integration.test.ts +52 -0
  316. package/src/__tests__/gpu-lod-schema.unit.test.ts +66 -0
  317. package/src/__tests__/gpu-lod-selector.unit.test.ts +28 -0
  318. package/src/__tests__/gpu-lod-silhouette.browser.test.ts +13 -0
  319. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +66 -1
  320. package/src/__tests__/gpu-scene.dawn.test.ts +8 -1
  321. package/src/__tests__/gpu-scene.unit.test.ts +49 -3
  322. package/src/__tests__/ibl/face-uniforms.unit.test.ts +2 -0
  323. package/src/__tests__/ibl-residency-publication.unit.test.ts +113 -0
  324. package/src/__tests__/light-buffer-layout.unit.test.ts +113 -3
  325. package/src/__tests__/light-inspection.unit.test.ts +55 -0
  326. package/src/__tests__/light-resource-error.unit.test.ts +43 -0
  327. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +109 -0
  328. package/src/__tests__/lod-bounds.unit.test.ts +42 -0
  329. package/src/__tests__/lod-cpu-lane.integration.test.ts +55 -0
  330. package/src/__tests__/lod-cpu-no-change.perf.test.ts +19 -0
  331. package/src/__tests__/lod-gpu-frame-timing.unit.test.ts +49 -0
  332. package/src/__tests__/lod-multi-view.integration.test.ts +63 -0
  333. package/src/__tests__/lod-occlusion-device-loss.integration.test.ts +27 -0
  334. package/src/__tests__/lod-occlusion-final-decision.integration.test.ts +47 -0
  335. package/src/__tests__/lod-occlusion-inspection.integration.test.ts +217 -0
  336. package/src/__tests__/lod-occlusion-inspection.schema.test-d.ts +14 -0
  337. package/src/__tests__/lod-occlusion-inspection.unit.test.ts +72 -0
  338. package/src/__tests__/lod-occlusion-visual-evidence.ts +91 -0
  339. package/src/__tests__/lod-occlusion.browser.test.ts +15 -0
  340. package/src/__tests__/lod-occlusion.dawn.test.ts +20 -0
  341. package/src/__tests__/lod-selector.profile.test.ts +35 -0
  342. package/src/__tests__/lod-selector.unit.test.ts +68 -0
  343. package/src/__tests__/lod-visibility-identity.unit.test.ts +198 -0
  344. package/src/__tests__/lod-visibility-lifecycle.integration.test.ts +132 -0
  345. package/src/__tests__/ltc-resources.unit.test.ts +32 -0
  346. package/src/__tests__/material-contract-inventory.unit.test.ts +41 -9
  347. package/src/__tests__/material-cooked-projection.unit.test.ts +19 -1
  348. package/src/__tests__/material-static-dynamic-route.unit.test.ts +29 -0
  349. package/src/__tests__/material-stride-surface.unit.test.ts +7 -3
  350. package/src/__tests__/materials-standard-contract.unit.test.ts +104 -0
  351. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
  352. package/src/__tests__/occlusion-confidence.unit.test.ts +168 -0
  353. package/src/__tests__/occlusion-invalidation.integration.test.ts +37 -0
  354. package/src/__tests__/occlusion-pass-routing.unit.test.ts +16 -0
  355. package/src/__tests__/occlusion-pass.dawn.test.ts +20 -0
  356. package/src/__tests__/occlusion-pass.integration.test.ts +43 -0
  357. package/src/__tests__/occlusion-pass.rhi-null.test.ts +22 -0
  358. package/src/__tests__/occlusion-query-pool.rhi-null.test.ts +21 -0
  359. package/src/__tests__/occlusion-query-pool.unit.test.ts +95 -0
  360. package/src/__tests__/occlusion-query-ticket.integration.test.ts +47 -0
  361. package/src/__tests__/occlusion-query.dawn.test.ts +16 -0
  362. package/src/__tests__/occlusion-query.evidence.ts +178 -0
  363. package/src/__tests__/occlusion-query.rhi-null.test.ts +31 -0
  364. package/src/__tests__/occlusion-runtime.unit.test.ts +120 -0
  365. package/src/__tests__/physical-clearcoat.integration.test.ts +89 -0
  366. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
  367. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +1 -1
  368. package/src/__tests__/probe-bindings.unit.test.ts +200 -0
  369. package/src/__tests__/probe-blend-numeric.unit.test.ts +67 -0
  370. package/src/__tests__/probe-blend-oracle.unit.test.ts +136 -0
  371. package/src/__tests__/probe-capacity.integration.test.ts +97 -0
  372. package/src/__tests__/probe-recovery.integration.test.ts +104 -0
  373. package/src/__tests__/probe-scene-dirty.integration.test.ts +211 -0
  374. package/src/__tests__/profiler-phase-catalog.test.ts +4 -1
  375. package/src/__tests__/profiler-phase-token.test.ts +1 -0
  376. package/src/__tests__/recover-error-policy-owner.unit.test.ts +6 -3
  377. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +140 -0
  378. package/src/__tests__/rect-area-boundary.unit.test.ts +24 -0
  379. package/src/__tests__/reflection-fallback-graph.unit.test.ts +67 -0
  380. package/src/__tests__/reflection-fallback-inspection.unit.test.ts +77 -0
  381. package/src/__tests__/reflection-fallback-lifecycle.integration.test.ts +21 -0
  382. package/src/__tests__/reflection-fallback-projection.unit.test.ts +90 -0
  383. package/src/__tests__/reflection-fallback-source.unit.test.ts +32 -0
  384. package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
  385. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
  386. package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
  387. package/src/__tests__/render-feature-docs.unit.test.ts +12 -7
  388. package/src/__tests__/render-graph-fallback.integration.test.ts +24 -0
  389. package/src/__tests__/render-perf/extended-lighting.bench.test.ts +66 -0
  390. package/src/__tests__/render-scene-projection.unit.test.ts +447 -18
  391. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +160 -17
  392. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +47 -0
  393. package/src/__tests__/renderer-generation-assembly.unit.test.ts +77 -0
  394. package/src/__tests__/renderer-generation-failure.unit.test.ts +108 -0
  395. package/src/__tests__/renderer-producer-root-matrix.integration.test.ts +33 -0
  396. package/src/__tests__/renderer-recovery-capability-matrix.unit.test.ts +59 -0
  397. package/src/__tests__/renderer-recovery-contract.unit.test.ts +73 -0
  398. package/src/__tests__/renderer-recovery-lifecycle.unit.test.ts +216 -0
  399. package/src/__tests__/renderer-target-history-recovery.integration.test.ts +80 -0
  400. package/src/__tests__/shader-manifest-fixture.ts +13 -16
  401. package/src/__tests__/shader-stage-surface.unit.test.ts +1 -1
  402. package/src/__tests__/skin-motion-regression.unit.test.ts +22 -0
  403. package/src/__tests__/skinned-shadow-caster.test.ts +2 -2
  404. package/src/__tests__/spot-modifier-projection.unit.test.ts +70 -0
  405. package/src/__tests__/ssr-admission-matrix.integration.test.ts +206 -0
  406. package/src/__tests__/ssr-composition.unit.test.ts +46 -0
  407. package/src/__tests__/ssr-fallback-zero-work.bench.test.ts +94 -0
  408. package/src/__tests__/ssr-recovery-errors.unit.test.ts +58 -0
  409. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +67 -0
  410. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +7 -0
  411. package/src/__tests__/standard-layer-projection.unit.test.ts +23 -0
  412. package/src/__tests__/standard-lighting-inspection.integration.test.ts +1 -1
  413. package/src/__tests__/standard-lighting-write.unit.test.ts +66 -2
  414. package/src/__tests__/temporal-fallback-generation.integration.test.ts +16 -0
  415. package/src/__tests__/temporal-view.unit.test.ts +3 -3
  416. package/src/__tests__/transmission-prewarm.unit.test.ts +111 -32
  417. package/src/__tests__/visibility-budget.integration.test.ts +140 -0
  418. package/src/__tests__/visibility-budget.unit.test.ts +70 -0
  419. package/src/__tests__/visibility-extract.integration.test.ts +11 -6
  420. package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +6 -3
  421. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +31 -28
  422. package/src/__tests__/volumetric-fog-topology.unit.test.ts +3 -1
  423. package/src/assembly/backend-contract.ts +13 -0
  424. package/src/assembly/bundler-contract.ts +9 -0
  425. package/src/assembly/device-feature-admission.ts +26 -9
  426. package/src/assembly/extended-lighting-fallback.ts +216 -0
  427. package/src/assembly/factory.ts +81 -9634
  428. package/src/assembly/host-contract.ts +10 -0
  429. package/src/assembly/material/assembly.ts +18 -2
  430. package/src/assembly/material/standard-layer-projection.ts +16 -0
  431. package/src/assembly/material-shader-policy.ts +854 -0
  432. package/src/assembly/material-shader-prewarm.ts +88 -0
  433. package/src/assembly/mesh-ssbo-grow.ts +270 -0
  434. package/src/assembly/recovery/device-loss-fanout.ts +89 -0
  435. package/src/assembly/recovery/generation.ts +141 -0
  436. package/src/assembly/recovery/recovery-attempt.ts +800 -0
  437. package/src/assembly/recovery/renderer-recover.ts +906 -0
  438. package/src/assembly/renderer-facade.ts +342 -0
  439. package/src/assembly/renderer-frame-transaction.ts +45 -0
  440. package/src/assembly/renderer-helpers.ts +99 -0
  441. package/src/assembly/renderer-lifecycle.ts +159 -0
  442. package/src/assembly/shader-prewarm-policy.ts +157 -0
  443. package/src/assembly/webgpu-ready-contract.ts +14 -0
  444. package/src/assembly/webgpu-ready.ts +4079 -0
  445. package/src/assembly/webgpu-renderer.ts +4095 -0
  446. package/src/cluster-binner.ts +31 -0
  447. package/src/components/__tests__/lighting-authoring.unit.test.ts +39 -0
  448. package/src/components/__tests__/rect-area-light.unit.test.ts +33 -0
  449. package/src/components/camera.ts +1 -1
  450. package/src/components/index.ts +3 -0
  451. package/src/components/light-helpers.ts +52 -1
  452. package/src/components/light-probe.ts +13 -0
  453. package/src/components/rect-area-light.ts +15 -0
  454. package/src/components/scene-instance.ts +6 -0
  455. package/src/components/spot-light.ts +3 -0
  456. package/src/debug-draw-glue.ts +1 -1
  457. package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
  458. package/src/device/device-scope.ts +35 -6
  459. package/src/device/gpu-residency.ts +334 -35
  460. package/src/device/lifecycle-transaction.ts +12 -0
  461. package/src/environment/frame.ts +6 -0
  462. package/src/environment/inspection.ts +10 -0
  463. package/src/environment/lifecycle.ts +122 -9
  464. package/src/errors/gpu-driven.ts +92 -0
  465. package/src/errors/index.ts +1 -0
  466. package/src/errors/recover.ts +108 -5
  467. package/src/errors/render.ts +72 -1
  468. package/src/extract/camera.ts +3 -3
  469. package/src/extract/contracts.ts +974 -0
  470. package/src/extract/gpu-driven.ts +108 -0
  471. package/src/extract/visibility.ts +0 -23
  472. package/src/features/host.ts +16 -0
  473. package/src/features/prepared-gpu-work.ts +20 -2
  474. package/src/features/prepared-graphics-store.ts +17 -0
  475. package/src/gpu-driven/batch-topology.ts +206 -28
  476. package/src/gpu-driven/prepared-draw.ts +208 -0
  477. package/src/gpu-driven/production-raster.ts +1046 -39
  478. package/src/gpu-driven/view-gpu.ts +411 -29
  479. package/src/gpu-scene-schema.ts +13 -0
  480. package/src/gpu-scene.ts +137 -67
  481. package/src/gpu-usage.ts +0 -1
  482. package/src/hdrp-buffers.ts +6 -6
  483. package/src/ibl/IblPipelineCache.ts +134 -50
  484. package/src/ibl/skylight-bind-group.ts +26 -0
  485. package/src/index.ts +83 -1
  486. package/src/inspection-types.ts +220 -1
  487. package/src/internal.ts +38 -0
  488. package/src/light-buffer-layout.ts +157 -324
  489. package/src/materials.ts +278 -47
  490. package/src/mesh-material-bindings.ts +59 -0
  491. package/src/occlusion-proxy.ts +64 -0
  492. package/src/pbr-pipeline.ts +290 -60
  493. package/src/pipeline/standard-forward-lane.ts +47 -0
  494. package/src/pipeline/standard-lighting/graph.ts +2 -1
  495. package/src/pipeline/standard-lighting/light-frame.ts +3 -2
  496. package/src/pipeline/standard-lighting/topology.ts +1 -1
  497. package/src/pipeline/standard-lighting/transport.ts +2 -1
  498. package/src/pipeline/standard-pipeline.ts +2 -0
  499. package/src/pipeline-builder.ts +5 -2
  500. package/src/pipeline-spec.ts +12 -1
  501. package/src/plugin.ts +4 -0
  502. package/src/points-lines/__tests__/cache-recovery.unit.test.ts +22 -0
  503. package/src/points-lines/prepare.ts +9 -0
  504. package/src/points-lines/standard-owner.ts +403 -0
  505. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +56 -0
  506. package/src/prepare/extended-lighting/ltc-resources.ts +136 -0
  507. package/src/prepare/extended-lighting/resources.ts +389 -0
  508. package/src/prepare/extended-lighting/spot-modifiers.ts +194 -0
  509. package/src/prepare/extended-lighting/state.ts +92 -0
  510. package/src/record/__tests__/frame-targets-recovery.unit.test.ts +60 -0
  511. package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
  512. package/src/record/__tests__/main-pass-geometry.unit.test.ts +26 -1
  513. package/src/record/__tests__/mesh-ssbo.unit.test.ts +38 -0
  514. package/src/record/__tests__/recovery-pipeline.unit.test.ts +124 -0
  515. package/src/record/__tests__/sprite-material-abi.unit.test.ts +28 -13
  516. package/src/record/__tests__/standard-pbr-ubo-layout.unit.test.ts +47 -4
  517. package/src/record/__tests__/temporal-payload.unit.test.ts +29 -28
  518. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +21 -2
  519. package/src/record/frame-lighting.ts +252 -53
  520. package/src/record/frame-snapshot.ts +72 -12
  521. package/src/record/frame-targets.ts +11 -1
  522. package/src/record/frame.ts +416 -95
  523. package/src/record/gpu-timing.ts +108 -44
  524. package/src/record/helpers.ts +1 -59
  525. package/src/record/main-pass-geometry.ts +434 -44
  526. package/src/record/main-pass-material.ts +324 -210
  527. package/src/record/main-pass-sprite-draws.ts +58 -92
  528. package/src/record/main-pass.ts +94 -6
  529. package/src/record/mesh-ssbo.ts +79 -46
  530. package/src/record/recovery-pipeline.ts +695 -0
  531. package/src/record/render-context.ts +99 -7
  532. package/src/record/shadow-pass.ts +66 -40
  533. package/src/record/typed-frame-graph.ts +270 -84
  534. package/src/record/view-ubo.ts +17 -27
  535. package/src/recovery/render-system-candidate.ts +839 -0
  536. package/src/reflection/inspection.ts +67 -0
  537. package/src/reflection/projection.ts +196 -1
  538. package/src/reflection/record-owner.ts +1283 -0
  539. package/src/render-contract.ts +82 -12
  540. package/src/render-pipeline.ts +5 -0
  541. package/src/render-system-extract-tail.ts +2983 -0
  542. package/src/render-system-extract.ts +290 -2784
  543. package/src/render-system.ts +1597 -1192
  544. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +36 -0
  545. package/src/scene/probe-blend-record.ts +54 -0
  546. package/src/scene/probe-blend.ts +813 -0
  547. package/src/scene/render-scene-types.ts +0 -7
  548. package/src/scene/render-scene.ts +972 -184
  549. package/src/scene/visibility/bounds.ts +57 -0
  550. package/src/scene/visibility/budget.ts +40 -0
  551. package/src/scene/visibility/facet.ts +400 -0
  552. package/src/scene/visibility/gpu-frame-timing.ts +101 -0
  553. package/src/scene/visibility/gpu-lod.ts +119 -0
  554. package/src/scene/visibility/inspection.ts +313 -0
  555. package/src/scene/visibility/lod-selector.ts +84 -0
  556. package/src/scene/visibility/occlusion-confidence.ts +478 -0
  557. package/src/scene/visibility/occlusion-pass.ts +165 -0
  558. package/src/scene/visibility/occlusion-query-pool.ts +178 -0
  559. package/src/scene/visibility/occlusion-runtime.ts +672 -0
  560. package/src/scene/visibility/types.ts +50 -0
  561. package/src/ssr/admission.ts +451 -0
  562. package/src/ssr/composition.ts +73 -0
  563. package/src/ssr/errors.ts +76 -0
  564. package/src/ssr/identity.ts +12 -0
  565. package/src/systems/skin-palette-allocator.ts +1 -1
  566. package/src/temporal/frame-coordinator.ts +30 -1
  567. package/src/temporal/frame.ts +14 -1
  568. package/src/temporal/taa-history-store.ts +46 -2
  569. package/src/temporal/temporal-view.ts +1 -1
  570. package/src/temporal/transaction.ts +9 -0
  571. package/src/temporal/view.ts +11 -0
  572. package/src/tilemap-chunk-extract-system.ts +5 -5
  573. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +19 -12
  574. package/src/typed-render-graph-primitives.ts +48 -0
  575. package/src/volume/passes.ts +46 -49
  576. package/dist/.tsbuildinfo +0 -1
  577. package/dist/chunk-5YADUCA7.mjs.map +0 -1
  578. package/dist/chunk-6OPXDQ2E.mjs.map +0 -1
  579. package/dist/chunk-BXBQQKFQ.mjs +0 -67
  580. package/dist/chunk-BXBQQKFQ.mjs.map +0 -1
  581. package/dist/chunk-FS2KNUQH.mjs.map +0 -1
  582. package/dist/chunk-PCHBPYML.mjs.map +0 -1
  583. package/dist/chunk-VFPLTKCU.mjs +0 -192
  584. package/dist/chunk-VFPLTKCU.mjs.map +0 -1
@@ -0,0 +1,899 @@
1
+ import type { AssetRegistry } from '@forgeax/engine-assets-runtime';
2
+ import type { EntityHandle, World } from '@forgeax/engine-ecs';
3
+ import type { Vec3 } from '@forgeax/engine-math';
4
+ import type { SceneHierarchySnapshot } from '@forgeax/engine-scene';
5
+ import type { Handle, MaterialAsset, MaterialPass, MaterialRenderState, MaterialTextureCoordinates, MeshLodLevel, ParamSchemaEntry, PrimitiveTopology, TextureAsset } from '@forgeax/engine-types';
6
+ import type { DirectionalShadowQuality } from '../components/directional-shadow-filter';
7
+ import type { LightValidationError } from '../components/light-helpers';
8
+ import type { RenderFeatureHiddenEntityReport, RenderFeatureWorldVisibilitySnapshot } from '../features/types';
9
+ import type { MeshMaterialBindingDiagnostic, MeshMaterialBindingSource } from '../mesh-material-bindings';
10
+ import type { PointsLinesRetainedSnapshot } from '../points-lines/snapshot';
11
+ import type { ReflectionProbeFact } from '../reflection/projection';
12
+ import type { CameraSnapshot, CubeCameraSnapshot } from '../render-contract';
13
+ import type { SkinPaletteAllocator } from '../systems/skin-palette-allocator';
14
+ import type { SkinPaletteSlice } from '../systems/skin-palette-types';
15
+ import type { RenderTargetTextureSource } from '../targets/contracts';
16
+ import type { ValidatedVolumetricFog } from '../volume/component';
17
+ import type { VolumeProjectorTuple } from '../volume/temporal';
18
+ import type { EnvironmentFrame, FogFrame, FogSelectionFailure } from './environment';
19
+ import type { VisibilitySnapshot } from './visibility';
20
+ export interface DirectionalLightSnapshot {
21
+ readonly kind: 'directional';
22
+ readonly entity?: EntityHandle;
23
+ readonly direction: Vec3;
24
+ readonly color: Vec3;
25
+ readonly intensity: number;
26
+ }
27
+ /**
28
+ * PointLightSnapshot — omnidirectional point variant. `position` from the
29
+ * companion Transform; `invRangeSquared = 1 / range^2` host-folded via
30
+ * `computeInvRangeSquared` (range = +Infinity -> 0; range = 0 -> 1e8 NaN
31
+ * protection per D-S5).
32
+ */
33
+ export interface PointLightSnapshot {
34
+ readonly kind: 'point';
35
+ readonly entity?: EntityHandle | number;
36
+ readonly position: Vec3;
37
+ readonly color: Vec3;
38
+ readonly intensity: number;
39
+ readonly invRangeSquared: number;
40
+ /**
41
+ * feat-20260612-point-light-shadows-urp-hdrp M1 / T-M1-8 + M4 / T-M4-4:
42
+ * cube_array atlas layer index for this light's shadow map (0..3 for shadow
43
+ * casters; sentinel `-1` for non-shadow lights). Default `-1` per
44
+ * plan-strategy §D-2 — record stage / shader skips shadow sampling when the
45
+ * lane equals the sentinel. Joined with `pointShadow[]` by entity at the
46
+ * end of extract; HDRP record stage threads `shadowAtlasLayer + shadowNear +
47
+ * shadowFar` through `packLightSlot` as the §D-8 pad-lane payload.
48
+ */
49
+ readonly shadowAtlasLayer?: number;
50
+ /**
51
+ * Per-face perspective near plane (matches `PointLightShadow.nearPlane`).
52
+ * Used by HDRP `evalPointShadowed` for depth-ref reconstruction; rides
53
+ * `LightSlot.kind_and_pad.z` (byte 56..60) on the std430 std layout.
54
+ */
55
+ readonly shadowNear?: number;
56
+ /**
57
+ * Per-face perspective far plane (matches `PointLightShadow.farPlane`).
58
+ * Rides `LightSlot.kind_and_pad.w` (byte 60..64).
59
+ */
60
+ readonly shadowFar?: number;
61
+ }
62
+ /**
63
+ * PointShadowSnapshot — extract-stage view of one shadow-casting point light
64
+ * (feat-20260612-point-light-shadows-urp-hdrp M1 / T-M1-7).
65
+ *
66
+ * `entity` is the spawning entity (joins PointLight + PointLightShadow on the
67
+ * same archetype); `position` is the light world-space position resolved from
68
+ * the companion Transform (mirrors PointLightSnapshot.position).
69
+ * `shadowMatrices` is the 96-float packed mat4[6] table (column-major,
70
+ * 6 mat4 * 16 floats = 384 bytes) ready for UBO upload.
71
+ *
72
+ * Plan-strategy §D-3: the record stage allocates a dynamic-offset uniform
73
+ * buffer (384 B per-light, aligned to minUniformBufferOffsetAlignment, WebGPU
74
+ * min 256 -> 512 B stride). Extract owns the host-side `Float32Array(96)`;
75
+ * record owns the GPU `RhiBuffer` lifetime.
76
+ *
77
+ * `mapSize` / `nearPlane` / `farPlane` ride here so record stage can size the
78
+ * cube atlas faces and feed shader the proj constants without re-querying ECS.
79
+ * `shadowAtlasLayer` is assigned by extract in spawn order (0 .. cap-1) so the
80
+ * downstream LightSlot / packPointLight packers carry the layer index in
81
+ * pointPadW (T-M1-8 will rename to shadowAtlasLayer).
82
+ */
83
+ export interface PointShadowSnapshot {
84
+ /** Spawning entity index (joins PointLight + PointLightShadow + Transform). */
85
+ readonly entity: number;
86
+ /** World-space light position (sourced from companion Transform). */
87
+ readonly position: Vec3;
88
+ /** PointLightShadow.mapSize (per-face cube square dimension; 512 default). */
89
+ readonly mapSize: number;
90
+ readonly nearPlane: number;
91
+ readonly farPlane: number;
92
+ /**
93
+ * Atlas layer assigned by extract in spawn order (0..cap-1, where cap=4
94
+ * matches PointLightShadow cardinality). Sentinel -1 is reserved by the
95
+ * shader-side LightSlot for no-shadow lights (T-M1-8).
96
+ */
97
+ readonly shadowAtlasLayer: number;
98
+ /**
99
+ * 6 view-proj mat4 in face order [+X, -X, +Y, -Y, +Z, -Z] packed into one
100
+ * Float32Array(96). 16 floats per face = 64 B; 6 * 64 = 384 B raw. The
101
+ * record stage pads each slot to 512 B (256 alignment) when packing into
102
+ * the per-light dynamic-offset UBO (plan-strategy §D-3).
103
+ */
104
+ readonly shadowMatrices: Float32Array;
105
+ }
106
+ /**
107
+ * SpotLightSnapshot — cone-restricted variant. `position` from companion
108
+ * Transform; `direction` raw outgoing-vector; `cosInner` / `cosOuter` host
109
+ * pre-converted via `degToCos` so the shader sees only cosines (D-S2).
110
+ *
111
+ * feat-20260625-spot-light-shadow-mapping M1 w5: added shadow fields.
112
+ * castShadow (bool) gates shadow projection; lightViewProj is the perspective
113
+ * light-view-projection matrix computed in extract (undefined when castShadow
114
+ * is false, dir degenerates, or the light is clipped). shadowAtlasTile
115
+ * (i32 sentinel -1) is the allocated tile index 0..3 or -1 for unassigned
116
+ * (plan-strategy D-4). mapSize / nearPlane / farPlane are the source
117
+ * component shadow parameters carried through to the record stage.
118
+ */
119
+ export interface SpotLightSnapshot {
120
+ readonly kind: 'spot';
121
+ readonly entity?: EntityHandle | number;
122
+ readonly position: Vec3;
123
+ readonly direction: Vec3;
124
+ readonly color: Vec3;
125
+ readonly intensity: number;
126
+ readonly invRangeSquared: number;
127
+ readonly cosInner: number;
128
+ readonly cosOuter: number;
129
+ readonly iesProfileHandle?: number;
130
+ readonly cookieHandle?: number;
131
+ readonly iesProfileSlice?: number;
132
+ readonly cookieSlice?: number;
133
+ readonly iesProfileData?: Uint8Array;
134
+ readonly cookieData?: Uint8Array;
135
+ readonly cookieMatrix?: Float32Array;
136
+ readonly projectorSlice?: number;
137
+ readonly projectorData?: Uint8Array;
138
+ readonly projectorMatrix?: Float32Array;
139
+ readonly rollDeg?: number;
140
+ readonly castShadow: boolean;
141
+ readonly lightViewProj: Float32Array | undefined;
142
+ readonly mapSize: number;
143
+ readonly nearPlane: number;
144
+ readonly farPlane: number;
145
+ readonly shadowAtlasTile: number;
146
+ readonly shadowIntensity?: number;
147
+ readonly depthBias?: number;
148
+ readonly normalBias?: number;
149
+ readonly pcfKernelSize?: number;
150
+ readonly projectorHandle?: Handle<'TextureAsset', 'shared'>;
151
+ readonly projectorAsset?: TextureAsset;
152
+ readonly projectorGuid?: string;
153
+ readonly projectorGeneration?: number;
154
+ readonly projectorRevision?: number;
155
+ }
156
+ export interface RectAreaDirectLightSnapshot {
157
+ readonly kind: 'rect-area';
158
+ readonly position: Vec3;
159
+ readonly color: Vec3;
160
+ readonly intensity: number;
161
+ readonly invRangeSquared: number;
162
+ readonly halfWidth: number;
163
+ readonly halfHeight: number;
164
+ readonly axisX: Vec3;
165
+ readonly axisY: Vec3;
166
+ readonly shadowAtlasTile?: number;
167
+ }
168
+ export interface RectAreaWorldFrame {
169
+ readonly center: Vec3;
170
+ readonly axisX: Vec3;
171
+ readonly axisY: Vec3;
172
+ readonly normal: Vec3;
173
+ readonly halfWidth: number;
174
+ readonly halfHeight: number;
175
+ }
176
+ /**
177
+ * LightSnapshot — discriminated union of the three KHR_lights_punctual
178
+ * variants. AI users + the record stage perform an exhaustive switch on
179
+ * `kind`; missing arms are caught at compile time (no `default`,
180
+ * `assertNever`-style guards). Plan-strategy R-10.
181
+ */
182
+ export type LightSnapshot = DirectionalLightSnapshot | PointLightSnapshot | SpotLightSnapshot | RectAreaDirectLightSnapshot;
183
+ /**
184
+ * ExtractedLights — three-bucket output of the extractFrame three-query
185
+ * union (M2 / w16 / AC-03). Plan-strategy section 3.1 EXT node:
186
+ * - `directional` — at most one (record-stage N>1 fail-fast lands in M3)
187
+ * - `point[]` — first-slice cap of 4 enforced at record stage (M3)
188
+ * - `spot[]` — first-slice cap of 4 enforced at record stage (M3)
189
+ * `directionalCount` exposes the raw count of DirectionalLight entities the
190
+ * extract observed (so the record stage can fire `render-system-multi-light`
191
+ * when N>1 without re-running the query). M3 / w19 will widen this with
192
+ * pointCount / spotCount fields once the matching record-time fail-fast
193
+ * lands; for M2 the field stays directional-only to keep AC-06 (a) intact.
194
+ */
195
+ export interface ExtractedLights {
196
+ readonly directional: DirectionalLightSnapshot | undefined;
197
+ readonly directionalCount: number;
198
+ readonly point: readonly PointLightSnapshot[];
199
+ readonly spot: readonly SpotLightSnapshot[];
200
+ readonly rect: readonly RectAreaDirectLightSnapshot[];
201
+ /**
202
+ * feat-20260613-csm-cascaded-shadow-maps M2 / w9: per-cascade light-view-
203
+ * projection matrices (one per cascade, length 4 pre-allocated). Each matrix
204
+ * is a column-major 16-float mat4 with atlas tile UV inset baked in
205
+ * (plan-strategy D-3). cascadeCount < 4: unused slots are zero matrices.
206
+ * Undefined when castShadow=false or no directional light.
207
+ */
208
+ readonly lightViewProj: readonly Float32Array[] | undefined;
209
+ /**
210
+ * feat-20260613-csm-cascaded-shadow-maps M2 / w9: view-space z depths
211
+ * of the PSSM split planes (length 4, Float32Array). cascadeCount < 4:
212
+ * unused slots are 0.0f. Undefined when castShadow=false or no directional
213
+ * light.
214
+ */
215
+ readonly splitPlanes: Float32Array | undefined;
216
+ /**
217
+ * feat-20260613-csm-cascaded-shadow-maps M2 / w9: effective cascade count
218
+ * from the DirectionalLight component (1..4). Undefined when castShadow=false
219
+ * or no directional light.
220
+ */
221
+ readonly cascadeCount: number | undefined;
222
+ /**
223
+ * feat-20260613-csm-cascaded-shadow-maps M2 / w9: cascade blend width
224
+ * from the DirectionalLight component (0..0.5). Undefined when castShadow=false
225
+ * or no directional light.
226
+ */
227
+ readonly cascadeBlend: number | undefined;
228
+ /**
229
+ * feat-20260520-directional-light-shadow-mapping M1c / w8:
230
+ * shadowMapSize from DirectionalLight.mapSize. Drives shadow RT
231
+ * lazy-allocate (idempotency: same size -> no rebuild). Undefined when
232
+ * castShadow=false or no directional light.
233
+ */
234
+ readonly shadowMapSize: number | undefined;
235
+ /**
236
+ * feat-20260621-merge-directionallightshadow-into-directionallight M2:
237
+ * depthBias from the merged DirectionalLight (constant shadow-bias floor).
238
+ * Populated when castShadow=true on the first-hit directional light;
239
+ * undefined otherwise.
240
+ */
241
+ readonly depthBias: number | undefined;
242
+ /**
243
+ * feat-20260621-merge-directionallightshadow-into-directionallight M2:
244
+ * normalBias from the merged DirectionalLight (slope-based shadow-bias
245
+ * coefficient).
246
+ * Populated when castShadow=true on the first-hit directional light;
247
+ * undefined otherwise.
248
+ */
249
+ readonly normalBias: number | undefined;
250
+ /**
251
+ * feat-20260621-merge-directionallightshadow-into-directionallight M2:
252
+ * pcfKernelSize from the merged DirectionalLight (PCF kernel width, odd>=1).
253
+ * Populated when castShadow=true on the first-hit directional light;
254
+ * undefined otherwise.
255
+ */
256
+ readonly directionalShadowQuality: DirectionalShadowQuality | undefined;
257
+ readonly directionalShadowError: LightValidationError | undefined;
258
+ /**
259
+ * feat-20260612-point-light-shadows-urp-hdrp M1 / T-M1-7:
260
+ * shadow-casting point lights (PointLight + PointLightShadow + Transform
261
+ * archetype join). Each entry carries the per-light 6-face VP matrices and
262
+ * the assigned cube_array atlas layer (0..3 in spawn order; sentinel -1 is
263
+ * reserved by the shader-side LightSlot for no-shadow point lights).
264
+ *
265
+ * Empty array when no PointLightShadow components exist (zero-cost gate per
266
+ * AC-09; record stage skips atlas allocation + shadow pass dispatch).
267
+ */
268
+ readonly pointShadow: readonly PointShadowSnapshot[];
269
+ /**
270
+ * bug-20260710-editor-cross-world-shadow: the RAW directional-shadow config
271
+ * (cascadeCount / splitLambda / cascadeBlend / mapSize / shadowDistance) of
272
+ * the first-hit castShadow DirectionalLight, carried unconditionally of
273
+ * whether this world had a camera. The {@link extractFrames} merge layer
274
+ * re-runs {@link computeDirectionalCsm} with this config + the surfaced
275
+ * camera so directional shadows work when the light and camera live in
276
+ * DIFFERENT worlds (editor editorWorld/sceneWorld super-composite). Undefined
277
+ * when castShadow=false or no directional light. The `lightViewProj` /
278
+ * `splitPlanes` fields above remain the *computed* per-world outputs (correct
279
+ * for single-world; recomputed at merge for cross-world).
280
+ */
281
+ readonly directionalCsmConfig: DirectionalCsmConfig | undefined;
282
+ /**
283
+ * bug-20260710-editor-cross-world-shadow: the light-direction of the
284
+ * first-hit castShadow DirectionalLight, carried so the merge layer can
285
+ * rebuild the light-view matrix. Redundant with `directional.direction` but
286
+ * kept explicit so the CSM recompute reads a single config bundle. Undefined
287
+ * when castShadow=false or no directional light.
288
+ */
289
+ readonly directionalCsmDirection: Vec3 | undefined;
290
+ }
291
+ /**
292
+ * SkylightSnapshot -- extract-stage view of one Skylight entity
293
+ * (feat-20260520-skylight-ibl-cubemap M4 / t26).
294
+ *
295
+ * `equirectHandle` carries the packed u32 handle for
296
+ * `Handle<EquirectAsset, 'shared'>`; the record stage drives the internal
297
+ * lazy cubemap projection from it and resolves the projected GPU cubemap via
298
+ * `GpuResidencyCache.getCubemapGpuView(...)` and related helpers
299
+ * (feat-20260630 M3 / w16-w18). The snapshot carries NO projection status
300
+ * field: the status truth lives in the store's CubemapGpuEntry (D-3 SSOT);
301
+ * record queries it once per frame.
302
+ *
303
+ * `intensity` defaults to 1.0 via the Skylight component token defaults
304
+ * (plan-strategy D-6: Skylight data flows through existing extract->record
305
+ * pipeline; no independent ECS system).
306
+ */
307
+ export interface SkylightSnapshot {
308
+ readonly equirectHandle: number;
309
+ readonly color: readonly [number, number, number];
310
+ readonly intensity: number;
311
+ /** Environment-space quaternion [x, y, z, w], identity by default. */
312
+ readonly rotation: readonly [number, number, number, number];
313
+ readonly entityHandle: number;
314
+ }
315
+ /**
316
+ * SkyboxSnapshot -- extract-stage view of one SkyboxBackground entity
317
+ * (feat-20260531-skybox-env-background M2 / w5).
318
+ *
319
+ * `equirectHandle` carries the packed u32 handle for
320
+ * `Handle<EquirectAsset, 'shared'>`; the record stage resolves the projected
321
+ * GPU cubemap via `GpuResidencyCache.getCubemapGpuView(...)`.
322
+ *
323
+ * `mode` carries the raw `f32` column value (`SKYBOX_MODE_CUBEMAP = 0`).
324
+ * First hit wins per plan-strategy D-6; multi-entity once-warn in record stage.
325
+ */
326
+ export interface SkyboxSnapshot {
327
+ readonly equirectHandle: number;
328
+ readonly mode: number;
329
+ /** Environment-space quaternion [x, y, z, w], identity by default. */
330
+ readonly rotation: readonly [number, number, number, number];
331
+ readonly entityHandle: number;
332
+ }
333
+ export interface LightProbeSnapshot {
334
+ readonly identity: string;
335
+ readonly position: readonly [number, number, number];
336
+ readonly radius: number;
337
+ readonly irradiance: Float32Array;
338
+ readonly admitted: boolean;
339
+ }
340
+ export interface ExtractedVolumetricFog {
341
+ readonly status: 'off' | 'available' | 'degraded';
342
+ readonly fog?: ValidatedVolumetricFog;
343
+ readonly densityHandle?: Handle<'TextureAsset', 'shared'>;
344
+ readonly densityAsset?: TextureAsset;
345
+ readonly guid?: string;
346
+ readonly generation?: number;
347
+ readonly digest?: string;
348
+ readonly worldId?: number;
349
+ readonly lightEntity?: EntityHandle;
350
+ readonly lightKind?: 'directional' | 'point' | 'spot';
351
+ readonly pointLightEntity?: EntityHandle;
352
+ readonly spotLightEntity?: EntityHandle;
353
+ readonly projector?: VolumeProjectorTuple;
354
+ readonly projectorHandle?: Handle<'TextureAsset', 'shared'>;
355
+ readonly projectorAsset?: TextureAsset;
356
+ }
357
+ export interface RenderableSnapshot {
358
+ readonly assetHandle: number;
359
+ readonly transform: TransformSnapshot;
360
+ readonly lods?: readonly MeshLodLevel[];
361
+ readonly lodHysteresis?: number;
362
+ /** Finite producer-owned local bounds retained for persistent CPU view work. */
363
+ readonly localAabb?: Float32Array;
364
+ /** Indexed single-submesh facts consumed by the first GPU-driven rigid lane. */
365
+ readonly gpuDrivenDraws?: readonly GpuDrivenDrawSnapshot[];
366
+ /**
367
+ * feat-20260608 M5 amend / w11-a: the entity's representative (first)
368
+ * material snapshot, kept as a same-name shorthand for `materials[0]`.
369
+ * Per-entity dispatch (shading model routing, sprite-vs-mesh split, the
370
+ * D-1/D-3 pipeline-tag pick) is uniform across the entity's submeshes
371
+ * today, so the existing 20+ `entry.source.material.X` consumers in the
372
+ * record stage stay unchanged. Per-submesh material data (baseColor /
373
+ * UBO payload / paramSnapshot) lives in `materials[i]`.
374
+ */
375
+ readonly material: MaterialSnapshot;
376
+ /**
377
+ * feat-20260608 M5 amend / w11-a: per-submesh MaterialSnapshot[]
378
+ * positionally aligned with `MeshAsset.submeshes[]` (plan §3.2 sequence
379
+ * step 6 + AC-08). Length always equals the entity's submesh count once
380
+ * the extract stage's count-mismatch validator (M2 / w12) has filtered
381
+ * misaligned spawns. The record stage reads `materials[i]` to upload the
382
+ * i-th material UBO slot before drawing the i-th submesh.
383
+ *
384
+ * Backward-compat: `materials[0] === material` (the legacy mid-grey
385
+ * default-material case-B path also routes through `materials = [default]`,
386
+ * keeping the legacy single-mesh-no-material spawn shape working without
387
+ * a special branch in record).
388
+ */
389
+ readonly materials: readonly MaterialSnapshot[];
390
+ /** Per-slot provenance trace from the shared mesh-material resolver. */
391
+ readonly materialBindingSources: readonly MeshMaterialBindingSource[];
392
+ /** Active structured override diagnostics for this renderable. */
393
+ readonly materialBindingDiagnostics?: readonly MeshMaterialBindingDiagnostic[];
394
+ /**
395
+ * feat-20260708-composited-multi-world-rendering M1 / D-1: the worldId
396
+ * of the world this renderable was extracted from. Defaults to 0 in
397
+ * single-world path (extractFrame always assigns 0). The merge layer
398
+ * (extractFrames in M2) stamps the correct worldId per world before
399
+ * the record stage consumes it. Combined with `entityKey` via
400
+ * `worldEntityKey(worldId, entityKey)` to form per-entity cache keys.
401
+ *
402
+ * Never rewrite `entityKey` itself — consumers that need the real
403
+ * entity handle (video provider, etc.) read the bare `entityKey`.
404
+ */
405
+ readonly worldId: number;
406
+ /**
407
+ * feat-20260531-per-frame-bind-group-cache M1 / w3: packed Entity u32
408
+ * (encodeEntity(indexSlot, generation)) surface'd from the extract
409
+ * stage. Stable per-entity identity for the record stage cache keys
410
+ * (material / instances / per-frame clean-up) without re-querying the
411
+ * World (charter P5 Pipeline Isolation: record stage only consumes
412
+ * snapshot POD). Reuses the encodeEntity calculation already performed
413
+ * at :1293 for the Instances path, and now also computed for plain
414
+ * (non-Instances) renderables.
415
+ *
416
+ * Never rewrite this field — cache keys use `worldEntityKey(worldId, entityKey)`,
417
+ * not the bare entityKey alone (D-1).
418
+ */
419
+ readonly entityKey: number;
420
+ /**
421
+ * feat-20260514 M3 (w15): when the entity carries an `Instances` component
422
+ * the extract stage materialises a fresh `Float32Array` snapshot of the
423
+ * packed mat4 transforms (16 f32 per instance, stride 16) plus a stable
424
+ * `cacheKey` (the entity's packed u32) and the `archVersion` (used by the
425
+ * record stage to invalidate its per-entity GPU buffer cache when the
426
+ * archetype storage grew). Absent (`undefined`) means the record stage
427
+ * falls back to the shared 1-element identity-mat4 storage buffer +
428
+ * `drawIndexed(.., 1, ..)`.
429
+ */
430
+ readonly instances?: InstancesSnapshot;
431
+ /**
432
+ * feat-20260625-sprite-instances-and-tilemap-terrain-static-batch M3 / w10
433
+ * (plan-strategy D-1 + D-9): when the entity carries a `SpriteInstances`
434
+ * component the extract stage materialises a paired snapshot — packed mat4
435
+ * `transforms` (16 f32, stride 16) + per-instance UV `regions` (4 f32,
436
+ * stride 4) — plus the same cache fingerprint pair (`cacheKey` = entity
437
+ * packed u32, `archVersion` = archetype version stamp at snapshot time).
438
+ * The record stage interleaves the two arrays into an 80B-per-instance
439
+ * single GPU buffer routed through `@group(3) @binding(0)` (BGL unchanged,
440
+ * D-1). Absent (`undefined`) means the entity is not a `SpriteInstances`
441
+ * carrier; the record stage falls back to its existing sprite path
442
+ * (material UBO region + identity-instance buffer).
443
+ *
444
+ * Three structured `EcsError` codes fire at extract entry and skip the
445
+ * renderable on violation (charter P3 explicit failure):
446
+ * - `'sprite-instances-mutually-exclusive-with-instances'`
447
+ * - `'sprite-instances-requires-sprite-shading-model'`
448
+ * - `'sprite-instances-count-mismatch'`
449
+ */
450
+ readonly spriteInstances?: SpriteInstancesSnapshot;
451
+ /**
452
+ * feat-20260523-skin-skeleton-animation M2 / T-21: when the entity carries
453
+ * a `Skin` component the extract stage populates this field with the
454
+ * skin palette slice metadata. The record stage uses this to route the
455
+ * draw to `forgeax::pbr-skin` pipeline + set the palette dynamic offset.
456
+ * Absent (`undefined`) means the entity is not skinned.
457
+ */
458
+ readonly skin?: SkinPaletteSlice;
459
+ /**
460
+ * ECS-owned morph weights. Presence selects the Standard Pipeline CPU
461
+ * specialized deformation lane; the asset remains the source of target
462
+ * deltas and the record stage only receives this frozen POD snapshot.
463
+ */
464
+ readonly morph?: MorphSnapshot;
465
+ /** Renderer-owned previous-frame facts attached during temporal projection. */
466
+ readonly temporal?: RenderableTemporalSnapshot;
467
+ /** Detached M2 authoring facts for the optional Points/Lines projection. */
468
+ readonly pointsLines?: PointsLinesRetainedSnapshot;
469
+ readonly probeBlendRecord?: import('../scene/probe-blend-record').ProbeBlendRecord;
470
+ }
471
+ export type RenderablePreviousSource = 'last-submitted' | 'current-seed';
472
+ export type RenderableReactiveReason = 'new-slot' | 'generation-reuse' | 'reentered' | 'geometry-revision' | 'material-revision' | 'skinning-deformation' | 'morph-deformation';
473
+ export interface RenderableTemporalSnapshot {
474
+ readonly previousEpoch: number | undefined;
475
+ readonly previousSource: RenderablePreviousSource;
476
+ readonly reactive: boolean;
477
+ readonly reactiveReasons: readonly RenderableReactiveReason[];
478
+ readonly previousTransform: TransformSnapshot;
479
+ readonly previousInstances: InstancesSnapshot | undefined;
480
+ readonly previousSkin: SkinPaletteSlice | undefined;
481
+ readonly previousMorphWeights: Float32Array | undefined;
482
+ }
483
+ export interface MorphSnapshot {
484
+ readonly weights: Float32Array;
485
+ readonly targetCount: number;
486
+ }
487
+ export interface GpuDrivenDrawSnapshot {
488
+ readonly kind: 'indexed' | 'non-indexed';
489
+ readonly first: number;
490
+ readonly count: number;
491
+ readonly baseVertex: number;
492
+ readonly materialSlot: number;
493
+ readonly topology: PrimitiveTopology;
494
+ readonly pipelineClass: string;
495
+ readonly materialResourceClass: string;
496
+ readonly projectedHeight?: number;
497
+ readonly lodRanges?: readonly {
498
+ readonly first: number;
499
+ readonly count: number;
500
+ readonly baseVertex: number;
501
+ }[];
502
+ }
503
+ export interface InstancesSnapshot {
504
+ /** Packed column-major mat4 transforms (16 f32 per instance). */
505
+ readonly transforms: Float32Array;
506
+ /** Number of instances (transforms.length / 16). */
507
+ readonly instanceCount: number;
508
+ /** Stable per-entity GPU buffer cache key (the packed Entity u32). */
509
+ readonly cacheKey: number;
510
+ /**
511
+ * Archetype version stamp at snapshot time. The record stage compares this
512
+ * against its cached version per cacheKey; a bump means the underlying
513
+ * BufferPool slot may have grown / been reallocated, forcing a fresh
514
+ * `device.createBuffer + queue.writeBuffer` round.
515
+ */
516
+ readonly archVersion: number;
517
+ }
518
+ /**
519
+ * feat-20260625-sprite-instances-and-tilemap-terrain-static-batch M3 / w10:
520
+ * extract-stage view of a `SpriteInstances` carrier (2D peer of
521
+ * `InstancesSnapshot`).
522
+ *
523
+ * Field shapes mirror `InstancesSnapshot` so the record-stage cache protocol
524
+ * (`(cacheKey, archVersion, byteLength)` fingerprint triple) is reused
525
+ * verbatim. The byte length consumed at upload time is the sum
526
+ * `transforms.byteLength + regions.byteLength` (= 80*N for N instances,
527
+ * plan-strategy D-1 interleaved single-buffer); the record stage builds the
528
+ * 80B/instance interleaved buffer once per (entity, archVersion, byteLength)
529
+ * fingerprint change.
530
+ */
531
+ export interface SpriteInstancesSnapshot {
532
+ /** Packed column-major mat4 transforms (16 f32 per instance, stride 16). */
533
+ readonly transforms: Float32Array;
534
+ /** Per-instance UV vec4 regions (4 f32 per instance, stride 4). */
535
+ readonly regions: Float32Array;
536
+ /**
537
+ * Number of instances. Derived from `transforms.length / 16` (equivalently
538
+ * `regions.length / 4`); the extract-entry validator guarantees the two
539
+ * derivations agree, otherwise it fires
540
+ * `'sprite-instances-count-mismatch'` and skips the renderable.
541
+ */
542
+ readonly instanceCount: number;
543
+ /** Stable per-entity GPU buffer cache key (the packed Entity u32, D-9). */
544
+ readonly cacheKey: number;
545
+ /** Archetype version stamp at snapshot time (cache invalidation fingerprint). */
546
+ readonly archVersion: number;
547
+ }
548
+ /**
549
+ * TransformSnapshot: extract-stage view of one entity's resolved world
550
+ * transform (feat-20260601 D-3). Holds the single `world` mat4 (column-major
551
+ * 16 floats, copied from the entity's `Transform.world` view written by
552
+ * propagateTransforms). The record stage copies these 16 floats straight into
553
+ * the mesh SSBO slot (zero `mat4.compose`); position / scale consumers derive
554
+ * from the mat4 via `mat4.getTranslation` / basis-column lengths.
555
+ */
556
+ export interface TransformSnapshot {
557
+ readonly world: Float32Array;
558
+ }
559
+ /**
560
+ * MaterialSnapshot: extract-stage view of one entity's material asset (M2 / w6
561
+ * of feat-20260517-merge-mesh-renderer-material-renderer; plan-strategy section 2.3).
562
+ *
563
+ * Adds optional `baseColorTexture` + `sampler` slots (consumed by the record
564
+ * stage's textured-material code path; M3 / w10 dropped the cast-over-firstMaterial
565
+ * pattern in favour of direct snapshot field reads).
566
+ *
567
+ * feat-20260522-learn-render-3-1-sponza-model-loading-with-multi-l M4 extends
568
+ * the snapshot with `metallicRoughnessTexture` and `normalTexture`
569
+ * so the record stage can wire PBR texture bindings 4 and 6
570
+ * from real GPU views instead of placeholder 1x1 white / flat-normal views.
571
+ *
572
+ * Bounded scope: the snapshot tracks only what the record stage actually
573
+ * consumes today (charter proposition 5 consistent abstraction; YAGNI for
574
+ * future-proof field bloat). Future MaterialAsset extensions (emissive / etc)
575
+ * drive snapshot extensions when the record stage starts consuming them, not
576
+ * vice-versa.
577
+ *
578
+ * tweak-20260701 M1: `shadingModel` field removed — shader identity via
579
+ * {@link materialShaderId} is the single source of truth for material dispatch.
580
+ */
581
+ export interface MaterialSnapshot {
582
+ readonly baseColor: Vec3;
583
+ readonly metallic: number;
584
+ readonly roughness: number;
585
+ readonly clearcoat?: number | undefined;
586
+ readonly clearcoatRoughness?: number | undefined;
587
+ /** Authored Standard PBR specular tint in linear runtime color space. */
588
+ readonly specularTint?: readonly [number, number, number] | undefined;
589
+ /**
590
+ * Schema-driven material shader identifier (feat-20260523 M4-T05).
591
+ * Populated when the material asset uses the schema-driven path
592
+ * (payload.materialShader set). Undefined for unlit/sprite legacy
593
+ * materials and for case-B defaultMaterialSnapshot.
594
+ *
595
+ * The record stage uses this as the pipeline cache key first-level
596
+ * discriminator (M4-T06).
597
+ */
598
+ readonly materialShaderId?: string | undefined;
599
+ /**
600
+ * Stable source handle for the material asset. Record uses this only for
601
+ * same-frame assembly reuse; GPU bind-group validity still comes from the
602
+ * resource-identity cache.
603
+ */
604
+ readonly materialHandle?: number | undefined;
605
+ /**
606
+ * The selected forward-pass state for this exact material. A mesh can bind
607
+ * different materials to its submeshes, so pipeline selection must read the
608
+ * state from the submesh snapshot rather than the entity's first material.
609
+ */
610
+ readonly renderState?: MaterialRenderState | undefined;
611
+ /**
612
+ * Schema-driven parameter snapshot (feat-20260523 M4-T05).
613
+ * Populated alongside materialShaderId. Maps param name to its
614
+ * runtime-resolved value: number for scalar params, number[] for
615
+ * vec/color params, string (GUID) for texture2d/sampler params.
616
+ */
617
+ readonly paramSnapshot?: Readonly<Record<string, number | number[] | string>> | undefined;
618
+ /** Effective MaterialAsset parameter contract used to lay out this snapshot. */
619
+ readonly materialParamSchema?: readonly ParamSchemaEntry[] | undefined;
620
+ /** Authored per-slot UV set and KHR texture transform metadata. */
621
+ readonly textureCoordinates?: ReadonlyMap<string, MaterialTextureCoordinates> | undefined;
622
+ /**
623
+ * User-region texture handles keyed by paramSchema field name
624
+ * (feat-20260621-learn-render-5-5-parallax M2 / w7). The SSOT carrier for
625
+ * EVERY texture the shader's `derive(paramSchema).textureFieldNames`
626
+ * declares — `baseColorTexture` / `metallicRoughnessTexture` /
627
+ * `normalTexture` for built-in standard-PBR, plus each custom field such as
628
+ * `heightTexture` (LO 5.5 parallax). The record stage iterates this map to
629
+ * assemble the user-region bind group per the per-shader BGL (w8), so a 4th
630
+ * (or Nth) texture flows end-to-end without a hardcoded field list.
631
+ *
632
+ * Populated by iterating `textureFieldNames`; absent keys mean the
633
+ * paramValue was missing / mis-typed (record falls back to default white).
634
+ * `emissiveTexture` / `occlusionTexture` are included here as ordinary
635
+ * Standard user-region fields; the production layout does not duplicate
636
+ * them in a lightmap injection region.
637
+ */
638
+ readonly textureHandles?: ReadonlyMap<string, Handle<'TextureAsset', 'shared'>> | undefined;
639
+ readonly textureSources?: ReadonlyMap<string, RenderTargetTextureSource> | undefined;
640
+ /**
641
+ * User-region texture field names whose paramValue resolved to a VideoAsset
642
+ * (kind `'video'`) rather than a static TextureAsset
643
+ * (feat-20260623-world-space-video-asset M4 / w14, D-5). The video GUID
644
+ * occupies the same texture2d values slot a static texture would (P4:
645
+ * one binding shape), but extract routes it here instead of `textureHandles`
646
+ * so the record stage pulls the current-frame view from the transient
647
+ * DynamicTextureStore (D-3) instead of `GpuResidencyCache.ensureResident`
648
+ * (which has no `video` arm; AC-08). Each entry also carries the resolved
649
+ * clip handle so the record stage can key the per-frame upload.
650
+ *
651
+ * Producer/consumer split (charter P5 / AC-07 gate): extract owns the
652
+ * asset->snapshot translation; record consumes this POD field only — it never
653
+ * reaches back into the MaterialAsset to learn a field is video-sourced.
654
+ */
655
+ readonly videoTextureFields?: ReadonlyMap<string, Handle<'VideoAsset', 'shared'>> | undefined;
656
+ /** Authored sampler handles keyed by their matching texture parameter. */
657
+ readonly samplerHandles?: ReadonlyMap<string, Handle<'SamplerAsset', 'shared'>> | undefined;
658
+ readonly baseColorTexture?: Handle<'TextureAsset', 'shared'> | undefined;
659
+ /**
660
+ * PBR metallic-roughness texture handle (present for PBR/sprite/skin
661
+ * shaders). Undefined for the default-unlit shader
662
+ * (materialShaderId === 'forgeax::default-unlit'). The record stage reads
663
+ * this to write GPU view at material bind-group binding 4, falling
664
+ * back to a 1x1 white placeholder when undefined.
665
+ *
666
+ * feat-20260522-learn-render-3-1-sponza-model-loading-with-multi-l M4:
667
+ * field added so the record stage can wire real metallic-roughness
668
+ * textures from Sponza glTF materials (M3 writes the handle into
669
+ * SchemaDrivenMaterialAsset values; M4 extract carries it through to the snapshot).
670
+ */
671
+ readonly metallicRoughnessTexture?: Handle<'TextureAsset', 'shared'> | undefined;
672
+ /**
673
+ * PBR tangent-space normal texture handle (present for PBR/sprite/skin
674
+ * shaders). Undefined for the default-unlit shader
675
+ * (materialShaderId === 'forgeax::default-unlit'). The record stage reads
676
+ * this to write GPU view at material bind-group binding 6, falling
677
+ * back to a (0.5,0.5,1.0) flat-normal placeholder when undefined.
678
+ *
679
+ * feat-20260522-learn-render-3-1-sponza-model-loading-with-multi-l M4:
680
+ * field added symmetrically with metallicRoughnessTexture so the record
681
+ * stage can wire real normal textures from Sponza glTF materials.
682
+ */
683
+ readonly normalTexture?: Handle<'TextureAsset', 'shared'> | undefined;
684
+ /** Scalar applied to tangent-space normal XY after the normal texture sample. */
685
+ readonly normalScale?: number | undefined;
686
+ readonly emissive?: readonly [number, number, number] | undefined;
687
+ readonly emissiveIntensity?: number | undefined;
688
+ readonly emissiveTexture?: Handle<'TextureAsset', 'shared'> | undefined;
689
+ readonly occlusionTexture?: Handle<'TextureAsset', 'shared'> | undefined;
690
+ readonly occlusionStrength?: number | undefined;
691
+ /**
692
+ * Transparent composition flag derived from the first pass's
693
+ * `renderState.blend` presence on the underlying
694
+ * {@link MaterialPass} (feat-20260626-collapse M2: blend
695
+ * presence is the SSOT after `MaterialPass.transparent` was
696
+ * dropped in M1).
697
+ *
698
+ * The record stage reads this to drive both the LDR split-pass
699
+ * decision and the premultiplied-alpha blend resolution on the
700
+ * generic materialShaderId pipeline path — shader-agnostic, decoupled
701
+ * from the legacy `shadingModel` discriminant (feat-20260625 M2 D-3,
702
+ * finalised in w15; `shadingModel` field removed in tweak-20260701 M1).
703
+ *
704
+ * Extract derives this from the first pass's `renderState.blend !==
705
+ * undefined` (post-feat-20260626-collapse: blend presence is the
706
+ * single SSOT for "this material is transparent on the geometry
707
+ * pipeline cache key"). Multi-pass materials whose mix of opaque +
708
+ * transparent passes need finer routing should split into separate
709
+ * MaterialAsset entries (the normal forgeax pattern).
710
+ *
711
+ * Type is `boolean | undefined` (derived): `undefined` means "no
712
+ * passes / unknown"; consumers must read `=== true` / `!== true` to
713
+ * stay correct under both populated and absent cases.
714
+ */
715
+ readonly transparent?: boolean | undefined;
716
+ }
717
+ export interface MaterialCacheChainIdentity {
718
+ readonly asset: MaterialAsset;
719
+ readonly parentGuid: string | undefined;
720
+ }
721
+ export interface MaterialSnapshotCacheEntry {
722
+ readonly snapshot: MaterialSnapshot;
723
+ readonly passes: readonly MaterialPass[];
724
+ /** Root/chain identities are present only on cross-frame-safe entries. */
725
+ readonly chain?: readonly MaterialCacheChainIdentity[];
726
+ /** AssetRegistry epoch at which the root/parent chain was last validated. */
727
+ readonly catalogEpoch?: number;
728
+ /** True only when every object reachable from the authored chain is frozen. */
729
+ readonly crossFrameSafe: boolean;
730
+ }
731
+ export type MaterialSnapshotCache = Map<number, MaterialSnapshotCacheEntry>;
732
+ export type MaterialSnapshotCachesByWorld = WeakMap<World, MaterialSnapshotCache>;
733
+ export interface DispatchEntry {
734
+ readonly entityIndex: number;
735
+ readonly materialHandle: number;
736
+ readonly renderableIndex: number;
737
+ readonly passIndex: number;
738
+ readonly queue: number;
739
+ /**
740
+ * Signed i32 from the entity's {@link Layer} component value (default 0 for
741
+ * entities without a Layer). Primary sort key for the transparent-dispatch
742
+ * sort in {@link render-system.ts}: lower value = drawn first (behind).
743
+ */
744
+ readonly layer: number;
745
+ readonly tags: Record<string, string>;
746
+ readonly renderState: MaterialRenderState | undefined;
747
+ readonly defines: Record<string, string> | undefined;
748
+ readonly vertexEntry: string | undefined;
749
+ readonly fragmentEntry: string | undefined;
750
+ readonly materialShaderId: string | undefined;
751
+ readonly paramSnapshot: Readonly<Record<string, number | number[] | string>> | undefined;
752
+ /**
753
+ * Stencil reference value from {@link MaterialPass.stencilReference}
754
+ * (draw-call dynamic state). Folded during extract for per-draw consumption
755
+ * in the record stage. `undefined` when the pass does not set a reference
756
+ * value (record stage falls back to WebGPU default 0).
757
+ */
758
+ readonly stencilReference?: number;
759
+ }
760
+ export interface ExtractedFrame {
761
+ readonly cameras: CameraSnapshot[];
762
+ readonly auxiliaryCameras: readonly CameraSnapshot[];
763
+ readonly cubeCameras: readonly CubeCameraSnapshot[];
764
+ readonly reflectionProbes?: readonly ReflectionProbeFact[];
765
+ readonly lights: ExtractedLights;
766
+ /** Resource-owner environment facts selected once at the extract boundary. */
767
+ readonly environment: EnvironmentFrame | undefined;
768
+ /** False when the resource-owner world failed environment/fog selection. */
769
+ readonly environmentReady: boolean;
770
+ readonly volumetricFog?: ExtractedVolumetricFog;
771
+ readonly renderables: RenderableSnapshot[];
772
+ /**
773
+ * Single dispatch list sorted by queue value (ascending, stable sort).
774
+ * Replaces the old opaqueDispatch / transparentDispatch / overlayDispatch
775
+ * three-bucket model per plan-strategy D-3.
776
+ */
777
+ readonly dispatch: DispatchEntry[];
778
+ readonly skylight: SkylightSnapshot | undefined;
779
+ readonly skylightCount: number;
780
+ readonly lightProbes?: readonly LightProbeSnapshot[];
781
+ readonly skybox: SkyboxSnapshot | undefined;
782
+ readonly skyboxCount: number;
783
+ /** Resource-owner Fog facts selected once at the frame boundary. */
784
+ readonly fog: FogFrame | undefined;
785
+ readonly fogFailure?: FogSelectionFailure;
786
+ /**
787
+ * feat-20260528-frustum-culling M3 / w11: frustum culling statistics
788
+ * collected during the extract phase. `total` is the count of entities
789
+ * that reached the culling decision point; `culled` is the count of
790
+ * those that were removed from renderables by frustum culling.
791
+ */
792
+ readonly frustumStats: {
793
+ readonly culled: number;
794
+ readonly total: number;
795
+ };
796
+ /** Candidate entities rejected by author visibility before resource parsing. */
797
+ readonly visibilityStats: {
798
+ readonly explicitlyHidden: number;
799
+ };
800
+ /**
801
+ * Per-frame post-process params snapshot collected from PostProcessParams
802
+ * entities (D-1: data-driven params channel). Maps shader id to the
803
+ * raw data bytes (Uint8Array = FieldValueType<'buffer'>). Last-one-wins
804
+ * when multiple entities bear the same shader id.
805
+ * Empty map when no PostProcessParams entities exist.
806
+ */
807
+ readonly postProcessParams: ReadonlyMap<string, Uint8Array>;
808
+ /** Visibility snapshots prepared for each contributing World. */
809
+ readonly visibilitySnapshots: readonly VisibilitySnapshot[];
810
+ /** World-labelled snapshots passed to generic RenderFeature extraction. */
811
+ readonly featureVisibilitySnapshots: readonly RenderFeatureWorldVisibilitySnapshot[];
812
+ /** Built-in hidden candidates, retained for host-side producer deduplication. */
813
+ readonly hiddenEntityReports: readonly RenderFeatureHiddenEntityReport[];
814
+ }
815
+ /**
816
+ * feat-20260612-skin-palette-per-frame-upload M2 / m2-6: narrow per-frame
817
+ * pipeline surface consumed by `extractFrame`. Today only `skinPaletteAllocator`
818
+ * crosses the seam (the allocator owns the per-frame palette buffer + cursor;
819
+ * extract calls `resetForFrame` at frame entry then `allocateSlice` +
820
+ * `writeJointPalette` per skinned entity). Kept narrow on purpose — extract
821
+ * does NOT see the rest of `PipelineState` to avoid a circular import via
822
+ * `render-system.ts`.
823
+ */
824
+ export interface ExtractPipelineSurface {
825
+ readonly skinPaletteAllocator: SkinPaletteAllocator | null;
826
+ }
827
+ /**
828
+ * bug-20260710-editor-cross-world-shadow: the camera-frustum subset of
829
+ * {@link CameraSnapshot} that the directional-CSM matrix builder consumes.
830
+ */
831
+ export interface CsmCameraData {
832
+ readonly world: Float32Array;
833
+ readonly fov: number;
834
+ readonly aspect: number;
835
+ readonly near: number;
836
+ readonly far: number;
837
+ readonly projection: 'perspective' | 'orthographic';
838
+ readonly orthoLeft: number;
839
+ readonly orthoRight: number;
840
+ readonly orthoBottom: number;
841
+ readonly orthoTop: number;
842
+ }
843
+ /**
844
+ * bug-20260710-editor-cross-world-shadow: the raw directional-shadow config a
845
+ * DirectionalLight carries, threaded onto {@link ExtractedLights} so the merge
846
+ * layer can recompute CSM matrices against the surfaced camera. Distinct from
847
+ * the *computed* outputs (lightViewProj / splitPlanes) also on ExtractedLights.
848
+ */
849
+ export interface DirectionalCsmConfig {
850
+ readonly cascadeCount: number;
851
+ readonly splitLambda: number;
852
+ readonly cascadeBlend: number;
853
+ readonly mapSize: number;
854
+ readonly shadowDistance: number;
855
+ readonly shadowFilter: number;
856
+ readonly shadowAngularRadius: number;
857
+ readonly maxPenumbraTexels: number;
858
+ }
859
+ /**
860
+ * bug-20260710-editor-cross-world-shadow: computed directional-CSM output —
861
+ * the per-cascade light-view-projection matrices plus the derived cascade
862
+ * metadata. Returned by {@link computeDirectionalCsm}; `undefined` when the
863
+ * config or camera is missing (caller leaves the fields undefined).
864
+ */
865
+ export interface DirectionalCsmResult {
866
+ readonly lightViewProj: Float32Array[];
867
+ readonly splitPlanes: Float32Array;
868
+ readonly cascadeCount: number;
869
+ readonly cascadeBlend: number;
870
+ readonly shadowMapSize: number;
871
+ readonly directionalShadowQuality: DirectionalShadowQuality;
872
+ }
873
+ /**
874
+ * feat-20260709-editor-world-partition M1 / w4 (AC-08, plan-strategy §2 D-3):
875
+ * the owner index that previously served BOTH cameras and singleton render
876
+ * resources (skylight / skybox / postProcessParams) is split into two
877
+ * independent indices. `cameraOwner` selects the world whose cameras are
878
+ * surfaced; `resourceOwner` selects the world whose singleton resources are
879
+ * surfaced. A single number is accepted as the backward-compatible legacy form
880
+ * where `cameraOwner === resourceOwner === owner` (single-world callers +
881
+ * frame-loop stay byte-identical; the hard `{ owner }` cutover lands in M2).
882
+ */
883
+ export interface ExtractFramesOwner {
884
+ readonly cameraOwner: number;
885
+ readonly resourceOwner: number;
886
+ }
887
+ export interface PreparedExtractContext {
888
+ readonly assets: AssetRegistry | null | undefined;
889
+ readonly pipelineState: ExtractPipelineSurface | null | undefined;
890
+ readonly materialSnapshotCache: MaterialSnapshotCache | undefined;
891
+ /** `undefined` keeps direct extractFrame's local Fog semantics; `null` means
892
+ * the frame owner already selected that no Fog is present for this world. */
893
+ readonly resourceOwnerFog: FogFrame | null | undefined;
894
+ readonly cull: 'self' | 'none' | 'external';
895
+ readonly cullCameras: readonly CameraSnapshot[] | undefined;
896
+ readonly hierarchy: SceneHierarchySnapshot;
897
+ readonly visibility: VisibilitySnapshot;
898
+ }
899
+ //# sourceMappingURL=contracts.d.ts.map