@forgeax/engine-render 0.1.3 → 0.1.6

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 (918) hide show
  1. package/README.md +130 -641
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts +2 -0
  4. package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts.map +1 -0
  5. package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts +2 -0
  6. package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts.map +1 -0
  7. package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts +2 -0
  8. package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts.map +1 -0
  9. package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts.map +1 -1
  10. package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts +6 -0
  11. package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts.map +1 -1
  12. package/dist/{gpu-driven/view-reference.d.ts → __tests__/gpu-driven-view-reference.d.ts} +4 -4
  13. package/dist/__tests__/gpu-driven-view-reference.d.ts.map +1 -0
  14. package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts.map +1 -1
  15. package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts +2 -0
  16. package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts.map +1 -0
  17. package/dist/__tests__/morph-feature-plan.unit.test.d.ts +2 -0
  18. package/dist/__tests__/morph-feature-plan.unit.test.d.ts.map +1 -0
  19. package/dist/__tests__/render-feature-plan.test-d.d.ts +2 -0
  20. package/dist/__tests__/render-feature-plan.test-d.d.ts.map +1 -0
  21. package/dist/__tests__/render-feature-plan.unit.test.d.ts +2 -0
  22. package/dist/__tests__/render-feature-plan.unit.test.d.ts.map +1 -0
  23. package/dist/__tests__/ssao-config.unit.test.d.ts +2 -0
  24. package/dist/__tests__/ssao-config.unit.test.d.ts.map +1 -0
  25. package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts +2 -0
  26. package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts.map +1 -0
  27. package/dist/__tests__/standard-descriptors.test-d.d.ts +2 -0
  28. package/dist/__tests__/standard-descriptors.test-d.d.ts.map +1 -0
  29. package/dist/__tests__/standard-pipeline.dawn.test.d.ts +2 -0
  30. package/dist/__tests__/standard-pipeline.dawn.test.d.ts.map +1 -0
  31. package/dist/__tests__/standard-pipeline.integration.test.d.ts +2 -0
  32. package/dist/__tests__/standard-pipeline.integration.test.d.ts.map +1 -0
  33. package/dist/__tests__/standard-profile-oracle.unit.test.d.ts +2 -0
  34. package/dist/__tests__/standard-profile-oracle.unit.test.d.ts.map +1 -0
  35. package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts +2 -0
  36. package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts.map +1 -0
  37. package/dist/{renderer/backend-selection.d.ts → assembly/backend-contract.d.ts} +15 -4
  38. package/dist/assembly/backend-contract.d.ts.map +1 -0
  39. package/dist/assembly/factory.d.ts +207 -0
  40. package/dist/assembly/factory.d.ts.map +1 -0
  41. package/dist/assembly/host-contract.d.ts +84 -0
  42. package/dist/assembly/host-contract.d.ts.map +1 -0
  43. package/dist/{renderer → assembly}/material/assembly.d.ts +1 -2
  44. package/dist/{renderer → assembly}/material/assembly.d.ts.map +1 -1
  45. package/dist/assembly/material/pipeline-projection.d.ts +30 -0
  46. package/dist/assembly/material/pipeline-projection.d.ts.map +1 -0
  47. package/dist/authoring.d.ts +10 -11
  48. package/dist/authoring.d.ts.map +1 -1
  49. package/dist/authoring.mjs +25 -3
  50. package/dist/authoring.mjs.map +1 -1
  51. package/dist/chunk-CQXZC5XI.mjs +182 -0
  52. package/dist/chunk-CQXZC5XI.mjs.map +1 -0
  53. package/dist/chunk-QC4VW3XJ.mjs +79 -0
  54. package/dist/chunk-QC4VW3XJ.mjs.map +1 -0
  55. package/dist/chunk-SCRSAK5B.mjs +480 -0
  56. package/dist/chunk-SCRSAK5B.mjs.map +1 -0
  57. package/dist/components/__tests__/schema-contract.unit.test.d.ts +2 -0
  58. package/dist/components/__tests__/schema-contract.unit.test.d.ts.map +1 -0
  59. package/dist/components/glyph-text.d.ts +1 -1
  60. package/dist/components/glyph-text.d.ts.map +1 -1
  61. package/dist/components/index.d.ts +2 -2
  62. package/dist/components/index.d.ts.map +1 -1
  63. package/dist/components/instances.d.ts +1 -1
  64. package/dist/components/instances.d.ts.map +1 -1
  65. package/dist/components/light-helpers.d.ts +1 -1
  66. package/dist/components/light-helpers.d.ts.map +1 -1
  67. package/dist/components/mesh-filter.d.ts +7 -7
  68. package/dist/components/mesh-filter.d.ts.map +1 -1
  69. package/dist/components/scene-instance.d.ts +11 -11
  70. package/dist/components/skybox-background.d.ts +56 -0
  71. package/dist/components/skybox-background.d.ts.map +1 -0
  72. package/dist/components/skylight.d.ts +55 -0
  73. package/dist/components/skylight.d.ts.map +1 -0
  74. package/dist/components/sprite-animation.d.ts +2 -3
  75. package/dist/components/sprite-animation.d.ts.map +1 -1
  76. package/dist/components/sprite-instances.d.ts +1 -1
  77. package/dist/components/sprite-playback-mode.d.ts +6 -1
  78. package/dist/components/sprite-playback-mode.d.ts.map +1 -1
  79. package/dist/components/sprite-region-override.d.ts +2 -3
  80. package/dist/components/sprite-region-override.d.ts.map +1 -1
  81. package/dist/components/tile-layer.d.ts +5 -0
  82. package/dist/components/tile-layer.d.ts.map +1 -1
  83. package/dist/construct-renderer.d.ts +18 -1
  84. package/dist/construct-renderer.d.ts.map +1 -1
  85. package/dist/construct-renderer.mjs +27008 -4
  86. package/dist/construct-renderer.mjs.map +1 -1
  87. package/dist/debug-draw-glue.d.ts +2 -53
  88. package/dist/debug-draw-glue.d.ts.map +1 -1
  89. package/dist/device/device-scope.d.ts +83 -0
  90. package/dist/device/device-scope.d.ts.map +1 -0
  91. package/dist/{gpu-resource-store.d.ts → device/gpu-residency.d.ts} +91 -48
  92. package/dist/device/gpu-residency.d.ts.map +1 -0
  93. package/dist/device/resource-types.d.ts +8 -0
  94. package/dist/device/resource-types.d.ts.map +1 -0
  95. package/dist/engine-metrics.d.ts +2 -2
  96. package/dist/engine-metrics.d.ts.map +1 -1
  97. package/dist/errors/recover.d.ts +28 -1
  98. package/dist/errors/recover.d.ts.map +1 -1
  99. package/dist/errors/render.d.ts +249 -258
  100. package/dist/errors/render.d.ts.map +1 -1
  101. package/dist/features/fullscreen.d.ts +19 -0
  102. package/dist/features/fullscreen.d.ts.map +1 -0
  103. package/dist/features/host.d.ts +32 -26
  104. package/dist/features/host.d.ts.map +1 -1
  105. package/dist/features/morph/morph-feature.d.ts +39 -5
  106. package/dist/features/morph/morph-feature.d.ts.map +1 -1
  107. package/dist/features/plan.d.ts +182 -0
  108. package/dist/features/plan.d.ts.map +1 -0
  109. package/dist/features/prepared-gpu-work.d.ts +21 -17
  110. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  111. package/dist/features/prepared-graphics-store.d.ts +2 -1
  112. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  113. package/dist/features/prepared-graphics.d.ts +11 -21
  114. package/dist/features/prepared-graphics.d.ts.map +1 -1
  115. package/dist/features/render-graph-compute.d.ts +2 -2
  116. package/dist/features/render-graph-compute.d.ts.map +1 -1
  117. package/dist/features/render-graph-contribution.d.ts +4 -7
  118. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  119. package/dist/features/render-graph-raster.d.ts +2 -2
  120. package/dist/features/render-graph-raster.d.ts.map +1 -1
  121. package/dist/features/render-graph-resources.d.ts +6 -6
  122. package/dist/features/render-graph-resources.d.ts.map +1 -1
  123. package/dist/features/targets.d.ts +5 -5
  124. package/dist/features/targets.d.ts.map +1 -1
  125. package/dist/features/types.d.ts +11 -190
  126. package/dist/features/types.d.ts.map +1 -1
  127. package/dist/features/vocabulary.d.ts +14 -0
  128. package/dist/features/vocabulary.d.ts.map +1 -0
  129. package/dist/fullscreen-post-process-pass.d.ts +4 -25
  130. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  131. package/dist/glyph-text-layout-system.d.ts +3 -2
  132. package/dist/glyph-text-layout-system.d.ts.map +1 -1
  133. package/dist/gpu-driven/batch-topology.d.ts +6 -75
  134. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  135. package/dist/gpu-driven/production-raster.d.ts +13 -112
  136. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  137. package/dist/gpu-driven/view-gpu.d.ts +10 -66
  138. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  139. package/dist/gpu-resource.d.ts +3 -3
  140. package/dist/gpu-scene-schema.d.ts +1 -94
  141. package/dist/gpu-scene-schema.d.ts.map +1 -1
  142. package/dist/gpu-scene.d.ts +7 -33
  143. package/dist/gpu-scene.d.ts.map +1 -1
  144. package/dist/hdrp-buffers.d.ts +3 -53
  145. package/dist/hdrp-buffers.d.ts.map +1 -1
  146. package/dist/ibl/IblPipelineCache.d.ts +74 -180
  147. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  148. package/dist/ibl/skylight-bind-group.d.ts +1 -1
  149. package/dist/index.d.ts +13 -43
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.mjs +165 -3
  152. package/dist/index.mjs.map +1 -1
  153. package/dist/inspection-types.d.ts +69 -0
  154. package/dist/inspection-types.d.ts.map +1 -0
  155. package/dist/instance-buffer-cache.d.ts +1 -4
  156. package/dist/instance-buffer-cache.d.ts.map +1 -1
  157. package/dist/internal.d.ts +1 -73
  158. package/dist/internal.d.ts.map +1 -1
  159. package/dist/internal.mjs +1 -43
  160. package/dist/internal.mjs.map +1 -1
  161. package/dist/lifecycle.d.ts +36 -2
  162. package/dist/lifecycle.d.ts.map +1 -1
  163. package/dist/materials.d.ts +0 -3
  164. package/dist/materials.d.ts.map +1 -1
  165. package/dist/mesh-material-bindings.d.ts +0 -1
  166. package/dist/mesh-material-bindings.d.ts.map +1 -1
  167. package/dist/pbr-pipeline.d.ts +75 -29
  168. package/dist/pbr-pipeline.d.ts.map +1 -1
  169. package/dist/pipeline/standard-forward-lane.d.ts +5 -0
  170. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -0
  171. package/dist/pipeline/standard-pipeline.d.ts +31 -0
  172. package/dist/pipeline/standard-pipeline.d.ts.map +1 -0
  173. package/dist/pipeline/standard-profile.d.ts +40 -0
  174. package/dist/pipeline/standard-profile.d.ts.map +1 -0
  175. package/dist/pipeline-builder.d.ts +3 -3
  176. package/dist/pipeline-builder.d.ts.map +1 -1
  177. package/dist/pipeline-spec-types.d.ts +24 -0
  178. package/dist/pipeline-spec-types.d.ts.map +1 -0
  179. package/dist/pipeline-spec.d.ts +16 -155
  180. package/dist/pipeline-spec.d.ts.map +1 -1
  181. package/dist/plugin.d.ts +1 -14
  182. package/dist/plugin.d.ts.map +1 -1
  183. package/dist/post-process-errors.d.ts +18 -18
  184. package/dist/post-process-errors.d.ts.map +1 -1
  185. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -5
  186. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  187. package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts +2 -0
  188. package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts.map +1 -0
  189. package/dist/record/frame-lighting.d.ts +7 -73
  190. package/dist/record/frame-lighting.d.ts.map +1 -1
  191. package/dist/record/frame-snapshot.d.ts +44 -44
  192. package/dist/record/frame-snapshot.d.ts.map +1 -1
  193. package/dist/record/frame-targets.d.ts +5 -38
  194. package/dist/record/frame-targets.d.ts.map +1 -1
  195. package/dist/record/frame.d.ts +64 -52
  196. package/dist/record/frame.d.ts.map +1 -1
  197. package/dist/record/helpers.d.ts +3 -2
  198. package/dist/record/helpers.d.ts.map +1 -1
  199. package/dist/record/main-pass-geometry.d.ts +5 -4
  200. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  201. package/dist/record/main-pass-material.d.ts +90 -59
  202. package/dist/record/main-pass-material.d.ts.map +1 -1
  203. package/dist/record/main-pass-sprite-draws.d.ts +28 -3
  204. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  205. package/dist/record/main-pass.d.ts +1 -1
  206. package/dist/record/main-pass.d.ts.map +1 -1
  207. package/dist/record/mesh-ssbo.d.ts +276 -3
  208. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  209. package/dist/record/render-context.d.ts +235 -0
  210. package/dist/record/render-context.d.ts.map +1 -0
  211. package/dist/record/shadow-pass.d.ts +15 -88
  212. package/dist/record/shadow-pass.d.ts.map +1 -1
  213. package/dist/record/skybox-post-pass.d.ts +1 -1
  214. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  215. package/dist/record/typed-frame-graph.d.ts +29 -7
  216. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  217. package/dist/record/view-ubo.d.ts +3 -3
  218. package/dist/record/view-ubo.d.ts.map +1 -1
  219. package/dist/render-contract.d.ts +416 -0
  220. package/dist/render-contract.d.ts.map +1 -0
  221. package/dist/render-data.d.ts.map +1 -1
  222. package/dist/render-graph-primitives.d.ts +14 -362
  223. package/dist/render-graph-primitives.d.ts.map +1 -1
  224. package/dist/render-pipeline.d.ts +25 -64
  225. package/dist/render-pipeline.d.ts.map +1 -1
  226. package/dist/render-system-extract.d.ts +107 -338
  227. package/dist/render-system-extract.d.ts.map +1 -1
  228. package/dist/render-system.d.ts +21 -713
  229. package/dist/render-system.d.ts.map +1 -1
  230. package/dist/scene/render-scene-types.d.ts +58 -0
  231. package/dist/scene/render-scene-types.d.ts.map +1 -0
  232. package/dist/scene/render-scene.d.ts +105 -0
  233. package/dist/scene/render-scene.d.ts.map +1 -0
  234. package/dist/scene-instances/post-spawn-resolve-joints.d.ts +2 -5
  235. package/dist/scene-instances/post-spawn-resolve-joints.d.ts.map +1 -1
  236. package/dist/ssao-buffers.d.ts +22 -3
  237. package/dist/ssao-buffers.d.ts.map +1 -1
  238. package/dist/systems/skin-palette-allocator.d.ts +2 -4
  239. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  240. package/dist/systems/skin-palette-types.d.ts +14 -0
  241. package/dist/systems/skin-palette-types.d.ts.map +1 -0
  242. package/dist/systems/transparent-sort-config.d.ts +23 -2
  243. package/dist/systems/transparent-sort-config.d.ts.map +1 -1
  244. package/dist/tilemap-chunk-extract-system.d.ts +4 -3
  245. package/dist/tilemap-chunk-extract-system.d.ts.map +1 -1
  246. package/dist/typed-render-graph-primitives.d.ts +2 -4
  247. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  248. package/dist/typed-shadow-passes.d.ts +3 -3
  249. package/dist/typed-shadow-passes.d.ts.map +1 -1
  250. package/package.json +23 -23
  251. package/src/__tests__/backend-selection-rhi-capture.test-d.ts +1 -1
  252. package/src/__tests__/callback-inference.test-d.ts +6 -3
  253. package/src/__tests__/cluster-grid-default-surface.unit.test.ts +7 -4
  254. package/src/__tests__/construct-renderer-identity.unit.test.ts +15 -2
  255. package/src/__tests__/device-scope-lifecycle.unit.test.ts +151 -0
  256. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +42 -0
  257. package/src/__tests__/direct-extract-consumer-contract.test-d.ts +8 -19
  258. package/src/__tests__/direct-light-snapshot.unit.test.ts +3 -13
  259. package/src/__tests__/factory-contract.integration.test.ts +158 -209
  260. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +1 -4
  261. package/src/__tests__/frame-observation.contract.test.ts +17 -8
  262. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +32 -0
  263. package/src/__tests__/glyph-text-layout-recovery.unit.test.ts +6 -11
  264. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +9 -16
  265. package/src/__tests__/gpu-driven-production.integration.test.ts +32 -205
  266. package/src/__tests__/gpu-driven-scaling.unit.test.ts +4 -7
  267. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +87 -8
  268. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +170 -8
  269. package/src/{gpu-driven/view-reference.ts → __tests__/gpu-driven-view-reference.ts} +4 -3
  270. package/src/__tests__/gpu-driven-view.browser.test.ts +12 -1
  271. package/src/__tests__/gpu-driven-view.dawn.test.ts +12 -1
  272. package/src/__tests__/gpu-driven-view.unit.test.ts +11 -267
  273. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +3 -3
  274. package/src/__tests__/gpu-scene-render-graph-gpu.ts +2 -3
  275. package/src/__tests__/gpu-scene.dawn.test.ts +2 -6
  276. package/src/__tests__/gpu-scene.unit.test.ts +10 -24
  277. package/src/__tests__/ibl/face-uniforms.unit.test.ts +46 -0
  278. package/src/__tests__/infinite-grid-no-vertex-probe.unit.test.ts +34 -66
  279. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +14 -5
  280. package/src/__tests__/light-buffer-layout.unit.test.ts +4 -49
  281. package/src/__tests__/material-cooked-projection.unit.test.ts +2 -51
  282. package/src/__tests__/material-snapshot-mutation.integration.test.ts +10 -15
  283. package/src/__tests__/material-static-dynamic-route.unit.test.ts +4 -23
  284. package/src/__tests__/material-stride-surface.unit.test.ts +2 -2
  285. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +7 -8
  286. package/src/__tests__/morph-culling-reentry.dawn.test.ts +29 -38
  287. package/src/__tests__/morph-feature-gpu-work.integration.test.ts +45 -43
  288. package/src/__tests__/morph-feature-plan.unit.test.ts +53 -0
  289. package/src/__tests__/morph-visual-evidence.integration.test.ts +47 -33
  290. package/src/__tests__/nineslice-handle-surface.unit.test.ts +11 -6
  291. package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -13
  292. package/src/__tests__/prepared-graphics-capability.unit.test.ts +6 -81
  293. package/src/__tests__/prepared-graphics-generation.unit.test.ts +3 -17
  294. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +6 -74
  295. package/src/__tests__/prepared-graphics-resolver.unit.test.ts +1 -3
  296. package/src/__tests__/prepared-graphics-snapshot.unit.test.ts +2 -2
  297. package/src/__tests__/profiler-default-off.test.ts +1 -1
  298. package/src/__tests__/profiler-phase-catalog.test.ts +2 -2
  299. package/src/__tests__/profiler-phase-integration.test.ts +5 -13
  300. package/src/__tests__/profiler-phase-token.test.ts +3 -8
  301. package/src/__tests__/public-surface.test-d.ts +65 -3
  302. package/src/__tests__/recover-error-policy-owner.unit.test.ts +1 -21
  303. package/src/__tests__/render-error-code-owner.test-d.ts +18 -23
  304. package/src/__tests__/render-error-detail-ssot.test-d.ts +0 -95
  305. package/src/__tests__/render-error-exhaustive.test-d.ts +8 -1
  306. package/src/__tests__/render-feature-assembly.test-d.ts +8 -16
  307. package/src/__tests__/render-feature-context.test-d.ts +16 -40
  308. package/src/__tests__/render-feature-contract.test-d.ts +9 -18
  309. package/src/__tests__/render-feature-diagnostics.unit.test.ts +6 -8
  310. package/src/__tests__/render-feature-docs.unit.test.ts +8 -7
  311. package/src/__tests__/render-feature-gpu-work.integration.test.ts +14 -75
  312. package/src/__tests__/render-feature-plan.test-d.ts +161 -0
  313. package/src/__tests__/render-feature-plan.unit.test.ts +170 -0
  314. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +8 -19
  315. package/src/__tests__/render-feature-prepared-errors.test-d.ts +3 -6
  316. package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +10 -71
  317. package/src/__tests__/render-feature-prepared-graphics-isolation.unit.test.ts +11 -61
  318. package/src/__tests__/render-feature-prepared-graphics-negative.test-d.ts +20 -43
  319. package/src/__tests__/render-feature-prepared-graphics.test-d.ts +56 -78
  320. package/src/__tests__/render-feature-public-surface.test-d.ts +6 -24
  321. package/src/__tests__/render-feature-retry.unit.test.ts +7 -48
  322. package/src/__tests__/render-feature-scheduling.unit.test.ts +15 -27
  323. package/src/__tests__/render-feature-stage-failed-policy-owner.unit.test.ts +0 -9
  324. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +19 -109
  325. package/src/__tests__/render-feature-visibility-context.test-d.ts +1 -6
  326. package/src/__tests__/render-feature-visibility-context.unit.test.ts +1 -2
  327. package/src/__tests__/render-feature-zero-work.unit.test.ts +14 -20
  328. package/src/__tests__/render-scene-projection.unit.test.ts +73 -111
  329. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +46 -50
  330. package/src/__tests__/renderer-lifecycle.integration.test.ts +49 -1
  331. package/src/__tests__/shader-stage-surface.unit.test.ts +14 -9
  332. package/src/__tests__/ssao-config.unit.test.ts +36 -0
  333. package/src/__tests__/ssao-kernel-surface.unit.test.ts +4 -5
  334. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +28 -0
  335. package/src/__tests__/standard-descriptors.test-d.ts +22 -0
  336. package/src/__tests__/standard-pipeline.dawn.test.ts +61 -0
  337. package/src/__tests__/standard-pipeline.integration.test.ts +124 -0
  338. package/src/__tests__/standard-profile-oracle.unit.test.ts +62 -0
  339. package/src/__tests__/surface-configuration.unit.test.ts +1 -2
  340. package/src/__tests__/texture-usage-surface.unit.test.ts +3 -6
  341. package/src/__tests__/typed-pipeline-topology.unit.test.ts +40 -206
  342. package/src/__tests__/urp-pipeline-targets.unit.test.ts +1 -11
  343. package/src/__tests__/urp-pipeline.unit.test.ts +2 -2
  344. package/src/__tests__/vertex-color-pipeline.unit.test.ts +10 -2
  345. package/src/__tests__/vertex-layout-consumer.unit.test.ts +1 -1
  346. package/src/__tests__/visibility-diagnostics.integration.test.ts +7 -11
  347. package/src/__tests__/visibility-extract.integration.test.ts +20 -11
  348. package/src/__tests__/visibility-extract.perf.test.ts +66 -32
  349. package/src/__tests__/visibility-feature-dedup.integration.test.ts +2 -4
  350. package/src/__tests__/visibility-hidden-report.unit.test.ts +1 -2
  351. package/src/__tests__/visibility-instances.integration.test.ts +7 -11
  352. package/src/__tests__/visibility-multi-world.integration.test.ts +38 -6
  353. package/src/__tests__/visibility-producer-matrix.integration.test.ts +18 -41
  354. package/src/__tests__/visibility-public-surface.test-d.ts +10 -9
  355. package/src/__tests__/visibility-resolver.unit.test.ts +2 -1
  356. package/src/__tests__/visibility-resource-short-circuit.unit.test.ts +80 -0
  357. package/src/__tests__/visibility-snapshot-contract.unit.test.ts +2 -1
  358. package/src/__tests__/vocabulary.unit.test.ts +1 -1
  359. package/src/assembly/backend-contract.ts +57 -0
  360. package/src/{renderer/renderer-factory.ts → assembly/factory.ts} +1709 -2693
  361. package/src/assembly/host-contract.ts +101 -0
  362. package/src/{renderer → assembly}/material/assembly.ts +1 -3
  363. package/src/assembly/material/pipeline-projection.ts +63 -0
  364. package/src/authoring.ts +14 -22
  365. package/src/components/__tests__/schema-contract.unit.test.ts +10 -0
  366. package/src/components/glyph-text.ts +3 -2
  367. package/src/components/index.ts +7 -9
  368. package/src/components/instances.ts +4 -5
  369. package/src/components/light-helpers.ts +1 -1
  370. package/src/components/mesh-filter.ts +11 -10
  371. package/src/components/post-process-params.ts +3 -3
  372. package/src/components/scene-instance.ts +12 -12
  373. package/src/components/skybox-background.ts +103 -0
  374. package/src/components/{environment.ts → skylight.ts} +2 -111
  375. package/src/components/sprite-animation.ts +3 -4
  376. package/src/components/sprite-instances.ts +2 -2
  377. package/src/components/sprite-playback-mode.ts +7 -1
  378. package/src/components/sprite-region-override.ts +2 -3
  379. package/src/components/tile-layer.ts +8 -2
  380. package/src/construct-renderer.ts +67 -4
  381. package/src/debug-draw-glue.ts +8 -129
  382. package/src/device/device-scope.ts +306 -0
  383. package/src/{gpu-resource-store.ts → device/gpu-residency.ts} +540 -639
  384. package/src/device/resource-types.ts +20 -0
  385. package/src/engine-metrics.ts +12 -19
  386. package/src/errors/recover.ts +45 -3
  387. package/src/errors/render.ts +357 -460
  388. package/src/features/fullscreen.ts +46 -0
  389. package/src/features/host.ts +575 -309
  390. package/src/features/morph/morph-feature.ts +195 -105
  391. package/src/features/plan.ts +447 -0
  392. package/src/features/prepared-gpu-work.ts +72 -15
  393. package/src/features/prepared-graphics-store.ts +20 -6
  394. package/src/features/prepared-graphics.ts +12 -71
  395. package/src/features/render-graph-compute.ts +14 -5
  396. package/src/features/render-graph-contribution.ts +43 -63
  397. package/src/features/render-graph-raster.ts +11 -6
  398. package/src/features/render-graph-resources.ts +25 -23
  399. package/src/features/targets.ts +8 -21
  400. package/src/features/types.ts +39 -227
  401. package/src/features/vocabulary.ts +24 -0
  402. package/src/fullscreen-post-process-pass.ts +14 -57
  403. package/src/glyph-text-layout-system.ts +70 -96
  404. package/src/gpu-driven/batch-topology.ts +24 -202
  405. package/src/gpu-driven/production-raster.ts +93 -1108
  406. package/src/gpu-driven/view-gpu.ts +46 -192
  407. package/src/gpu-resource.ts +4 -4
  408. package/src/gpu-scene-schema.ts +11 -99
  409. package/src/gpu-scene.ts +231 -364
  410. package/src/hdrp-buffers.ts +12 -221
  411. package/src/ibl/IblPipelineCache.ts +471 -711
  412. package/src/ibl/skylight-bind-group.ts +4 -4
  413. package/src/index.ts +58 -217
  414. package/src/inspection-types.ts +76 -0
  415. package/src/instance-buffer-cache.ts +1 -29
  416. package/src/internal.ts +6 -85
  417. package/src/lifecycle.ts +64 -19
  418. package/src/materials.ts +7 -29
  419. package/src/mesh-material-bindings.ts +0 -1
  420. package/src/pbr-pipeline.ts +434 -53
  421. package/src/{urp-pipeline.ts → pipeline/standard-forward-lane.ts} +38 -149
  422. package/src/{hdrp-pipeline.ts → pipeline/standard-pipeline.ts} +221 -191
  423. package/src/pipeline/standard-profile.ts +65 -0
  424. package/src/pipeline-builder.ts +60 -64
  425. package/src/pipeline-spec-types.ts +28 -0
  426. package/src/pipeline-spec.ts +72 -609
  427. package/src/plugin.ts +3 -75
  428. package/src/post-process-errors.ts +31 -33
  429. package/src/prepare/prepared-graphics-resolver.ts +5 -4
  430. package/src/record/__tests__/material-slot-plan.unit.test.ts +1 -33
  431. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +41 -0
  432. package/src/record/__tests__/video-texture-view.unit.test.ts +1 -1
  433. package/src/record/frame-lighting.ts +74 -195
  434. package/src/record/frame-snapshot.ts +45 -60
  435. package/src/record/frame-targets.ts +8 -243
  436. package/src/record/frame.ts +509 -796
  437. package/src/record/helpers.ts +6 -11
  438. package/src/record/main-pass-geometry.ts +106 -147
  439. package/src/record/main-pass-material.ts +517 -190
  440. package/src/record/main-pass-sprite-draws.ts +198 -117
  441. package/src/record/main-pass.ts +162 -143
  442. package/src/record/mesh-ssbo.ts +517 -38
  443. package/src/record/render-context.ts +364 -0
  444. package/src/record/shadow-pass.ts +138 -1838
  445. package/src/record/skybox-post-pass.ts +12 -14
  446. package/src/record/typed-frame-graph.ts +215 -254
  447. package/src/record/view-ubo.ts +6 -37
  448. package/src/render-contract.ts +571 -0
  449. package/src/render-data.ts +3 -3
  450. package/src/render-graph-primitives.ts +76 -851
  451. package/src/render-pipeline.ts +104 -188
  452. package/src/render-system-extract.ts +1048 -1729
  453. package/src/render-system.ts +330 -1957
  454. package/src/scene/render-scene-types.ts +64 -0
  455. package/src/scene/render-scene.ts +1032 -0
  456. package/src/scene-instances/post-spawn-resolve-joints.ts +4 -7
  457. package/src/ssao-buffers.ts +167 -8
  458. package/src/systems/skin-palette-allocator.ts +21 -64
  459. package/src/systems/skin-palette-types.ts +14 -0
  460. package/src/systems/transparent-sort-config.ts +25 -3
  461. package/src/tilemap-chunk-extract-system.ts +53 -70
  462. package/src/typed-render-graph-primitives.ts +35 -24
  463. package/src/typed-shadow-passes.ts +26 -56
  464. package/dist/__tests__/analytic-sky-contract.test.d.ts +0 -2
  465. package/dist/__tests__/analytic-sky-contract.test.d.ts.map +0 -1
  466. package/dist/__tests__/analytic-sky-falsify.test.d.ts +0 -2
  467. package/dist/__tests__/analytic-sky-falsify.test.d.ts.map +0 -1
  468. package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts +0 -2
  469. package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts.map +0 -1
  470. package/dist/__tests__/backend-selection.integration.test.d.ts +0 -2
  471. package/dist/__tests__/backend-selection.integration.test.d.ts.map +0 -1
  472. package/dist/__tests__/camera-temporal.test-d.d.ts +0 -2
  473. package/dist/__tests__/camera-temporal.test-d.d.ts.map +0 -1
  474. package/dist/__tests__/camera-temporal.test.d.ts +0 -2
  475. package/dist/__tests__/camera-temporal.test.d.ts.map +0 -1
  476. package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts +0 -2
  477. package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts.map +0 -1
  478. package/dist/__tests__/environment-inspection.test.d.ts +0 -2
  479. package/dist/__tests__/environment-inspection.test.d.ts.map +0 -1
  480. package/dist/__tests__/fog-ai-user.fixture.d.ts +0 -2
  481. package/dist/__tests__/fog-ai-user.fixture.d.ts.map +0 -1
  482. package/dist/__tests__/fog-custom-render-feature.fixture.d.ts +0 -16
  483. package/dist/__tests__/fog-custom-render-feature.fixture.d.ts.map +0 -1
  484. package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts +0 -2
  485. package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts.map +0 -1
  486. package/dist/__tests__/fog-inspection.integration.test.d.ts +0 -2
  487. package/dist/__tests__/fog-inspection.integration.test.d.ts.map +0 -1
  488. package/dist/__tests__/fog-owner-state.integration.test.d.ts +0 -2
  489. package/dist/__tests__/fog-owner-state.integration.test.d.ts.map +0 -1
  490. package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts +0 -2
  491. package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts.map +0 -1
  492. package/dist/__tests__/fog-public-surface.integration.test.d.ts +0 -2
  493. package/dist/__tests__/fog-public-surface.integration.test.d.ts.map +0 -1
  494. package/dist/__tests__/fog-ray-contract.integration.test.d.ts +0 -2
  495. package/dist/__tests__/fog-ray-contract.integration.test.d.ts.map +0 -1
  496. package/dist/__tests__/fog-source-absence.integration.test.d.ts +0 -2
  497. package/dist/__tests__/fog-source-absence.integration.test.d.ts.map +0 -1
  498. package/dist/__tests__/fog-temporal.integration.test.d.ts +0 -2
  499. package/dist/__tests__/fog-temporal.integration.test.d.ts.map +0 -1
  500. package/dist/__tests__/frame-chain.unit.test.d.ts +0 -2
  501. package/dist/__tests__/frame-chain.unit.test.d.ts.map +0 -1
  502. package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts +0 -2
  503. package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts.map +0 -1
  504. package/dist/__tests__/hdrp-pipeline.unit.test.d.ts +0 -2
  505. package/dist/__tests__/hdrp-pipeline.unit.test.d.ts.map +0 -1
  506. package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts +0 -2
  507. package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts.map +0 -1
  508. package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts +0 -2
  509. package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts.map +0 -1
  510. package/dist/__tests__/material-derived-payload.integration.test.d.ts +0 -2
  511. package/dist/__tests__/material-derived-payload.integration.test.d.ts.map +0 -1
  512. package/dist/__tests__/materials.unit.test.d.ts +0 -2
  513. package/dist/__tests__/materials.unit.test.d.ts.map +0 -1
  514. package/dist/__tests__/param-schema-projection-census.unit.test.d.ts +0 -2
  515. package/dist/__tests__/param-schema-projection-census.unit.test.d.ts.map +0 -1
  516. package/dist/__tests__/persistent-render-scene.unit.test.d.ts +0 -2
  517. package/dist/__tests__/persistent-render-scene.unit.test.d.ts.map +0 -1
  518. package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts +0 -2
  519. package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts.map +0 -1
  520. package/dist/__tests__/pipeline-pass-trace.test.d.ts +0 -2
  521. package/dist/__tests__/pipeline-pass-trace.test.d.ts.map +0 -1
  522. package/dist/__tests__/pipeline-stage-owner.test-d.d.ts +0 -2
  523. package/dist/__tests__/pipeline-stage-owner.test-d.d.ts.map +0 -1
  524. package/dist/__tests__/plugin.test.d.ts +0 -2
  525. package/dist/__tests__/plugin.test.d.ts.map +0 -1
  526. package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts +0 -2
  527. package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts.map +0 -1
  528. package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts +0 -2
  529. package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts.map +0 -1
  530. package/dist/__tests__/public-pipeline-id.test-d.d.ts +0 -2
  531. package/dist/__tests__/public-pipeline-id.test-d.d.ts.map +0 -1
  532. package/dist/__tests__/render-dispatch-membership.unit.test.d.ts +0 -2
  533. package/dist/__tests__/render-dispatch-membership.unit.test.d.ts.map +0 -1
  534. package/dist/__tests__/render-feature-construction.unit.test.d.ts +0 -2
  535. package/dist/__tests__/render-feature-construction.unit.test.d.ts.map +0 -1
  536. package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts +0 -2
  537. package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts.map +0 -1
  538. package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts +0 -2
  539. package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts.map +0 -1
  540. package/dist/__tests__/render-feature-graph.integration.test.d.ts +0 -2
  541. package/dist/__tests__/render-feature-graph.integration.test.d.ts.map +0 -1
  542. package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts +0 -2
  543. package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts.map +0 -1
  544. package/dist/__tests__/render-feature-order.unit.test.d.ts +0 -2
  545. package/dist/__tests__/render-feature-order.unit.test.d.ts.map +0 -1
  546. package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts +0 -2
  547. package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts.map +0 -1
  548. package/dist/__tests__/render-feature-staging.unit.test.d.ts +0 -2
  549. package/dist/__tests__/render-feature-staging.unit.test.d.ts.map +0 -1
  550. package/dist/__tests__/renderer-render-scene-public.test-d.d.ts +0 -2
  551. package/dist/__tests__/renderer-render-scene-public.test-d.d.ts.map +0 -1
  552. package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts +0 -2
  553. package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts.map +0 -1
  554. package/dist/__tests__/sun-snapshot-consumers.test.d.ts +0 -2
  555. package/dist/__tests__/sun-snapshot-consumers.test.d.ts.map +0 -1
  556. package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts +0 -2
  557. package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts.map +0 -1
  558. package/dist/__tests__/taa-history-store.unit.test.d.ts +0 -2
  559. package/dist/__tests__/taa-history-store.unit.test.d.ts.map +0 -1
  560. package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts +0 -2
  561. package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts.map +0 -1
  562. package/dist/__tests__/temporal-inspection.unit.test.d.ts +0 -2
  563. package/dist/__tests__/temporal-inspection.unit.test.d.ts.map +0 -1
  564. package/dist/assets/__tests__/asset-decoders.unit.test.d.ts +0 -2
  565. package/dist/assets/__tests__/asset-decoders.unit.test.d.ts.map +0 -1
  566. package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts +0 -2
  567. package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts.map +0 -1
  568. package/dist/assets/__tests__/render-asset-port.unit.test.d.ts +0 -2
  569. package/dist/assets/__tests__/render-asset-port.unit.test.d.ts.map +0 -1
  570. package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts +0 -2
  571. package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts.map +0 -1
  572. package/dist/chunk-33UF5SAO.mjs +0 -7397
  573. package/dist/chunk-33UF5SAO.mjs.map +0 -1
  574. package/dist/chunk-A5QCJSNL.mjs +0 -29913
  575. package/dist/chunk-A5QCJSNL.mjs.map +0 -1
  576. package/dist/chunk-JMSB7AR4.mjs +0 -3
  577. package/dist/chunk-JMSB7AR4.mjs.map +0 -1
  578. package/dist/chunk-LXNGO6AO.mjs +0 -569
  579. package/dist/chunk-LXNGO6AO.mjs.map +0 -1
  580. package/dist/chunk-QRXPSX4X.mjs +0 -659
  581. package/dist/chunk-QRXPSX4X.mjs.map +0 -1
  582. package/dist/chunk-YAKEQPWO.mjs +0 -1439
  583. package/dist/chunk-YAKEQPWO.mjs.map +0 -1
  584. package/dist/components/__tests__/atmosphere-red.test.d.ts +0 -2
  585. package/dist/components/__tests__/atmosphere-red.test.d.ts.map +0 -1
  586. package/dist/components/__tests__/atmosphere.test.d.ts +0 -2
  587. package/dist/components/__tests__/atmosphere.test.d.ts.map +0 -1
  588. package/dist/components/__tests__/fog.test-d.d.ts +0 -2
  589. package/dist/components/__tests__/fog.test-d.d.ts.map +0 -1
  590. package/dist/components/__tests__/fog.test.d.ts +0 -2
  591. package/dist/components/__tests__/fog.test.d.ts.map +0 -1
  592. package/dist/components/atmosphere.d.ts +0 -18
  593. package/dist/components/atmosphere.d.ts.map +0 -1
  594. package/dist/components/environment.d.ts +0 -116
  595. package/dist/components/environment.d.ts.map +0 -1
  596. package/dist/deferred-lighting.d.ts +0 -13
  597. package/dist/deferred-lighting.d.ts.map +0 -1
  598. package/dist/dynamic-texture-store.d.ts +0 -42
  599. package/dist/dynamic-texture-store.d.ts.map +0 -1
  600. package/dist/environment/__tests__/failure-injection.test.d.ts +0 -2
  601. package/dist/environment/__tests__/failure-injection.test.d.ts.map +0 -1
  602. package/dist/environment/__tests__/generation-red.test.d.ts +0 -2
  603. package/dist/environment/__tests__/generation-red.test.d.ts.map +0 -1
  604. package/dist/environment/__tests__/generation.test.d.ts +0 -2
  605. package/dist/environment/__tests__/generation.test.d.ts.map +0 -1
  606. package/dist/environment/__tests__/graph-transaction.test.d.ts +0 -2
  607. package/dist/environment/__tests__/graph-transaction.test.d.ts.map +0 -1
  608. package/dist/environment/__tests__/inspection-red.test.d.ts +0 -2
  609. package/dist/environment/__tests__/inspection-red.test.d.ts.map +0 -1
  610. package/dist/environment/__tests__/lifecycle-evidence.test.d.ts +0 -2
  611. package/dist/environment/__tests__/lifecycle-evidence.test.d.ts.map +0 -1
  612. package/dist/environment/__tests__/pipeline-topology.test.d.ts +0 -2
  613. package/dist/environment/__tests__/pipeline-topology.test.d.ts.map +0 -1
  614. package/dist/environment/__tests__/readiness.test.d.ts +0 -2
  615. package/dist/environment/__tests__/readiness.test.d.ts.map +0 -1
  616. package/dist/environment/__tests__/recovery.test.d.ts +0 -2
  617. package/dist/environment/__tests__/recovery.test.d.ts.map +0 -1
  618. package/dist/environment/__tests__/resize-dispose.test.d.ts +0 -2
  619. package/dist/environment/__tests__/resize-dispose.test.d.ts.map +0 -1
  620. package/dist/environment/__tests__/signature-red.test.d.ts +0 -2
  621. package/dist/environment/__tests__/signature-red.test.d.ts.map +0 -1
  622. package/dist/environment/__tests__/signature.test.d.ts +0 -2
  623. package/dist/environment/__tests__/signature.test.d.ts.map +0 -1
  624. package/dist/environment/descriptors.d.ts +0 -2
  625. package/dist/environment/descriptors.d.ts.map +0 -1
  626. package/dist/environment/extracted-environment.d.ts +0 -53
  627. package/dist/environment/extracted-environment.d.ts.map +0 -1
  628. package/dist/environment/generation.d.ts +0 -62
  629. package/dist/environment/generation.d.ts.map +0 -1
  630. package/dist/environment/gpu-bundle.d.ts +0 -23
  631. package/dist/environment/gpu-bundle.d.ts.map +0 -1
  632. package/dist/environment/graph.d.ts +0 -108
  633. package/dist/environment/graph.d.ts.map +0 -1
  634. package/dist/environment/inspection.d.ts +0 -48
  635. package/dist/environment/inspection.d.ts.map +0 -1
  636. package/dist/environment/lifecycle.d.ts +0 -22
  637. package/dist/environment/lifecycle.d.ts.map +0 -1
  638. package/dist/environment/readiness.d.ts +0 -29
  639. package/dist/environment/readiness.d.ts.map +0 -1
  640. package/dist/environment/signature.d.ts +0 -70
  641. package/dist/environment/signature.d.ts.map +0 -1
  642. package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts +0 -2
  643. package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts.map +0 -1
  644. package/dist/extract/__tests__/environment-source.test.d.ts +0 -2
  645. package/dist/extract/__tests__/environment-source.test.d.ts.map +0 -1
  646. package/dist/extract/__tests__/schema-readers.unit.test.d.ts +0 -2
  647. package/dist/extract/__tests__/schema-readers.unit.test.d.ts.map +0 -1
  648. package/dist/extract/directional-csm.d.ts +0 -129
  649. package/dist/extract/directional-csm.d.ts.map +0 -1
  650. package/dist/extract/index.d.ts +0 -5
  651. package/dist/extract/index.d.ts.map +0 -1
  652. package/dist/extract/material-interface.d.ts +0 -56
  653. package/dist/extract/material-interface.d.ts.map +0 -1
  654. package/dist/extract/schema-readers.d.ts +0 -20
  655. package/dist/extract/schema-readers.d.ts.map +0 -1
  656. package/dist/features/graph-contribution.d.ts +0 -64
  657. package/dist/features/graph-contribution.d.ts.map +0 -1
  658. package/dist/features/index.d.ts +0 -21
  659. package/dist/features/index.d.ts.map +0 -1
  660. package/dist/features/morph/index.d.ts +0 -3
  661. package/dist/features/morph/index.d.ts.map +0 -1
  662. package/dist/features/morph/morph-bounds.d.ts +0 -42
  663. package/dist/features/morph/morph-bounds.d.ts.map +0 -1
  664. package/dist/features/scene-temporal.d.ts +0 -45
  665. package/dist/features/scene-temporal.d.ts.map +0 -1
  666. package/dist/features/taa-resolve.d.ts +0 -21
  667. package/dist/features/taa-resolve.d.ts.map +0 -1
  668. package/dist/frame-chain.d.ts +0 -14
  669. package/dist/frame-chain.d.ts.map +0 -1
  670. package/dist/gpu-driven/view-reference.d.ts.map +0 -1
  671. package/dist/gpu-resource-store.d.ts.map +0 -1
  672. package/dist/hdrp-cluster-membership.d.ts +0 -2
  673. package/dist/hdrp-cluster-membership.d.ts.map +0 -1
  674. package/dist/hdrp-pipeline.d.ts +0 -36
  675. package/dist/hdrp-pipeline.d.ts.map +0 -1
  676. package/dist/ibl/cubemap-projection.d.ts +0 -23
  677. package/dist/ibl/cubemap-projection.d.ts.map +0 -1
  678. package/dist/ibl/face-uniforms.d.ts +0 -65
  679. package/dist/ibl/face-uniforms.d.ts.map +0 -1
  680. package/dist/mesh-update-errors.d.ts +0 -71
  681. package/dist/mesh-update-errors.d.ts.map +0 -1
  682. package/dist/mipmap-generator.d.ts +0 -39
  683. package/dist/mipmap-generator.d.ts.map +0 -1
  684. package/dist/param-schema-projection-census.d.ts +0 -18
  685. package/dist/param-schema-projection-census.d.ts.map +0 -1
  686. package/dist/persistent-render-scene.d.ts +0 -158
  687. package/dist/persistent-render-scene.d.ts.map +0 -1
  688. package/dist/pipeline/index.d.ts +0 -11
  689. package/dist/pipeline/index.d.ts.map +0 -1
  690. package/dist/pipeline-errors.d.ts +0 -110
  691. package/dist/pipeline-errors.d.ts.map +0 -1
  692. package/dist/prepare/__tests__/schema-readers.unit.test.d.ts +0 -2
  693. package/dist/prepare/__tests__/schema-readers.unit.test.d.ts.map +0 -1
  694. package/dist/prepare/index.d.ts +0 -4
  695. package/dist/prepare/index.d.ts.map +0 -1
  696. package/dist/prepare/schema-readers.d.ts +0 -11
  697. package/dist/prepare/schema-readers.d.ts.map +0 -1
  698. package/dist/record/__tests__/environment-record.test.d.ts +0 -2
  699. package/dist/record/__tests__/environment-record.test.d.ts.map +0 -1
  700. package/dist/record/__tests__/frame-targets.unit.test.d.ts +0 -2
  701. package/dist/record/__tests__/frame-targets.unit.test.d.ts.map +0 -1
  702. package/dist/record/__tests__/membership-timing.unit.test.d.ts +0 -2
  703. package/dist/record/__tests__/membership-timing.unit.test.d.ts.map +0 -1
  704. package/dist/record/__tests__/render-submission.integration.test.d.ts +0 -2
  705. package/dist/record/__tests__/render-submission.integration.test.d.ts.map +0 -1
  706. package/dist/record/__tests__/render-submission.perf.test.d.ts +0 -2
  707. package/dist/record/__tests__/render-submission.perf.test.d.ts.map +0 -1
  708. package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts +0 -2
  709. package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts.map +0 -1
  710. package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts +0 -2
  711. package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts.map +0 -1
  712. package/dist/record/frame-observation.d.ts +0 -38
  713. package/dist/record/frame-observation.d.ts.map +0 -1
  714. package/dist/record/index.d.ts +0 -15
  715. package/dist/record/index.d.ts.map +0 -1
  716. package/dist/record/main-pass-skin.d.ts +0 -46
  717. package/dist/record/main-pass-skin.d.ts.map +0 -1
  718. package/dist/record/main-pass-sprite.d.ts +0 -69
  719. package/dist/record/main-pass-sprite.d.ts.map +0 -1
  720. package/dist/record/material-payload.d.ts +0 -43
  721. package/dist/record/material-payload.d.ts.map +0 -1
  722. package/dist/record/material-slot-plan.d.ts +0 -26
  723. package/dist/record/material-slot-plan.d.ts.map +0 -1
  724. package/dist/record/membership-timing.d.ts +0 -232
  725. package/dist/record/membership-timing.d.ts.map +0 -1
  726. package/dist/record/shadow-caster-uniform.d.ts +0 -8
  727. package/dist/record/shadow-caster-uniform.d.ts.map +0 -1
  728. package/dist/record/shadow-submit-mode.d.ts +0 -66
  729. package/dist/record/shadow-submit-mode.d.ts.map +0 -1
  730. package/dist/render-dispatch-membership.d.ts +0 -47
  731. package/dist/render-dispatch-membership.d.ts.map +0 -1
  732. package/dist/render-pipeline-context.d.ts +0 -289
  733. package/dist/render-pipeline-context.d.ts.map +0 -1
  734. package/dist/render-pipeline-target.d.ts +0 -16
  735. package/dist/render-pipeline-target.d.ts.map +0 -1
  736. package/dist/render-scene-projection.d.ts +0 -174
  737. package/dist/render-scene-projection.d.ts.map +0 -1
  738. package/dist/render-system-fold.d.ts +0 -266
  739. package/dist/render-system-fold.d.ts.map +0 -1
  740. package/dist/renderer/asset-service.d.ts +0 -10
  741. package/dist/renderer/asset-service.d.ts.map +0 -1
  742. package/dist/renderer/backend-selection.d.ts.map +0 -1
  743. package/dist/renderer/environment-classify.d.ts +0 -6
  744. package/dist/renderer/environment-classify.d.ts.map +0 -1
  745. package/dist/renderer/environment-error.d.ts +0 -13
  746. package/dist/renderer/environment-error.d.ts.map +0 -1
  747. package/dist/renderer/material/pipeline-projection.d.ts +0 -91
  748. package/dist/renderer/material/pipeline-projection.d.ts.map +0 -1
  749. package/dist/renderer/renderer-factory.d.ts +0 -283
  750. package/dist/renderer/renderer-factory.d.ts.map +0 -1
  751. package/dist/renderer.d.ts +0 -771
  752. package/dist/renderer.d.ts.map +0 -1
  753. package/dist/scene-utils/collect-subtree.d.ts +0 -11
  754. package/dist/scene-utils/collect-subtree.d.ts.map +0 -1
  755. package/dist/ssao-data.d.ts +0 -34
  756. package/dist/ssao-data.d.ts.map +0 -1
  757. package/dist/surface-format.d.ts +0 -10
  758. package/dist/surface-format.d.ts.map +0 -1
  759. package/dist/taa-history-store.d.ts +0 -88
  760. package/dist/taa-history-store.d.ts.map +0 -1
  761. package/dist/temporal-coverage.d.ts +0 -35
  762. package/dist/temporal-coverage.d.ts.map +0 -1
  763. package/dist/temporal-frame-transaction.d.ts +0 -92
  764. package/dist/temporal-frame-transaction.d.ts.map +0 -1
  765. package/dist/temporal-inspection.d.ts +0 -57
  766. package/dist/temporal-inspection.d.ts.map +0 -1
  767. package/dist/temporal-view.d.ts +0 -43
  768. package/dist/temporal-view.d.ts.map +0 -1
  769. package/dist/tilemap/resolve-tileset-runtime.d.ts +0 -23
  770. package/dist/tilemap/resolve-tileset-runtime.d.ts.map +0 -1
  771. package/dist/urp-pipeline.d.ts +0 -4
  772. package/dist/urp-pipeline.d.ts.map +0 -1
  773. package/src/__tests__/analytic-sky-contract.test.ts +0 -27
  774. package/src/__tests__/analytic-sky-falsify-carriers.mjs +0 -43
  775. package/src/__tests__/analytic-sky-falsify.test.ts +0 -94
  776. package/src/__tests__/assets-runtime-handoff.integration.test.ts +0 -36
  777. package/src/__tests__/backend-selection.integration.test.ts +0 -11
  778. package/src/__tests__/camera-temporal.test-d.ts +0 -8
  779. package/src/__tests__/camera-temporal.test.ts +0 -188
  780. package/src/__tests__/directional-shadow-probe-atlas-layout.unit.test.ts +0 -18
  781. package/src/__tests__/environment-inspection.test.ts +0 -45
  782. package/src/__tests__/fog-ai-user.fixture.ts +0 -350
  783. package/src/__tests__/fog-custom-render-feature.fixture.ts +0 -33
  784. package/src/__tests__/fog-custom-render-feature.integration.test.ts +0 -76
  785. package/src/__tests__/fog-inspection.integration.test.ts +0 -127
  786. package/src/__tests__/fog-owner-state.integration.test.ts +0 -112
  787. package/src/__tests__/fog-pipeline-topology.integration.test.ts +0 -93
  788. package/src/__tests__/fog-public-surface.integration.test.ts +0 -60
  789. package/src/__tests__/fog-ray-contract.integration.test.ts +0 -73
  790. package/src/__tests__/fog-source-absence.integration.test.ts +0 -51
  791. package/src/__tests__/fog-temporal.integration.test.ts +0 -115
  792. package/src/__tests__/frame-chain.unit.test.ts +0 -26
  793. package/src/__tests__/gpu-scene-field-type-owner.test-d.ts +0 -27
  794. package/src/__tests__/hdrp-pipeline.unit.test.ts +0 -100
  795. package/src/__tests__/ibl/ibl-fallback.unit.test.ts +0 -23
  796. package/src/__tests__/material-derived-error-stop-draw.integration.test.ts +0 -69
  797. package/src/__tests__/material-derived-payload.integration.test.ts +0 -164
  798. package/src/__tests__/materials.unit.test.ts +0 -25
  799. package/src/__tests__/param-schema-projection-census.unit.test.ts +0 -40
  800. package/src/__tests__/persistent-render-scene.unit.test.ts +0 -1311
  801. package/src/__tests__/pipeline-error-policy-owner.unit.test.ts +0 -167
  802. package/src/__tests__/pipeline-pass-trace.test.ts +0 -92
  803. package/src/__tests__/pipeline-stage-owner.test-d.ts +0 -13
  804. package/src/__tests__/plugin.test.ts +0 -25
  805. package/src/__tests__/prepared-graphics-backend-matrix.unit.test.ts +0 -129
  806. package/src/__tests__/prepared-graphics-resolver-recording.unit.test.ts +0 -180
  807. package/src/__tests__/public-pipeline-id.test-d.ts +0 -6
  808. package/src/__tests__/render-dispatch-membership.unit.test.ts +0 -117
  809. package/src/__tests__/render-feature-construction.unit.test.ts +0 -124
  810. package/src/__tests__/render-feature-error-code-owner.test-d.ts +0 -27
  811. package/src/__tests__/render-feature-gpu-buffer-usage-owner.test-d.ts +0 -46
  812. package/src/__tests__/render-feature-graph.integration.test.ts +0 -205
  813. package/src/__tests__/render-feature-graphics-staging.unit.test.ts +0 -200
  814. package/src/__tests__/render-feature-order.unit.test.ts +0 -66
  815. package/src/__tests__/render-feature-prepared-graphics-recording.unit.test.ts +0 -107
  816. package/src/__tests__/render-feature-staging.unit.test.ts +0 -94
  817. package/src/__tests__/renderer-render-scene-public.test-d.ts +0 -27
  818. package/src/__tests__/scene-temporal-coverage.unit.test.ts +0 -259
  819. package/src/__tests__/sun-snapshot-consumers.test.ts +0 -35
  820. package/src/__tests__/surface-backend-kind-owner.test-d.ts +0 -42
  821. package/src/__tests__/taa-history-store.unit.test.ts +0 -196
  822. package/src/__tests__/temporal-frame-transaction.integration.test.ts +0 -537
  823. package/src/__tests__/temporal-inspection.unit.test.ts +0 -138
  824. package/src/assets/__tests__/asset-decoders.unit.test.ts +0 -92
  825. package/src/assets/__tests__/mipmap-generator.unit.test.ts +0 -52
  826. package/src/assets/__tests__/render-asset-port.unit.test.ts +0 -54
  827. package/src/assets/__tests__/resolve-render-asset.unit.test.ts +0 -47
  828. package/src/components/__tests__/atmosphere-red.test.ts +0 -51
  829. package/src/components/__tests__/atmosphere.test.ts +0 -79
  830. package/src/components/__tests__/fog.test-d.ts +0 -49
  831. package/src/components/__tests__/fog.test.ts +0 -60
  832. package/src/components/atmosphere.ts +0 -64
  833. package/src/deferred-lighting.ts +0 -92
  834. package/src/dynamic-texture-store.ts +0 -111
  835. package/src/environment/README.md +0 -76
  836. package/src/environment/__tests__/failure-injection.test.ts +0 -50
  837. package/src/environment/__tests__/generation-red.test.ts +0 -64
  838. package/src/environment/__tests__/generation.test.ts +0 -37
  839. package/src/environment/__tests__/graph-transaction.test.ts +0 -85
  840. package/src/environment/__tests__/inspection-red.test.ts +0 -53
  841. package/src/environment/__tests__/lifecycle-evidence.test.ts +0 -40
  842. package/src/environment/__tests__/pipeline-topology.test.ts +0 -33
  843. package/src/environment/__tests__/readiness.test.ts +0 -42
  844. package/src/environment/__tests__/recovery.test.ts +0 -62
  845. package/src/environment/__tests__/resize-dispose.test.ts +0 -30
  846. package/src/environment/__tests__/signature-red.test.ts +0 -45
  847. package/src/environment/__tests__/signature.test.ts +0 -60
  848. package/src/environment/descriptors.ts +0 -7
  849. package/src/environment/extracted-environment.ts +0 -239
  850. package/src/environment/generation.ts +0 -158
  851. package/src/environment/gpu-bundle.ts +0 -144
  852. package/src/environment/graph.ts +0 -588
  853. package/src/environment/inspection.ts +0 -107
  854. package/src/environment/lifecycle.ts +0 -124
  855. package/src/environment/readiness.ts +0 -76
  856. package/src/environment/signature.ts +0 -185
  857. package/src/extract/__tests__/directional-csm-domain.unit.test.ts +0 -391
  858. package/src/extract/__tests__/environment-source.test.ts +0 -105
  859. package/src/extract/__tests__/schema-readers.unit.test.ts +0 -16
  860. package/src/extract/directional-csm.ts +0 -959
  861. package/src/extract/index.ts +0 -10
  862. package/src/extract/material-interface.ts +0 -604
  863. package/src/extract/schema-readers.ts +0 -27
  864. package/src/features/graph-contribution.ts +0 -577
  865. package/src/features/index.ts +0 -100
  866. package/src/features/morph/index.ts +0 -24
  867. package/src/features/morph/morph-bounds.ts +0 -123
  868. package/src/features/scene-temporal.ts +0 -274
  869. package/src/features/taa-resolve.ts +0 -244
  870. package/src/frame-chain.ts +0 -21
  871. package/src/hdrp-cluster-membership.ts +0 -70
  872. package/src/ibl/cubemap-projection.ts +0 -60
  873. package/src/ibl/face-uniforms.ts +0 -150
  874. package/src/mesh-update-errors.ts +0 -113
  875. package/src/mipmap-generator.ts +0 -244
  876. package/src/param-schema-projection-census.ts +0 -73
  877. package/src/persistent-render-scene.ts +0 -1752
  878. package/src/pipeline/index.ts +0 -40
  879. package/src/pipeline-errors.ts +0 -172
  880. package/src/prepare/__tests__/schema-readers.unit.test.ts +0 -16
  881. package/src/prepare/index.ts +0 -8
  882. package/src/prepare/schema-readers.ts +0 -20
  883. package/src/record/__tests__/environment-record.test.ts +0 -35
  884. package/src/record/__tests__/frame-targets.unit.test.ts +0 -54
  885. package/src/record/__tests__/membership-timing.unit.test.ts +0 -524
  886. package/src/record/__tests__/render-submission.integration.test.ts +0 -76
  887. package/src/record/__tests__/render-submission.perf.test.ts +0 -141
  888. package/src/record/__tests__/shadow-submit-mode.unit.test.ts +0 -88
  889. package/src/record/__tests__/view-ubo-layout.unit.test.ts +0 -101
  890. package/src/record/frame-observation.ts +0 -122
  891. package/src/record/index.ts +0 -15
  892. package/src/record/main-pass-skin.ts +0 -51
  893. package/src/record/main-pass-sprite.ts +0 -166
  894. package/src/record/material-payload.ts +0 -292
  895. package/src/record/material-slot-plan.ts +0 -68
  896. package/src/record/membership-timing.ts +0 -1012
  897. package/src/record/shadow-caster-uniform.ts +0 -37
  898. package/src/record/shadow-submit-mode.ts +0 -277
  899. package/src/render-dispatch-membership.ts +0 -155
  900. package/src/render-pipeline-context.ts +0 -332
  901. package/src/render-pipeline-target.ts +0 -96
  902. package/src/render-scene-projection.ts +0 -1738
  903. package/src/render-system-fold.ts +0 -531
  904. package/src/renderer/asset-service.ts +0 -32
  905. package/src/renderer/backend-selection.ts +0 -121
  906. package/src/renderer/environment-classify.ts +0 -30
  907. package/src/renderer/environment-error.ts +0 -19
  908. package/src/renderer/material/pipeline-projection.ts +0 -140
  909. package/src/renderer.ts +0 -940
  910. package/src/scene-utils/collect-subtree.ts +0 -40
  911. package/src/ssao-data.ts +0 -106
  912. package/src/surface-format.ts +0 -37
  913. package/src/taa-history-store.ts +0 -429
  914. package/src/temporal-coverage.ts +0 -106
  915. package/src/temporal-frame-transaction.ts +0 -301
  916. package/src/temporal-inspection.ts +0 -194
  917. package/src/temporal-view.ts +0 -174
  918. package/src/tilemap/resolve-tileset-runtime.ts +0 -72
