@forgeax/engine-render 0.1.21 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (584) hide show
  1. package/README.md +281 -38
  2. package/dist/assembly/backend-contract.d.ts +13 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/bundler-contract.d.ts +9 -0
  5. package/dist/assembly/bundler-contract.d.ts.map +1 -0
  6. package/dist/assembly/device-feature-admission.d.ts +8 -0
  7. package/dist/assembly/device-feature-admission.d.ts.map +1 -1
  8. package/dist/assembly/extended-lighting-fallback.d.ts +13 -0
  9. package/dist/assembly/extended-lighting-fallback.d.ts.map +1 -0
  10. package/dist/assembly/factory.d.ts +7 -235
  11. package/dist/assembly/factory.d.ts.map +1 -1
  12. package/dist/assembly/host-contract.d.ts +10 -0
  13. package/dist/assembly/host-contract.d.ts.map +1 -1
  14. package/dist/assembly/material/assembly.d.ts +3 -2
  15. package/dist/assembly/material/assembly.d.ts.map +1 -1
  16. package/dist/assembly/material/standard-layer-projection.d.ts +10 -0
  17. package/dist/assembly/material/standard-layer-projection.d.ts.map +1 -0
  18. package/dist/assembly/material-shader-policy.d.ts +168 -0
  19. package/dist/assembly/material-shader-policy.d.ts.map +1 -0
  20. package/dist/assembly/material-shader-prewarm.d.ts +21 -0
  21. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -0
  22. package/dist/assembly/mesh-ssbo-grow.d.ts +88 -0
  23. package/dist/assembly/mesh-ssbo-grow.d.ts.map +1 -0
  24. package/dist/assembly/recovery/device-loss-fanout.d.ts +14 -0
  25. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -0
  26. package/dist/assembly/recovery/generation.d.ts +46 -0
  27. package/dist/assembly/recovery/generation.d.ts.map +1 -0
  28. package/dist/assembly/recovery/recovery-attempt.d.ts +63 -0
  29. package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -0
  30. package/dist/assembly/recovery/renderer-recover.d.ts +115 -0
  31. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -0
  32. package/dist/assembly/renderer-facade.d.ts +10 -0
  33. package/dist/assembly/renderer-facade.d.ts.map +1 -0
  34. package/dist/assembly/renderer-frame-transaction.d.ts +17 -0
  35. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  36. package/dist/assembly/renderer-helpers.d.ts +19 -0
  37. package/dist/assembly/renderer-helpers.d.ts.map +1 -0
  38. package/dist/assembly/renderer-lifecycle.d.ts +34 -0
  39. package/dist/assembly/renderer-lifecycle.d.ts.map +1 -1
  40. package/dist/assembly/shader-prewarm-policy.d.ts +15 -0
  41. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -0
  42. package/dist/assembly/webgpu-ready-contract.d.ts +9 -0
  43. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -0
  44. package/dist/assembly/webgpu-ready.d.ts +55 -0
  45. package/dist/assembly/webgpu-ready.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-renderer.d.ts +152 -0
  47. package/dist/assembly/webgpu-renderer.d.ts.map +1 -0
  48. package/dist/authoring.mjs +1 -1
  49. package/dist/{chunk-PCHBPYML.mjs → chunk-GE3SDD72.mjs} +37 -5
  50. package/dist/chunk-GE3SDD72.mjs.map +1 -0
  51. package/dist/chunk-KZFTK6DO.mjs +1191 -0
  52. package/dist/chunk-KZFTK6DO.mjs.map +1 -0
  53. package/dist/{chunk-FS2KNUQH.mjs → chunk-Q752SHI5.mjs} +332 -568
  54. package/dist/chunk-Q752SHI5.mjs.map +1 -0
  55. package/dist/{chunk-6OPXDQ2E.mjs → chunk-RR5L4SRS.mjs} +33 -294
  56. package/dist/chunk-RR5L4SRS.mjs.map +1 -0
  57. package/dist/chunk-TFH5I7JJ.mjs +296 -0
  58. package/dist/chunk-TFH5I7JJ.mjs.map +1 -0
  59. package/dist/chunk-UQYS7FRM.mjs +1003 -0
  60. package/dist/chunk-UQYS7FRM.mjs.map +1 -0
  61. package/dist/chunk-YKB5DQV7.mjs +345 -0
  62. package/dist/chunk-YKB5DQV7.mjs.map +1 -0
  63. package/dist/{chunk-5YADUCA7.mjs → chunk-YRUYGA4A.mjs} +1189 -1217
  64. package/dist/chunk-YRUYGA4A.mjs.map +1 -0
  65. package/dist/chunk-Z3YYH2MB.mjs +5082 -0
  66. package/dist/chunk-Z3YYH2MB.mjs.map +1 -0
  67. package/dist/cluster-binner.d.ts +5 -0
  68. package/dist/cluster-binner.d.ts.map +1 -1
  69. package/dist/components/index.d.ts +3 -0
  70. package/dist/components/index.d.ts.map +1 -1
  71. package/dist/components/light-helpers.d.ts +4 -0
  72. package/dist/components/light-helpers.d.ts.map +1 -1
  73. package/dist/components/light-probe.d.ts +9 -0
  74. package/dist/components/light-probe.d.ts.map +1 -0
  75. package/dist/components/rect-area-light.d.ts +12 -0
  76. package/dist/components/rect-area-light.d.ts.map +1 -0
  77. package/dist/components/scene-instance.d.ts +4 -0
  78. package/dist/components/scene-instance.d.ts.map +1 -1
  79. package/dist/components/spot-light.d.ts +3 -0
  80. package/dist/components/spot-light.d.ts.map +1 -1
  81. package/dist/construct-renderer.mjs +27276 -23232
  82. package/dist/construct-renderer.mjs.map +1 -1
  83. package/dist/device/device-scope.d.ts +2 -0
  84. package/dist/device/device-scope.d.ts.map +1 -1
  85. package/dist/device/gpu-residency.d.ts +32 -5
  86. package/dist/device/gpu-residency.d.ts.map +1 -1
  87. package/dist/device/lifecycle-transaction.d.ts +2 -0
  88. package/dist/device/lifecycle-transaction.d.ts.map +1 -0
  89. package/dist/environment/frame.d.ts +5 -0
  90. package/dist/environment/frame.d.ts.map +1 -1
  91. package/dist/environment/inspection.d.ts +7 -0
  92. package/dist/environment/inspection.d.ts.map +1 -1
  93. package/dist/environment/lifecycle.d.ts +20 -2
  94. package/dist/environment/lifecycle.d.ts.map +1 -1
  95. package/dist/errors/gpu-driven.d.ts +26 -0
  96. package/dist/errors/gpu-driven.d.ts.map +1 -0
  97. package/dist/errors/index.d.ts +1 -0
  98. package/dist/errors/index.d.ts.map +1 -1
  99. package/dist/errors/recover.d.ts +67 -3
  100. package/dist/errors/recover.d.ts.map +1 -1
  101. package/dist/errors/render.d.ts +39 -1
  102. package/dist/errors/render.d.ts.map +1 -1
  103. package/dist/extract/contracts.d.ts +899 -0
  104. package/dist/extract/contracts.d.ts.map +1 -0
  105. package/dist/extract/gpu-driven.d.ts +50 -0
  106. package/dist/extract/gpu-driven.d.ts.map +1 -0
  107. package/dist/extract/visibility.d.ts.map +1 -1
  108. package/dist/features/host.d.ts +2 -0
  109. package/dist/features/host.d.ts.map +1 -1
  110. package/dist/features/prepared-gpu-work.d.ts +3 -0
  111. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  112. package/dist/features/prepared-graphics-store.d.ts +2 -0
  113. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  114. package/dist/gpu-driven/batch-topology.d.ts +34 -0
  115. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  116. package/dist/gpu-driven/prepared-draw.d.ts +63 -0
  117. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -0
  118. package/dist/gpu-driven/production-raster.d.ts +126 -2
  119. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  120. package/dist/gpu-driven/view-gpu.d.ts +64 -1
  121. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  122. package/dist/gpu-scene-schema.d.ts +14 -0
  123. package/dist/gpu-scene-schema.d.ts.map +1 -1
  124. package/dist/gpu-scene.d.ts +9 -1
  125. package/dist/gpu-scene.d.ts.map +1 -1
  126. package/dist/gpu-usage.d.ts +0 -1
  127. package/dist/gpu-usage.d.ts.map +1 -1
  128. package/dist/hdrp-buffers.d.ts +3 -3
  129. package/dist/hdrp-buffers.d.ts.map +1 -1
  130. package/dist/ibl/IblPipelineCache.d.ts +7 -6
  131. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  132. package/dist/ibl/skylight-bind-group.d.ts +7 -1
  133. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  134. package/dist/index.d.ts +13 -2
  135. package/dist/index.d.ts.map +1 -1
  136. package/dist/index.mjs +90 -5
  137. package/dist/index.mjs.map +1 -1
  138. package/dist/inspection-types.d.ts +163 -1
  139. package/dist/inspection-types.d.ts.map +1 -1
  140. package/dist/internal.d.ts +9 -0
  141. package/dist/internal.d.ts.map +1 -1
  142. package/dist/internal.mjs +23 -2
  143. package/dist/internal.mjs.map +1 -1
  144. package/dist/light-buffer-layout.d.ts +60 -148
  145. package/dist/light-buffer-layout.d.ts.map +1 -1
  146. package/dist/materials.d.ts +34 -10
  147. package/dist/materials.d.ts.map +1 -1
  148. package/dist/mesh-material-bindings.d.ts +56 -0
  149. package/dist/mesh-material-bindings.d.ts.map +1 -1
  150. package/dist/occlusion-proxy.d.ts +4 -0
  151. package/dist/occlusion-proxy.d.ts.map +1 -0
  152. package/dist/pbr-pipeline.d.ts +58 -21
  153. package/dist/pbr-pipeline.d.ts.map +1 -1
  154. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  155. package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -1
  156. package/dist/pipeline/standard-lighting/light-frame.d.ts +3 -3
  157. package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -1
  158. package/dist/pipeline/standard-lighting/topology.d.ts +1 -1
  159. package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -1
  160. package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -1
  161. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  162. package/dist/pipeline-builder.d.ts +2 -0
  163. package/dist/pipeline-builder.d.ts.map +1 -1
  164. package/dist/pipeline-spec.d.ts +1 -1
  165. package/dist/pipeline-spec.d.ts.map +1 -1
  166. package/dist/plugin.d.ts.map +1 -1
  167. package/dist/points-lines/prepare.d.ts +3 -0
  168. package/dist/points-lines/prepare.d.ts.map +1 -1
  169. package/dist/points-lines/standard-owner.d.ts +33 -0
  170. package/dist/points-lines/standard-owner.d.ts.map +1 -0
  171. package/dist/prepare/extended-lighting/ltc-resources.d.ts +31 -0
  172. package/dist/prepare/extended-lighting/ltc-resources.d.ts.map +1 -0
  173. package/dist/prepare/extended-lighting/resources.d.ts +72 -0
  174. package/dist/prepare/extended-lighting/resources.d.ts.map +1 -0
  175. package/dist/prepare/extended-lighting/spot-modifiers.d.ts +42 -0
  176. package/dist/prepare/extended-lighting/spot-modifiers.d.ts.map +1 -0
  177. package/dist/prepare/extended-lighting/state.d.ts +24 -0
  178. package/dist/prepare/extended-lighting/state.d.ts.map +1 -0
  179. package/dist/record/frame-lighting.d.ts +8 -6
  180. package/dist/record/frame-lighting.d.ts.map +1 -1
  181. package/dist/record/frame-snapshot.d.ts +55 -10
  182. package/dist/record/frame-snapshot.d.ts.map +1 -1
  183. package/dist/record/frame-targets.d.ts.map +1 -1
  184. package/dist/record/frame.d.ts +21 -5
  185. package/dist/record/frame.d.ts.map +1 -1
  186. package/dist/record/gpu-timing.d.ts +19 -7
  187. package/dist/record/gpu-timing.d.ts.map +1 -1
  188. package/dist/record/helpers.d.ts +0 -20
  189. package/dist/record/helpers.d.ts.map +1 -1
  190. package/dist/record/main-pass-geometry.d.ts +20 -2
  191. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  192. package/dist/record/main-pass-material.d.ts +10 -18
  193. package/dist/record/main-pass-material.d.ts.map +1 -1
  194. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  195. package/dist/record/main-pass.d.ts.map +1 -1
  196. package/dist/record/mesh-ssbo.d.ts +11 -3
  197. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  198. package/dist/record/recovery-pipeline.d.ts +30 -0
  199. package/dist/record/recovery-pipeline.d.ts.map +1 -0
  200. package/dist/record/render-context.d.ts +82 -9
  201. package/dist/record/render-context.d.ts.map +1 -1
  202. package/dist/record/shadow-pass.d.ts.map +1 -1
  203. package/dist/record/typed-frame-graph.d.ts +49 -2
  204. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  205. package/dist/record/view-ubo.d.ts +1 -2
  206. package/dist/record/view-ubo.d.ts.map +1 -1
  207. package/dist/recovery/render-system-candidate.d.ts +65 -0
  208. package/dist/recovery/render-system-candidate.d.ts.map +1 -0
  209. package/dist/reflection/inspection.d.ts +10 -0
  210. package/dist/reflection/inspection.d.ts.map +1 -0
  211. package/dist/reflection/projection.d.ts +49 -0
  212. package/dist/reflection/projection.d.ts.map +1 -1
  213. package/dist/reflection/record-owner.d.ts +60 -0
  214. package/dist/reflection/record-owner.d.ts.map +1 -0
  215. package/dist/render-contract.d.ts +78 -15
  216. package/dist/render-contract.d.ts.map +1 -1
  217. package/dist/render-pipeline.d.ts +7 -0
  218. package/dist/render-pipeline.d.ts.map +1 -1
  219. package/dist/render-system-extract-tail.d.ts +12 -0
  220. package/dist/render-system-extract-tail.d.ts.map +1 -0
  221. package/dist/render-system-extract.d.ts +252 -30
  222. package/dist/render-system-extract.d.ts.map +1 -1
  223. package/dist/render-system.d.ts +140 -5
  224. package/dist/render-system.d.ts.map +1 -1
  225. package/dist/scene/probe-blend-record.d.ts +22 -0
  226. package/dist/scene/probe-blend-record.d.ts.map +1 -0
  227. package/dist/scene/probe-blend.d.ts +142 -0
  228. package/dist/scene/probe-blend.d.ts.map +1 -0
  229. package/dist/scene/render-scene-types.d.ts +0 -6
  230. package/dist/scene/render-scene-types.d.ts.map +1 -1
  231. package/dist/scene/render-scene.d.ts +122 -9
  232. package/dist/scene/render-scene.d.ts.map +1 -1
  233. package/dist/scene/visibility/bounds.d.ts +20 -0
  234. package/dist/scene/visibility/bounds.d.ts.map +1 -0
  235. package/dist/scene/visibility/budget.d.ts +16 -0
  236. package/dist/scene/visibility/budget.d.ts.map +1 -0
  237. package/dist/scene/visibility/facet.d.ts +73 -0
  238. package/dist/scene/visibility/facet.d.ts.map +1 -0
  239. package/dist/scene/visibility/gpu-frame-timing.d.ts +41 -0
  240. package/dist/scene/visibility/gpu-frame-timing.d.ts.map +1 -0
  241. package/dist/scene/visibility/gpu-lod.d.ts +46 -0
  242. package/dist/scene/visibility/gpu-lod.d.ts.map +1 -0
  243. package/dist/scene/visibility/inspection.d.ts +132 -0
  244. package/dist/scene/visibility/inspection.d.ts.map +1 -0
  245. package/dist/scene/visibility/lod-selector.d.ts +25 -0
  246. package/dist/scene/visibility/lod-selector.d.ts.map +1 -0
  247. package/dist/scene/visibility/occlusion-confidence.d.ts +81 -0
  248. package/dist/scene/visibility/occlusion-confidence.d.ts.map +1 -0
  249. package/dist/scene/visibility/occlusion-pass.d.ts +57 -0
  250. package/dist/scene/visibility/occlusion-pass.d.ts.map +1 -0
  251. package/dist/scene/visibility/occlusion-query-pool.d.ts +57 -0
  252. package/dist/scene/visibility/occlusion-query-pool.d.ts.map +1 -0
  253. package/dist/scene/visibility/occlusion-runtime.d.ts +96 -0
  254. package/dist/scene/visibility/occlusion-runtime.d.ts.map +1 -0
  255. package/dist/scene/visibility/types.d.ts +34 -0
  256. package/dist/scene/visibility/types.d.ts.map +1 -0
  257. package/dist/ssr/admission.d.ts +122 -0
  258. package/dist/ssr/admission.d.ts.map +1 -0
  259. package/dist/ssr/composition.d.ts +32 -0
  260. package/dist/ssr/composition.d.ts.map +1 -0
  261. package/dist/ssr/errors.d.ts +39 -0
  262. package/dist/ssr/errors.d.ts.map +1 -0
  263. package/dist/ssr/identity.d.ts +13 -0
  264. package/dist/ssr/identity.d.ts.map +1 -0
  265. package/dist/systems/skin-palette-allocator.d.ts +1 -1
  266. package/dist/temporal/frame-coordinator.d.ts +13 -0
  267. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  268. package/dist/temporal/frame.d.ts +2 -0
  269. package/dist/temporal/frame.d.ts.map +1 -1
  270. package/dist/temporal/index.mjs +6 -5
  271. package/dist/temporal/taa-history-store.d.ts +15 -1
  272. package/dist/temporal/taa-history-store.d.ts.map +1 -1
  273. package/dist/temporal/transaction.d.ts +5 -0
  274. package/dist/temporal/transaction.d.ts.map +1 -1
  275. package/dist/temporal/view.d.ts +7 -0
  276. package/dist/temporal/view.d.ts.map +1 -1
  277. package/dist/tilemap-chunk-extract-system.d.ts +1 -1
  278. package/dist/typed-render-graph-primitives.d.ts +4 -0
  279. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  280. package/dist/volume/passes.d.ts +8 -4
  281. package/dist/volume/passes.d.ts.map +1 -1
  282. package/package.json +20 -20
  283. package/src/__tests__/cluster-grid-default-surface.unit.test.ts +5 -0
  284. package/src/__tests__/detached-inspection.integration.test.ts +6 -0
  285. package/src/__tests__/device-feature-admission.unit.test.ts +19 -1
  286. package/src/__tests__/device-loss-fanout.unit.test.ts +107 -0
  287. package/src/__tests__/device-scope-lifecycle.unit.test.ts +21 -0
  288. package/src/__tests__/direct-light-snapshot.unit.test.ts +59 -3
  289. package/src/__tests__/environment-generation.integration.test.ts +39 -0
  290. package/src/__tests__/evidence-identity.ts +13 -0
  291. package/src/__tests__/evidence-identity.unit.test.ts +24 -0
  292. package/src/__tests__/expose-renderer-errors.unit.test.ts +34 -0
  293. package/src/__tests__/extended-lighting-recovery.browser.test.ts +14 -0
  294. package/src/__tests__/extended-lighting-recovery.dawn.test.ts +14 -0
  295. package/src/__tests__/extended-lighting-recovery.integration.test.ts +81 -0
  296. package/src/__tests__/extended-lighting-resources.unit.test.ts +51 -0
  297. package/src/__tests__/extended-lighting-zero-feature.integration.test.ts +52 -0
  298. package/src/__tests__/factory-contract.integration.test.ts +154 -6
  299. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +4 -1
  300. package/src/__tests__/frame-observation.contract.test.ts +15 -0
  301. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
  302. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +1 -0
  303. package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +1 -0
  304. package/src/__tests__/gpu-driven-production.integration.test.ts +572 -9
  305. package/src/__tests__/gpu-driven-scaling.unit.test.ts +66 -2
  306. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +26 -1
  307. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +89 -2
  308. package/src/__tests__/gpu-driven-view.browser.test.ts +3 -3
  309. package/src/__tests__/gpu-driven-view.dawn.test.ts +3 -3
  310. package/src/__tests__/gpu-driven-view.unit.test.ts +50 -0
  311. package/src/__tests__/gpu-lod-evidence.ts +188 -0
  312. package/src/__tests__/gpu-lod-fallback.integration.test.ts +10 -0
  313. package/src/__tests__/gpu-lod-indirect.integration.test.ts +40 -0
  314. package/src/__tests__/gpu-lod-parity.dawn.test.ts +29 -0
  315. package/src/__tests__/gpu-lod-readiness.integration.test.ts +52 -0
  316. package/src/__tests__/gpu-lod-schema.unit.test.ts +66 -0
  317. package/src/__tests__/gpu-lod-selector.unit.test.ts +28 -0
  318. package/src/__tests__/gpu-lod-silhouette.browser.test.ts +13 -0
  319. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +66 -1
  320. package/src/__tests__/gpu-scene.dawn.test.ts +8 -1
  321. package/src/__tests__/gpu-scene.unit.test.ts +49 -3
  322. package/src/__tests__/ibl/face-uniforms.unit.test.ts +2 -0
  323. package/src/__tests__/ibl-residency-publication.unit.test.ts +113 -0
  324. package/src/__tests__/light-buffer-layout.unit.test.ts +113 -3
  325. package/src/__tests__/light-inspection.unit.test.ts +55 -0
  326. package/src/__tests__/light-resource-error.unit.test.ts +43 -0
  327. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +109 -0
  328. package/src/__tests__/lod-bounds.unit.test.ts +42 -0
  329. package/src/__tests__/lod-cpu-lane.integration.test.ts +55 -0
  330. package/src/__tests__/lod-cpu-no-change.perf.test.ts +19 -0
  331. package/src/__tests__/lod-gpu-frame-timing.unit.test.ts +49 -0
  332. package/src/__tests__/lod-multi-view.integration.test.ts +63 -0
  333. package/src/__tests__/lod-occlusion-device-loss.integration.test.ts +27 -0
  334. package/src/__tests__/lod-occlusion-final-decision.integration.test.ts +47 -0
  335. package/src/__tests__/lod-occlusion-inspection.integration.test.ts +217 -0
  336. package/src/__tests__/lod-occlusion-inspection.schema.test-d.ts +14 -0
  337. package/src/__tests__/lod-occlusion-inspection.unit.test.ts +72 -0
  338. package/src/__tests__/lod-occlusion-visual-evidence.ts +91 -0
  339. package/src/__tests__/lod-occlusion.browser.test.ts +15 -0
  340. package/src/__tests__/lod-occlusion.dawn.test.ts +20 -0
  341. package/src/__tests__/lod-selector.profile.test.ts +35 -0
  342. package/src/__tests__/lod-selector.unit.test.ts +68 -0
  343. package/src/__tests__/lod-visibility-identity.unit.test.ts +198 -0
  344. package/src/__tests__/lod-visibility-lifecycle.integration.test.ts +132 -0
  345. package/src/__tests__/ltc-resources.unit.test.ts +32 -0
  346. package/src/__tests__/material-contract-inventory.unit.test.ts +41 -9
  347. package/src/__tests__/material-cooked-projection.unit.test.ts +19 -1
  348. package/src/__tests__/material-static-dynamic-route.unit.test.ts +29 -0
  349. package/src/__tests__/material-stride-surface.unit.test.ts +7 -3
  350. package/src/__tests__/materials-standard-contract.unit.test.ts +104 -0
  351. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
  352. package/src/__tests__/occlusion-confidence.unit.test.ts +168 -0
  353. package/src/__tests__/occlusion-invalidation.integration.test.ts +37 -0
  354. package/src/__tests__/occlusion-pass-routing.unit.test.ts +16 -0
  355. package/src/__tests__/occlusion-pass.dawn.test.ts +20 -0
  356. package/src/__tests__/occlusion-pass.integration.test.ts +43 -0
  357. package/src/__tests__/occlusion-pass.rhi-null.test.ts +22 -0
  358. package/src/__tests__/occlusion-query-pool.rhi-null.test.ts +21 -0
  359. package/src/__tests__/occlusion-query-pool.unit.test.ts +95 -0
  360. package/src/__tests__/occlusion-query-ticket.integration.test.ts +47 -0
  361. package/src/__tests__/occlusion-query.dawn.test.ts +16 -0
  362. package/src/__tests__/occlusion-query.evidence.ts +178 -0
  363. package/src/__tests__/occlusion-query.rhi-null.test.ts +31 -0
  364. package/src/__tests__/occlusion-runtime.unit.test.ts +120 -0
  365. package/src/__tests__/physical-clearcoat.integration.test.ts +89 -0
  366. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
  367. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +1 -1
  368. package/src/__tests__/probe-bindings.unit.test.ts +200 -0
  369. package/src/__tests__/probe-blend-numeric.unit.test.ts +67 -0
  370. package/src/__tests__/probe-blend-oracle.unit.test.ts +136 -0
  371. package/src/__tests__/probe-capacity.integration.test.ts +97 -0
  372. package/src/__tests__/probe-recovery.integration.test.ts +104 -0
  373. package/src/__tests__/probe-scene-dirty.integration.test.ts +211 -0
  374. package/src/__tests__/profiler-phase-catalog.test.ts +4 -1
  375. package/src/__tests__/profiler-phase-token.test.ts +1 -0
  376. package/src/__tests__/recover-error-policy-owner.unit.test.ts +6 -3
  377. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +140 -0
  378. package/src/__tests__/rect-area-boundary.unit.test.ts +24 -0
  379. package/src/__tests__/reflection-fallback-graph.unit.test.ts +67 -0
  380. package/src/__tests__/reflection-fallback-inspection.unit.test.ts +77 -0
  381. package/src/__tests__/reflection-fallback-lifecycle.integration.test.ts +21 -0
  382. package/src/__tests__/reflection-fallback-projection.unit.test.ts +90 -0
  383. package/src/__tests__/reflection-fallback-source.unit.test.ts +32 -0
  384. package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
  385. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
  386. package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
  387. package/src/__tests__/render-feature-docs.unit.test.ts +12 -7
  388. package/src/__tests__/render-graph-fallback.integration.test.ts +24 -0
  389. package/src/__tests__/render-perf/extended-lighting.bench.test.ts +66 -0
  390. package/src/__tests__/render-scene-projection.unit.test.ts +447 -18
  391. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +160 -17
  392. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +47 -0
  393. package/src/__tests__/renderer-generation-assembly.unit.test.ts +77 -0
  394. package/src/__tests__/renderer-generation-failure.unit.test.ts +108 -0
  395. package/src/__tests__/renderer-producer-root-matrix.integration.test.ts +33 -0
  396. package/src/__tests__/renderer-recovery-capability-matrix.unit.test.ts +59 -0
  397. package/src/__tests__/renderer-recovery-contract.unit.test.ts +73 -0
  398. package/src/__tests__/renderer-recovery-lifecycle.unit.test.ts +216 -0
  399. package/src/__tests__/renderer-target-history-recovery.integration.test.ts +80 -0
  400. package/src/__tests__/shader-manifest-fixture.ts +13 -16
  401. package/src/__tests__/shader-stage-surface.unit.test.ts +1 -1
  402. package/src/__tests__/skin-motion-regression.unit.test.ts +22 -0
  403. package/src/__tests__/skinned-shadow-caster.test.ts +2 -2
  404. package/src/__tests__/spot-modifier-projection.unit.test.ts +70 -0
  405. package/src/__tests__/ssr-admission-matrix.integration.test.ts +206 -0
  406. package/src/__tests__/ssr-composition.unit.test.ts +46 -0
  407. package/src/__tests__/ssr-fallback-zero-work.bench.test.ts +94 -0
  408. package/src/__tests__/ssr-recovery-errors.unit.test.ts +58 -0
  409. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +67 -0
  410. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +7 -0
  411. package/src/__tests__/standard-layer-projection.unit.test.ts +23 -0
  412. package/src/__tests__/standard-lighting-inspection.integration.test.ts +1 -1
  413. package/src/__tests__/standard-lighting-write.unit.test.ts +66 -2
  414. package/src/__tests__/temporal-fallback-generation.integration.test.ts +16 -0
  415. package/src/__tests__/temporal-view.unit.test.ts +3 -3
  416. package/src/__tests__/transmission-prewarm.unit.test.ts +111 -32
  417. package/src/__tests__/visibility-budget.integration.test.ts +140 -0
  418. package/src/__tests__/visibility-budget.unit.test.ts +70 -0
  419. package/src/__tests__/visibility-extract.integration.test.ts +11 -6
  420. package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +6 -3
  421. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +31 -28
  422. package/src/__tests__/volumetric-fog-topology.unit.test.ts +3 -1
  423. package/src/assembly/backend-contract.ts +13 -0
  424. package/src/assembly/bundler-contract.ts +9 -0
  425. package/src/assembly/device-feature-admission.ts +26 -9
  426. package/src/assembly/extended-lighting-fallback.ts +216 -0
  427. package/src/assembly/factory.ts +81 -9634
  428. package/src/assembly/host-contract.ts +10 -0
  429. package/src/assembly/material/assembly.ts +18 -2
  430. package/src/assembly/material/standard-layer-projection.ts +16 -0
  431. package/src/assembly/material-shader-policy.ts +854 -0
  432. package/src/assembly/material-shader-prewarm.ts +88 -0
  433. package/src/assembly/mesh-ssbo-grow.ts +270 -0
  434. package/src/assembly/recovery/device-loss-fanout.ts +89 -0
  435. package/src/assembly/recovery/generation.ts +141 -0
  436. package/src/assembly/recovery/recovery-attempt.ts +800 -0
  437. package/src/assembly/recovery/renderer-recover.ts +906 -0
  438. package/src/assembly/renderer-facade.ts +342 -0
  439. package/src/assembly/renderer-frame-transaction.ts +45 -0
  440. package/src/assembly/renderer-helpers.ts +99 -0
  441. package/src/assembly/renderer-lifecycle.ts +159 -0
  442. package/src/assembly/shader-prewarm-policy.ts +157 -0
  443. package/src/assembly/webgpu-ready-contract.ts +14 -0
  444. package/src/assembly/webgpu-ready.ts +4079 -0
  445. package/src/assembly/webgpu-renderer.ts +4095 -0
  446. package/src/cluster-binner.ts +31 -0
  447. package/src/components/__tests__/lighting-authoring.unit.test.ts +39 -0
  448. package/src/components/__tests__/rect-area-light.unit.test.ts +33 -0
  449. package/src/components/camera.ts +1 -1
  450. package/src/components/index.ts +3 -0
  451. package/src/components/light-helpers.ts +52 -1
  452. package/src/components/light-probe.ts +13 -0
  453. package/src/components/rect-area-light.ts +15 -0
  454. package/src/components/scene-instance.ts +6 -0
  455. package/src/components/spot-light.ts +3 -0
  456. package/src/debug-draw-glue.ts +1 -1
  457. package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
  458. package/src/device/device-scope.ts +35 -6
  459. package/src/device/gpu-residency.ts +334 -35
  460. package/src/device/lifecycle-transaction.ts +12 -0
  461. package/src/environment/frame.ts +6 -0
  462. package/src/environment/inspection.ts +10 -0
  463. package/src/environment/lifecycle.ts +122 -9
  464. package/src/errors/gpu-driven.ts +92 -0
  465. package/src/errors/index.ts +1 -0
  466. package/src/errors/recover.ts +108 -5
  467. package/src/errors/render.ts +72 -1
  468. package/src/extract/camera.ts +3 -3
  469. package/src/extract/contracts.ts +974 -0
  470. package/src/extract/gpu-driven.ts +108 -0
  471. package/src/extract/visibility.ts +0 -23
  472. package/src/features/host.ts +16 -0
  473. package/src/features/prepared-gpu-work.ts +20 -2
  474. package/src/features/prepared-graphics-store.ts +17 -0
  475. package/src/gpu-driven/batch-topology.ts +206 -28
  476. package/src/gpu-driven/prepared-draw.ts +208 -0
  477. package/src/gpu-driven/production-raster.ts +1046 -39
  478. package/src/gpu-driven/view-gpu.ts +411 -29
  479. package/src/gpu-scene-schema.ts +13 -0
  480. package/src/gpu-scene.ts +137 -67
  481. package/src/gpu-usage.ts +0 -1
  482. package/src/hdrp-buffers.ts +6 -6
  483. package/src/ibl/IblPipelineCache.ts +134 -50
  484. package/src/ibl/skylight-bind-group.ts +26 -0
  485. package/src/index.ts +83 -1
  486. package/src/inspection-types.ts +220 -1
  487. package/src/internal.ts +38 -0
  488. package/src/light-buffer-layout.ts +157 -324
  489. package/src/materials.ts +278 -47
  490. package/src/mesh-material-bindings.ts +59 -0
  491. package/src/occlusion-proxy.ts +64 -0
  492. package/src/pbr-pipeline.ts +290 -60
  493. package/src/pipeline/standard-forward-lane.ts +47 -0
  494. package/src/pipeline/standard-lighting/graph.ts +2 -1
  495. package/src/pipeline/standard-lighting/light-frame.ts +3 -2
  496. package/src/pipeline/standard-lighting/topology.ts +1 -1
  497. package/src/pipeline/standard-lighting/transport.ts +2 -1
  498. package/src/pipeline/standard-pipeline.ts +2 -0
  499. package/src/pipeline-builder.ts +5 -2
  500. package/src/pipeline-spec.ts +12 -1
  501. package/src/plugin.ts +4 -0
  502. package/src/points-lines/__tests__/cache-recovery.unit.test.ts +22 -0
  503. package/src/points-lines/prepare.ts +9 -0
  504. package/src/points-lines/standard-owner.ts +403 -0
  505. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +56 -0
  506. package/src/prepare/extended-lighting/ltc-resources.ts +136 -0
  507. package/src/prepare/extended-lighting/resources.ts +389 -0
  508. package/src/prepare/extended-lighting/spot-modifiers.ts +194 -0
  509. package/src/prepare/extended-lighting/state.ts +92 -0
  510. package/src/record/__tests__/frame-targets-recovery.unit.test.ts +60 -0
  511. package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
  512. package/src/record/__tests__/main-pass-geometry.unit.test.ts +26 -1
  513. package/src/record/__tests__/mesh-ssbo.unit.test.ts +38 -0
  514. package/src/record/__tests__/recovery-pipeline.unit.test.ts +124 -0
  515. package/src/record/__tests__/sprite-material-abi.unit.test.ts +28 -13
  516. package/src/record/__tests__/standard-pbr-ubo-layout.unit.test.ts +47 -4
  517. package/src/record/__tests__/temporal-payload.unit.test.ts +29 -28
  518. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +21 -2
  519. package/src/record/frame-lighting.ts +252 -53
  520. package/src/record/frame-snapshot.ts +72 -12
  521. package/src/record/frame-targets.ts +11 -1
  522. package/src/record/frame.ts +416 -95
  523. package/src/record/gpu-timing.ts +108 -44
  524. package/src/record/helpers.ts +1 -59
  525. package/src/record/main-pass-geometry.ts +434 -44
  526. package/src/record/main-pass-material.ts +324 -210
  527. package/src/record/main-pass-sprite-draws.ts +58 -92
  528. package/src/record/main-pass.ts +94 -6
  529. package/src/record/mesh-ssbo.ts +79 -46
  530. package/src/record/recovery-pipeline.ts +695 -0
  531. package/src/record/render-context.ts +99 -7
  532. package/src/record/shadow-pass.ts +66 -40
  533. package/src/record/typed-frame-graph.ts +270 -84
  534. package/src/record/view-ubo.ts +17 -27
  535. package/src/recovery/render-system-candidate.ts +839 -0
  536. package/src/reflection/inspection.ts +67 -0
  537. package/src/reflection/projection.ts +196 -1
  538. package/src/reflection/record-owner.ts +1283 -0
  539. package/src/render-contract.ts +82 -12
  540. package/src/render-pipeline.ts +5 -0
  541. package/src/render-system-extract-tail.ts +2983 -0
  542. package/src/render-system-extract.ts +290 -2784
  543. package/src/render-system.ts +1597 -1192
  544. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +36 -0
  545. package/src/scene/probe-blend-record.ts +54 -0
  546. package/src/scene/probe-blend.ts +813 -0
  547. package/src/scene/render-scene-types.ts +0 -7
  548. package/src/scene/render-scene.ts +972 -184
  549. package/src/scene/visibility/bounds.ts +57 -0
  550. package/src/scene/visibility/budget.ts +40 -0
  551. package/src/scene/visibility/facet.ts +400 -0
  552. package/src/scene/visibility/gpu-frame-timing.ts +101 -0
  553. package/src/scene/visibility/gpu-lod.ts +119 -0
  554. package/src/scene/visibility/inspection.ts +313 -0
  555. package/src/scene/visibility/lod-selector.ts +84 -0
  556. package/src/scene/visibility/occlusion-confidence.ts +478 -0
  557. package/src/scene/visibility/occlusion-pass.ts +165 -0
  558. package/src/scene/visibility/occlusion-query-pool.ts +178 -0
  559. package/src/scene/visibility/occlusion-runtime.ts +672 -0
  560. package/src/scene/visibility/types.ts +50 -0
  561. package/src/ssr/admission.ts +451 -0
  562. package/src/ssr/composition.ts +73 -0
  563. package/src/ssr/errors.ts +76 -0
  564. package/src/ssr/identity.ts +12 -0
  565. package/src/systems/skin-palette-allocator.ts +1 -1
  566. package/src/temporal/frame-coordinator.ts +30 -1
  567. package/src/temporal/frame.ts +14 -1
  568. package/src/temporal/taa-history-store.ts +46 -2
  569. package/src/temporal/temporal-view.ts +1 -1
  570. package/src/temporal/transaction.ts +9 -0
  571. package/src/temporal/view.ts +11 -0
  572. package/src/tilemap-chunk-extract-system.ts +5 -5
  573. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +19 -12
  574. package/src/typed-render-graph-primitives.ts +48 -0
  575. package/src/volume/passes.ts +46 -49
  576. package/dist/.tsbuildinfo +0 -1
  577. package/dist/chunk-5YADUCA7.mjs.map +0 -1
  578. package/dist/chunk-6OPXDQ2E.mjs.map +0 -1
  579. package/dist/chunk-BXBQQKFQ.mjs +0 -67
  580. package/dist/chunk-BXBQQKFQ.mjs.map +0 -1
  581. package/dist/chunk-FS2KNUQH.mjs.map +0 -1
  582. package/dist/chunk-PCHBPYML.mjs.map +0 -1
  583. package/dist/chunk-VFPLTKCU.mjs +0 -192
  584. package/dist/chunk-VFPLTKCU.mjs.map +0 -1
