@forgeax/engine-render 0.1.4 → 0.1.7

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 (979) hide show
  1. package/README.md +268 -640
  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 +214 -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 +0 -1
  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 +11 -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-HCOGPHKS.mjs +93 -0
  54. package/dist/chunk-HCOGPHKS.mjs.map +1 -0
  55. package/dist/chunk-YEJIUW7D.mjs +1152 -0
  56. package/dist/chunk-YEJIUW7D.mjs.map +1 -0
  57. package/dist/components/__tests__/points-lines-admission.unit.test.d.ts +2 -0
  58. package/dist/components/__tests__/points-lines-admission.unit.test.d.ts.map +1 -0
  59. package/dist/components/__tests__/points-lines-schema.unit.test.d.ts +2 -0
  60. package/dist/components/__tests__/points-lines-schema.unit.test.d.ts.map +1 -0
  61. package/dist/components/__tests__/schema-contract.unit.test.d.ts +2 -0
  62. package/dist/components/__tests__/schema-contract.unit.test.d.ts.map +1 -0
  63. package/dist/components/glyph-text.d.ts +1 -1
  64. package/dist/components/glyph-text.d.ts.map +1 -1
  65. package/dist/components/index.d.ts +4 -2
  66. package/dist/components/index.d.ts.map +1 -1
  67. package/dist/components/instances.d.ts +1 -1
  68. package/dist/components/instances.d.ts.map +1 -1
  69. package/dist/components/light-helpers.d.ts +1 -1
  70. package/dist/components/light-helpers.d.ts.map +1 -1
  71. package/dist/components/lines.d.ts +5 -0
  72. package/dist/components/lines.d.ts.map +1 -0
  73. package/dist/components/mesh-filter.d.ts +7 -7
  74. package/dist/components/mesh-filter.d.ts.map +1 -1
  75. package/dist/components/points.d.ts +15 -0
  76. package/dist/components/points.d.ts.map +1 -0
  77. package/dist/components/scene-instance.d.ts +11 -11
  78. package/dist/components/skybox-background.d.ts +56 -0
  79. package/dist/components/skybox-background.d.ts.map +1 -0
  80. package/dist/components/skylight.d.ts +55 -0
  81. package/dist/components/skylight.d.ts.map +1 -0
  82. package/dist/components/sprite-animation.d.ts +2 -3
  83. package/dist/components/sprite-animation.d.ts.map +1 -1
  84. package/dist/components/sprite-instances.d.ts +1 -1
  85. package/dist/components/sprite-playback-mode.d.ts +6 -1
  86. package/dist/components/sprite-playback-mode.d.ts.map +1 -1
  87. package/dist/components/sprite-region-override.d.ts +2 -3
  88. package/dist/components/sprite-region-override.d.ts.map +1 -1
  89. package/dist/components/tile-layer.d.ts +5 -0
  90. package/dist/components/tile-layer.d.ts.map +1 -1
  91. package/dist/construct-renderer.d.ts +18 -1
  92. package/dist/construct-renderer.d.ts.map +1 -1
  93. package/dist/construct-renderer.mjs +27463 -4
  94. package/dist/construct-renderer.mjs.map +1 -1
  95. package/dist/debug-draw-glue.d.ts +2 -53
  96. package/dist/debug-draw-glue.d.ts.map +1 -1
  97. package/dist/device/device-scope.d.ts +83 -0
  98. package/dist/device/device-scope.d.ts.map +1 -0
  99. package/dist/{gpu-resource-store.d.ts → device/gpu-residency.d.ts} +91 -48
  100. package/dist/device/gpu-residency.d.ts.map +1 -0
  101. package/dist/device/resource-types.d.ts +8 -0
  102. package/dist/device/resource-types.d.ts.map +1 -0
  103. package/dist/engine-metrics.d.ts +2 -2
  104. package/dist/engine-metrics.d.ts.map +1 -1
  105. package/dist/errors/recover.d.ts +28 -1
  106. package/dist/errors/recover.d.ts.map +1 -1
  107. package/dist/errors/render.d.ts +320 -248
  108. package/dist/errors/render.d.ts.map +1 -1
  109. package/dist/features/fullscreen.d.ts +19 -0
  110. package/dist/features/fullscreen.d.ts.map +1 -0
  111. package/dist/features/host.d.ts +32 -26
  112. package/dist/features/host.d.ts.map +1 -1
  113. package/dist/features/morph/morph-feature.d.ts +39 -5
  114. package/dist/features/morph/morph-feature.d.ts.map +1 -1
  115. package/dist/features/plan.d.ts +182 -0
  116. package/dist/features/plan.d.ts.map +1 -0
  117. package/dist/features/prepared-gpu-work.d.ts +21 -17
  118. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  119. package/dist/features/prepared-graphics-store.d.ts +2 -1
  120. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  121. package/dist/features/prepared-graphics.d.ts +11 -21
  122. package/dist/features/prepared-graphics.d.ts.map +1 -1
  123. package/dist/features/render-graph-compute.d.ts +2 -2
  124. package/dist/features/render-graph-compute.d.ts.map +1 -1
  125. package/dist/features/render-graph-contribution.d.ts +4 -7
  126. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  127. package/dist/features/render-graph-raster.d.ts +7 -3
  128. package/dist/features/render-graph-raster.d.ts.map +1 -1
  129. package/dist/features/render-graph-resources.d.ts +6 -6
  130. package/dist/features/render-graph-resources.d.ts.map +1 -1
  131. package/dist/features/targets.d.ts +5 -5
  132. package/dist/features/targets.d.ts.map +1 -1
  133. package/dist/features/types.d.ts +11 -190
  134. package/dist/features/types.d.ts.map +1 -1
  135. package/dist/features/vocabulary.d.ts +14 -0
  136. package/dist/features/vocabulary.d.ts.map +1 -0
  137. package/dist/fullscreen-post-process-pass.d.ts +4 -25
  138. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  139. package/dist/glyph-text-layout-system.d.ts +3 -2
  140. package/dist/glyph-text-layout-system.d.ts.map +1 -1
  141. package/dist/gpu-driven/batch-topology.d.ts +6 -75
  142. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  143. package/dist/gpu-driven/production-raster.d.ts +13 -112
  144. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  145. package/dist/gpu-driven/view-gpu.d.ts +10 -66
  146. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  147. package/dist/gpu-resource.d.ts +3 -3
  148. package/dist/gpu-scene-schema.d.ts +1 -94
  149. package/dist/gpu-scene-schema.d.ts.map +1 -1
  150. package/dist/gpu-scene.d.ts +7 -33
  151. package/dist/gpu-scene.d.ts.map +1 -1
  152. package/dist/hdrp-buffers.d.ts +3 -53
  153. package/dist/hdrp-buffers.d.ts.map +1 -1
  154. package/dist/ibl/IblPipelineCache.d.ts +74 -180
  155. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  156. package/dist/ibl/skylight-bind-group.d.ts +1 -1
  157. package/dist/index.d.ts +17 -43
  158. package/dist/index.d.ts.map +1 -1
  159. package/dist/index.mjs +167 -3
  160. package/dist/index.mjs.map +1 -1
  161. package/dist/inspection-types.d.ts +72 -0
  162. package/dist/inspection-types.d.ts.map +1 -0
  163. package/dist/instance-buffer-cache.d.ts +1 -4
  164. package/dist/instance-buffer-cache.d.ts.map +1 -1
  165. package/dist/internal.d.ts +1 -73
  166. package/dist/internal.d.ts.map +1 -1
  167. package/dist/internal.mjs +1 -43
  168. package/dist/internal.mjs.map +1 -1
  169. package/dist/lifecycle.d.ts +36 -2
  170. package/dist/lifecycle.d.ts.map +1 -1
  171. package/dist/materials.d.ts +0 -3
  172. package/dist/materials.d.ts.map +1 -1
  173. package/dist/mesh-material-bindings.d.ts +0 -1
  174. package/dist/mesh-material-bindings.d.ts.map +1 -1
  175. package/dist/pbr-pipeline.d.ts +77 -29
  176. package/dist/pbr-pipeline.d.ts.map +1 -1
  177. package/dist/pipeline/standard-forward-lane.d.ts +5 -0
  178. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -0
  179. package/dist/pipeline/standard-pipeline.d.ts +31 -0
  180. package/dist/pipeline/standard-pipeline.d.ts.map +1 -0
  181. package/dist/pipeline/standard-profile.d.ts +40 -0
  182. package/dist/pipeline/standard-profile.d.ts.map +1 -0
  183. package/dist/pipeline-builder.d.ts +3 -3
  184. package/dist/pipeline-builder.d.ts.map +1 -1
  185. package/dist/pipeline-spec-types.d.ts +24 -0
  186. package/dist/pipeline-spec-types.d.ts.map +1 -0
  187. package/dist/pipeline-spec.d.ts +16 -155
  188. package/dist/pipeline-spec.d.ts.map +1 -1
  189. package/dist/plugin.d.ts +1 -14
  190. package/dist/plugin.d.ts.map +1 -1
  191. package/dist/points-lines/__tests__/bounds.unit.test.d.ts +2 -0
  192. package/dist/points-lines/__tests__/bounds.unit.test.d.ts.map +1 -0
  193. package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts +2 -0
  194. package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts.map +1 -0
  195. package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts +2 -0
  196. package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts.map +1 -0
  197. package/dist/points-lines/__tests__/inspection.unit.test.d.ts +2 -0
  198. package/dist/points-lines/__tests__/inspection.unit.test.d.ts.map +1 -0
  199. package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts +2 -0
  200. package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts.map +1 -0
  201. package/dist/points-lines/__tests__/points-lines.bench.d.ts +2 -0
  202. package/dist/points-lines/__tests__/points-lines.bench.d.ts.map +1 -0
  203. package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts +2 -0
  204. package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts.map +1 -0
  205. package/dist/points-lines/__tests__/snapshot.unit.test.d.ts +2 -0
  206. package/dist/points-lines/__tests__/snapshot.unit.test.d.ts.map +1 -0
  207. package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts +2 -0
  208. package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts.map +1 -0
  209. package/dist/points-lines/admission.d.ts +36 -0
  210. package/dist/points-lines/admission.d.ts.map +1 -0
  211. package/dist/points-lines/bounds.d.ts +8 -0
  212. package/dist/points-lines/bounds.d.ts.map +1 -0
  213. package/dist/points-lines/expansion-cache.d.ts +28 -0
  214. package/dist/points-lines/expansion-cache.d.ts.map +1 -0
  215. package/dist/points-lines/inspection.d.ts +53 -0
  216. package/dist/points-lines/inspection.d.ts.map +1 -0
  217. package/dist/points-lines/prepare.d.ts +67 -0
  218. package/dist/points-lines/prepare.d.ts.map +1 -0
  219. package/dist/points-lines/record.d.ts +60 -0
  220. package/dist/points-lines/record.d.ts.map +1 -0
  221. package/dist/points-lines/snapshot.d.ts +49 -0
  222. package/dist/points-lines/snapshot.d.ts.map +1 -0
  223. package/dist/post-process-errors.d.ts +18 -18
  224. package/dist/post-process-errors.d.ts.map +1 -1
  225. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -5
  226. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  227. package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts +2 -0
  228. package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts.map +1 -0
  229. package/dist/record/frame-lighting.d.ts +7 -73
  230. package/dist/record/frame-lighting.d.ts.map +1 -1
  231. package/dist/record/frame-snapshot.d.ts +44 -44
  232. package/dist/record/frame-snapshot.d.ts.map +1 -1
  233. package/dist/record/frame-targets.d.ts +5 -38
  234. package/dist/record/frame-targets.d.ts.map +1 -1
  235. package/dist/record/frame.d.ts +64 -52
  236. package/dist/record/frame.d.ts.map +1 -1
  237. package/dist/record/helpers.d.ts +3 -2
  238. package/dist/record/helpers.d.ts.map +1 -1
  239. package/dist/record/main-pass-geometry.d.ts +12 -4
  240. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  241. package/dist/record/main-pass-material.d.ts +90 -59
  242. package/dist/record/main-pass-material.d.ts.map +1 -1
  243. package/dist/record/main-pass-sprite-draws.d.ts +28 -3
  244. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  245. package/dist/record/main-pass.d.ts +1 -1
  246. package/dist/record/main-pass.d.ts.map +1 -1
  247. package/dist/record/mesh-ssbo.d.ts +276 -3
  248. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  249. package/dist/record/render-context.d.ts +252 -0
  250. package/dist/record/render-context.d.ts.map +1 -0
  251. package/dist/record/shadow-pass.d.ts +15 -88
  252. package/dist/record/shadow-pass.d.ts.map +1 -1
  253. package/dist/record/skybox-post-pass.d.ts +1 -1
  254. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  255. package/dist/record/typed-frame-graph.d.ts +29 -7
  256. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  257. package/dist/record/view-ubo.d.ts +9 -3
  258. package/dist/record/view-ubo.d.ts.map +1 -1
  259. package/dist/render-contract.d.ts +424 -0
  260. package/dist/render-contract.d.ts.map +1 -0
  261. package/dist/render-data.d.ts.map +1 -1
  262. package/dist/render-graph-primitives.d.ts +14 -362
  263. package/dist/render-graph-primitives.d.ts.map +1 -1
  264. package/dist/render-pipeline.d.ts +25 -64
  265. package/dist/render-pipeline.d.ts.map +1 -1
  266. package/dist/render-system-extract.d.ts +110 -338
  267. package/dist/render-system-extract.d.ts.map +1 -1
  268. package/dist/render-system.d.ts +24 -713
  269. package/dist/render-system.d.ts.map +1 -1
  270. package/dist/scene/render-scene-types.d.ts +61 -0
  271. package/dist/scene/render-scene-types.d.ts.map +1 -0
  272. package/dist/scene/render-scene.d.ts +112 -0
  273. package/dist/scene/render-scene.d.ts.map +1 -0
  274. package/dist/scene-instances/post-spawn-resolve-joints.d.ts +2 -5
  275. package/dist/scene-instances/post-spawn-resolve-joints.d.ts.map +1 -1
  276. package/dist/ssao-buffers.d.ts +22 -3
  277. package/dist/ssao-buffers.d.ts.map +1 -1
  278. package/dist/systems/skin-palette-allocator.d.ts +2 -4
  279. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  280. package/dist/systems/skin-palette-types.d.ts +14 -0
  281. package/dist/systems/skin-palette-types.d.ts.map +1 -0
  282. package/dist/systems/transparent-sort-config.d.ts +23 -2
  283. package/dist/systems/transparent-sort-config.d.ts.map +1 -1
  284. package/dist/tilemap-chunk-extract-system.d.ts +4 -3
  285. package/dist/tilemap-chunk-extract-system.d.ts.map +1 -1
  286. package/dist/typed-render-graph-primitives.d.ts +2 -4
  287. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  288. package/dist/typed-shadow-passes.d.ts +3 -3
  289. package/dist/typed-shadow-passes.d.ts.map +1 -1
  290. package/package.json +23 -23
  291. package/src/__tests__/authoring-path.unit.test.ts +9 -0
  292. package/src/__tests__/backend-selection-rhi-capture.test-d.ts +1 -1
  293. package/src/__tests__/callback-inference.test-d.ts +6 -3
  294. package/src/__tests__/cluster-grid-default-surface.unit.test.ts +7 -4
  295. package/src/__tests__/construct-renderer-identity.unit.test.ts +15 -2
  296. package/src/__tests__/device-scope-lifecycle.unit.test.ts +151 -0
  297. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +42 -0
  298. package/src/__tests__/direct-extract-consumer-contract.test-d.ts +8 -19
  299. package/src/__tests__/direct-light-snapshot.unit.test.ts +3 -13
  300. package/src/__tests__/factory-contract.integration.test.ts +158 -209
  301. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +1 -4
  302. package/src/__tests__/frame-observation.contract.test.ts +17 -8
  303. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +32 -0
  304. package/src/__tests__/glyph-text-layout-recovery.unit.test.ts +6 -11
  305. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +21 -18
  306. package/src/__tests__/gpu-driven-production.integration.test.ts +32 -205
  307. package/src/__tests__/gpu-driven-scaling.unit.test.ts +4 -7
  308. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +87 -8
  309. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +170 -8
  310. package/src/{gpu-driven/view-reference.ts → __tests__/gpu-driven-view-reference.ts} +4 -3
  311. package/src/__tests__/gpu-driven-view.browser.test.ts +12 -1
  312. package/src/__tests__/gpu-driven-view.dawn.test.ts +12 -1
  313. package/src/__tests__/gpu-driven-view.unit.test.ts +11 -267
  314. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +3 -3
  315. package/src/__tests__/gpu-scene-render-graph-gpu.ts +2 -3
  316. package/src/__tests__/gpu-scene.dawn.test.ts +2 -6
  317. package/src/__tests__/gpu-scene.unit.test.ts +10 -24
  318. package/src/__tests__/ibl/face-uniforms.unit.test.ts +46 -0
  319. package/src/__tests__/infinite-grid-no-vertex-probe.unit.test.ts +34 -66
  320. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +14 -5
  321. package/src/__tests__/light-buffer-layout.unit.test.ts +4 -49
  322. package/src/__tests__/material-cooked-projection.unit.test.ts +31 -58
  323. package/src/__tests__/material-snapshot-mutation.integration.test.ts +10 -15
  324. package/src/__tests__/material-static-dynamic-route.unit.test.ts +31 -50
  325. package/src/__tests__/material-stride-surface.unit.test.ts +2 -2
  326. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +7 -8
  327. package/src/__tests__/morph-culling-reentry.dawn.test.ts +29 -38
  328. package/src/__tests__/morph-feature-gpu-work.integration.test.ts +45 -43
  329. package/src/__tests__/morph-feature-plan.unit.test.ts +53 -0
  330. package/src/__tests__/morph-visual-evidence.integration.test.ts +47 -33
  331. package/src/__tests__/nineslice-handle-surface.unit.test.ts +11 -6
  332. package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -13
  333. package/src/__tests__/prepared-graphics-capability.unit.test.ts +6 -81
  334. package/src/__tests__/prepared-graphics-generation.unit.test.ts +3 -17
  335. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +6 -74
  336. package/src/__tests__/prepared-graphics-resolver.unit.test.ts +1 -3
  337. package/src/__tests__/prepared-graphics-snapshot.unit.test.ts +2 -2
  338. package/src/__tests__/profiler-default-off.test.ts +1 -1
  339. package/src/__tests__/profiler-phase-catalog.test.ts +2 -2
  340. package/src/__tests__/profiler-phase-integration.test.ts +5 -13
  341. package/src/__tests__/profiler-phase-token.test.ts +3 -8
  342. package/src/__tests__/public-surface.test-d.ts +65 -3
  343. package/src/__tests__/recover-error-policy-owner.unit.test.ts +1 -21
  344. package/src/__tests__/render-error-code-owner.test-d.ts +24 -23
  345. package/src/__tests__/render-error-detail-ssot.test-d.ts +0 -95
  346. package/src/__tests__/render-error-exhaustive.test-d.ts +27 -1
  347. package/src/__tests__/render-feature-assembly.test-d.ts +8 -16
  348. package/src/__tests__/render-feature-context.test-d.ts +16 -40
  349. package/src/__tests__/render-feature-contract.test-d.ts +9 -18
  350. package/src/__tests__/render-feature-diagnostics.unit.test.ts +6 -8
  351. package/src/__tests__/render-feature-docs.unit.test.ts +8 -7
  352. package/src/__tests__/render-feature-gpu-work.integration.test.ts +14 -75
  353. package/src/__tests__/render-feature-plan.test-d.ts +161 -0
  354. package/src/__tests__/render-feature-plan.unit.test.ts +170 -0
  355. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +8 -19
  356. package/src/__tests__/render-feature-prepared-errors.test-d.ts +3 -6
  357. package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +10 -71
  358. package/src/__tests__/render-feature-prepared-graphics-isolation.unit.test.ts +11 -61
  359. package/src/__tests__/render-feature-prepared-graphics-negative.test-d.ts +20 -43
  360. package/src/__tests__/render-feature-prepared-graphics.test-d.ts +56 -78
  361. package/src/__tests__/render-feature-public-surface.test-d.ts +6 -24
  362. package/src/__tests__/render-feature-retry.unit.test.ts +7 -48
  363. package/src/__tests__/render-feature-scheduling.unit.test.ts +15 -27
  364. package/src/__tests__/render-feature-stage-failed-policy-owner.unit.test.ts +0 -9
  365. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +19 -109
  366. package/src/__tests__/render-feature-visibility-context.test-d.ts +1 -6
  367. package/src/__tests__/render-feature-visibility-context.unit.test.ts +1 -2
  368. package/src/__tests__/render-feature-zero-work.unit.test.ts +14 -20
  369. package/src/__tests__/render-scene-projection.unit.test.ts +73 -111
  370. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +82 -95
  371. package/src/__tests__/renderer-lifecycle.integration.test.ts +49 -1
  372. package/src/__tests__/shader-stage-surface.unit.test.ts +14 -9
  373. package/src/__tests__/ssao-config.unit.test.ts +36 -0
  374. package/src/__tests__/ssao-kernel-surface.unit.test.ts +4 -5
  375. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +28 -0
  376. package/src/__tests__/standard-descriptors.test-d.ts +22 -0
  377. package/src/__tests__/standard-pipeline.dawn.test.ts +61 -0
  378. package/src/__tests__/standard-pipeline.integration.test.ts +124 -0
  379. package/src/__tests__/standard-profile-oracle.unit.test.ts +62 -0
  380. package/src/__tests__/surface-configuration.unit.test.ts +1 -2
  381. package/src/__tests__/texture-usage-surface.unit.test.ts +3 -6
  382. package/src/__tests__/typed-pipeline-topology.unit.test.ts +40 -206
  383. package/src/__tests__/urp-pipeline-targets.unit.test.ts +1 -11
  384. package/src/__tests__/urp-pipeline.unit.test.ts +2 -2
  385. package/src/__tests__/vertex-color-pipeline.unit.test.ts +10 -2
  386. package/src/__tests__/vertex-layout-consumer.unit.test.ts +1 -1
  387. package/src/__tests__/visibility-diagnostics.integration.test.ts +7 -11
  388. package/src/__tests__/visibility-extract.integration.test.ts +20 -11
  389. package/src/__tests__/visibility-extract.perf.test.ts +66 -32
  390. package/src/__tests__/visibility-feature-dedup.integration.test.ts +2 -4
  391. package/src/__tests__/visibility-hidden-report.unit.test.ts +1 -2
  392. package/src/__tests__/visibility-instances.integration.test.ts +7 -11
  393. package/src/__tests__/visibility-multi-world.integration.test.ts +38 -6
  394. package/src/__tests__/visibility-producer-matrix.integration.test.ts +18 -41
  395. package/src/__tests__/visibility-public-surface.test-d.ts +10 -9
  396. package/src/__tests__/visibility-resolver.unit.test.ts +2 -1
  397. package/src/__tests__/visibility-resource-short-circuit.unit.test.ts +80 -0
  398. package/src/__tests__/visibility-snapshot-contract.unit.test.ts +2 -1
  399. package/src/__tests__/vocabulary.unit.test.ts +1 -1
  400. package/src/assembly/backend-contract.ts +57 -0
  401. package/src/{renderer/renderer-factory.ts → assembly/factory.ts} +1741 -2699
  402. package/src/assembly/host-contract.ts +101 -0
  403. package/src/{renderer → assembly}/material/assembly.ts +2 -7
  404. package/src/assembly/material/pipeline-projection.ts +63 -0
  405. package/src/authoring.ts +15 -22
  406. package/src/components/__tests__/points-lines-admission.unit.test.ts +219 -0
  407. package/src/components/__tests__/points-lines-schema.unit.test.ts +56 -0
  408. package/src/components/__tests__/schema-contract.unit.test.ts +10 -0
  409. package/src/components/glyph-text.ts +3 -2
  410. package/src/components/index.ts +14 -9
  411. package/src/components/instances.ts +4 -5
  412. package/src/components/light-helpers.ts +1 -1
  413. package/src/components/lines.ts +18 -0
  414. package/src/components/mesh-filter.ts +11 -10
  415. package/src/components/points.ts +40 -0
  416. package/src/components/post-process-params.ts +3 -3
  417. package/src/components/scene-instance.ts +12 -12
  418. package/src/components/skybox-background.ts +103 -0
  419. package/src/components/{environment.ts → skylight.ts} +2 -110
  420. package/src/components/sprite-animation.ts +3 -4
  421. package/src/components/sprite-instances.ts +2 -2
  422. package/src/components/sprite-playback-mode.ts +7 -1
  423. package/src/components/sprite-region-override.ts +2 -3
  424. package/src/components/tile-layer.ts +8 -2
  425. package/src/construct-renderer.ts +67 -4
  426. package/src/debug-draw-glue.ts +8 -129
  427. package/src/device/device-scope.ts +306 -0
  428. package/src/{gpu-resource-store.ts → device/gpu-residency.ts} +540 -639
  429. package/src/device/resource-types.ts +20 -0
  430. package/src/engine-metrics.ts +12 -19
  431. package/src/errors/recover.ts +45 -3
  432. package/src/errors/render.ts +469 -429
  433. package/src/features/fullscreen.ts +46 -0
  434. package/src/features/host.ts +575 -309
  435. package/src/features/morph/morph-feature.ts +195 -105
  436. package/src/features/plan.ts +447 -0
  437. package/src/features/prepared-gpu-work.ts +72 -15
  438. package/src/features/prepared-graphics-store.ts +20 -6
  439. package/src/features/prepared-graphics.ts +12 -71
  440. package/src/features/render-graph-compute.ts +14 -5
  441. package/src/features/render-graph-contribution.ts +43 -63
  442. package/src/features/render-graph-raster.ts +32 -8
  443. package/src/features/render-graph-resources.ts +25 -23
  444. package/src/features/targets.ts +8 -21
  445. package/src/features/types.ts +39 -227
  446. package/src/features/vocabulary.ts +24 -0
  447. package/src/fullscreen-post-process-pass.ts +14 -57
  448. package/src/glyph-text-layout-system.ts +70 -96
  449. package/src/gpu-driven/batch-topology.ts +24 -202
  450. package/src/gpu-driven/production-raster.ts +99 -1109
  451. package/src/gpu-driven/view-gpu.ts +46 -192
  452. package/src/gpu-resource.ts +4 -4
  453. package/src/gpu-scene-schema.ts +11 -99
  454. package/src/gpu-scene.ts +231 -364
  455. package/src/hdrp-buffers.ts +12 -221
  456. package/src/ibl/IblPipelineCache.ts +471 -711
  457. package/src/ibl/skylight-bind-group.ts +4 -4
  458. package/src/index.ts +75 -217
  459. package/src/inspection-types.ts +80 -0
  460. package/src/instance-buffer-cache.ts +1 -29
  461. package/src/internal.ts +6 -85
  462. package/src/lifecycle.ts +64 -19
  463. package/src/materials.ts +7 -29
  464. package/src/mesh-material-bindings.ts +0 -1
  465. package/src/pbr-pipeline.ts +441 -53
  466. package/src/{urp-pipeline.ts → pipeline/standard-forward-lane.ts} +38 -149
  467. package/src/{hdrp-pipeline.ts → pipeline/standard-pipeline.ts} +221 -191
  468. package/src/pipeline/standard-profile.ts +65 -0
  469. package/src/pipeline-builder.ts +60 -64
  470. package/src/pipeline-spec-types.ts +28 -0
  471. package/src/pipeline-spec.ts +72 -609
  472. package/src/plugin.ts +7 -75
  473. package/src/points-lines/__tests__/bounds.unit.test.ts +21 -0
  474. package/src/points-lines/__tests__/cache-recovery.unit.test.ts +157 -0
  475. package/src/points-lines/__tests__/inspection-lanes.integration.test.ts +146 -0
  476. package/src/points-lines/__tests__/inspection.unit.test.ts +173 -0
  477. package/src/points-lines/__tests__/lane-structural.integration.test.ts +122 -0
  478. package/src/points-lines/__tests__/points-lines.bench.ts +400 -0
  479. package/src/points-lines/__tests__/raster-lane.integration.test.ts +44 -0
  480. package/src/points-lines/__tests__/snapshot.unit.test.ts +101 -0
  481. package/src/points-lines/__tests__/view-ubo.unit.test.ts +73 -0
  482. package/src/points-lines/admission.ts +238 -0
  483. package/src/points-lines/bounds.ts +23 -0
  484. package/src/points-lines/expansion-cache.ts +215 -0
  485. package/src/points-lines/inspection.ts +97 -0
  486. package/src/points-lines/prepare.ts +177 -0
  487. package/src/points-lines/record.ts +125 -0
  488. package/src/points-lines/snapshot.ts +130 -0
  489. package/src/post-process-errors.ts +31 -33
  490. package/src/prepare/prepared-graphics-resolver.ts +5 -4
  491. package/src/record/__tests__/material-slot-plan.unit.test.ts +1 -33
  492. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +41 -0
  493. package/src/record/__tests__/video-texture-view.unit.test.ts +1 -1
  494. package/src/record/frame-lighting.ts +88 -197
  495. package/src/record/frame-snapshot.ts +45 -60
  496. package/src/record/frame-targets.ts +8 -243
  497. package/src/record/frame.ts +521 -797
  498. package/src/record/helpers.ts +6 -11
  499. package/src/record/main-pass-geometry.ts +198 -147
  500. package/src/record/main-pass-material.ts +517 -190
  501. package/src/record/main-pass-sprite-draws.ts +199 -118
  502. package/src/record/main-pass.ts +166 -144
  503. package/src/record/mesh-ssbo.ts +517 -38
  504. package/src/record/render-context.ts +384 -0
  505. package/src/record/shadow-pass.ts +154 -1843
  506. package/src/record/skybox-post-pass.ts +14 -15
  507. package/src/record/typed-frame-graph.ts +224 -262
  508. package/src/record/view-ubo.ts +53 -37
  509. package/src/render-contract.ts +582 -0
  510. package/src/render-data.ts +3 -3
  511. package/src/render-graph-primitives.ts +76 -851
  512. package/src/render-pipeline.ts +104 -188
  513. package/src/render-system-extract.ts +1114 -1732
  514. package/src/render-system.ts +614 -1939
  515. package/src/scene/render-scene-types.ts +67 -0
  516. package/src/scene/render-scene.ts +1087 -0
  517. package/src/scene-instances/post-spawn-resolve-joints.ts +4 -7
  518. package/src/ssao-buffers.ts +167 -8
  519. package/src/systems/skin-palette-allocator.ts +21 -64
  520. package/src/systems/skin-palette-types.ts +14 -0
  521. package/src/systems/transparent-sort-config.ts +25 -3
  522. package/src/tilemap-chunk-extract-system.ts +53 -70
  523. package/src/typed-render-graph-primitives.ts +35 -24
  524. package/src/typed-shadow-passes.ts +26 -56
  525. package/dist/__tests__/analytic-sky-contract.test.d.ts +0 -2
  526. package/dist/__tests__/analytic-sky-contract.test.d.ts.map +0 -1
  527. package/dist/__tests__/analytic-sky-falsify.test.d.ts +0 -2
  528. package/dist/__tests__/analytic-sky-falsify.test.d.ts.map +0 -1
  529. package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts +0 -2
  530. package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts.map +0 -1
  531. package/dist/__tests__/backend-selection.integration.test.d.ts +0 -2
  532. package/dist/__tests__/backend-selection.integration.test.d.ts.map +0 -1
  533. package/dist/__tests__/camera-temporal.test-d.d.ts +0 -2
  534. package/dist/__tests__/camera-temporal.test-d.d.ts.map +0 -1
  535. package/dist/__tests__/camera-temporal.test.d.ts +0 -2
  536. package/dist/__tests__/camera-temporal.test.d.ts.map +0 -1
  537. package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts +0 -2
  538. package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts.map +0 -1
  539. package/dist/__tests__/environment-inspection.test.d.ts +0 -2
  540. package/dist/__tests__/environment-inspection.test.d.ts.map +0 -1
  541. package/dist/__tests__/fog-ai-user.fixture.d.ts +0 -2
  542. package/dist/__tests__/fog-ai-user.fixture.d.ts.map +0 -1
  543. package/dist/__tests__/fog-custom-render-feature.fixture.d.ts +0 -16
  544. package/dist/__tests__/fog-custom-render-feature.fixture.d.ts.map +0 -1
  545. package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts +0 -2
  546. package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts.map +0 -1
  547. package/dist/__tests__/fog-inspection.integration.test.d.ts +0 -2
  548. package/dist/__tests__/fog-inspection.integration.test.d.ts.map +0 -1
  549. package/dist/__tests__/fog-owner-state.integration.test.d.ts +0 -2
  550. package/dist/__tests__/fog-owner-state.integration.test.d.ts.map +0 -1
  551. package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts +0 -2
  552. package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts.map +0 -1
  553. package/dist/__tests__/fog-public-surface.integration.test.d.ts +0 -2
  554. package/dist/__tests__/fog-public-surface.integration.test.d.ts.map +0 -1
  555. package/dist/__tests__/fog-ray-contract.integration.test.d.ts +0 -2
  556. package/dist/__tests__/fog-ray-contract.integration.test.d.ts.map +0 -1
  557. package/dist/__tests__/fog-source-absence.integration.test.d.ts +0 -2
  558. package/dist/__tests__/fog-source-absence.integration.test.d.ts.map +0 -1
  559. package/dist/__tests__/fog-temporal.integration.test.d.ts +0 -2
  560. package/dist/__tests__/fog-temporal.integration.test.d.ts.map +0 -1
  561. package/dist/__tests__/frame-chain.unit.test.d.ts +0 -2
  562. package/dist/__tests__/frame-chain.unit.test.d.ts.map +0 -1
  563. package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts +0 -2
  564. package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts.map +0 -1
  565. package/dist/__tests__/hdrp-pipeline.unit.test.d.ts +0 -2
  566. package/dist/__tests__/hdrp-pipeline.unit.test.d.ts.map +0 -1
  567. package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts +0 -2
  568. package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts.map +0 -1
  569. package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts +0 -2
  570. package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts.map +0 -1
  571. package/dist/__tests__/material-derived-payload.integration.test.d.ts +0 -2
  572. package/dist/__tests__/material-derived-payload.integration.test.d.ts.map +0 -1
  573. package/dist/__tests__/materials.unit.test.d.ts +0 -2
  574. package/dist/__tests__/materials.unit.test.d.ts.map +0 -1
  575. package/dist/__tests__/param-schema-projection-census.unit.test.d.ts +0 -2
  576. package/dist/__tests__/param-schema-projection-census.unit.test.d.ts.map +0 -1
  577. package/dist/__tests__/persistent-render-scene.unit.test.d.ts +0 -2
  578. package/dist/__tests__/persistent-render-scene.unit.test.d.ts.map +0 -1
  579. package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts +0 -2
  580. package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts.map +0 -1
  581. package/dist/__tests__/pipeline-pass-trace.test.d.ts +0 -2
  582. package/dist/__tests__/pipeline-pass-trace.test.d.ts.map +0 -1
  583. package/dist/__tests__/pipeline-stage-owner.test-d.d.ts +0 -2
  584. package/dist/__tests__/pipeline-stage-owner.test-d.d.ts.map +0 -1
  585. package/dist/__tests__/plugin.test.d.ts +0 -2
  586. package/dist/__tests__/plugin.test.d.ts.map +0 -1
  587. package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts +0 -2
  588. package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts.map +0 -1
  589. package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts +0 -2
  590. package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts.map +0 -1
  591. package/dist/__tests__/public-pipeline-id.test-d.d.ts +0 -2
  592. package/dist/__tests__/public-pipeline-id.test-d.d.ts.map +0 -1
  593. package/dist/__tests__/render-dispatch-membership.unit.test.d.ts +0 -2
  594. package/dist/__tests__/render-dispatch-membership.unit.test.d.ts.map +0 -1
  595. package/dist/__tests__/render-feature-construction.unit.test.d.ts +0 -2
  596. package/dist/__tests__/render-feature-construction.unit.test.d.ts.map +0 -1
  597. package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts +0 -2
  598. package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts.map +0 -1
  599. package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts +0 -2
  600. package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts.map +0 -1
  601. package/dist/__tests__/render-feature-graph.integration.test.d.ts +0 -2
  602. package/dist/__tests__/render-feature-graph.integration.test.d.ts.map +0 -1
  603. package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts +0 -2
  604. package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts.map +0 -1
  605. package/dist/__tests__/render-feature-order.unit.test.d.ts +0 -2
  606. package/dist/__tests__/render-feature-order.unit.test.d.ts.map +0 -1
  607. package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts +0 -2
  608. package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts.map +0 -1
  609. package/dist/__tests__/render-feature-staging.unit.test.d.ts +0 -2
  610. package/dist/__tests__/render-feature-staging.unit.test.d.ts.map +0 -1
  611. package/dist/__tests__/renderer-render-scene-public.test-d.d.ts +0 -2
  612. package/dist/__tests__/renderer-render-scene-public.test-d.d.ts.map +0 -1
  613. package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts +0 -2
  614. package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts.map +0 -1
  615. package/dist/__tests__/sun-snapshot-consumers.test.d.ts +0 -2
  616. package/dist/__tests__/sun-snapshot-consumers.test.d.ts.map +0 -1
  617. package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts +0 -2
  618. package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts.map +0 -1
  619. package/dist/__tests__/taa-history-store.unit.test.d.ts +0 -2
  620. package/dist/__tests__/taa-history-store.unit.test.d.ts.map +0 -1
  621. package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts +0 -2
  622. package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts.map +0 -1
  623. package/dist/__tests__/temporal-inspection.unit.test.d.ts +0 -2
  624. package/dist/__tests__/temporal-inspection.unit.test.d.ts.map +0 -1
  625. package/dist/assets/__tests__/asset-decoders.unit.test.d.ts +0 -2
  626. package/dist/assets/__tests__/asset-decoders.unit.test.d.ts.map +0 -1
  627. package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts +0 -2
  628. package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts.map +0 -1
  629. package/dist/assets/__tests__/render-asset-port.unit.test.d.ts +0 -2
  630. package/dist/assets/__tests__/render-asset-port.unit.test.d.ts.map +0 -1
  631. package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts +0 -2
  632. package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts.map +0 -1
  633. package/dist/chunk-DJIMFYX6.mjs +0 -1439
  634. package/dist/chunk-DJIMFYX6.mjs.map +0 -1
  635. package/dist/chunk-F2SIOCRM.mjs +0 -7423
  636. package/dist/chunk-F2SIOCRM.mjs.map +0 -1
  637. package/dist/chunk-JMSB7AR4.mjs +0 -3
  638. package/dist/chunk-JMSB7AR4.mjs.map +0 -1
  639. package/dist/chunk-KHI6K4C6.mjs +0 -659
  640. package/dist/chunk-KHI6K4C6.mjs.map +0 -1
  641. package/dist/chunk-PORZOL2V.mjs +0 -569
  642. package/dist/chunk-PORZOL2V.mjs.map +0 -1
  643. package/dist/chunk-UOJGMDGP.mjs +0 -29913
  644. package/dist/chunk-UOJGMDGP.mjs.map +0 -1
  645. package/dist/components/__tests__/atmosphere-red.test.d.ts +0 -2
  646. package/dist/components/__tests__/atmosphere-red.test.d.ts.map +0 -1
  647. package/dist/components/__tests__/atmosphere.test.d.ts +0 -2
  648. package/dist/components/__tests__/atmosphere.test.d.ts.map +0 -1
  649. package/dist/components/__tests__/fog.test-d.d.ts +0 -2
  650. package/dist/components/__tests__/fog.test-d.d.ts.map +0 -1
  651. package/dist/components/__tests__/fog.test.d.ts +0 -2
  652. package/dist/components/__tests__/fog.test.d.ts.map +0 -1
  653. package/dist/components/atmosphere.d.ts +0 -18
  654. package/dist/components/atmosphere.d.ts.map +0 -1
  655. package/dist/components/environment.d.ts +0 -115
  656. package/dist/components/environment.d.ts.map +0 -1
  657. package/dist/deferred-lighting.d.ts +0 -13
  658. package/dist/deferred-lighting.d.ts.map +0 -1
  659. package/dist/dynamic-texture-store.d.ts +0 -42
  660. package/dist/dynamic-texture-store.d.ts.map +0 -1
  661. package/dist/environment/__tests__/failure-injection.test.d.ts +0 -2
  662. package/dist/environment/__tests__/failure-injection.test.d.ts.map +0 -1
  663. package/dist/environment/__tests__/generation-red.test.d.ts +0 -2
  664. package/dist/environment/__tests__/generation-red.test.d.ts.map +0 -1
  665. package/dist/environment/__tests__/generation.test.d.ts +0 -2
  666. package/dist/environment/__tests__/generation.test.d.ts.map +0 -1
  667. package/dist/environment/__tests__/graph-transaction.test.d.ts +0 -2
  668. package/dist/environment/__tests__/graph-transaction.test.d.ts.map +0 -1
  669. package/dist/environment/__tests__/inspection-red.test.d.ts +0 -2
  670. package/dist/environment/__tests__/inspection-red.test.d.ts.map +0 -1
  671. package/dist/environment/__tests__/lifecycle-evidence.test.d.ts +0 -2
  672. package/dist/environment/__tests__/lifecycle-evidence.test.d.ts.map +0 -1
  673. package/dist/environment/__tests__/pipeline-topology.test.d.ts +0 -2
  674. package/dist/environment/__tests__/pipeline-topology.test.d.ts.map +0 -1
  675. package/dist/environment/__tests__/readiness.test.d.ts +0 -2
  676. package/dist/environment/__tests__/readiness.test.d.ts.map +0 -1
  677. package/dist/environment/__tests__/recovery.test.d.ts +0 -2
  678. package/dist/environment/__tests__/recovery.test.d.ts.map +0 -1
  679. package/dist/environment/__tests__/resize-dispose.test.d.ts +0 -2
  680. package/dist/environment/__tests__/resize-dispose.test.d.ts.map +0 -1
  681. package/dist/environment/__tests__/signature-red.test.d.ts +0 -2
  682. package/dist/environment/__tests__/signature-red.test.d.ts.map +0 -1
  683. package/dist/environment/__tests__/signature.test.d.ts +0 -2
  684. package/dist/environment/__tests__/signature.test.d.ts.map +0 -1
  685. package/dist/environment/descriptors.d.ts +0 -2
  686. package/dist/environment/descriptors.d.ts.map +0 -1
  687. package/dist/environment/extracted-environment.d.ts +0 -53
  688. package/dist/environment/extracted-environment.d.ts.map +0 -1
  689. package/dist/environment/generation.d.ts +0 -62
  690. package/dist/environment/generation.d.ts.map +0 -1
  691. package/dist/environment/gpu-bundle.d.ts +0 -23
  692. package/dist/environment/gpu-bundle.d.ts.map +0 -1
  693. package/dist/environment/graph.d.ts +0 -108
  694. package/dist/environment/graph.d.ts.map +0 -1
  695. package/dist/environment/inspection.d.ts +0 -48
  696. package/dist/environment/inspection.d.ts.map +0 -1
  697. package/dist/environment/lifecycle.d.ts +0 -22
  698. package/dist/environment/lifecycle.d.ts.map +0 -1
  699. package/dist/environment/readiness.d.ts +0 -29
  700. package/dist/environment/readiness.d.ts.map +0 -1
  701. package/dist/environment/signature.d.ts +0 -70
  702. package/dist/environment/signature.d.ts.map +0 -1
  703. package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts +0 -2
  704. package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts.map +0 -1
  705. package/dist/extract/__tests__/environment-source.test.d.ts +0 -2
  706. package/dist/extract/__tests__/environment-source.test.d.ts.map +0 -1
  707. package/dist/extract/__tests__/schema-readers.unit.test.d.ts +0 -2
  708. package/dist/extract/__tests__/schema-readers.unit.test.d.ts.map +0 -1
  709. package/dist/extract/directional-csm.d.ts +0 -129
  710. package/dist/extract/directional-csm.d.ts.map +0 -1
  711. package/dist/extract/index.d.ts +0 -5
  712. package/dist/extract/index.d.ts.map +0 -1
  713. package/dist/extract/material-interface.d.ts +0 -56
  714. package/dist/extract/material-interface.d.ts.map +0 -1
  715. package/dist/extract/schema-readers.d.ts +0 -20
  716. package/dist/extract/schema-readers.d.ts.map +0 -1
  717. package/dist/features/graph-contribution.d.ts +0 -64
  718. package/dist/features/graph-contribution.d.ts.map +0 -1
  719. package/dist/features/index.d.ts +0 -21
  720. package/dist/features/index.d.ts.map +0 -1
  721. package/dist/features/morph/index.d.ts +0 -3
  722. package/dist/features/morph/index.d.ts.map +0 -1
  723. package/dist/features/morph/morph-bounds.d.ts +0 -42
  724. package/dist/features/morph/morph-bounds.d.ts.map +0 -1
  725. package/dist/features/scene-temporal.d.ts +0 -45
  726. package/dist/features/scene-temporal.d.ts.map +0 -1
  727. package/dist/features/taa-resolve.d.ts +0 -21
  728. package/dist/features/taa-resolve.d.ts.map +0 -1
  729. package/dist/frame-chain.d.ts +0 -14
  730. package/dist/frame-chain.d.ts.map +0 -1
  731. package/dist/gpu-driven/view-reference.d.ts.map +0 -1
  732. package/dist/gpu-resource-store.d.ts.map +0 -1
  733. package/dist/hdrp-cluster-membership.d.ts +0 -2
  734. package/dist/hdrp-cluster-membership.d.ts.map +0 -1
  735. package/dist/hdrp-pipeline.d.ts +0 -36
  736. package/dist/hdrp-pipeline.d.ts.map +0 -1
  737. package/dist/ibl/cubemap-projection.d.ts +0 -23
  738. package/dist/ibl/cubemap-projection.d.ts.map +0 -1
  739. package/dist/ibl/face-uniforms.d.ts +0 -65
  740. package/dist/ibl/face-uniforms.d.ts.map +0 -1
  741. package/dist/mesh-update-errors.d.ts +0 -71
  742. package/dist/mesh-update-errors.d.ts.map +0 -1
  743. package/dist/mipmap-generator.d.ts +0 -39
  744. package/dist/mipmap-generator.d.ts.map +0 -1
  745. package/dist/param-schema-projection-census.d.ts +0 -18
  746. package/dist/param-schema-projection-census.d.ts.map +0 -1
  747. package/dist/persistent-render-scene.d.ts +0 -158
  748. package/dist/persistent-render-scene.d.ts.map +0 -1
  749. package/dist/pipeline/index.d.ts +0 -11
  750. package/dist/pipeline/index.d.ts.map +0 -1
  751. package/dist/pipeline-errors.d.ts +0 -110
  752. package/dist/pipeline-errors.d.ts.map +0 -1
  753. package/dist/prepare/__tests__/schema-readers.unit.test.d.ts +0 -2
  754. package/dist/prepare/__tests__/schema-readers.unit.test.d.ts.map +0 -1
  755. package/dist/prepare/index.d.ts +0 -4
  756. package/dist/prepare/index.d.ts.map +0 -1
  757. package/dist/prepare/schema-readers.d.ts +0 -11
  758. package/dist/prepare/schema-readers.d.ts.map +0 -1
  759. package/dist/record/__tests__/environment-record.test.d.ts +0 -2
  760. package/dist/record/__tests__/environment-record.test.d.ts.map +0 -1
  761. package/dist/record/__tests__/frame-targets.unit.test.d.ts +0 -2
  762. package/dist/record/__tests__/frame-targets.unit.test.d.ts.map +0 -1
  763. package/dist/record/__tests__/membership-timing.unit.test.d.ts +0 -2
  764. package/dist/record/__tests__/membership-timing.unit.test.d.ts.map +0 -1
  765. package/dist/record/__tests__/render-submission.integration.test.d.ts +0 -2
  766. package/dist/record/__tests__/render-submission.integration.test.d.ts.map +0 -1
  767. package/dist/record/__tests__/render-submission.perf.test.d.ts +0 -2
  768. package/dist/record/__tests__/render-submission.perf.test.d.ts.map +0 -1
  769. package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts +0 -2
  770. package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts.map +0 -1
  771. package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts +0 -2
  772. package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts.map +0 -1
  773. package/dist/record/frame-observation.d.ts +0 -38
  774. package/dist/record/frame-observation.d.ts.map +0 -1
  775. package/dist/record/index.d.ts +0 -15
  776. package/dist/record/index.d.ts.map +0 -1
  777. package/dist/record/main-pass-skin.d.ts +0 -46
  778. package/dist/record/main-pass-skin.d.ts.map +0 -1
  779. package/dist/record/main-pass-sprite.d.ts +0 -69
  780. package/dist/record/main-pass-sprite.d.ts.map +0 -1
  781. package/dist/record/material-payload.d.ts +0 -43
  782. package/dist/record/material-payload.d.ts.map +0 -1
  783. package/dist/record/material-slot-plan.d.ts +0 -26
  784. package/dist/record/material-slot-plan.d.ts.map +0 -1
  785. package/dist/record/membership-timing.d.ts +0 -232
  786. package/dist/record/membership-timing.d.ts.map +0 -1
  787. package/dist/record/shadow-caster-uniform.d.ts +0 -8
  788. package/dist/record/shadow-caster-uniform.d.ts.map +0 -1
  789. package/dist/record/shadow-submit-mode.d.ts +0 -66
  790. package/dist/record/shadow-submit-mode.d.ts.map +0 -1
  791. package/dist/render-dispatch-membership.d.ts +0 -47
  792. package/dist/render-dispatch-membership.d.ts.map +0 -1
  793. package/dist/render-pipeline-context.d.ts +0 -289
  794. package/dist/render-pipeline-context.d.ts.map +0 -1
  795. package/dist/render-pipeline-target.d.ts +0 -16
  796. package/dist/render-pipeline-target.d.ts.map +0 -1
  797. package/dist/render-scene-projection.d.ts +0 -174
  798. package/dist/render-scene-projection.d.ts.map +0 -1
  799. package/dist/render-system-fold.d.ts +0 -266
  800. package/dist/render-system-fold.d.ts.map +0 -1
  801. package/dist/renderer/asset-service.d.ts +0 -10
  802. package/dist/renderer/asset-service.d.ts.map +0 -1
  803. package/dist/renderer/backend-selection.d.ts.map +0 -1
  804. package/dist/renderer/environment-classify.d.ts +0 -6
  805. package/dist/renderer/environment-classify.d.ts.map +0 -1
  806. package/dist/renderer/environment-error.d.ts +0 -13
  807. package/dist/renderer/environment-error.d.ts.map +0 -1
  808. package/dist/renderer/material/pipeline-projection.d.ts +0 -91
  809. package/dist/renderer/material/pipeline-projection.d.ts.map +0 -1
  810. package/dist/renderer/renderer-factory.d.ts +0 -289
  811. package/dist/renderer/renderer-factory.d.ts.map +0 -1
  812. package/dist/renderer.d.ts +0 -771
  813. package/dist/renderer.d.ts.map +0 -1
  814. package/dist/scene-utils/collect-subtree.d.ts +0 -11
  815. package/dist/scene-utils/collect-subtree.d.ts.map +0 -1
  816. package/dist/ssao-data.d.ts +0 -34
  817. package/dist/ssao-data.d.ts.map +0 -1
  818. package/dist/surface-format.d.ts +0 -10
  819. package/dist/surface-format.d.ts.map +0 -1
  820. package/dist/taa-history-store.d.ts +0 -88
  821. package/dist/taa-history-store.d.ts.map +0 -1
  822. package/dist/temporal-coverage.d.ts +0 -35
  823. package/dist/temporal-coverage.d.ts.map +0 -1
  824. package/dist/temporal-frame-transaction.d.ts +0 -92
  825. package/dist/temporal-frame-transaction.d.ts.map +0 -1
  826. package/dist/temporal-inspection.d.ts +0 -57
  827. package/dist/temporal-inspection.d.ts.map +0 -1
  828. package/dist/temporal-view.d.ts +0 -43
  829. package/dist/temporal-view.d.ts.map +0 -1
  830. package/dist/tilemap/resolve-tileset-runtime.d.ts +0 -23
  831. package/dist/tilemap/resolve-tileset-runtime.d.ts.map +0 -1
  832. package/dist/urp-pipeline.d.ts +0 -4
  833. package/dist/urp-pipeline.d.ts.map +0 -1
  834. package/src/__tests__/analytic-sky-contract.test.ts +0 -27
  835. package/src/__tests__/analytic-sky-falsify-carriers.mjs +0 -43
  836. package/src/__tests__/analytic-sky-falsify.test.ts +0 -94
  837. package/src/__tests__/assets-runtime-handoff.integration.test.ts +0 -36
  838. package/src/__tests__/backend-selection.integration.test.ts +0 -11
  839. package/src/__tests__/camera-temporal.test-d.ts +0 -8
  840. package/src/__tests__/camera-temporal.test.ts +0 -188
  841. package/src/__tests__/directional-shadow-probe-atlas-layout.unit.test.ts +0 -18
  842. package/src/__tests__/environment-inspection.test.ts +0 -45
  843. package/src/__tests__/fog-ai-user.fixture.ts +0 -350
  844. package/src/__tests__/fog-custom-render-feature.fixture.ts +0 -33
  845. package/src/__tests__/fog-custom-render-feature.integration.test.ts +0 -76
  846. package/src/__tests__/fog-inspection.integration.test.ts +0 -127
  847. package/src/__tests__/fog-owner-state.integration.test.ts +0 -112
  848. package/src/__tests__/fog-pipeline-topology.integration.test.ts +0 -93
  849. package/src/__tests__/fog-public-surface.integration.test.ts +0 -60
  850. package/src/__tests__/fog-ray-contract.integration.test.ts +0 -73
  851. package/src/__tests__/fog-source-absence.integration.test.ts +0 -51
  852. package/src/__tests__/fog-temporal.integration.test.ts +0 -115
  853. package/src/__tests__/frame-chain.unit.test.ts +0 -26
  854. package/src/__tests__/gpu-scene-field-type-owner.test-d.ts +0 -27
  855. package/src/__tests__/hdrp-pipeline.unit.test.ts +0 -100
  856. package/src/__tests__/ibl/ibl-fallback.unit.test.ts +0 -23
  857. package/src/__tests__/material-derived-error-stop-draw.integration.test.ts +0 -69
  858. package/src/__tests__/material-derived-payload.integration.test.ts +0 -164
  859. package/src/__tests__/materials.unit.test.ts +0 -25
  860. package/src/__tests__/param-schema-projection-census.unit.test.ts +0 -40
  861. package/src/__tests__/persistent-render-scene.unit.test.ts +0 -1311
  862. package/src/__tests__/pipeline-error-policy-owner.unit.test.ts +0 -167
  863. package/src/__tests__/pipeline-pass-trace.test.ts +0 -92
  864. package/src/__tests__/pipeline-stage-owner.test-d.ts +0 -13
  865. package/src/__tests__/plugin.test.ts +0 -25
  866. package/src/__tests__/prepared-graphics-backend-matrix.unit.test.ts +0 -129
  867. package/src/__tests__/prepared-graphics-resolver-recording.unit.test.ts +0 -180
  868. package/src/__tests__/public-pipeline-id.test-d.ts +0 -6
  869. package/src/__tests__/render-dispatch-membership.unit.test.ts +0 -117
  870. package/src/__tests__/render-feature-construction.unit.test.ts +0 -124
  871. package/src/__tests__/render-feature-error-code-owner.test-d.ts +0 -27
  872. package/src/__tests__/render-feature-gpu-buffer-usage-owner.test-d.ts +0 -46
  873. package/src/__tests__/render-feature-graph.integration.test.ts +0 -205
  874. package/src/__tests__/render-feature-graphics-staging.unit.test.ts +0 -200
  875. package/src/__tests__/render-feature-order.unit.test.ts +0 -66
  876. package/src/__tests__/render-feature-prepared-graphics-recording.unit.test.ts +0 -107
  877. package/src/__tests__/render-feature-staging.unit.test.ts +0 -94
  878. package/src/__tests__/renderer-render-scene-public.test-d.ts +0 -27
  879. package/src/__tests__/scene-temporal-coverage.unit.test.ts +0 -259
  880. package/src/__tests__/sun-snapshot-consumers.test.ts +0 -35
  881. package/src/__tests__/surface-backend-kind-owner.test-d.ts +0 -42
  882. package/src/__tests__/taa-history-store.unit.test.ts +0 -196
  883. package/src/__tests__/temporal-frame-transaction.integration.test.ts +0 -537
  884. package/src/__tests__/temporal-inspection.unit.test.ts +0 -138
  885. package/src/assets/__tests__/asset-decoders.unit.test.ts +0 -92
  886. package/src/assets/__tests__/mipmap-generator.unit.test.ts +0 -52
  887. package/src/assets/__tests__/render-asset-port.unit.test.ts +0 -54
  888. package/src/assets/__tests__/resolve-render-asset.unit.test.ts +0 -47
  889. package/src/components/__tests__/atmosphere-red.test.ts +0 -51
  890. package/src/components/__tests__/atmosphere.test.ts +0 -79
  891. package/src/components/__tests__/fog.test-d.ts +0 -49
  892. package/src/components/__tests__/fog.test.ts +0 -60
  893. package/src/components/atmosphere.ts +0 -64
  894. package/src/deferred-lighting.ts +0 -92
  895. package/src/dynamic-texture-store.ts +0 -111
  896. package/src/environment/README.md +0 -76
  897. package/src/environment/__tests__/failure-injection.test.ts +0 -50
  898. package/src/environment/__tests__/generation-red.test.ts +0 -64
  899. package/src/environment/__tests__/generation.test.ts +0 -37
  900. package/src/environment/__tests__/graph-transaction.test.ts +0 -85
  901. package/src/environment/__tests__/inspection-red.test.ts +0 -53
  902. package/src/environment/__tests__/lifecycle-evidence.test.ts +0 -40
  903. package/src/environment/__tests__/pipeline-topology.test.ts +0 -33
  904. package/src/environment/__tests__/readiness.test.ts +0 -42
  905. package/src/environment/__tests__/recovery.test.ts +0 -62
  906. package/src/environment/__tests__/resize-dispose.test.ts +0 -30
  907. package/src/environment/__tests__/signature-red.test.ts +0 -45
  908. package/src/environment/__tests__/signature.test.ts +0 -60
  909. package/src/environment/descriptors.ts +0 -7
  910. package/src/environment/extracted-environment.ts +0 -239
  911. package/src/environment/generation.ts +0 -158
  912. package/src/environment/gpu-bundle.ts +0 -144
  913. package/src/environment/graph.ts +0 -588
  914. package/src/environment/inspection.ts +0 -107
  915. package/src/environment/lifecycle.ts +0 -124
  916. package/src/environment/readiness.ts +0 -76
  917. package/src/environment/signature.ts +0 -185
  918. package/src/extract/__tests__/directional-csm-domain.unit.test.ts +0 -391
  919. package/src/extract/__tests__/environment-source.test.ts +0 -105
  920. package/src/extract/__tests__/schema-readers.unit.test.ts +0 -16
  921. package/src/extract/directional-csm.ts +0 -959
  922. package/src/extract/index.ts +0 -10
  923. package/src/extract/material-interface.ts +0 -604
  924. package/src/extract/schema-readers.ts +0 -27
  925. package/src/features/graph-contribution.ts +0 -577
  926. package/src/features/index.ts +0 -100
  927. package/src/features/morph/index.ts +0 -24
  928. package/src/features/morph/morph-bounds.ts +0 -123
  929. package/src/features/scene-temporal.ts +0 -274
  930. package/src/features/taa-resolve.ts +0 -244
  931. package/src/frame-chain.ts +0 -21
  932. package/src/hdrp-cluster-membership.ts +0 -70
  933. package/src/ibl/cubemap-projection.ts +0 -60
  934. package/src/ibl/face-uniforms.ts +0 -150
  935. package/src/mesh-update-errors.ts +0 -113
  936. package/src/mipmap-generator.ts +0 -244
  937. package/src/param-schema-projection-census.ts +0 -73
  938. package/src/persistent-render-scene.ts +0 -1752
  939. package/src/pipeline/index.ts +0 -40
  940. package/src/pipeline-errors.ts +0 -172
  941. package/src/prepare/__tests__/schema-readers.unit.test.ts +0 -16
  942. package/src/prepare/index.ts +0 -8
  943. package/src/prepare/schema-readers.ts +0 -20
  944. package/src/record/__tests__/environment-record.test.ts +0 -35
  945. package/src/record/__tests__/frame-targets.unit.test.ts +0 -54
  946. package/src/record/__tests__/membership-timing.unit.test.ts +0 -524
  947. package/src/record/__tests__/render-submission.integration.test.ts +0 -76
  948. package/src/record/__tests__/render-submission.perf.test.ts +0 -141
  949. package/src/record/__tests__/shadow-submit-mode.unit.test.ts +0 -88
  950. package/src/record/__tests__/view-ubo-layout.unit.test.ts +0 -101
  951. package/src/record/frame-observation.ts +0 -122
  952. package/src/record/index.ts +0 -15
  953. package/src/record/main-pass-skin.ts +0 -51
  954. package/src/record/main-pass-sprite.ts +0 -166
  955. package/src/record/material-payload.ts +0 -292
  956. package/src/record/material-slot-plan.ts +0 -68
  957. package/src/record/membership-timing.ts +0 -1012
  958. package/src/record/shadow-caster-uniform.ts +0 -37
  959. package/src/record/shadow-submit-mode.ts +0 -277
  960. package/src/render-dispatch-membership.ts +0 -155
  961. package/src/render-pipeline-context.ts +0 -332
  962. package/src/render-pipeline-target.ts +0 -96
  963. package/src/render-scene-projection.ts +0 -1738
  964. package/src/render-system-fold.ts +0 -531
  965. package/src/renderer/asset-service.ts +0 -32
  966. package/src/renderer/backend-selection.ts +0 -121
  967. package/src/renderer/environment-classify.ts +0 -30
  968. package/src/renderer/environment-error.ts +0 -19
  969. package/src/renderer/material/pipeline-projection.ts +0 -140
  970. package/src/renderer.ts +0 -940
  971. package/src/scene-utils/collect-subtree.ts +0 -40
  972. package/src/ssao-data.ts +0 -106
  973. package/src/surface-format.ts +0 -37
  974. package/src/taa-history-store.ts +0 -429
  975. package/src/temporal-coverage.ts +0 -106
  976. package/src/temporal-frame-transaction.ts +0 -301
  977. package/src/temporal-inspection.ts +0 -194
  978. package/src/temporal-view.ts +0 -174
  979. package/src/tilemap/resolve-tileset-runtime.ts +0 -72