@@ -1,959 +0,0 @@
1
- import { type Mat4, mat4, type Vec3, vec3 } from '@forgeax/engine-math';
2
- import { ShadowInvalidConfigError } from '../errors/render';
3
-
4
- const DEFAULT_PCF_KERNEL_SIZE = 3;
5
-
6
- export interface CsmCameraData {
7
- readonly world: Float32Array;
8
- readonly fov: number;
9
- readonly aspect: number;
10
- readonly near: number;
11
- readonly far: number;
12
- readonly projection: 'perspective' | 'orthographic';
13
- readonly orthoLeft: number;
14
- readonly orthoRight: number;
15
- readonly orthoBottom: number;
16
- readonly orthoTop: number;
17
- }
18
-
19
- export interface DirectionalCsmConfig {
20
- readonly cascadeCount: number;
21
- readonly splitLambda: number;
22
- readonly cascadeBlend: number;
23
- readonly mapSize: number;
24
- readonly shadowDistance: number;
25
- /** Optional only for old internal callers; DirectionalLight supplies it. */
26
- readonly pcfKernelSize?: number;
27
- /** @internal Collect producer-owned per-candidate decisions for RHI evidence. */
28
- readonly collectCandidateDecisions?: boolean;
29
- }
30
-
31
- export interface CascadeRasterViewport {
32
- readonly x: number;
33
- readonly y: number;
34
- readonly w: number;
35
- readonly h: number;
36
- }
37
-
38
- export interface CascadeVolume {
39
- readonly cascadeIndex: number;
40
- readonly revision: number;
41
- readonly lightViewProj: Float32Array;
42
- readonly receiverViewDepth: readonly [number, number];
43
- readonly receiverLightBounds: Float32Array;
44
- readonly clipLightBounds: Float32Array;
45
- /** Raster bounds are the exact clip array consumed by the matrix fit. */
46
- readonly rasterLightBounds: Float32Array;
47
- readonly depthLightRange: readonly [number, number];
48
- /** Conservative world-space AABB used by static and dynamic broadphase owners. */
49
- readonly casterBroadphaseWorldAabb: Float32Array;
50
- readonly rasterViewport: CascadeRasterViewport;
51
- /** Stable X/Y extent; casters never enlarge this receiver-driven domain. */
52
- readonly stableExtent: number;
53
- /** Receiver sphere center before texel-grid snapping. */
54
- readonly unsnappedCenter: readonly [number, number];
55
- readonly snappedCenter: readonly [number, number];
56
- readonly halfExtent: number;
57
- readonly worldUnitsPerTexel: number;
58
- readonly guardBandTexels: number;
59
- /** Candidate indices are stable before main-view culling. */
60
- readonly casterRenderableIndices: Uint32Array;
61
- /** Optional complete CPU decision stream, enabled only for debug capture. */
62
- readonly candidateDecisions?: readonly DirectionalCsmCandidateDecision[];
63
- readonly unboundedFallback: readonly DirectionalCsmFallback[];
64
- readonly unboundedFallbackCount: number;
65
- /** Historical whole-frustum away-light extent retained for fallback casters. */
66
- readonly lightSpaceMinZFull: number;
67
- /** Historical whole-frustum toward-light reach retained for fallback casters. */
68
- readonly lightSpaceMaxZFull: number;
69
- }
70
-
71
- /** Compatibility name for existing record and debug consumers. */
72
- export type DirectionalCsmCascadePlan = CascadeVolume;
73
-
74
- export interface DirectionalCsmFallback {
75
- readonly renderableIndex: number;
76
- readonly reason: string;
77
- }
78
-
79
- export interface DirectionalCsmCasterCandidate {
80
- readonly renderableIndex: number;
81
- readonly worldId: number;
82
- readonly entityKey: number;
83
- readonly worldAabb: Float32Array | null;
84
- readonly bounded: boolean;
85
- readonly shadowCaster: boolean;
86
- readonly fallbackReason?: string;
87
- }
88
-
89
- export interface DirectionalCsmCandidateSource {
90
- readonly renderableIndex: number;
91
- readonly worldId: number;
92
- readonly entityKey: number;
93
- readonly localAabb?: Float32Array | undefined;
94
- readonly transformWorld: Float32Array;
95
- readonly instanceTransforms?: Float32Array | undefined;
96
- /** Skin/morph bounds are feature-owned; do not infer them from a static mesh AABB. */
97
- readonly featureOwnedBoundsUnavailable?: boolean;
98
- readonly shadowCaster: boolean;
99
- }
100
-
101
- export interface DirectionalCsmCandidateDecision {
102
- readonly renderableIndex: number;
103
- readonly worldId: number;
104
- readonly entityKey: number;
105
- readonly selected: boolean;
106
- readonly reason: string;
107
- readonly lightSpaceBounds?: Float32Array;
108
- }
109
-
110
- /**
111
- * Optional persistent-scene broadphase owner. Returned indices address the
112
- * stable candidate domain supplied to the CSM builder; the builder still owns
113
- * the exact light-space membership test.
114
- */
115
- export type DirectionalCsmCandidateBroadphase = (worldAabb: Float32Array) => readonly number[];
116
-
117
- export interface CascadeVolumeSet {
118
- readonly revision: number;
119
- readonly volumes: readonly CascadeVolume[];
120
- }
121
-
122
- export interface DirectionalCsmResult extends CascadeVolumeSet {
123
- readonly lightViewProj: Float32Array[];
124
- readonly splitPlanes: Float32Array;
125
- readonly cascadeCount: number;
126
- readonly cascadeBlend: number;
127
- readonly shadowMapSize: number;
128
- readonly cascades: readonly DirectionalCsmCascadePlan[];
129
- }
130
-
131
- export function directionalCascadeRasterViewport(
132
- cascadeIndex: number,
133
- cascadeCount: number,
134
- mapSize: number,
135
- ): CascadeRasterViewport {
136
- const count = Math.max(1, Math.min(4, Math.round(cascadeCount)));
137
- const index = Math.max(0, Math.min(count - 1, Math.round(cascadeIndex)));
138
- const tileSize = Math.max(1, mapSize);
139
- const tilesPerSide = Math.ceil(Math.sqrt(count));
140
- return {
141
- x: (index % tilesPerSide) * tileSize,
142
- y: Math.floor(index / tilesPerSide) * tileSize,
143
- w: tileSize,
144
- h: tileSize,
145
- };
146
- }
147
-
148
- /** Exact depth-atlas dimensions for the raster viewport layout. */
149
- export function directionalCascadeAtlasSize(
150
- cascadeCount: number,
151
- mapSize: number,
152
- ): { readonly width: number; readonly height: number } {
153
- const count = Math.max(1, Math.min(4, Math.round(cascadeCount)));
154
- const tileSize = Math.max(1, mapSize);
155
- const tilesPerSide = Math.ceil(Math.sqrt(count));
156
- return {
157
- width: tilesPerSide * tileSize,
158
- height: Math.ceil(count / tilesPerSide) * tileSize,
159
- };
160
- }
161
-
162
- interface Sphere {
163
- readonly center: Vec3;
164
- readonly radius: number;
165
- }
166
-
167
- function dot(a: Vec3, b: Vec3): number {
168
- return (a[0] ?? 0) * (b[0] ?? 0) + (a[1] ?? 0) * (b[1] ?? 0) + (a[2] ?? 0) * (b[2] ?? 0);
169
- }
170
- function unprojectNDC(invVP: Mat4, ndcX: number, ndcY: number, ndcZ: number): Vec3 {
171
- const ws = vec3.create();
172
- mat4.unproject(ws, vec3.create(ndcX, ndcY, ndcZ), invVP);
173
- return ws;
174
- }
175
-
176
- function computeFrustumCorners(
177
- vp: Mat4,
178
- camNear: number,
179
- camFar: number,
180
- nearZ: number,
181
- farZ: number,
182
- projection: 'perspective' | 'orthographic',
183
- ): Vec3[] {
184
- const invVP = mat4.create();
185
- mat4.invert(invVP, vp);
186
- const span = camFar - camNear;
187
- const ndcNear =
188
- projection === 'orthographic'
189
- ? (nearZ - camNear) / span
190
- : (camFar * (nearZ - camNear)) / (nearZ * span);
191
- const ndcFar =
192
- projection === 'orthographic'
193
- ? (farZ - camNear) / span
194
- : (camFar * (farZ - camNear)) / (farZ * span);
195
- const corners: Vec3[] = [];
196
- for (const ndcZ of [ndcNear, ndcFar]) {
197
- for (const ndcX of [-1, 1]) {
198
- for (const ndcY of [-1, 1]) corners.push(unprojectNDC(invVP, ndcX, ndcY, ndcZ));
199
- }
200
- }
201
- return corners;
202
- }
203
-
204
- function validateGuardConfig(config: DirectionalCsmConfig): {
205
- readonly pcfKernelSize: number;
206
- readonly guardBandTexels: number;
207
- readonly halfExtentDenominator: number;
208
- } {
209
- const pcfKernelSize = config.pcfKernelSize ?? DEFAULT_PCF_KERNEL_SIZE;
210
- if (
211
- !Number.isFinite(pcfKernelSize) ||
212
- !Number.isInteger(pcfKernelSize) ||
213
- pcfKernelSize < 1 ||
214
- pcfKernelSize % 2 === 0
215
- ) {
216
- throw new ShadowInvalidConfigError('pcfKernelSize', pcfKernelSize, 1);
217
- }
218
- if (!Number.isFinite(config.mapSize) || config.mapSize <= 0) {
219
- throw new ShadowInvalidConfigError('mapSize', config.mapSize, 1);
220
- }
221
- const radius = (pcfKernelSize - 1) / 2;
222
- const guardBandTexels = radius + 1;
223
- const halfExtentDenominator = 1 - (2 * guardBandTexels) / config.mapSize;
224
- if (!(halfExtentDenominator > 0)) {
225
- throw new Error(
226
- `directional CSM guard formula is unsatisfiable: mapSize=${config.mapSize}, pcfKernelSize=${pcfKernelSize}`,
227
- );
228
- }
229
- return { pcfKernelSize, guardBandTexels, halfExtentDenominator };
230
- }
231
-
232
- function createLightView(direction: Vec3): Mat4 {
233
- const lengthSquared = dot(direction, direction);
234
- if (!(lengthSquared > 0) || !Number.isFinite(lengthSquared)) {
235
- throw new Error('directional CSM light direction must be finite and non-zero');
236
- }
237
- const lightDirection = vec3.normalize(vec3.create(), direction);
238
- const axes: readonly Vec3[] = [vec3.create(1, 0, 0), vec3.create(0, 1, 0), vec3.create(0, 0, 1)];
239
- const firstAxis = axes[0];
240
- if (firstAxis === undefined) throw new Error('directional CSM light basis has no canonical axis');
241
- let up = firstAxis;
242
- let leastAlignment = Math.abs(dot(lightDirection, up));
243
- for (let index = 1; index < axes.length; index++) {
244
- const candidate = axes[index];
245
- if (candidate === undefined) continue;
246
- const alignment = Math.abs(dot(lightDirection, candidate));
247
- if (alignment < leastAlignment) {
248
- leastAlignment = alignment;
249
- up = candidate;
250
- }
251
- }
252
- const target = vec3.clone(lightDirection);
253
- const view = mat4.create();
254
- mat4.lookAt(view, vec3.create(), target, up);
255
- return view;
256
- }
257
-
258
- function transformBounds(
259
- points: readonly Vec3[],
260
- view: Mat4,
261
- ): {
262
- readonly points: Vec3[];
263
- readonly bounds: Float32Array;
264
- } {
265
- const transformed: Vec3[] = [];
266
- let minX = Infinity;
267
- let maxX = -Infinity;
268
- let minY = Infinity;
269
- let maxY = -Infinity;
270
- let minZ = Infinity;
271
- let maxZ = -Infinity;
272
- for (const point of points) {
273
- const lightPoint = vec3.create();
274
- mat4.transformVec3(lightPoint, view, point);
275
- transformed.push(lightPoint);
276
- minX = Math.min(minX, lightPoint[0] ?? 0);
277
- maxX = Math.max(maxX, lightPoint[0] ?? 0);
278
- minY = Math.min(minY, lightPoint[1] ?? 0);
279
- maxY = Math.max(maxY, lightPoint[1] ?? 0);
280
- minZ = Math.min(minZ, lightPoint[2] ?? 0);
281
- maxZ = Math.max(maxZ, lightPoint[2] ?? 0);
282
- }
283
- return {
284
- points: transformed,
285
- bounds: new Float32Array([minX, maxX, minY, maxY, minZ, maxZ]),
286
- };
287
- }
288
-
289
- function finiteOrderedAabb(aabb: readonly number[] | Float32Array | undefined): boolean {
290
- if (aabb === undefined || aabb.length < 6) return false;
291
- const values = [aabb[0], aabb[1], aabb[2], aabb[3], aabb[4], aabb[5]];
292
- return (
293
- values.every((value) => Number.isFinite(value)) &&
294
- (values[0] ?? 0) <= (values[3] ?? 0) &&
295
- (values[1] ?? 0) <= (values[4] ?? 0) &&
296
- (values[2] ?? 0) <= (values[5] ?? 0)
297
- );
298
- }
299
-
300
- function finiteMatrix(matrix: Float32Array): boolean {
301
- if (matrix.length < 16) return false;
302
- for (let index = 0; index < 16; index += 1) {
303
- if (!Number.isFinite(matrix[index])) return false;
304
- }
305
- return true;
306
- }
307
-
308
- function validCsmCamera(cameraData: CsmCameraData): boolean {
309
- if (!finiteMatrix(cameraData.world)) return false;
310
- if (
311
- !Number.isFinite(cameraData.near) ||
312
- !Number.isFinite(cameraData.far) ||
313
- !(cameraData.near > 0) ||
314
- !(cameraData.far > cameraData.near)
315
- ) {
316
- return false;
317
- }
318
- if (cameraData.projection === 'orthographic') {
319
- return (
320
- Number.isFinite(cameraData.orthoLeft) &&
321
- Number.isFinite(cameraData.orthoRight) &&
322
- Number.isFinite(cameraData.orthoBottom) &&
323
- Number.isFinite(cameraData.orthoTop) &&
324
- cameraData.orthoRight > cameraData.orthoLeft &&
325
- cameraData.orthoTop > cameraData.orthoBottom
326
- );
327
- }
328
- return (
329
- Number.isFinite(cameraData.fov) &&
330
- Number.isFinite(cameraData.aspect) &&
331
- cameraData.fov > 0 &&
332
- cameraData.aspect > 0
333
- );
334
- }
335
-
336
- function transformBoundsToAabb(
337
- xBounds: readonly [number, number],
338
- yBounds: readonly [number, number],
339
- zBounds: readonly [number, number],
340
- transform: Mat4,
341
- ): Float32Array {
342
- let minX = Infinity;
343
- let minY = Infinity;
344
- let minZ = Infinity;
345
- let maxX = -Infinity;
346
- let maxY = -Infinity;
347
- let maxZ = -Infinity;
348
- for (const x of xBounds) {
349
- for (const y of yBounds) {
350
- for (const z of zBounds) {
351
- const point = vec3.create();
352
- mat4.transformVec3(point, transform, vec3.create(x, y, z));
353
- minX = Math.min(minX, point[0] ?? 0);
354
- minY = Math.min(minY, point[1] ?? 0);
355
- minZ = Math.min(minZ, point[2] ?? 0);
356
- maxX = Math.max(maxX, point[0] ?? 0);
357
- maxY = Math.max(maxY, point[1] ?? 0);
358
- maxZ = Math.max(maxZ, point[2] ?? 0);
359
- }
360
- }
361
- }
362
- return new Float32Array([minX, minY, minZ, maxX, maxY, maxZ]);
363
- }
364
-
365
- function transformAabb(aabb: Float32Array, transform: Mat4): Float32Array {
366
- return transformBoundsToAabb(
367
- [aabb[0] ?? 0, aabb[3] ?? 0],
368
- [aabb[1] ?? 0, aabb[4] ?? 0],
369
- [aabb[2] ?? 0, aabb[5] ?? 0],
370
- transform,
371
- );
372
- }
373
-
374
- export function buildDirectionalCsmCasterCandidates(
375
- sources: readonly DirectionalCsmCandidateSource[],
376
- ): DirectionalCsmCasterCandidate[] {
377
- return sources.map((source) => {
378
- if (!source.shadowCaster) {
379
- return {
380
- renderableIndex: source.renderableIndex,
381
- worldId: source.worldId,
382
- entityKey: source.entityKey,
383
- worldAabb: null,
384
- bounded: false,
385
- shadowCaster: false,
386
- };
387
- }
388
- if (source.featureOwnedBoundsUnavailable === true) {
389
- return {
390
- renderableIndex: source.renderableIndex,
391
- worldId: source.worldId,
392
- entityKey: source.entityKey,
393
- worldAabb: null,
394
- bounded: false,
395
- shadowCaster: true,
396
- fallbackReason: 'feature-owned-conservative-bounds-unavailable',
397
- };
398
- }
399
- if (!finiteOrderedAabb(source.localAabb)) {
400
- return {
401
- renderableIndex: source.renderableIndex,
402
- worldId: source.worldId,
403
- entityKey: source.entityKey,
404
- worldAabb: null,
405
- bounded: false,
406
- shadowCaster: true,
407
- fallbackReason: 'missing-or-invalid-local-bounds',
408
- };
409
- }
410
- const localAabb = source.localAabb;
411
- if (localAabb === undefined) {
412
- return {
413
- renderableIndex: source.renderableIndex,
414
- worldId: source.worldId,
415
- entityKey: source.entityKey,
416
- worldAabb: null,
417
- bounded: false,
418
- shadowCaster: true,
419
- fallbackReason: 'missing-or-invalid-local-bounds',
420
- };
421
- }
422
- if (!finiteMatrix(source.transformWorld)) {
423
- return {
424
- renderableIndex: source.renderableIndex,
425
- worldId: source.worldId,
426
- entityKey: source.entityKey,
427
- worldAabb: null,
428
- bounded: false,
429
- shadowCaster: true,
430
- fallbackReason: 'missing-or-invalid-world-transform',
431
- };
432
- }
433
- let worldAabb = transformAabb(
434
- localAabb,
435
- source.transformWorld as unknown as Mat4, // brand-cast-ok
436
- );
437
- const instanceTransforms = source.instanceTransforms;
438
- if (instanceTransforms !== undefined) {
439
- if (instanceTransforms.length % 16 !== 0) {
440
- return {
441
- renderableIndex: source.renderableIndex,
442
- worldId: source.worldId,
443
- entityKey: source.entityKey,
444
- worldAabb: null,
445
- bounded: false,
446
- shadowCaster: true,
447
- fallbackReason: 'invalid-instance-transform-stride',
448
- };
449
- }
450
- let aggregate: Float32Array | undefined;
451
- for (let offset = 0; offset < instanceTransforms.length; offset += 16) {
452
- const instanceWorld = mat4.create();
453
- mat4.multiply(
454
- instanceWorld,
455
- source.transformWorld as unknown as Mat4, // brand-cast-ok
456
- instanceTransforms.subarray(offset, offset + 16) as unknown as Mat4, // brand-cast-ok
457
- );
458
- const instanceAabb = transformAabb(localAabb, instanceWorld);
459
- if (aggregate === undefined) aggregate = instanceAabb;
460
- else {
461
- aggregate = new Float32Array([
462
- Math.min(aggregate[0] ?? 0, instanceAabb[0] ?? 0),
463
- Math.min(aggregate[1] ?? 0, instanceAabb[1] ?? 0),
464
- Math.min(aggregate[2] ?? 0, instanceAabb[2] ?? 0),
465
- Math.max(aggregate[3] ?? 0, instanceAabb[3] ?? 0),
466
- Math.max(aggregate[4] ?? 0, instanceAabb[4] ?? 0),
467
- Math.max(aggregate[5] ?? 0, instanceAabb[5] ?? 0),
468
- ]);
469
- }
470
- }
471
- if (aggregate !== undefined) worldAabb = aggregate;
472
- }
473
- return {
474
- renderableIndex: source.renderableIndex,
475
- worldId: source.worldId,
476
- entityKey: source.entityKey,
477
- worldAabb,
478
- bounded: true,
479
- shadowCaster: true,
480
- };
481
- });
482
- }
483
-
484
- function aabbToPoints(aabb: Float32Array): Vec3[] {
485
- const points: Vec3[] = [];
486
- for (const x of [aabb[0] ?? 0, aabb[3] ?? 0]) {
487
- for (const y of [aabb[1] ?? 0, aabb[4] ?? 0]) {
488
- for (const z of [aabb[2] ?? 0, aabb[5] ?? 0]) points.push(vec3.create(x, y, z));
489
- }
490
- }
491
- return points;
492
- }
493
-
494
- function lightBoundsToWorldAabb(bounds: Float32Array, lightView: Mat4): Float32Array {
495
- const inverseLightView = mat4.create();
496
- mat4.invert(inverseLightView, lightView);
497
- return transformBoundsToAabb(
498
- [bounds[0] ?? 0, bounds[1] ?? 0],
499
- [bounds[2] ?? 0, bounds[3] ?? 0],
500
- [bounds[4] ?? 0, bounds[5] ?? 0],
501
- inverseLightView,
502
- );
503
- }
504
-
505
- function contentRevision(values: Iterable<number>): number {
506
- let hash = 0x811c9dc5;
507
- const bytes = new DataView(new ArrayBuffer(8));
508
- for (const value of values) {
509
- bytes.setFloat64(0, value, true);
510
- for (let index = 0; index < 8; index += 1) {
511
- hash ^= bytes.getUint8(index);
512
- hash = Math.imul(hash, 0x01000193);
513
- }
514
- }
515
- return hash >>> 0;
516
- }
517
-
518
- function symmetricFrustumSphere(
519
- cameraData: CsmCameraData,
520
- nearDepth: number,
521
- farDepth: number,
522
- ): Sphere {
523
- let localX = 0;
524
- let localY = 0;
525
- let localDepth = (nearDepth + farDepth) * 0.5;
526
- let radiusSquared: number;
527
- if (cameraData.projection === 'orthographic') {
528
- const halfWidth = (cameraData.orthoRight - cameraData.orthoLeft) * 0.5;
529
- const halfHeight = (cameraData.orthoTop - cameraData.orthoBottom) * 0.5;
530
- localX = (cameraData.orthoLeft + cameraData.orthoRight) * 0.5;
531
- localY = (cameraData.orthoBottom + cameraData.orthoTop) * 0.5;
532
- radiusSquared = halfWidth ** 2 + halfHeight ** 2 + ((farDepth - nearDepth) * 0.5) ** 2;
533
- } else {
534
- const tangent = Math.tan(cameraData.fov * 0.5);
535
- const nearHalfWidth = tangent * cameraData.aspect * nearDepth;
536
- const nearHalfHeight = tangent * nearDepth;
537
- const farHalfWidth = tangent * cameraData.aspect * farDepth;
538
- const farHalfHeight = tangent * farDepth;
539
- const squaredDistance = (
540
- depth: number,
541
- planeDepth: number,
542
- halfWidth: number,
543
- halfHeight: number,
544
- ) => halfWidth ** 2 + halfHeight ** 2 + (depth - planeDepth) ** 2;
545
- const intersectionDepth =
546
- (farHalfWidth ** 2 +
547
- farHalfHeight ** 2 +
548
- farDepth ** 2 -
549
- nearHalfWidth ** 2 -
550
- nearHalfHeight ** 2 -
551
- nearDepth ** 2) /
552
- (2 * (farDepth - nearDepth));
553
- const candidateDepths = [nearDepth, farDepth, intersectionDepth];
554
- let bestScore = Infinity;
555
- for (const candidateDepth of candidateDepths) {
556
- if (!Number.isFinite(candidateDepth)) continue;
557
- const score = Math.max(
558
- squaredDistance(candidateDepth, nearDepth, nearHalfWidth, nearHalfHeight),
559
- squaredDistance(candidateDepth, farDepth, farHalfWidth, farHalfHeight),
560
- );
561
- if (score < bestScore) {
562
- bestScore = score;
563
- localDepth = candidateDepth;
564
- }
565
- }
566
- radiusSquared = bestScore;
567
- }
568
- const localCenter = vec3.create(localX, localY, -localDepth);
569
- const worldCenter = vec3.create();
570
- mat4.transformVec3(
571
- worldCenter,
572
- cameraData.world as unknown as Mat4, // brand-cast-ok
573
- localCenter,
574
- );
575
- return { center: worldCenter, radius: Math.sqrt(radiusSquared) };
576
- }
577
-
578
- export function pssmSplit(
579
- nearPlane: number,
580
- farPlane: number,
581
- cascadeCount: number,
582
- splitLambda: number,
583
- ): Float32Array {
584
- const EPS = 1e-6;
585
- if (farPlane <= nearPlane + EPS) {
586
- throw new ShadowInvalidConfigError('shadowDistance', farPlane, nearPlane + EPS);
587
- }
588
- const result = new Float32Array(cascadeCount);
589
- const ratio = farPlane / nearPlane;
590
- for (let index = 1; index <= cascadeCount; index++) {
591
- const t = index / cascadeCount;
592
- const logPart = nearPlane * ratio ** t;
593
- const uniformPart = nearPlane + t * (farPlane - nearPlane);
594
- result[index - 1] = splitLambda * logPart + (1 - splitLambda) * uniformPart;
595
- }
596
- return result;
597
- }
598
-
599
- function buildCascadeVolumeSet(
600
- direction: Vec3,
601
- config: DirectionalCsmConfig,
602
- cameraData: CsmCameraData | undefined,
603
- casterCandidates: readonly DirectionalCsmCasterCandidate[] = [],
604
- candidateBroadphase: DirectionalCsmCandidateBroadphase | undefined = undefined,
605
- ): DirectionalCsmResult | null {
606
- const cascadeCount = Math.round(config.cascadeCount);
607
- const sNear = cameraData?.near ?? 0.1;
608
- const sFar = config.shadowDistance;
609
- const guard = validateGuardConfig(config);
610
- const splits = pssmSplit(sNear, sFar, cascadeCount, config.splitLambda);
611
- const paddedSplits = new Float32Array(4);
612
- for (let index = 0; index < splits.length; index++) paddedSplits[index] = splits[index] ?? 0;
613
- if (cameraData === undefined) return null;
614
- // Match extract-stage frustum culling's malformed-camera contract: an
615
- // incomplete camera is an always-visible/CSM-unavailable input, not a
616
- // reason to poison the render frame with NaN matrices or a depth-fit throw.
617
- // Valid cameras still use the receiver-driven stable clip domain below.
618
- if (!validCsmCamera(cameraData)) return null;
619
-
620
- const camProj = mat4.create();
621
- if (cameraData.projection === 'orthographic') {
622
- mat4.orthographic(
623
- camProj,
624
- cameraData.orthoLeft,
625
- cameraData.orthoRight,
626
- cameraData.orthoBottom,
627
- cameraData.orthoTop,
628
- cameraData.near,
629
- cameraData.far,
630
- );
631
- } else {
632
- mat4.perspective(camProj, cameraData.fov, cameraData.aspect, cameraData.near, cameraData.far);
633
- }
634
- const camView = mat4.create();
635
- mat4.invert(camView, cameraData.world as unknown as mat4.Mat4Like);
636
- const cameraVP = mat4.create();
637
- mat4.multiply(cameraVP, camProj, camView);
638
- const lightView = createLightView(direction);
639
-
640
- const fullCorners = computeFrustumCorners(
641
- cameraVP,
642
- cameraData.near,
643
- cameraData.far,
644
- sNear,
645
- sFar,
646
- cameraData.projection,
647
- );
648
- const fullBounds = transformBounds(fullCorners, lightView).bounds;
649
- const fullSphere = symmetricFrustumSphere(cameraData, sNear, sFar);
650
- const candidateLightBounds = new Map<number, Float32Array>();
651
- let casterSceneMinZ = fullBounds[4] ?? 0;
652
- let casterSceneMaxZ = fullBounds[5] ?? 0;
653
- for (const candidate of casterCandidates) {
654
- if (!candidate.shadowCaster || !candidate.bounded || candidate.worldAabb === null) continue;
655
- const bounds = transformBounds(aabbToPoints(candidate.worldAabb), lightView).bounds;
656
- candidateLightBounds.set(candidate.renderableIndex, bounds);
657
- casterSceneMinZ = Math.min(casterSceneMinZ, bounds[4] ?? casterSceneMinZ);
658
- casterSceneMaxZ = Math.max(casterSceneMaxZ, bounds[5] ?? casterSceneMaxZ);
659
- }
660
- const resultLightViewProjs: Float32Array[] = [];
661
- const cascades: CascadeVolume[] = [];
662
-
663
- for (let cascadeIndex = 0; cascadeIndex < 4; cascadeIndex++) {
664
- if (cascadeIndex >= cascadeCount) {
665
- resultLightViewProjs.push(new Float32Array(16));
666
- continue;
667
- }
668
- const cascadeNear = cascadeIndex === 0 ? sNear : (splits[cascadeIndex - 1] ?? sFar);
669
- const cascadeFar = splits[cascadeIndex] ?? sFar;
670
- const receiverNear =
671
- cascadeIndex === 0
672
- ? sNear
673
- : Math.max(sNear, cascadeNear - (splits[cascadeIndex - 1] ?? sFar) * config.cascadeBlend);
674
- const receiverCorners = computeFrustumCorners(
675
- cameraVP,
676
- cameraData.near,
677
- cameraData.far,
678
- receiverNear,
679
- cascadeFar,
680
- cameraData.projection,
681
- );
682
- const transformed = transformBounds(receiverCorners, lightView);
683
- const sphere = symmetricFrustumSphere(cameraData, receiverNear, cascadeFar);
684
- const sphereCenterLight = vec3.create();
685
- mat4.transformVec3(sphereCenterLight, lightView, sphere.center);
686
- const halfExtent = sphere.radius / guard.halfExtentDenominator;
687
- const worldUnitsPerTexel = (2 * halfExtent) / config.mapSize;
688
- const snappedX =
689
- Math.round((sphereCenterLight[0] ?? 0) / worldUnitsPerTexel) * worldUnitsPerTexel;
690
- const snappedY =
691
- Math.round((sphereCenterLight[1] ?? 0) / worldUnitsPerTexel) * worldUnitsPerTexel;
692
- const unsnappedClipMaxZ = Math.max(transformed.bounds[5] ?? 0, fullBounds[5] ?? 0);
693
- const clipMaxZ = Math.ceil(unsnappedClipMaxZ / worldUnitsPerTexel) * worldUnitsPerTexel;
694
- const clipMinZ =
695
- Math.floor((clipMaxZ - fullSphere.radius * 2) / worldUnitsPerTexel) * worldUnitsPerTexel;
696
- if (!(clipMaxZ > clipMinZ)) {
697
- throw new Error(`directional CSM receiver depth is degenerate for cascade ${cascadeIndex}`);
698
- }
699
- const clipBounds = new Float32Array([
700
- snappedX - halfExtent,
701
- snappedX + halfExtent,
702
- snappedY - halfExtent,
703
- snappedY + halfExtent,
704
- clipMinZ,
705
- clipMaxZ,
706
- ]);
707
- const casterBroadphaseLightBounds = new Float32Array([
708
- clipBounds[0] ?? 0,
709
- clipBounds[1] ?? 0,
710
- clipBounds[2] ?? 0,
711
- clipBounds[3] ?? 0,
712
- Math.min(clipBounds[4] ?? 0, casterSceneMinZ),
713
- Math.max(clipBounds[5] ?? 0, casterSceneMaxZ),
714
- ]);
715
- const casterBroadphaseWorldAabb = lightBoundsToWorldAabb(
716
- casterBroadphaseLightBounds,
717
- lightView,
718
- );
719
- const boundedMembers: number[] = [];
720
- const unboundedFallback: DirectionalCsmFallback[] = [];
721
- const candidateDecisions: DirectionalCsmCandidateDecision[] | undefined =
722
- config.collectCandidateDecisions ? [] : undefined;
723
- let boundedMemberMaxZ = -Infinity;
724
- const broadphaseIndices = candidateBroadphase?.(casterBroadphaseWorldAabb);
725
- const candidateDomain =
726
- broadphaseIndices === undefined
727
- ? casterCandidates
728
- : broadphaseIndices.flatMap((index) => {
729
- const candidate = casterCandidates[index];
730
- return candidate === undefined ? [] : [candidate];
731
- });
732
- for (const candidate of candidateDomain) {
733
- if (!candidate.shadowCaster) {
734
- if (candidateDecisions !== undefined) {
735
- candidateDecisions.push({
736
- renderableIndex: candidate.renderableIndex,
737
- worldId: candidate.worldId,
738
- entityKey: candidate.entityKey,
739
- selected: false,
740
- reason: 'no-shadow-caster-pass',
741
- });
742
- }
743
- continue;
744
- }
745
- if (!candidate.bounded || candidate.worldAabb === null) {
746
- unboundedFallback.push({
747
- renderableIndex: candidate.renderableIndex,
748
- reason: candidate.fallbackReason ?? 'missing-or-invalid-world-bounds',
749
- });
750
- candidateDecisions?.push({
751
- renderableIndex: candidate.renderableIndex,
752
- worldId: candidate.worldId,
753
- entityKey: candidate.entityKey,
754
- selected: true,
755
- reason: 'unbounded-fallback',
756
- });
757
- continue;
758
- }
759
- const casterLightBounds =
760
- candidateLightBounds.get(candidate.renderableIndex) ??
761
- transformBounds(aabbToPoints(candidate.worldAabb), lightView).bounds;
762
- // Membership must use the same final XY domain that owns the cascade
763
- // map. Testing against the raw frustum AABB is narrower than the
764
- // receiver-driven sphere fit: a caster can still project into the
765
- // stable map while falling just outside the current frustum corner
766
- // bounds. That mismatch is the camera-crossing door-frame failure mode:
767
- // the map remains valid, but the caster is culled before the depth pass.
768
- // `halfExtent` already includes the PCF/snapping guard in clipBounds, so
769
- // do not apply a second guard expansion here; the final clip is the sole
770
- // XY truth for membership and raster coverage.
771
- const overlapsStableClipXY =
772
- (casterLightBounds[1] ?? -Infinity) >= (clipBounds[0] ?? -Infinity) &&
773
- (casterLightBounds[0] ?? Infinity) <= (clipBounds[1] ?? Infinity) &&
774
- (casterLightBounds[3] ?? -Infinity) >= (clipBounds[2] ?? -Infinity) &&
775
- (casterLightBounds[2] ?? Infinity) <= (clipBounds[3] ?? Infinity);
776
- const reachesReceiver =
777
- (casterLightBounds[5] ?? -Infinity) >= (transformed.bounds[4] ?? Infinity);
778
- if (overlapsStableClipXY && reachesReceiver) {
779
- boundedMembers.push(candidate.renderableIndex);
780
- boundedMemberMaxZ = Math.max(boundedMemberMaxZ, casterLightBounds[5] ?? -Infinity);
781
- candidateDecisions?.push({
782
- renderableIndex: candidate.renderableIndex,
783
- worldId: candidate.worldId,
784
- entityKey: candidate.entityKey,
785
- selected: true,
786
- reason: 'stable-clip-xy-overlap-and-toward-light',
787
- lightSpaceBounds: new Float32Array(casterLightBounds),
788
- });
789
- } else {
790
- candidateDecisions?.push({
791
- renderableIndex: candidate.renderableIndex,
792
- worldId: candidate.worldId,
793
- entityKey: candidate.entityKey,
794
- selected: false,
795
- reason: overlapsStableClipXY
796
- ? 'behind-receiver-toward-light-test'
797
- : 'outside-stable-clip-xy',
798
- lightSpaceBounds: new Float32Array(casterLightBounds),
799
- });
800
- }
801
- }
802
- if (candidateDecisions !== undefined && broadphaseIndices !== undefined) {
803
- const domain = new Set(candidateDomain.map((candidate) => candidate.renderableIndex));
804
- for (const candidate of casterCandidates) {
805
- if (domain.has(candidate.renderableIndex)) continue;
806
- candidateDecisions.push({
807
- renderableIndex: candidate.renderableIndex,
808
- worldId: candidate.worldId,
809
- entityKey: candidate.entityKey,
810
- selected: false,
811
- reason: 'outside-spatial-broadphase',
812
- });
813
- }
814
- candidateDecisions.sort((left, right) => left.renderableIndex - right.renderableIndex);
815
- }
816
- const casterRenderableIndices = new Uint32Array(
817
- [
818
- ...new Set([...boundedMembers, ...unboundedFallback.map((entry) => entry.renderableIndex)]),
819
- ].sort((left, right) => left - right),
820
- );
821
- const receiverMaxZ = transformed.bounds[5] ?? 0;
822
- const historicalMinZ = fullBounds[4] ?? transformed.bounds[4] ?? receiverMaxZ;
823
- const historicalMaxZ = fullBounds[5] ?? receiverMaxZ;
824
- const hasWholeFrustumFallback = casterCandidates.length === 0 || unboundedFallback.length > 0;
825
- // An empty candidate domain is the legacy standalone math API: without a
826
- // producer snapshot there is no trustworthy caster census, so retain the
827
- // historical conservative depth. The render extract path always supplies
828
- // the author-visible candidate domain and therefore uses receiver-plus-
829
- // bounded-member fitting unless an explicit unbounded fallback exists.
830
- const fallbackMaxZ = hasWholeFrustumFallback ? historicalMaxZ : -Infinity;
831
- // Keep the complete XYZ fit on the same temporal grid. X/Y snapping alone
832
- // is insufficient: receiver/caster Z bounds move with the camera and can
833
- // otherwise continuously change the orthographic depth scale/translation,
834
- // reintroducing shadow shimmer even when the lateral matrix is stable.
835
- // Round outward so the quantization is conservative and never clips a
836
- // receiver or a bounded caster at a grid boundary.
837
- const rawClipMaxZWithCasters = Math.max(fallbackMaxZ, receiverMaxZ, boundedMemberMaxZ);
838
- const clipMaxZWithCasters =
839
- Math.ceil(rawClipMaxZWithCasters / worldUnitsPerTexel) * worldUnitsPerTexel;
840
- const receiverMinZ = transformed.bounds[4] ?? clipMaxZWithCasters;
841
- const rawClipMinZWithReceiver = hasWholeFrustumFallback
842
- ? Math.min(receiverMinZ, historicalMinZ)
843
- : receiverMinZ;
844
- const clipMinZWithReceiver =
845
- Math.floor(rawClipMinZWithReceiver / worldUnitsPerTexel) * worldUnitsPerTexel;
846
- clipBounds[4] = clipMinZWithReceiver;
847
- clipBounds[5] = clipMaxZWithCasters;
848
- const orthoProj = mat4.create();
849
- const clipMax = clipBounds[5] ?? 0;
850
- const clipMin = clipBounds[4] ?? 0;
851
- mat4.orthographic(
852
- orthoProj,
853
- clipBounds[0] ?? 0,
854
- clipBounds[1] ?? 0,
855
- clipBounds[2] ?? 0,
856
- clipBounds[3] ?? 0,
857
- -clipMax,
858
- -clipMin,
859
- );
860
- const lightViewProj = new Float32Array(mat4.multiply(mat4.create(), orthoProj, lightView));
861
- resultLightViewProjs.push(lightViewProj);
862
- const rasterViewport = directionalCascadeRasterViewport(
863
- cascadeIndex,
864
- cascadeCount,
865
- config.mapSize,
866
- );
867
- const depthLightRange = [clipBounds[4] ?? 0, clipBounds[5] ?? 0] as const;
868
- const revision = contentRevision([
869
- cascadeIndex,
870
- ...lightViewProj,
871
- ...clipBounds,
872
- ...casterBroadphaseWorldAabb,
873
- ...casterRenderableIndices,
874
- rasterViewport.x,
875
- rasterViewport.y,
876
- rasterViewport.w,
877
- rasterViewport.h,
878
- ]);
879
- cascades.push({
880
- cascadeIndex,
881
- revision,
882
- lightViewProj,
883
- receiverViewDepth: [receiverNear, cascadeFar],
884
- receiverLightBounds: transformed.bounds,
885
- clipLightBounds: clipBounds,
886
- rasterLightBounds: clipBounds,
887
- depthLightRange,
888
- casterBroadphaseWorldAabb,
889
- rasterViewport,
890
- stableExtent: halfExtent,
891
- unsnappedCenter: [sphereCenterLight[0] ?? 0, sphereCenterLight[1] ?? 0],
892
- snappedCenter: [snappedX, snappedY],
893
- halfExtent,
894
- worldUnitsPerTexel,
895
- guardBandTexels: guard.guardBandTexels,
896
- casterRenderableIndices,
897
- ...(candidateDecisions === undefined ? {} : { candidateDecisions }),
898
- unboundedFallback,
899
- unboundedFallbackCount: unboundedFallback.length,
900
- lightSpaceMinZFull: historicalMinZ,
901
- lightSpaceMaxZFull: historicalMaxZ,
902
- });
903
- }
904
-
905
- const revision = contentRevision([
906
- cascadeCount,
907
- config.mapSize,
908
- ...paddedSplits,
909
- ...cascades.map((cascade) => cascade.revision),
910
- ]);
911
- return {
912
- revision,
913
- volumes: cascades,
914
- lightViewProj: resultLightViewProjs,
915
- splitPlanes: paddedSplits,
916
- cascadeCount,
917
- cascadeBlend: config.cascadeBlend,
918
- shadowMapSize: config.mapSize,
919
- cascades,
920
- };
921
- }
922
-
923
- /** Sole producer for directional cascade matrices, bounds, raster, depth, and membership. */
924
- export class CascadeVolumeSetBuilder {
925
- build(
926
- direction: Vec3,
927
- config: DirectionalCsmConfig,
928
- cameraData: CsmCameraData | undefined,
929
- casterCandidates: readonly DirectionalCsmCasterCandidate[] = [],
930
- candidateBroadphase: DirectionalCsmCandidateBroadphase | undefined = undefined,
931
- ): DirectionalCsmResult | null {
932
- return buildCascadeVolumeSet(
933
- direction,
934
- config,
935
- cameraData,
936
- casterCandidates,
937
- candidateBroadphase,
938
- );
939
- }
940
- }
941
-
942
- const CASCADE_VOLUME_SET_BUILDER = new CascadeVolumeSetBuilder();
943
-
944
- /** Compatibility entry backed by the canonical CascadeVolumeSet producer. */
945
- export function computeDirectionalCsm(
946
- direction: Vec3,
947
- config: DirectionalCsmConfig,
948
- cameraData: CsmCameraData | undefined,
949
- casterCandidates: readonly DirectionalCsmCasterCandidate[] = [],
950
- candidateBroadphase: DirectionalCsmCandidateBroadphase | undefined = undefined,
951
- ): DirectionalCsmResult | null {
952
- return CASCADE_VOLUME_SET_BUILDER.build(
953
- direction,
954
- config,
955
- cameraData,
956
- casterCandidates,
957
- candidateBroadphase,
958
- );
959
- }