package/src/gpu-scene.ts CHANGED
@@ -37,6 +37,8 @@ interface PrimitiveAllocation {
37
37
  readonly instanceStart: number;
38
38
  readonly instanceCount: number;
39
39
  readonly transformStart: number;
40
+ readonly instanceTransformStart: number;
41
+ readonly instanceTransformCount: number;
40
42
  readonly drawStart: number;
41
43
  readonly drawCount: number;
42
44
  readonly materialStart: number;
@@ -85,8 +87,8 @@ class StableRangeAllocator {
85
87
  return this.next;
86
88
  }
87
89
 
88
- reset(): void {
89
- this.next = 0;
90
+ reset(start = 0): void {
91
+ this.next = start;
90
92
  this.free.length = 0;
91
93
  }
92
94
  }
@@ -177,7 +179,14 @@ function stableU32(value: string): number {
177
179
  function coalesceSlots(
178
180
  slots: readonly number[],
179
181
  ): readonly { readonly start: number; readonly end: number }[] {
180
- const ordered = [...new Set(slots)].sort((a, b) => a - b);
182
+ let alreadyOrdered = true;
183
+ for (let index = 1; index < slots.length; index += 1) {
184
+ if ((slots[index] ?? 0) <= (slots[index - 1] ?? 0)) {
185
+ alreadyOrdered = false;
186
+ break;
187
+ }
188
+ }
189
+ const ordered = alreadyOrdered ? slots : [...new Set(slots)].sort((a, b) => a - b);
181
190
  const ranges: Array<{ start: number; end: number }> = [];
182
191
  for (const slot of ordered) {
183
192
  const previous = ranges.at(-1);
@@ -192,7 +201,10 @@ function coalesceSlots(
192
201
 
193
202
  /** Persistent GPU tables derived only from renderer projection slots. */
194
203
  export class GpuScene {
204
+ private disposed = false;
195
205
  private tableBytes: Record<GpuSceneTableName, ArrayBuffer>;
206
+ private transformBytes: Uint8Array;
207
+ private transformView: DataView;
196
208
  private buffers: GpuSceneBuffers;
197
209
  private uploadRanges = 0;
198
210
  private uploadBytes = 0;
@@ -200,11 +212,19 @@ export class GpuScene {
200
212
  private fullRebuilds = 0;
201
213
  private clearedSlots = 0;
202
214
  private noChangeFrames = 0;
203
- private readonly allocations = new Map<number, PrimitiveAllocation>();
215
+ private identityUploaded = false;
216
+ private readonly allocations: Array<PrimitiveAllocation | undefined> = [];
204
217
  private readonly instances = new StableRangeAllocator();
205
218
  private readonly transforms = new StableRangeAllocator();
206
219
  private readonly draws = new StableRangeAllocator();
207
220
  private readonly materials = new StableRangeAllocator();
221
+ private readonly writesByTable: Record<GpuSceneTableName, number[]> = {
222
+ primitive: [],
223
+ instance: [],
224
+ transform: [],
225
+ drawTemplate: [],
226
+ material: [],
227
+ };
208
228
 
209
229
  private constructor(
210
230
  private readonly device: RhiDevice,
@@ -213,6 +233,10 @@ export class GpuScene {
213
233
  ) {
214
234
  this.buffers = buffers;
215
235
  this.tableBytes = this.allocateCpuTables(capacity);
236
+ this.transformBytes = new Uint8Array(this.tableBytes.transform);
237
+ this.transformView = new DataView(this.tableBytes.transform);
238
+ this.transforms.reset(1);
239
+ this.writeIdentityTransform();
216
240
  }
217
241
 
218
242
  static create(device: RhiDevice, initialCapacity = 256): Result<GpuSceneAvailability, RhiError> {
@@ -249,25 +273,33 @@ export class GpuScene {
249
273
  }
250
274
 
251
275
  sync(delta: RenderSceneApplyResult): Result<GpuSceneSyncResult, RhiError> {
252
- const writes = [...delta.createdSlots, ...delta.updatedSlots, ...delta.recreatedSlots];
253
- const changedSlots = [
254
- ...writes.map((record) => record.slot),
255
- ...delta.removedSlots.map((r) => r.slot),
256
- ];
257
- if (changedSlots.length === 0) {
276
+ if (
277
+ delta.createdSlots.length === 0 &&
278
+ delta.updatedSlots.length === 0 &&
279
+ delta.recreatedSlots.length === 0 &&
280
+ delta.removedSlots.length === 0
281
+ ) {
258
282
  this.noChangeFrames += 1;
259
283
  return ok({ ranges: 0, bytes: 0, grew: false, cleared: 0 });
260
284
  }
261
- const writesByTable: Record<GpuSceneTableName, number[]> = {
262
- primitive: [],
263
- instance: [],
264
- transform: [],
265
- drawTemplate: [],
266
- material: [],
267
- };
268
- for (const record of writes) this.ensureAllocation(record, writesByTable);
285
+ const writesByTable = this.writesByTable;
286
+ for (const name of TABLE_NAMES) writesByTable[name].length = 0;
287
+ if (!this.identityUploaded) writesByTable.transform.push(0);
288
+ let highestChangedSlot = -1;
289
+ for (const records of [delta.createdSlots, delta.recreatedSlots]) {
290
+ for (const record of records) {
291
+ this.ensureAllocation(record, writesByTable);
292
+ if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
293
+ }
294
+ }
295
+ for (const record of delta.updatedSlots) {
296
+ if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
297
+ }
298
+ for (const record of delta.removedSlots) {
299
+ if (record.slot > highestChangedSlot) highestChangedSlot = record.slot;
300
+ }
269
301
  const requiredCapacity = Math.max(
270
- Math.max(...changedSlots) + 1,
302
+ highestChangedSlot + 1,
271
303
  this.instances.requiredCapacity(),
272
304
  this.transforms.requiredCapacity(),
273
305
  this.draws.requiredCapacity(),
@@ -280,11 +312,12 @@ export class GpuScene {
280
312
  }
281
313
 
282
314
  for (const record of delta.createdSlots) this.writeSlot(record, true, writesByTable);
283
- for (const record of delta.updatedSlots) this.writeSlot(record, false, writesByTable);
315
+ for (const record of delta.updatedSlots) this.writeRootTransform(record, false, writesByTable);
284
316
  for (const record of delta.recreatedSlots) this.writeSlot(record, true, writesByTable);
285
317
  for (const record of delta.removedSlots) this.clearSlot(record.slot, writesByTable);
286
318
  const uploaded = this.uploadRows(writesByTable);
287
319
  if (!uploaded.ok) return uploaded;
320
+ this.identityUploaded = true;
288
321
  this.clearedSlots += delta.removedSlots.length;
289
322
  return ok({
290
323
  ranges: uploaded.value.ranges,
@@ -295,10 +328,11 @@ export class GpuScene {
295
328
  }
296
329
 
297
330
  /** Publish current transforms as previous only after a successful submit. */
298
- commitTemporalFrame(): Result<void, RhiError> {
331
+ commitTemporalFrame(enabled = true): Result<void, RhiError> {
332
+ if (!enabled) return ok(undefined);
299
333
  const nextTransform = this.tableBytes.transform.slice(0);
300
334
  const next = new Uint8Array(nextTransform);
301
- const current = new Uint8Array(this.tableBytes.transform);
335
+ const current = this.transformBytes;
302
336
  const currentOffset = offset(TRANSFORM, 'currentWorld');
303
337
  const previousOffset = offset(TRANSFORM, 'previousWorld');
304
338
  for (let index = 0; index < this.capacity; index += 1) {
@@ -313,15 +347,16 @@ export class GpuScene {
313
347
  const uploaded = this.device.queue.writeBuffer(this.buffers.transform, 0, next);
314
348
  if (!uploaded.ok) return uploaded;
315
349
  this.tableBytes.transform = nextTransform;
350
+ this.refreshTransformViews();
316
351
  this.uploadRanges += 1;
317
352
  this.uploadBytes += next.byteLength;
318
353
  return ok(undefined);
319
354
  }
320
355
 
321
356
  rebuild(slots: readonly RenderSceneSlot[]): Result<GpuSceneSyncResult, RhiError> {
322
- this.allocations.clear();
357
+ this.allocations.length = 0;
323
358
  this.instances.reset();
324
- this.transforms.reset();
359
+ this.transforms.reset(1);
325
360
  this.draws.reset();
326
361
  this.materials.reset();
327
362
  const writesByTable: Record<GpuSceneTableName, number[]> = {
@@ -347,6 +382,7 @@ export class GpuScene {
347
382
  grew = true;
348
383
  }
349
384
  for (const bytes of Object.values(this.tableBytes)) new Uint8Array(bytes).fill(0);
385
+ this.writeIdentityTransform();
350
386
  for (const slot of slots) this.writeSlot(slot, true, writesByTable);
351
387
  let bytes = 0;
352
388
  for (const name of TABLE_NAMES) {
@@ -358,6 +394,7 @@ export class GpuScene {
358
394
  this.uploadRanges += TABLE_NAMES.length;
359
395
  this.uploadBytes += bytes;
360
396
  this.fullRebuilds += 1;
397
+ this.identityUploaded = true;
361
398
  return ok({ ranges: TABLE_NAMES.length, bytes, grew, cleared: 0 });
362
399
  }
363
400
 
@@ -396,6 +433,8 @@ export class GpuScene {
396
433
  }
397
434
 
398
435
  dispose(): void {
436
+ if (this.disposed) return;
437
+ this.disposed = true;
399
438
  for (const buffer of Object.values(this.buffers)) this.device.destroyBuffer(buffer);
400
439
  }
401
440
 
@@ -404,7 +443,7 @@ export class GpuScene {
404
443
  resetPrevious: boolean,
405
444
  writes: Record<GpuSceneTableName, number[]>,
406
445
  ): void {
407
- const allocation = this.allocations.get(record.slot);
446
+ const allocation = this.allocations[record.slot];
408
447
  if (allocation === undefined) throw new RangeError('GPU Scene allocation unavailable');
409
448
  const primitiveOffset = record.slot * PRIMITIVE.stride;
410
449
  const primitive = new DataView(this.tableBytes.primitive);
@@ -461,45 +500,34 @@ export class GpuScene {
461
500
  ]);
462
501
 
463
502
  const instance = new DataView(this.tableBytes.instance);
464
- const transform = new DataView(this.tableBytes.transform);
503
+ const transform = this.transformView;
465
504
  for (let ordinal = 0; ordinal < allocation.instanceCount; ordinal += 1) {
466
505
  const instanceIndex = allocation.instanceStart + ordinal;
467
506
  const instanceOffset = instanceIndex * INSTANCE.stride;
468
- const transformIndex = allocation.transformStart + 1 + ordinal;
507
+ const transformIndex =
508
+ allocation.instanceTransformCount === 0 ? 0 : allocation.instanceTransformStart + ordinal;
469
509
  instance.setUint32(instanceOffset + offset(INSTANCE, 'primitiveIndex'), record.slot, true);
470
510
  instance.setUint32(instanceOffset + offset(INSTANCE, 'transformIndex'), transformIndex, true);
471
511
  instance.setUint32(instanceOffset + offset(INSTANCE, 'customDataStart'), 0, true);
472
512
  instance.setUint32(instanceOffset + offset(INSTANCE, 'flags'), PRIMITIVE_ACTIVE, true);
473
- const local = record.snapshot.instances?.transforms.subarray(ordinal * 16, ordinal * 16 + 16);
474
- const localWorld = local?.length === 16 ? local : IDENTITY_MATRIX;
475
- const localOffset = transformIndex * TRANSFORM.stride;
476
- const localCurrentOffset = localOffset + offset(TRANSFORM, 'currentWorld');
477
- const localPreviousOffset = localOffset + offset(TRANSFORM, 'previousWorld');
478
- const priorLocal = new Uint8Array(
479
- this.tableBytes.transform.slice(localCurrentOffset, localCurrentOffset + 64),
480
- );
481
- writeMat4(transform, localCurrentOffset, localWorld);
482
- if (!resetPrevious && priorLocal.some((value) => value !== 0)) {
483
- new Uint8Array(this.tableBytes.transform, localPreviousOffset, 64).set(priorLocal);
484
- } else {
513
+ if (allocation.instanceTransformCount > 0) {
514
+ const local = record.snapshot.instances?.transforms.subarray(
515
+ ordinal * 16,
516
+ ordinal * 16 + 16,
517
+ );
518
+ const localWorld = local?.length === 16 ? local : IDENTITY_MATRIX;
519
+ const localOffset = transformIndex * TRANSFORM.stride;
520
+ const localCurrentOffset = localOffset + offset(TRANSFORM, 'currentWorld');
521
+ const localPreviousOffset = localOffset + offset(TRANSFORM, 'previousWorld');
522
+ writeMat4(transform, localCurrentOffset, localWorld);
485
523
  writeMat4(transform, localPreviousOffset, localWorld);
524
+ writes.transform.push(transformIndex);
486
525
  }
487
526
  writes.instance.push(instanceIndex);
488
- writes.transform.push(transformIndex);
489
527
  }
490
528
 
491
- const transformOffset = allocation.transformStart * TRANSFORM.stride;
492
- const currentOffset = transformOffset + offset(TRANSFORM, 'currentWorld');
493
- const previousOffset = transformOffset + offset(TRANSFORM, 'previousWorld');
494
- const priorCurrent = new Uint8Array(
495
- this.tableBytes.transform.slice(currentOffset, currentOffset + 64),
496
- );
497
- const hasPrior = !resetPrevious && priorCurrent.some((value) => value !== 0);
498
- writeMat4(transform, currentOffset, record.snapshot.transform.world);
499
- if (hasPrior) new Uint8Array(this.tableBytes.transform, previousOffset, 64).set(priorCurrent);
500
- else writeMat4(transform, previousOffset, record.snapshot.transform.world);
529
+ this.writeRootTransform(record, resetPrevious, writes);
501
530
  writes.primitive.push(record.slot);
502
- writes.transform.push(allocation.transformStart);
503
531
 
504
532
  const draw = new DataView(this.tableBytes.drawTemplate);
505
533
  const drawSnapshots = record.snapshot.gpuDrivenDraws ?? [];
@@ -509,7 +537,13 @@ export class GpuScene {
509
537
  const drawSnapshot = drawSnapshots[ordinal];
510
538
  draw.setUint32(
511
539
  drawOffset + offset(DRAW_TEMPLATE, 'pipelineClass'),
512
- drawSnapshot === undefined ? 0 : stableU32(drawSnapshot.pipelineClass),
540
+ drawSnapshot === undefined
541
+ ? 0
542
+ : stableU32(
543
+ drawSnapshot.prepared === undefined
544
+ ? drawSnapshot.pipelineClass
545
+ : `${drawSnapshot.prepared.identity.material}|${drawSnapshot.prepared.identity.geometry}|${drawSnapshot.prepared.identity.deformation}`,
546
+ ),
513
547
  true,
514
548
  );
515
549
  draw.setUint32(
@@ -519,17 +553,17 @@ export class GpuScene {
519
553
  );
520
554
  draw.setUint32(
521
555
  drawOffset + offset(DRAW_TEMPLATE, 'firstIndex'),
522
- drawSnapshot?.first ?? 0,
556
+ drawSnapshot?.prepared?.first ?? drawSnapshot?.first ?? 0,
523
557
  true,
524
558
  );
525
559
  draw.setUint32(
526
560
  drawOffset + offset(DRAW_TEMPLATE, 'indexCount'),
527
- drawSnapshot?.count ?? 0,
561
+ drawSnapshot?.prepared?.count ?? drawSnapshot?.count ?? 0,
528
562
  true,
529
563
  );
530
564
  draw.setInt32(
531
565
  drawOffset + offset(DRAW_TEMPLATE, 'baseVertex'),
532
- drawSnapshot?.baseVertex ?? 0,
566
+ drawSnapshot?.prepared?.baseVertex ?? drawSnapshot?.baseVertex ?? 0,
533
567
  true,
534
568
  );
535
569
  draw.setUint32(drawOffset + offset(DRAW_TEMPLATE, 'firstInstance'), 0, true);
@@ -552,8 +586,6 @@ export class GpuScene {
552
586
  writeVec4(material, materialOffset + offset(MATERIAL, 'params1'), [
553
587
  snapshot.metallic ?? 0,
554
588
  snapshot.roughness ?? 1,
555
- snapshot.clearcoat ?? 0,
556
- snapshot.clearcoatRoughness ?? 0,
557
589
  ]);
558
590
  writeVec4(material, materialOffset + offset(MATERIAL, 'params2'), [
559
591
  snapshot.emissive?.[0] ?? 0,
@@ -591,16 +623,35 @@ export class GpuScene {
591
623
  }
592
624
  }
593
625
 
626
+ private writeRootTransform(
627
+ record: RenderSceneSlot,
628
+ resetPrevious: boolean,
629
+ writes: Record<GpuSceneTableName, number[]>,
630
+ ): void {
631
+ const allocation = this.allocations[record.slot];
632
+ if (allocation === undefined) throw new RangeError('GPU Scene allocation unavailable');
633
+ const transformOffset = allocation.transformStart * TRANSFORM.stride;
634
+ const currentOffset = transformOffset + offset(TRANSFORM, 'currentWorld');
635
+ const previousOffset = transformOffset + offset(TRANSFORM, 'previousWorld');
636
+ if (resetPrevious) {
637
+ writeMat4(this.transformView, previousOffset, record.snapshot.transform.world);
638
+ } else {
639
+ this.transformBytes.copyWithin(previousOffset, currentOffset, currentOffset + 64);
640
+ }
641
+ writeMat4(this.transformView, currentOffset, record.snapshot.transform.world);
642
+ writes.transform.push(allocation.transformStart);
643
+ }
644
+
594
645
  private clearSlot(slot: number, writes: Record<GpuSceneTableName, number[]>): void {
595
646
  for (const name of ['primitive'] as const) {
596
647
  const layout = TABLE_LAYOUTS[name];
597
648
  new Uint8Array(this.tableBytes[name], slot * layout.stride, layout.stride).fill(0);
598
649
  writes[name].push(slot);
599
650
  }
600
- const allocation = this.allocations.get(slot);
651
+ const allocation = this.allocations[slot];
601
652
  if (allocation === undefined) return;
602
653
  this.clearAllocation(allocation, writes);
603
- this.allocations.delete(slot);
654
+ this.allocations[slot] = undefined;
604
655
  }
605
656
 
606
657
  private uploadRows(
@@ -637,15 +688,18 @@ export class GpuScene {
637
688
  // empty: preserve zero so neither the GPU Scene nor the indirect topology
638
689
  // turns it into a synthetic identity instance. Entities without the
639
690
  // component retain the ordinary one-instance identity path.
691
+ const explicitInstances = record.snapshot.instances;
640
692
  const instanceCount =
641
- record.snapshot.instances === undefined
693
+ explicitInstances === undefined
642
694
  ? 1
643
- : Math.max(0, Math.floor(record.snapshot.instances.instanceCount));
695
+ : Math.max(0, Math.floor(explicitInstances.instanceCount));
696
+ const instanceTransformCount = explicitInstances === undefined ? 0 : instanceCount;
644
697
  const drawCount = Math.max(1, record.snapshot.gpuDrivenDraws?.length ?? 0);
645
698
  const materialCount = Math.max(1, record.snapshot.materials.length);
646
- const existing = this.allocations.get(record.slot);
699
+ const existing = this.allocations[record.slot];
647
700
  if (
648
701
  existing?.instanceCount === instanceCount &&
702
+ existing.instanceTransformCount === instanceTransformCount &&
649
703
  existing.drawCount === drawCount &&
650
704
  existing.materialCount === materialCount
651
705
  ) {
@@ -655,13 +709,16 @@ export class GpuScene {
655
709
  const allocation = {
656
710
  instanceStart: this.instances.allocate(instanceCount),
657
711
  instanceCount,
658
- transformStart: this.transforms.allocate(instanceCount + 1),
712
+ transformStart: this.transforms.allocate(1),
713
+ instanceTransformStart:
714
+ instanceTransformCount === 0 ? 0 : this.transforms.allocate(instanceTransformCount),
715
+ instanceTransformCount,
659
716
  drawStart: this.draws.allocate(drawCount),
660
717
  drawCount,
661
718
  materialStart: this.materials.allocate(materialCount),
662
719
  materialCount,
663
720
  };
664
- this.allocations.set(record.slot, allocation);
721
+ this.allocations[record.slot] = allocation;
665
722
  }
666
723
 
667
724
  private clearAllocation(
@@ -677,8 +734,9 @@ export class GpuScene {
677
734
  ).fill(0);
678
735
  writes.instance.push(instanceIndex);
679
736
  }
680
- for (let ordinal = 0; ordinal <= allocation.instanceCount; ordinal += 1) {
681
- const transformIndex = allocation.transformStart + ordinal;
737
+ for (let ordinal = -1; ordinal < allocation.instanceTransformCount; ordinal += 1) {
738
+ const transformIndex =
739
+ ordinal < 0 ? allocation.transformStart : allocation.instanceTransformStart + ordinal;
682
740
  new Uint8Array(
683
741
  this.tableBytes.transform,
684
742
  transformIndex * TRANSFORM.stride,
@@ -705,7 +763,8 @@ export class GpuScene {
705
763
  writes.material.push(materialIndex);
706
764
  }
707
765
  this.instances.release(allocation.instanceStart, allocation.instanceCount);
708
- this.transforms.release(allocation.transformStart, allocation.instanceCount + 1);
766
+ this.transforms.release(allocation.transformStart, 1);
767
+ this.transforms.release(allocation.instanceTransformStart, allocation.instanceTransformCount);
709
768
  this.draws.release(allocation.drawStart, allocation.drawCount);
710
769
  this.materials.release(allocation.materialStart, allocation.materialCount);
711
770
  }
@@ -731,6 +790,7 @@ export class GpuScene {
731
790
  for (const buffer of Object.values(this.buffers)) this.device.destroyBuffer(buffer);
732
791
  this.buffers = nextBuffers.value;
733
792
  this.tableBytes = nextTables;
793
+ this.refreshTransformViews();
734
794
  this.capacity = nextCapacity;
735
795
  this.capacityGrows += 1;
736
796
  this.uploadRanges += TABLE_NAMES.length;
@@ -750,4 +810,14 @@ export class GpuScene {
750
810
  material: new ArrayBuffer(capacity * MATERIAL.stride),
751
811
  };
752
812
  }
813
+
814
+ private refreshTransformViews(): void {
815
+ this.transformBytes = new Uint8Array(this.tableBytes.transform);
816
+ this.transformView = new DataView(this.tableBytes.transform);
817
+ }
818
+
819
+ private writeIdentityTransform(): void {
820
+ writeMat4(this.transformView, offset(TRANSFORM, 'currentWorld'), IDENTITY_MATRIX);
821
+ writeMat4(this.transformView, offset(TRANSFORM, 'previousWorld'), IDENTITY_MATRIX);
822
+ }
753
823
  }
package/src/gpu-usage.ts CHANGED
@@ -12,5 +12,4 @@ export const GPU_BUFFER_USAGE_UNIFORM = 0x40;
12
12
  export const GPU_BUFFER_USAGE_STORAGE = 0x80;
13
13
  export const GPU_BUFFER_USAGE_INDIRECT = 0x100;
14
14
  export const GPU_BUFFER_USAGE_MAP_READ = 0x01;
15
- /** GPUBufferUsage.QUERY_RESOLVE, used by optional timestamp captures. */
16
15
  export const GPU_BUFFER_USAGE_QUERY_RESOLVE = 0x200;
@@ -19,7 +19,7 @@
19
19
  // usage owner; this module stays decoupled from renderer bootstrap.
20
20
  //
21
21
  // Sizes:
22
- // - light_data : 256 x 64 B = 16 384 B
22
+ // - light_data : 256 x 80 B = 20 480 B
23
23
  // - cluster_grid : maxGridCells x 8 B = 64 x 64 x 64 x 8 B = 2 097 152 B max
24
24
  // (plan D-grid: x,y,z each in [1..64]; maxCells=262144;
25
25
  // stride 2 u32 = 8B; we allocate at the install-time
@@ -47,7 +47,7 @@ import {
47
47
  GPU_BUFFER_USAGE_STORAGE,
48
48
  GPU_BUFFER_USAGE_UNIFORM,
49
49
  } from './gpu-usage';
50
- import { BYTES_PER_LIGHT_SLOT } from './light-buffer-layout';
50
+ import { BYTES_PER_DIRECT_LIGHT_SLOT } from './light-buffer-layout';
51
51
  import { createPbrSkinMeshBindGroupEntries } from './pbr-pipeline';
52
52
  import {
53
53
  CLUSTER_GRID_STRIDE_U32,
@@ -95,8 +95,8 @@ export function createHdrpClusterMembershipBindGroupLayoutDescriptor(): BindGrou
95
95
  * The persistent HDRP GPU buffers (plan D-1, BGL slot 3..6) plus the unified
96
96
  * BGL layout for group(2) (plan D-6, feat-20260609-hdrp-cluster-fragment-ggx M3).
97
97
  *
98
- * AC-11: light_data stride = `BYTES_PER_LIGHT_SLOT` = 64 (double-sided lock with
99
- * WGSL hdrp-cluster-forward.wgsl LightSlot).
98
+ * AC-11: light_data stride = `BYTES_PER_DIRECT_LIGHT_SLOT` = 80 (double-sided
99
+ * lock with WGSL hdrp-cluster-forward.wgsl DirectLightSlot).
100
100
  * AC-13: 4 distinct RHI Buffer handles, ready for slot-3..6 BGL binding.
101
101
  * AC-14: clusterUniform is a uniform buffer (not storage); runtime grid change
102
102
  * is a writeBuffer field update, not a PSO rebuild.
@@ -106,7 +106,7 @@ export function createHdrpClusterMembershipBindGroupLayoutDescriptor(): BindGrou
106
106
  export interface HdrpBuffers {
107
107
  /** Device identity that owns every handle in this bundle. */
108
108
  readonly device: RenderSystemRuntime['device'];
109
- /** light_data -- the full 256 x 64 B Standard light budget. */
109
+ /** light_data -- the full 256 x 80 B DirectLightSlot budget. */
110
110
  readonly lightDataBuffer: Buffer;
111
111
  readonly lightDataBytes: number;
112
112
  /** cluster_grid SSBO -- gridX*gridY*gridZ * 2 u32, BGL slot 4. */
@@ -175,7 +175,7 @@ export function getOrCreateHdrpBuffers(
175
175
  }
176
176
  const device = runtime.device;
177
177
  const clusterUniformBytes = 32;
178
- const lightDataBytes = MAX_LIGHTS * BYTES_PER_LIGHT_SLOT;
178
+ const lightDataBytes = MAX_LIGHTS * BYTES_PER_DIRECT_LIGHT_SLOT;
179
179
  const clusterCells = grid.x * grid.y * grid.z;
180
180
  const clusterGridBytes = clusterCells * CLUSTER_GRID_STRIDE_U32 * 4;
181
181
  const lightIndexListBytes = LIGHT_INDEX_LIST_CAPACITY * 4;