@forgeax/engine-render 0.1.3 → 0.1.6

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