@@ -0,0 +1,1087 @@
1
+ import type { EntityHandle, World } from '@forgeax/engine-ecs';
2
+ import { componentId } from '@forgeax/engine-ecs/internal';
3
+ import type { RenderReadLease } from '@forgeax/engine-ecs/projection';
4
+ import { box3, frustum, mat4 } from '@forgeax/engine-math';
5
+ import type { RhiDevice, RhiError } from '@forgeax/engine-rhi';
6
+ import { ChildOf, Transform } from '@forgeax/engine-scene';
7
+ import { Skin } from '@forgeax/engine-skinning';
8
+ import {
9
+ Camera,
10
+ DirectionalLight,
11
+ Instances,
12
+ Layer,
13
+ MeshFilter,
14
+ MeshRenderer,
15
+ PointLight,
16
+ PointLightShadow,
17
+ PostProcessParams,
18
+ SkyboxBackground,
19
+ Skylight,
20
+ SpotLight,
21
+ SpriteInstances,
22
+ SpriteRegionOverride,
23
+ Visibility,
24
+ } from '../components';
25
+ import {
26
+ BatchTopology,
27
+ type BatchTopologyInspection,
28
+ type SubmissionPlan,
29
+ } from '../gpu-driven/batch-topology';
30
+ import { GpuScene } from '../gpu-scene';
31
+ import type { PersistentRenderSceneInspection } from '../inspection-types';
32
+ import type { PointsLinesInspection } from '../points-lines/inspection';
33
+ import type { PointsLinesRetainedSnapshot } from '../points-lines/snapshot';
34
+ import type { CameraSnapshot } from '../render-contract';
35
+ import type {
36
+ DispatchEntry,
37
+ ExtractedFrame,
38
+ MaterialSnapshotCachesByWorld,
39
+ RenderableSnapshot,
40
+ } from '../render-system-extract';
41
+ import type {
42
+ RenderSceneApplyResult,
43
+ RenderSceneBounds,
44
+ RenderSceneDelta,
45
+ RenderSceneInspection,
46
+ RenderSceneOperation,
47
+ RenderSceneRecord,
48
+ RenderSceneResyncReason,
49
+ RenderSceneSlot,
50
+ } from './render-scene-types';
51
+
52
+ export type {
53
+ RenderSceneApplyResult,
54
+ RenderSceneBounds,
55
+ RenderSceneDelta,
56
+ RenderSceneIdentity,
57
+ RenderSceneInspection,
58
+ RenderSceneOperation,
59
+ RenderSceneRecord,
60
+ RenderSceneResyncReason,
61
+ RenderSceneSlot,
62
+ } from './render-scene-types';
63
+
64
+ interface PendingIdentity {
65
+ readonly worldId: number;
66
+ readonly entityKey: number;
67
+ readonly initial: RenderSceneSlot | undefined;
68
+ current: RenderableSnapshot | undefined;
69
+ removed: boolean;
70
+ }
71
+
72
+ function identityKey(worldId: number, entityKey: number): string {
73
+ return `${worldId}:${entityKey}`;
74
+ }
75
+
76
+ function ownSnapshot(snapshot: RenderableSnapshot): RenderableSnapshot {
77
+ return {
78
+ ...snapshot,
79
+ transform: { ...snapshot.transform, world: new Float32Array(snapshot.transform.world) },
80
+ ...(snapshot.localAabb === undefined
81
+ ? {}
82
+ : { localAabb: new Float32Array(snapshot.localAabb) }),
83
+ ...(snapshot.instances === undefined
84
+ ? {}
85
+ : {
86
+ instances: {
87
+ ...snapshot.instances,
88
+ transforms: new Float32Array(snapshot.instances.transforms),
89
+ },
90
+ }),
91
+ ...(snapshot.spriteInstances === undefined
92
+ ? {}
93
+ : {
94
+ spriteInstances: {
95
+ ...snapshot.spriteInstances,
96
+ transforms: new Float32Array(snapshot.spriteInstances.transforms),
97
+ regions: new Float32Array(snapshot.spriteInstances.regions),
98
+ },
99
+ }),
100
+ ...(snapshot.pointsLines === undefined
101
+ ? {}
102
+ : { pointsLines: ownPointsLinesSnapshot(snapshot.pointsLines) }),
103
+ };
104
+ }
105
+
106
+ function ownPointsLinesSnapshot(
107
+ snapshot: PointsLinesRetainedSnapshot,
108
+ ): PointsLinesRetainedSnapshot {
109
+ return {
110
+ ...snapshot,
111
+ style: snapshot.style === undefined ? undefined : { ...snapshot.style },
112
+ sourceBounds: new Float32Array(snapshot.sourceBounds),
113
+ viewport: { ...snapshot.viewport },
114
+ projection: new Float32Array(snapshot.projection),
115
+ };
116
+ }
117
+
118
+ function withWorld(snapshot: RenderableSnapshot, world: Float32Array): RenderableSnapshot {
119
+ return {
120
+ ...snapshot,
121
+ transform: { ...snapshot.transform, world: new Float32Array(world) },
122
+ };
123
+ }
124
+
125
+ function intersects(left: RenderSceneBounds, right: RenderSceneBounds): boolean {
126
+ return (
127
+ left.min[0] <= right.max[0] &&
128
+ left.max[0] >= right.min[0] &&
129
+ left.min[1] <= right.max[1] &&
130
+ left.max[1] >= right.min[1] &&
131
+ left.min[2] <= right.max[2] &&
132
+ left.max[2] >= right.min[2]
133
+ );
134
+ }
135
+
136
+ function worldBounds(snapshot: RenderableSnapshot): RenderSceneBounds | undefined {
137
+ const local = snapshot.localAabb;
138
+ if (local === undefined || local.length < 6) return undefined;
139
+ const world = snapshot.transform.world;
140
+ const min: [number, number, number] = [Infinity, Infinity, Infinity];
141
+ const max: [number, number, number] = [-Infinity, -Infinity, -Infinity];
142
+ for (const x of [local[0] ?? 0, local[3] ?? 0]) {
143
+ for (const y of [local[1] ?? 0, local[4] ?? 0]) {
144
+ for (const z of [local[2] ?? 0, local[5] ?? 0]) {
145
+ const tx =
146
+ (world[0] ?? 0) * x + (world[4] ?? 0) * y + (world[8] ?? 0) * z + (world[12] ?? 0);
147
+ const ty =
148
+ (world[1] ?? 0) * x + (world[5] ?? 0) * y + (world[9] ?? 0) * z + (world[13] ?? 0);
149
+ const tz =
150
+ (world[2] ?? 0) * x + (world[6] ?? 0) * y + (world[10] ?? 0) * z + (world[14] ?? 0);
151
+ min[0] = Math.min(min[0], tx);
152
+ min[1] = Math.min(min[1], ty);
153
+ min[2] = Math.min(min[2], tz);
154
+ max[0] = Math.max(max[0], tx);
155
+ max[1] = Math.max(max[1], ty);
156
+ max[2] = Math.max(max[2], tz);
157
+ }
158
+ }
159
+ }
160
+ return { min, max };
161
+ }
162
+
163
+ /**
164
+ * The renderer's single rebuildable CPU scene authority.
165
+ *
166
+ * World/entity identity maps, stable slot generations, material reverse
167
+ * lookup, and spatial facts live together here. Frame-local consumers read
168
+ * snapshots from this owner and never create a second projection ledger.
169
+ */
170
+ export class RenderScene {
171
+ private readonly slots: Array<RenderSceneSlot | undefined> = [];
172
+ private readonly generations: number[] = [];
173
+ private readonly freeSlots: number[] = [];
174
+ private readonly slotsByWorld = new Map<number, Map<number, number>>();
175
+ private readonly slotsByMaterial = new Map<number, Set<number>>();
176
+ // World bounds are a pure projection of each immutable snapshot. Cache the
177
+ // derived value by snapshot identity so repeated view queries do not redo
178
+ // the eight-corner transform for every view in the same frame.
179
+ private readonly worldBoundsCache = new WeakMap<RenderableSnapshot, RenderSceneBounds | null>();
180
+ private orderedSlots: number[] = [];
181
+ private materialized: readonly RenderableSnapshot[] | undefined;
182
+ private slotSnapshot: readonly RenderSceneSlot[] | undefined;
183
+ private revision = 0;
184
+ private noChangeFrames = 0;
185
+ private deltaFrames = 0;
186
+ private renderableScans = 0;
187
+ private fullRebuilds = 0;
188
+ private resyncs = 0;
189
+ private lastResyncReason: RenderSceneResyncReason | undefined;
190
+
191
+ apply(operations: readonly RenderSceneOperation[]): RenderSceneApplyResult {
192
+ if (operations.length === 0) {
193
+ this.noChangeFrames += 1;
194
+ this.renderableScans = 0;
195
+ return this.emptyResult();
196
+ }
197
+
198
+ this.deltaFrames += 1;
199
+ this.renderableScans = operations.length;
200
+ const pendingByWorld = new Map<number, Map<number, PendingIdentity>>();
201
+ const pendingOrder: PendingIdentity[] = [];
202
+ let ignoredLateUpdates = 0;
203
+
204
+ const pendingFor = (worldId: number, entityKey: number): PendingIdentity => {
205
+ let entities = pendingByWorld.get(worldId);
206
+ if (entities === undefined) {
207
+ entities = new Map<number, PendingIdentity>();
208
+ pendingByWorld.set(worldId, entities);
209
+ }
210
+ let pending = entities.get(entityKey);
211
+ if (pending !== undefined) return pending;
212
+ const initial = this.lookup(worldId, entityKey);
213
+ pending = {
214
+ worldId,
215
+ entityKey,
216
+ initial,
217
+ current: initial?.snapshot,
218
+ removed: false,
219
+ };
220
+ entities.set(entityKey, pending);
221
+ pendingOrder.push(pending);
222
+ return pending;
223
+ };
224
+
225
+ for (const operation of operations) {
226
+ if (operation.kind === 'create') {
227
+ const { worldId, entityKey } = operation.snapshot;
228
+ const pending = pendingFor(worldId, entityKey);
229
+ pending.current = ownSnapshot(operation.snapshot);
230
+ continue;
231
+ }
232
+ const pending = pendingFor(operation.worldId, operation.entityKey);
233
+ if (operation.kind === 'remove') {
234
+ pending.current = undefined;
235
+ pending.removed = true;
236
+ continue;
237
+ }
238
+ if (pending.current === undefined) {
239
+ ignoredLateUpdates += 1;
240
+ continue;
241
+ }
242
+ pending.current = withWorld(pending.current, operation.world);
243
+ }
244
+
245
+ let created = 0;
246
+ let updated = 0;
247
+ let removed = 0;
248
+ let recreated = 0;
249
+ const createdSlots: RenderSceneSlot[] = [];
250
+ const updatedSlots: RenderSceneSlot[] = [];
251
+ const removedSlots: RenderSceneRecord[] = [];
252
+ const recreatedSlots: RenderSceneSlot[] = [];
253
+ for (const pending of pendingOrder) {
254
+ if (pending.initial === undefined) {
255
+ if (pending.current === undefined) continue;
256
+ createdSlots.push(this.allocate(pending.current));
257
+ created += 1;
258
+ continue;
259
+ }
260
+ if (pending.current === undefined) {
261
+ this.release(pending.initial);
262
+ removedSlots.push(pending.initial);
263
+ removed += 1;
264
+ continue;
265
+ }
266
+ if (pending.removed) {
267
+ this.release(pending.initial);
268
+ recreatedSlots.push(this.allocate(pending.current));
269
+ recreated += 1;
270
+ continue;
271
+ }
272
+ const updatedSlot: RenderSceneSlot = {
273
+ ...pending.initial,
274
+ snapshot: pending.current,
275
+ };
276
+ this.unindexMaterials(pending.initial);
277
+ this.slots[pending.initial.slot] = updatedSlot;
278
+ this.indexMaterials(updatedSlot);
279
+ updatedSlots.push(updatedSlot);
280
+ updated += 1;
281
+ }
282
+
283
+ const changed = created + updated + removed + recreated > 0;
284
+ if (changed) {
285
+ this.revision += 1;
286
+ this.invalidateSnapshots();
287
+ }
288
+ return {
289
+ created,
290
+ updated,
291
+ removed,
292
+ recreated,
293
+ ignoredLateUpdates,
294
+ createdSlots,
295
+ updatedSlots,
296
+ removedSlots,
297
+ recreatedSlots,
298
+ resynced: 0,
299
+ };
300
+ }
301
+
302
+ applyDelta(delta: RenderSceneDelta): RenderSceneApplyResult {
303
+ if (delta.overflowed || delta.resync !== undefined) {
304
+ const snapshots = delta.resync ?? [];
305
+ this.reset(snapshots);
306
+ this.resyncs += 1;
307
+ this.lastResyncReason = delta.reason ?? 'journal-overflow';
308
+ return {
309
+ ...this.emptyResult(),
310
+ created: snapshots.length,
311
+ resynced: 1,
312
+ };
313
+ }
314
+ return this.apply(delta.operations);
315
+ }
316
+
317
+ /** Reconcile the current identity set while retaining slots for survivors. */
318
+ reset(snapshots: readonly RenderableSnapshot[], countAsRebuild = true): void {
319
+ const desired = new Map<string, RenderableSnapshot>();
320
+ for (const snapshot of snapshots) {
321
+ desired.set(identityKey(snapshot.worldId, snapshot.entityKey), snapshot);
322
+ }
323
+
324
+ for (const slot of this.slots) {
325
+ if (slot === undefined) continue;
326
+ if (!desired.has(identityKey(slot.worldId, slot.entityKey))) this.release(slot);
327
+ }
328
+
329
+ this.orderedSlots = [];
330
+ for (const snapshot of desired.values()) {
331
+ const existing = this.lookup(snapshot.worldId, snapshot.entityKey);
332
+ if (existing === undefined) {
333
+ this.allocate(snapshot);
334
+ continue;
335
+ }
336
+ const updated: RenderSceneSlot = {
337
+ ...existing,
338
+ snapshot: ownSnapshot(snapshot),
339
+ };
340
+ this.unindexMaterials(existing);
341
+ this.slots[existing.slot] = updated;
342
+ this.indexMaterials(updated);
343
+ this.orderedSlots.push(existing.slot);
344
+ }
345
+
346
+ this.revision += 1;
347
+ if (countAsRebuild) this.fullRebuilds += 1;
348
+ this.invalidateSnapshots();
349
+ }
350
+
351
+ rebuild(snapshots: readonly RenderableSnapshot[]): void {
352
+ this.reset(snapshots);
353
+ }
354
+
355
+ materialize(): readonly RenderableSnapshot[] {
356
+ if (this.materialized !== undefined) return this.materialized;
357
+ const snapshots: RenderableSnapshot[] = [];
358
+ for (const slot of this.orderedSlots) {
359
+ const record = this.slots[slot];
360
+ if (record !== undefined) snapshots.push(record.snapshot);
361
+ }
362
+ this.materialized = Object.freeze(snapshots);
363
+ return this.materialized;
364
+ }
365
+
366
+ slotsSnapshot(): readonly RenderSceneSlot[] {
367
+ if (this.slotSnapshot !== undefined) return this.slotSnapshot;
368
+ const records: RenderSceneSlot[] = [];
369
+ for (const slot of this.orderedSlots) {
370
+ const record = this.slots[slot];
371
+ if (record !== undefined) records.push(record);
372
+ }
373
+ this.slotSnapshot = Object.freeze(records);
374
+ return this.slotSnapshot;
375
+ }
376
+
377
+ slot(worldId: number, entityKey: number): RenderSceneSlot | undefined {
378
+ return this.lookup(worldId, entityKey);
379
+ }
380
+
381
+ has(worldId: number, entityKey: number): boolean {
382
+ return this.lookup(worldId, entityKey) !== undefined;
383
+ }
384
+
385
+ snapshot(worldId: number, entityKey: number): RenderableSnapshot | undefined {
386
+ return this.lookup(worldId, entityKey)?.snapshot;
387
+ }
388
+
389
+ pointsLinesSnapshots(): readonly PointsLinesRetainedSnapshot[] {
390
+ const snapshots: PointsLinesRetainedSnapshot[] = [];
391
+ for (const slot of this.orderedSlots) {
392
+ const record = this.slots[slot];
393
+ const snapshot = record?.snapshot.pointsLines;
394
+ if (record !== undefined && snapshot !== undefined) {
395
+ snapshots.push(ownPointsLinesSnapshot({ ...snapshot, worldId: record.worldId }));
396
+ }
397
+ }
398
+ return Object.freeze(snapshots);
399
+ }
400
+
401
+ slotsForMaterial(materialHandle: number): readonly RenderSceneSlot[] {
402
+ const slots = this.slotsByMaterial.get(materialHandle);
403
+ if (slots === undefined) return [];
404
+ const records: RenderSceneSlot[] = [];
405
+ for (const slot of slots) {
406
+ const record = this.slots[slot];
407
+ if (record !== undefined) records.push(record);
408
+ }
409
+ return records;
410
+ }
411
+
412
+ querySpatial(bounds: RenderSceneBounds): readonly RenderSceneSlot[] {
413
+ const records: RenderSceneSlot[] = [];
414
+ for (const slot of this.orderedSlots) {
415
+ const record = this.slots[slot];
416
+ if (record === undefined) continue;
417
+ const snapshot = record.snapshot;
418
+ let candidate = this.worldBoundsCache.get(snapshot);
419
+ if (candidate === undefined && !this.worldBoundsCache.has(snapshot)) {
420
+ candidate = worldBounds(snapshot) ?? null;
421
+ this.worldBoundsCache.set(snapshot, candidate);
422
+ }
423
+ if (candidate === null || candidate === undefined) continue;
424
+ if (intersects(candidate, bounds)) records.push(record);
425
+ }
426
+ return records;
427
+ }
428
+
429
+ inspect(): RenderSceneInspection {
430
+ return {
431
+ records: this.slotsSnapshot().map(({ slot, generation, worldId, entityKey }) => ({
432
+ slot,
433
+ generation,
434
+ worldId,
435
+ entityKey,
436
+ })),
437
+ slotCapacity: this.slots.length,
438
+ freeSlots: this.freeSlots.length,
439
+ revision: this.revision,
440
+ noChangeFrames: this.noChangeFrames,
441
+ deltaFrames: this.deltaFrames,
442
+ renderableScans: this.renderableScans,
443
+ fullRebuilds: this.fullRebuilds,
444
+ resyncs: this.resyncs,
445
+ lastResyncReason: this.lastResyncReason,
446
+ };
447
+ }
448
+
449
+ private emptyResult(): RenderSceneApplyResult {
450
+ return {
451
+ created: 0,
452
+ updated: 0,
453
+ removed: 0,
454
+ recreated: 0,
455
+ ignoredLateUpdates: 0,
456
+ createdSlots: [],
457
+ updatedSlots: [],
458
+ removedSlots: [],
459
+ recreatedSlots: [],
460
+ resynced: 0,
461
+ };
462
+ }
463
+
464
+ private lookup(worldId: number, entityKey: number): RenderSceneSlot | undefined {
465
+ const slot = this.slotsByWorld.get(worldId)?.get(entityKey);
466
+ return slot === undefined ? undefined : this.slots[slot];
467
+ }
468
+
469
+ private allocate(snapshot: RenderableSnapshot): RenderSceneSlot {
470
+ const reused = this.freeSlots.pop();
471
+ const slot = reused ?? this.slots.length;
472
+ const generation = reused === undefined ? 0 : (this.generations[slot] ?? -1) + 1;
473
+ const record: RenderSceneSlot = {
474
+ slot,
475
+ generation,
476
+ worldId: snapshot.worldId,
477
+ entityKey: snapshot.entityKey,
478
+ snapshot: ownSnapshot(snapshot),
479
+ };
480
+ this.generations[slot] = generation;
481
+ this.slots[slot] = record;
482
+ let entities = this.slotsByWorld.get(snapshot.worldId);
483
+ if (entities === undefined) {
484
+ entities = new Map<number, number>();
485
+ this.slotsByWorld.set(snapshot.worldId, entities);
486
+ }
487
+ entities.set(snapshot.entityKey, slot);
488
+ this.indexMaterials(record);
489
+ this.orderedSlots.push(slot);
490
+ return record;
491
+ }
492
+
493
+ private release(record: RenderSceneSlot): void {
494
+ this.slots[record.slot] = undefined;
495
+ this.unindexMaterials(record);
496
+ const entities = this.slotsByWorld.get(record.worldId);
497
+ entities?.delete(record.entityKey);
498
+ if (entities?.size === 0) this.slotsByWorld.delete(record.worldId);
499
+ const orderIndex = this.orderedSlots.indexOf(record.slot);
500
+ if (orderIndex >= 0) this.orderedSlots.splice(orderIndex, 1);
501
+ this.freeSlots.push(record.slot);
502
+ }
503
+
504
+ private indexMaterials(record: RenderSceneSlot): void {
505
+ for (const material of record.snapshot.materials) {
506
+ const handle = material.materialHandle ?? 0;
507
+ let slots = this.slotsByMaterial.get(handle);
508
+ if (slots === undefined) {
509
+ slots = new Set<number>();
510
+ this.slotsByMaterial.set(handle, slots);
511
+ }
512
+ slots.add(record.slot);
513
+ }
514
+ }
515
+
516
+ private unindexMaterials(record: RenderSceneSlot): void {
517
+ for (const material of record.snapshot.materials) {
518
+ const handle = material.materialHandle ?? 0;
519
+ const slots = this.slotsByMaterial.get(handle);
520
+ slots?.delete(record.slot);
521
+ if (slots?.size === 0) this.slotsByMaterial.delete(handle);
522
+ }
523
+ }
524
+
525
+ private invalidateSnapshots(): void {
526
+ this.materialized = undefined;
527
+ this.slotSnapshot = undefined;
528
+ }
529
+ }
530
+
531
+ function readTransformWorld(world: World, entity: EntityHandle): Float32Array | undefined {
532
+ const transform = world.get(entity, Transform);
533
+ return transform.ok ? new Float32Array(transform.value.world) : undefined;
534
+ }
535
+
536
+ export interface PersistentRenderSceneOptions {
537
+ readonly getDevice?: (() => RhiDevice) | undefined;
538
+ readonly onGpuError?: ((error: RhiError) => void) | undefined;
539
+ readonly onSharedRefMutation?: ((worldId: number, handle: number) => void) | undefined;
540
+ }
541
+
542
+ export interface PersistentGpuDrivenState {
543
+ readonly scene: GpuScene;
544
+ readonly plan: SubmissionPlan;
545
+ readonly slots: readonly RenderSceneSlot[];
546
+ }
547
+
548
+ type PersistentGpuSceneInspection = PersistentRenderSceneInspection['gpu'];
549
+
550
+ interface PersistentCompositionEntry {
551
+ readonly token: object;
552
+ readonly worlds: readonly World[];
553
+ readonly cameraOwner: number;
554
+ readonly resourceOwner: number;
555
+ readonly projection: RenderScene;
556
+ readonly topology: BatchTopology;
557
+ readonly readCursors: number[];
558
+ readonly leaseIdentities: readonly string[];
559
+ catalogEpoch: number;
560
+ readonly rigidOnly: boolean;
561
+ gpuDrivenCoverageKey: string | undefined;
562
+ gpuDrivenOwnsAll: boolean;
563
+ }
564
+
565
+ const RENDER_RELEVANT_COMPONENT_IDS = new Set([
566
+ componentId(Transform),
567
+ componentId(ChildOf),
568
+ componentId(MeshFilter),
569
+ componentId(MeshRenderer),
570
+ componentId(Instances),
571
+ componentId(SpriteInstances),
572
+ componentId(SpriteRegionOverride),
573
+ componentId(Skin),
574
+ componentId(Layer),
575
+ componentId(Visibility),
576
+ componentId(Camera),
577
+ componentId(DirectionalLight),
578
+ componentId(PointLight),
579
+ componentId(PointLightShadow),
580
+ componentId(SpotLight),
581
+ componentId(Skylight),
582
+ componentId(SkyboxBackground),
583
+ componentId(PostProcessParams),
584
+ ]);
585
+
586
+ const NON_RENDERABLE_TRANSFORM_CONSUMERS = [
587
+ Camera,
588
+ DirectionalLight,
589
+ PointLight,
590
+ SpotLight,
591
+ ] as const;
592
+
593
+ function cameraFrusta(cameras: readonly CameraSnapshot[]): readonly Float32Array[] {
594
+ const planes: Float32Array[] = [];
595
+ for (const camera of cameras) {
596
+ if (
597
+ (camera.projection === 'perspective' && (camera.fov <= 0 || camera.aspect <= 0)) ||
598
+ camera.near >= camera.far
599
+ ) {
600
+ planes.push(new Float32Array(0));
601
+ continue;
602
+ }
603
+ const projection = mat4.create();
604
+ if (camera.projection === 'orthographic') {
605
+ mat4.orthographic(
606
+ projection,
607
+ camera.orthoLeft,
608
+ camera.orthoRight,
609
+ camera.orthoBottom,
610
+ camera.orthoTop,
611
+ camera.near,
612
+ camera.far,
613
+ );
614
+ } else {
615
+ mat4.perspective(projection, camera.fov, camera.aspect, camera.near, camera.far);
616
+ }
617
+ const view = mat4.create();
618
+ mat4.invert(view, camera.world);
619
+ const viewProjection = mat4.create();
620
+ mat4.multiply(viewProjection, projection, view);
621
+ const cameraPlanes = frustum.create();
622
+ frustum.fromViewProjection(cameraPlanes, viewProjection);
623
+ planes.push(cameraPlanes);
624
+ }
625
+ return planes;
626
+ }
627
+
628
+ function cullPersistentFrame(
629
+ frame: ExtractedFrame,
630
+ candidates: readonly RenderableSnapshot[],
631
+ ): ExtractedFrame {
632
+ const planes = cameraFrusta(frame.cameras);
633
+ const visible: RenderableSnapshot[] = [];
634
+ const projectedIndex = new Int32Array(candidates.length);
635
+ projectedIndex.fill(-1);
636
+ let total = 0;
637
+ let culled = 0;
638
+
639
+ for (let index = 0; index < candidates.length; index += 1) {
640
+ const candidate = candidates[index];
641
+ if (candidate === undefined) continue;
642
+ let isVisible = true;
643
+ if (candidate.localAabb !== undefined) {
644
+ total += 1;
645
+ const worldAabb = box3.create();
646
+ box3.transformBox3(worldAabb, candidate.localAabb, candidate.transform.world);
647
+ isVisible = planes.length === 0;
648
+ for (const cameraPlanes of planes) {
649
+ if (
650
+ cameraPlanes.length === 0 ||
651
+ frustum.intersectsBox(cameraPlanes as frustum.Frustum, worldAabb as box3.Box3Like)
652
+ ) {
653
+ isVisible = true;
654
+ break;
655
+ }
656
+ }
657
+ }
658
+ if (!isVisible) {
659
+ culled += 1;
660
+ continue;
661
+ }
662
+ projectedIndex[index] = visible.length;
663
+ visible.push(candidate);
664
+ }
665
+
666
+ const dispatch: DispatchEntry[] = [];
667
+ for (const entry of frame.dispatch) {
668
+ const candidateIndex = entry.renderableIndex;
669
+ const renderableIndex = projectedIndex[candidateIndex];
670
+ if (renderableIndex === undefined || renderableIndex < 0) continue;
671
+ dispatch.push({ ...entry, renderableIndex });
672
+ }
673
+ return {
674
+ ...frame,
675
+ renderables: visible,
676
+ dispatch,
677
+ frustumStats: { culled, total },
678
+ };
679
+ }
680
+
681
+ /** Persistent scene projection used by the renderer's multi-World composition path. */
682
+ export class PersistentRenderScene {
683
+ private readonly materialSnapshotCaches: MaterialSnapshotCachesByWorld = new WeakMap();
684
+ private fullRebuilds = 0;
685
+ private worldEntitiesScanned = 0;
686
+ private noChangeFrames = 0;
687
+ private deltaFrames = 0;
688
+ private transformUpdates = 0;
689
+ private lastResyncReason: RenderSceneResyncReason | undefined;
690
+ private composition: PersistentCompositionEntry | undefined;
691
+ private gpuScene: GpuScene | undefined;
692
+ private gpuOwner: object | undefined;
693
+ private gpuDevice: RhiDevice | undefined;
694
+ private gpuStatus: 'inactive' | 'unsupported' | 'resident' | 'rebuild-pending' | 'error' =
695
+ 'inactive';
696
+ private pointsLinesInspections: readonly PointsLinesInspection[] = [];
697
+
698
+ constructor(private readonly options: PersistentRenderSceneOptions = {}) {}
699
+
700
+ /** RenderScene owns the per-World material fact cache used during extraction. */
701
+ materialSnapshotCacheStore(): MaterialSnapshotCachesByWorld {
702
+ return this.materialSnapshotCaches;
703
+ }
704
+
705
+ extractComposition(
706
+ worlds: readonly World[],
707
+ owner: { readonly cameraOwner: number; readonly resourceOwner: number },
708
+ catalogEpoch: number,
709
+ buildCandidateFrame: () => ExtractedFrame,
710
+ leases?: readonly RenderReadLease[],
711
+ ): ExtractedFrame {
712
+ this.worldEntitiesScanned = 0;
713
+ const entry = this.composition;
714
+ if (
715
+ entry === undefined ||
716
+ entry.catalogEpoch !== catalogEpoch ||
717
+ entry.cameraOwner !== owner.cameraOwner ||
718
+ entry.resourceOwner !== owner.resourceOwner ||
719
+ entry.worlds.length !== worlds.length ||
720
+ entry.worlds.some((world, index) => world !== worlds[index]) ||
721
+ leases === undefined ||
722
+ leases.length !== worlds.length
723
+ ) {
724
+ return this.rebuildComposition(worlds, owner, catalogEpoch, buildCandidateFrame, leases);
725
+ }
726
+ if (!entry.rigidOnly) {
727
+ return this.rebuildComposition(worlds, owner, catalogEpoch, buildCandidateFrame, leases);
728
+ }
729
+
730
+ const operations: RenderSceneOperation[] = [];
731
+ let requiresRebuild = false;
732
+ for (let worldId = 0; worldId < worlds.length; worldId += 1) {
733
+ const world = worlds[worldId];
734
+ if (world === undefined) continue;
735
+ const lease = leases?.[worldId];
736
+ if (lease === undefined || entry.leaseIdentities[worldId] !== lease.worldIdentity) {
737
+ requiresRebuild = true;
738
+ break;
739
+ }
740
+ let read: ReturnType<RenderReadLease['readChanges']>;
741
+ try {
742
+ read = lease.readChanges(entry.readCursors[worldId] ?? 0);
743
+ } catch {
744
+ requiresRebuild = true;
745
+ break;
746
+ }
747
+ if (read.status === 'overflow') {
748
+ requiresRebuild = true;
749
+ break;
750
+ }
751
+ const changes = read.world;
752
+ const shared = read.sharedRefs;
753
+ if (shared.records.length > 0) {
754
+ for (const record of shared.records) {
755
+ this.options.onSharedRefMutation?.(worldId, record.handle);
756
+ }
757
+ requiresRebuild = true;
758
+ break;
759
+ }
760
+ const derivedTransforms = new Set<EntityHandle>();
761
+ for (const record of changes.records) {
762
+ if (
763
+ record.kind === 'derived-component-changed' &&
764
+ record.componentId === componentId(Transform)
765
+ ) {
766
+ derivedTransforms.add(record.entity as EntityHandle);
767
+ }
768
+ }
769
+ for (const record of changes.records) {
770
+ if (
771
+ record.kind !== 'entity-removed' &&
772
+ record.componentId !== undefined &&
773
+ !RENDER_RELEVANT_COMPONENT_IDS.has(record.componentId)
774
+ ) {
775
+ continue;
776
+ }
777
+ const authoredTransform =
778
+ record.kind === 'component-changed' && record.componentId === componentId(Transform);
779
+ const derivedTransform =
780
+ record.kind === 'derived-component-changed' &&
781
+ record.componentId === componentId(Transform);
782
+ if (derivedTransform) continue;
783
+ if (authoredTransform && derivedTransforms.has(record.entity as EntityHandle)) continue;
784
+ if (
785
+ (authoredTransform || record.componentId === componentId(Transform)) &&
786
+ entry.projection.has(worldId, record.entity)
787
+ ) {
788
+ const worldView = readTransformWorld(world, record.entity as EntityHandle);
789
+ if (worldView === undefined) {
790
+ requiresRebuild = true;
791
+ break;
792
+ }
793
+ operations.push({
794
+ kind: 'update-transform',
795
+ worldId,
796
+ entityKey: record.entity,
797
+ world: new Float32Array(worldView),
798
+ });
799
+ continue;
800
+ }
801
+ requiresRebuild = true;
802
+ break;
803
+ }
804
+ if (!requiresRebuild) {
805
+ for (const entity of derivedTransforms) {
806
+ if (entry.projection.has(worldId, entity)) {
807
+ const worldView = readTransformWorld(world, entity);
808
+ if (worldView === undefined) {
809
+ requiresRebuild = true;
810
+ break;
811
+ }
812
+ operations.push({
813
+ kind: 'update-transform',
814
+ worldId,
815
+ entityKey: entity,
816
+ world: new Float32Array(worldView),
817
+ });
818
+ continue;
819
+ }
820
+ if (
821
+ NON_RENDERABLE_TRANSFORM_CONSUMERS.some((component) =>
822
+ world.hasComponent(entity, component),
823
+ )
824
+ ) {
825
+ requiresRebuild = true;
826
+ break;
827
+ }
828
+ }
829
+ }
830
+ if (requiresRebuild) break;
831
+ entry.readCursors[worldId] = read.cursor;
832
+ }
833
+ if (requiresRebuild) {
834
+ return this.rebuildComposition(worlds, owner, catalogEpoch, buildCandidateFrame, leases);
835
+ }
836
+ if (operations.length === 0) {
837
+ this.noChangeFrames += 1;
838
+ this.syncGpuOwner(entry.token, entry.projection);
839
+ return this.deriveFramePlan(entry, buildCandidateFrame);
840
+ }
841
+ const delta = entry.projection.apply(operations);
842
+ entry.topology.apply(delta);
843
+ this.syncGpuOwner(entry.token, entry.projection, delta);
844
+ this.deltaFrames += 1;
845
+ this.transformUpdates += operations.length;
846
+ return this.deriveFramePlan(entry, buildCandidateFrame);
847
+ }
848
+
849
+ invalidate(): void {
850
+ this.composition = undefined;
851
+ this.lastResyncReason = 'explicit-invalidate';
852
+ }
853
+
854
+ setCompositionGpuDrivenCoverage(key: string, ownsAll: boolean): void {
855
+ const entry = this.composition;
856
+ if (entry === undefined) return;
857
+ entry.gpuDrivenCoverageKey = key;
858
+ entry.gpuDrivenOwnsAll = ownsAll;
859
+ }
860
+
861
+ detach(world: World): void {
862
+ this.materialSnapshotCaches.delete(world);
863
+ const detachedComposition = this.composition?.worlds.includes(world)
864
+ ? this.composition
865
+ : undefined;
866
+ if (detachedComposition !== undefined) this.composition = undefined;
867
+ if (this.gpuOwner !== world && this.gpuOwner !== detachedComposition?.token) return;
868
+ this.gpuScene?.dispose();
869
+ this.gpuScene = undefined;
870
+ this.gpuOwner = undefined;
871
+ this.gpuDevice = undefined;
872
+ this.gpuStatus = 'inactive';
873
+ }
874
+
875
+ /** Drop only device-owned tables; the CPU projection remains the recovery authority. */
876
+ resetGpuForRecover(): void {
877
+ if (this.composition !== undefined) this.composition.gpuDrivenOwnsAll = false;
878
+ this.gpuScene = undefined;
879
+ this.gpuOwner = undefined;
880
+ this.gpuDevice = undefined;
881
+ this.gpuStatus = this.options.getDevice === undefined ? 'inactive' : 'rebuild-pending';
882
+ }
883
+
884
+ setPointsLinesInspections(inspections: readonly PointsLinesInspection[]): void {
885
+ this.pointsLinesInspections = inspections.map((inspection) => ({
886
+ ...inspection,
887
+ cache: { ...inspection.cache },
888
+ ...(inspection.refusal === undefined ? {} : { refusal: { ...inspection.refusal } }),
889
+ }));
890
+ }
891
+
892
+ dispose(): void {
893
+ this.gpuScene?.dispose();
894
+ this.gpuScene = undefined;
895
+ this.gpuOwner = undefined;
896
+ this.gpuDevice = undefined;
897
+ this.gpuStatus = 'inactive';
898
+ this.composition = undefined;
899
+ this.pointsLinesInspections = [];
900
+ }
901
+
902
+ inspect(): PersistentRenderSceneInspection {
903
+ const entry = this.composition;
904
+ const pointsLines = this.pointsLinesInspections;
905
+ return {
906
+ worldEntitiesScanned: this.worldEntitiesScanned,
907
+ fullRebuilds: this.fullRebuilds,
908
+ noChangeFrames: this.noChangeFrames,
909
+ deltaFrames: this.deltaFrames,
910
+ transformUpdates: this.transformUpdates,
911
+ lastResyncReason: this.lastResyncReason,
912
+ projectionRecords: entry?.projection.inspect().records.length ?? 0,
913
+ topology:
914
+ entry?.topology.inspect() ??
915
+ ({
916
+ revision: 0,
917
+ batchCount: 0,
918
+ candidateCount: 0,
919
+ rebuilds: 0,
920
+ patches: 0,
921
+ ineligible: 0,
922
+ } satisfies BatchTopologyInspection),
923
+ gpu: this.inspectGpu(),
924
+ pointsLines,
925
+ };
926
+ }
927
+
928
+ compositionGpuDrivenState(): PersistentGpuDrivenState | undefined {
929
+ const entry = this.composition;
930
+ if (entry === undefined || this.gpuOwner !== entry.token || this.gpuScene === undefined) {
931
+ return undefined;
932
+ }
933
+ return {
934
+ scene: this.gpuScene,
935
+ plan: entry.topology.plan(),
936
+ slots: entry.projection.slotsSnapshot(),
937
+ };
938
+ }
939
+
940
+ pointsLinesSnapshots(): readonly PointsLinesRetainedSnapshot[] {
941
+ return this.composition?.projection.pointsLinesSnapshots() ?? [];
942
+ }
943
+
944
+ private inspectGpu(): PersistentGpuSceneInspection {
945
+ if (this.gpuStatus === 'resident' && this.gpuScene !== undefined) {
946
+ return { status: 'resident', ...this.gpuScene.inspect() };
947
+ }
948
+ if (this.gpuStatus === 'unsupported') {
949
+ return { status: 'unsupported', reason: 'storage-buffer-unavailable' };
950
+ }
951
+ if (this.gpuStatus === 'rebuild-pending') return { status: 'rebuild-pending' };
952
+ if (this.gpuStatus === 'error') return { status: 'error' };
953
+ return { status: 'inactive' };
954
+ }
955
+
956
+ private rebuildComposition(
957
+ worlds: readonly World[],
958
+ owner: { readonly cameraOwner: number; readonly resourceOwner: number },
959
+ catalogEpoch: number,
960
+ buildCandidateFrame: () => ExtractedFrame,
961
+ leases?: readonly RenderReadLease[],
962
+ ): ExtractedFrame {
963
+ const candidateFrame = buildCandidateFrame();
964
+ this.worldEntitiesScanned = candidateFrame.renderables.length;
965
+ const projection = new RenderScene();
966
+ projection.reset(candidateFrame.renderables);
967
+ const topology = new BatchTopology();
968
+ topology.rebuild(projection.slotsSnapshot());
969
+ const token = {};
970
+ const entry: PersistentCompositionEntry = {
971
+ token,
972
+ worlds: [...worlds],
973
+ cameraOwner: owner.cameraOwner,
974
+ resourceOwner: owner.resourceOwner,
975
+ projection,
976
+ topology,
977
+ readCursors:
978
+ leases === undefined || leases.length !== worlds.length
979
+ ? []
980
+ : leases.map((lease) => lease.inspectCursor()),
981
+ leaseIdentities:
982
+ leases === undefined || leases.length !== worlds.length
983
+ ? []
984
+ : leases.map((lease) => lease.worldIdentity),
985
+ catalogEpoch,
986
+ rigidOnly: candidateFrame.renderables.every((renderable) => renderable.skin === undefined),
987
+ gpuDrivenCoverageKey: undefined,
988
+ gpuDrivenOwnsAll: false,
989
+ };
990
+ this.composition = entry;
991
+ this.syncGpuOwner(token, projection, undefined, true);
992
+ this.fullRebuilds += 1;
993
+ this.lastResyncReason = 'attach';
994
+ return cullPersistentFrame(candidateFrame, projection.materialize());
995
+ }
996
+
997
+ /**
998
+ * Derive an ephemeral frame plan from persistent scene facts. The scene
999
+ * retains identity/topology/cursors; no prior frame object is an authority.
1000
+ */
1001
+ private deriveFramePlan(
1002
+ entry: PersistentCompositionEntry,
1003
+ buildCandidateFrame: () => ExtractedFrame,
1004
+ ): ExtractedFrame {
1005
+ const candidateFrame = buildCandidateFrame();
1006
+ const candidates = entry.projection.materialize();
1007
+ return cullPersistentFrame({ ...candidateFrame, renderables: [...candidates] }, candidates);
1008
+ }
1009
+
1010
+ private syncGpuOwner(
1011
+ owner: object,
1012
+ projection: RenderScene,
1013
+ delta?: RenderSceneApplyResult,
1014
+ full = false,
1015
+ ): void {
1016
+ const acquired = this.acquireGpuScene(owner, projection);
1017
+ if (acquired === undefined || acquired.rebuilt) return;
1018
+ const result = full
1019
+ ? acquired.scene.rebuild(projection.slotsSnapshot())
1020
+ : delta === undefined
1021
+ ? acquired.scene.sync({
1022
+ created: 0,
1023
+ updated: 0,
1024
+ removed: 0,
1025
+ recreated: 0,
1026
+ ignoredLateUpdates: 0,
1027
+ createdSlots: [],
1028
+ updatedSlots: [],
1029
+ removedSlots: [],
1030
+ recreatedSlots: [],
1031
+ resynced: 0,
1032
+ })
1033
+ : acquired.scene.sync(delta);
1034
+ if (!result.ok) this.failGpu(result.error);
1035
+ }
1036
+
1037
+ private acquireGpuScene(
1038
+ owner: object,
1039
+ projection: RenderScene,
1040
+ ): { readonly scene: GpuScene; readonly rebuilt: boolean } | undefined {
1041
+ const getDevice = this.options.getDevice;
1042
+ if (getDevice === undefined) return undefined;
1043
+ const device = getDevice();
1044
+ if (this.gpuDevice !== undefined && this.gpuDevice !== device) {
1045
+ this.gpuScene = undefined;
1046
+ this.gpuOwner = undefined;
1047
+ this.gpuStatus = 'rebuild-pending';
1048
+ }
1049
+ if (this.gpuStatus === 'error' && this.gpuDevice === device) return undefined;
1050
+ if (this.gpuStatus === 'unsupported' && this.gpuDevice === device) return undefined;
1051
+ if (this.gpuScene !== undefined && this.gpuOwner === owner) {
1052
+ return { scene: this.gpuScene, rebuilt: false };
1053
+ }
1054
+ if (this.gpuScene !== undefined) this.gpuScene.dispose();
1055
+ this.gpuScene = undefined;
1056
+ this.gpuOwner = undefined;
1057
+ this.gpuDevice = device;
1058
+ const created = GpuScene.create(device, Math.max(256, projection.inspect().slotCapacity));
1059
+ if (!created.ok) {
1060
+ this.failGpu(created.error);
1061
+ return undefined;
1062
+ }
1063
+ if (created.value.status === 'unavailable') {
1064
+ this.gpuStatus = 'unsupported';
1065
+ return undefined;
1066
+ }
1067
+ const scene = created.value.scene;
1068
+ const rebuilt = scene.rebuild(projection.slotsSnapshot());
1069
+ if (!rebuilt.ok) {
1070
+ scene.dispose();
1071
+ this.failGpu(rebuilt.error);
1072
+ return undefined;
1073
+ }
1074
+ this.gpuScene = scene;
1075
+ this.gpuOwner = owner;
1076
+ this.gpuStatus = 'resident';
1077
+ return { scene, rebuilt: true };
1078
+ }
1079
+
1080
+ private failGpu(error: RhiError): void {
1081
+ this.gpuScene?.dispose();
1082
+ this.gpuScene = undefined;
1083
+ this.gpuOwner = undefined;
1084
+ this.gpuStatus = 'error';
1085
+ this.options.onGpuError?.(error);
1086
+ }
1087
+ }