@forgeax/engine-render 0.1.21 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (584) hide show
  1. package/README.md +281 -38
  2. package/dist/assembly/backend-contract.d.ts +13 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/bundler-contract.d.ts +9 -0
  5. package/dist/assembly/bundler-contract.d.ts.map +1 -0
  6. package/dist/assembly/device-feature-admission.d.ts +8 -0
  7. package/dist/assembly/device-feature-admission.d.ts.map +1 -1
  8. package/dist/assembly/extended-lighting-fallback.d.ts +13 -0
  9. package/dist/assembly/extended-lighting-fallback.d.ts.map +1 -0
  10. package/dist/assembly/factory.d.ts +7 -235
  11. package/dist/assembly/factory.d.ts.map +1 -1
  12. package/dist/assembly/host-contract.d.ts +10 -0
  13. package/dist/assembly/host-contract.d.ts.map +1 -1
  14. package/dist/assembly/material/assembly.d.ts +3 -2
  15. package/dist/assembly/material/assembly.d.ts.map +1 -1
  16. package/dist/assembly/material/standard-layer-projection.d.ts +10 -0
  17. package/dist/assembly/material/standard-layer-projection.d.ts.map +1 -0
  18. package/dist/assembly/material-shader-policy.d.ts +168 -0
  19. package/dist/assembly/material-shader-policy.d.ts.map +1 -0
  20. package/dist/assembly/material-shader-prewarm.d.ts +21 -0
  21. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -0
  22. package/dist/assembly/mesh-ssbo-grow.d.ts +88 -0
  23. package/dist/assembly/mesh-ssbo-grow.d.ts.map +1 -0
  24. package/dist/assembly/recovery/device-loss-fanout.d.ts +14 -0
  25. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -0
  26. package/dist/assembly/recovery/generation.d.ts +46 -0
  27. package/dist/assembly/recovery/generation.d.ts.map +1 -0
  28. package/dist/assembly/recovery/recovery-attempt.d.ts +63 -0
  29. package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -0
  30. package/dist/assembly/recovery/renderer-recover.d.ts +115 -0
  31. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -0
  32. package/dist/assembly/renderer-facade.d.ts +10 -0
  33. package/dist/assembly/renderer-facade.d.ts.map +1 -0
  34. package/dist/assembly/renderer-frame-transaction.d.ts +17 -0
  35. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  36. package/dist/assembly/renderer-helpers.d.ts +19 -0
  37. package/dist/assembly/renderer-helpers.d.ts.map +1 -0
  38. package/dist/assembly/renderer-lifecycle.d.ts +34 -0
  39. package/dist/assembly/renderer-lifecycle.d.ts.map +1 -1
  40. package/dist/assembly/shader-prewarm-policy.d.ts +15 -0
  41. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -0
  42. package/dist/assembly/webgpu-ready-contract.d.ts +9 -0
  43. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -0
  44. package/dist/assembly/webgpu-ready.d.ts +55 -0
  45. package/dist/assembly/webgpu-ready.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-renderer.d.ts +152 -0
  47. package/dist/assembly/webgpu-renderer.d.ts.map +1 -0
  48. package/dist/authoring.mjs +1 -1
  49. package/dist/{chunk-PCHBPYML.mjs → chunk-GE3SDD72.mjs} +37 -5
  50. package/dist/chunk-GE3SDD72.mjs.map +1 -0
  51. package/dist/chunk-KZFTK6DO.mjs +1191 -0
  52. package/dist/chunk-KZFTK6DO.mjs.map +1 -0
  53. package/dist/{chunk-FS2KNUQH.mjs → chunk-Q752SHI5.mjs} +332 -568
  54. package/dist/chunk-Q752SHI5.mjs.map +1 -0
  55. package/dist/{chunk-6OPXDQ2E.mjs → chunk-RR5L4SRS.mjs} +33 -294
  56. package/dist/chunk-RR5L4SRS.mjs.map +1 -0
  57. package/dist/chunk-TFH5I7JJ.mjs +296 -0
  58. package/dist/chunk-TFH5I7JJ.mjs.map +1 -0
  59. package/dist/chunk-UQYS7FRM.mjs +1003 -0
  60. package/dist/chunk-UQYS7FRM.mjs.map +1 -0
  61. package/dist/chunk-YKB5DQV7.mjs +345 -0
  62. package/dist/chunk-YKB5DQV7.mjs.map +1 -0
  63. package/dist/{chunk-5YADUCA7.mjs → chunk-YRUYGA4A.mjs} +1189 -1217
  64. package/dist/chunk-YRUYGA4A.mjs.map +1 -0
  65. package/dist/chunk-Z3YYH2MB.mjs +5082 -0
  66. package/dist/chunk-Z3YYH2MB.mjs.map +1 -0
  67. package/dist/cluster-binner.d.ts +5 -0
  68. package/dist/cluster-binner.d.ts.map +1 -1
  69. package/dist/components/index.d.ts +3 -0
  70. package/dist/components/index.d.ts.map +1 -1
  71. package/dist/components/light-helpers.d.ts +4 -0
  72. package/dist/components/light-helpers.d.ts.map +1 -1
  73. package/dist/components/light-probe.d.ts +9 -0
  74. package/dist/components/light-probe.d.ts.map +1 -0
  75. package/dist/components/rect-area-light.d.ts +12 -0
  76. package/dist/components/rect-area-light.d.ts.map +1 -0
  77. package/dist/components/scene-instance.d.ts +4 -0
  78. package/dist/components/scene-instance.d.ts.map +1 -1
  79. package/dist/components/spot-light.d.ts +3 -0
  80. package/dist/components/spot-light.d.ts.map +1 -1
  81. package/dist/construct-renderer.mjs +27276 -23232
  82. package/dist/construct-renderer.mjs.map +1 -1
  83. package/dist/device/device-scope.d.ts +2 -0
  84. package/dist/device/device-scope.d.ts.map +1 -1
  85. package/dist/device/gpu-residency.d.ts +32 -5
  86. package/dist/device/gpu-residency.d.ts.map +1 -1
  87. package/dist/device/lifecycle-transaction.d.ts +2 -0
  88. package/dist/device/lifecycle-transaction.d.ts.map +1 -0
  89. package/dist/environment/frame.d.ts +5 -0
  90. package/dist/environment/frame.d.ts.map +1 -1
  91. package/dist/environment/inspection.d.ts +7 -0
  92. package/dist/environment/inspection.d.ts.map +1 -1
  93. package/dist/environment/lifecycle.d.ts +20 -2
  94. package/dist/environment/lifecycle.d.ts.map +1 -1
  95. package/dist/errors/gpu-driven.d.ts +26 -0
  96. package/dist/errors/gpu-driven.d.ts.map +1 -0
  97. package/dist/errors/index.d.ts +1 -0
  98. package/dist/errors/index.d.ts.map +1 -1
  99. package/dist/errors/recover.d.ts +67 -3
  100. package/dist/errors/recover.d.ts.map +1 -1
  101. package/dist/errors/render.d.ts +39 -1
  102. package/dist/errors/render.d.ts.map +1 -1
  103. package/dist/extract/contracts.d.ts +899 -0
  104. package/dist/extract/contracts.d.ts.map +1 -0
  105. package/dist/extract/gpu-driven.d.ts +50 -0
  106. package/dist/extract/gpu-driven.d.ts.map +1 -0
  107. package/dist/extract/visibility.d.ts.map +1 -1
  108. package/dist/features/host.d.ts +2 -0
  109. package/dist/features/host.d.ts.map +1 -1
  110. package/dist/features/prepared-gpu-work.d.ts +3 -0
  111. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  112. package/dist/features/prepared-graphics-store.d.ts +2 -0
  113. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  114. package/dist/gpu-driven/batch-topology.d.ts +34 -0
  115. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  116. package/dist/gpu-driven/prepared-draw.d.ts +63 -0
  117. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -0
  118. package/dist/gpu-driven/production-raster.d.ts +126 -2
  119. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  120. package/dist/gpu-driven/view-gpu.d.ts +64 -1
  121. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  122. package/dist/gpu-scene-schema.d.ts +14 -0
  123. package/dist/gpu-scene-schema.d.ts.map +1 -1
  124. package/dist/gpu-scene.d.ts +9 -1
  125. package/dist/gpu-scene.d.ts.map +1 -1
  126. package/dist/gpu-usage.d.ts +0 -1
  127. package/dist/gpu-usage.d.ts.map +1 -1
  128. package/dist/hdrp-buffers.d.ts +3 -3
  129. package/dist/hdrp-buffers.d.ts.map +1 -1
  130. package/dist/ibl/IblPipelineCache.d.ts +7 -6
  131. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  132. package/dist/ibl/skylight-bind-group.d.ts +7 -1
  133. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  134. package/dist/index.d.ts +13 -2
  135. package/dist/index.d.ts.map +1 -1
  136. package/dist/index.mjs +90 -5
  137. package/dist/index.mjs.map +1 -1
  138. package/dist/inspection-types.d.ts +163 -1
  139. package/dist/inspection-types.d.ts.map +1 -1
  140. package/dist/internal.d.ts +9 -0
  141. package/dist/internal.d.ts.map +1 -1
  142. package/dist/internal.mjs +23 -2
  143. package/dist/internal.mjs.map +1 -1
  144. package/dist/light-buffer-layout.d.ts +60 -148
  145. package/dist/light-buffer-layout.d.ts.map +1 -1
  146. package/dist/materials.d.ts +34 -10
  147. package/dist/materials.d.ts.map +1 -1
  148. package/dist/mesh-material-bindings.d.ts +56 -0
  149. package/dist/mesh-material-bindings.d.ts.map +1 -1
  150. package/dist/occlusion-proxy.d.ts +4 -0
  151. package/dist/occlusion-proxy.d.ts.map +1 -0
  152. package/dist/pbr-pipeline.d.ts +58 -21
  153. package/dist/pbr-pipeline.d.ts.map +1 -1
  154. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  155. package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -1
  156. package/dist/pipeline/standard-lighting/light-frame.d.ts +3 -3
  157. package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -1
  158. package/dist/pipeline/standard-lighting/topology.d.ts +1 -1
  159. package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -1
  160. package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -1
  161. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  162. package/dist/pipeline-builder.d.ts +2 -0
  163. package/dist/pipeline-builder.d.ts.map +1 -1
  164. package/dist/pipeline-spec.d.ts +1 -1
  165. package/dist/pipeline-spec.d.ts.map +1 -1
  166. package/dist/plugin.d.ts.map +1 -1
  167. package/dist/points-lines/prepare.d.ts +3 -0
  168. package/dist/points-lines/prepare.d.ts.map +1 -1
  169. package/dist/points-lines/standard-owner.d.ts +33 -0
  170. package/dist/points-lines/standard-owner.d.ts.map +1 -0
  171. package/dist/prepare/extended-lighting/ltc-resources.d.ts +31 -0
  172. package/dist/prepare/extended-lighting/ltc-resources.d.ts.map +1 -0
  173. package/dist/prepare/extended-lighting/resources.d.ts +72 -0
  174. package/dist/prepare/extended-lighting/resources.d.ts.map +1 -0
  175. package/dist/prepare/extended-lighting/spot-modifiers.d.ts +42 -0
  176. package/dist/prepare/extended-lighting/spot-modifiers.d.ts.map +1 -0
  177. package/dist/prepare/extended-lighting/state.d.ts +24 -0
  178. package/dist/prepare/extended-lighting/state.d.ts.map +1 -0
  179. package/dist/record/frame-lighting.d.ts +8 -6
  180. package/dist/record/frame-lighting.d.ts.map +1 -1
  181. package/dist/record/frame-snapshot.d.ts +55 -10
  182. package/dist/record/frame-snapshot.d.ts.map +1 -1
  183. package/dist/record/frame-targets.d.ts.map +1 -1
  184. package/dist/record/frame.d.ts +21 -5
  185. package/dist/record/frame.d.ts.map +1 -1
  186. package/dist/record/gpu-timing.d.ts +19 -7
  187. package/dist/record/gpu-timing.d.ts.map +1 -1
  188. package/dist/record/helpers.d.ts +0 -20
  189. package/dist/record/helpers.d.ts.map +1 -1
  190. package/dist/record/main-pass-geometry.d.ts +20 -2
  191. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  192. package/dist/record/main-pass-material.d.ts +10 -18
  193. package/dist/record/main-pass-material.d.ts.map +1 -1
  194. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  195. package/dist/record/main-pass.d.ts.map +1 -1
  196. package/dist/record/mesh-ssbo.d.ts +11 -3
  197. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  198. package/dist/record/recovery-pipeline.d.ts +30 -0
  199. package/dist/record/recovery-pipeline.d.ts.map +1 -0
  200. package/dist/record/render-context.d.ts +82 -9
  201. package/dist/record/render-context.d.ts.map +1 -1
  202. package/dist/record/shadow-pass.d.ts.map +1 -1
  203. package/dist/record/typed-frame-graph.d.ts +49 -2
  204. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  205. package/dist/record/view-ubo.d.ts +1 -2
  206. package/dist/record/view-ubo.d.ts.map +1 -1
  207. package/dist/recovery/render-system-candidate.d.ts +65 -0
  208. package/dist/recovery/render-system-candidate.d.ts.map +1 -0
  209. package/dist/reflection/inspection.d.ts +10 -0
  210. package/dist/reflection/inspection.d.ts.map +1 -0
  211. package/dist/reflection/projection.d.ts +49 -0
  212. package/dist/reflection/projection.d.ts.map +1 -1
  213. package/dist/reflection/record-owner.d.ts +60 -0
  214. package/dist/reflection/record-owner.d.ts.map +1 -0
  215. package/dist/render-contract.d.ts +78 -15
  216. package/dist/render-contract.d.ts.map +1 -1
  217. package/dist/render-pipeline.d.ts +7 -0
  218. package/dist/render-pipeline.d.ts.map +1 -1
  219. package/dist/render-system-extract-tail.d.ts +12 -0
  220. package/dist/render-system-extract-tail.d.ts.map +1 -0
  221. package/dist/render-system-extract.d.ts +252 -30
  222. package/dist/render-system-extract.d.ts.map +1 -1
  223. package/dist/render-system.d.ts +140 -5
  224. package/dist/render-system.d.ts.map +1 -1
  225. package/dist/scene/probe-blend-record.d.ts +22 -0
  226. package/dist/scene/probe-blend-record.d.ts.map +1 -0
  227. package/dist/scene/probe-blend.d.ts +142 -0
  228. package/dist/scene/probe-blend.d.ts.map +1 -0
  229. package/dist/scene/render-scene-types.d.ts +0 -6
  230. package/dist/scene/render-scene-types.d.ts.map +1 -1
  231. package/dist/scene/render-scene.d.ts +122 -9
  232. package/dist/scene/render-scene.d.ts.map +1 -1
  233. package/dist/scene/visibility/bounds.d.ts +20 -0
  234. package/dist/scene/visibility/bounds.d.ts.map +1 -0
  235. package/dist/scene/visibility/budget.d.ts +16 -0
  236. package/dist/scene/visibility/budget.d.ts.map +1 -0
  237. package/dist/scene/visibility/facet.d.ts +73 -0
  238. package/dist/scene/visibility/facet.d.ts.map +1 -0
  239. package/dist/scene/visibility/gpu-frame-timing.d.ts +41 -0
  240. package/dist/scene/visibility/gpu-frame-timing.d.ts.map +1 -0
  241. package/dist/scene/visibility/gpu-lod.d.ts +46 -0
  242. package/dist/scene/visibility/gpu-lod.d.ts.map +1 -0
  243. package/dist/scene/visibility/inspection.d.ts +132 -0
  244. package/dist/scene/visibility/inspection.d.ts.map +1 -0
  245. package/dist/scene/visibility/lod-selector.d.ts +25 -0
  246. package/dist/scene/visibility/lod-selector.d.ts.map +1 -0
  247. package/dist/scene/visibility/occlusion-confidence.d.ts +81 -0
  248. package/dist/scene/visibility/occlusion-confidence.d.ts.map +1 -0
  249. package/dist/scene/visibility/occlusion-pass.d.ts +57 -0
  250. package/dist/scene/visibility/occlusion-pass.d.ts.map +1 -0
  251. package/dist/scene/visibility/occlusion-query-pool.d.ts +57 -0
  252. package/dist/scene/visibility/occlusion-query-pool.d.ts.map +1 -0
  253. package/dist/scene/visibility/occlusion-runtime.d.ts +96 -0
  254. package/dist/scene/visibility/occlusion-runtime.d.ts.map +1 -0
  255. package/dist/scene/visibility/types.d.ts +34 -0
  256. package/dist/scene/visibility/types.d.ts.map +1 -0
  257. package/dist/ssr/admission.d.ts +122 -0
  258. package/dist/ssr/admission.d.ts.map +1 -0
  259. package/dist/ssr/composition.d.ts +32 -0
  260. package/dist/ssr/composition.d.ts.map +1 -0
  261. package/dist/ssr/errors.d.ts +39 -0
  262. package/dist/ssr/errors.d.ts.map +1 -0
  263. package/dist/ssr/identity.d.ts +13 -0
  264. package/dist/ssr/identity.d.ts.map +1 -0
  265. package/dist/systems/skin-palette-allocator.d.ts +1 -1
  266. package/dist/temporal/frame-coordinator.d.ts +13 -0
  267. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  268. package/dist/temporal/frame.d.ts +2 -0
  269. package/dist/temporal/frame.d.ts.map +1 -1
  270. package/dist/temporal/index.mjs +6 -5
  271. package/dist/temporal/taa-history-store.d.ts +15 -1
  272. package/dist/temporal/taa-history-store.d.ts.map +1 -1
  273. package/dist/temporal/transaction.d.ts +5 -0
  274. package/dist/temporal/transaction.d.ts.map +1 -1
  275. package/dist/temporal/view.d.ts +7 -0
  276. package/dist/temporal/view.d.ts.map +1 -1
  277. package/dist/tilemap-chunk-extract-system.d.ts +1 -1
  278. package/dist/typed-render-graph-primitives.d.ts +4 -0
  279. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  280. package/dist/volume/passes.d.ts +8 -4
  281. package/dist/volume/passes.d.ts.map +1 -1
  282. package/package.json +20 -20
  283. package/src/__tests__/cluster-grid-default-surface.unit.test.ts +5 -0
  284. package/src/__tests__/detached-inspection.integration.test.ts +6 -0
  285. package/src/__tests__/device-feature-admission.unit.test.ts +19 -1
  286. package/src/__tests__/device-loss-fanout.unit.test.ts +107 -0
  287. package/src/__tests__/device-scope-lifecycle.unit.test.ts +21 -0
  288. package/src/__tests__/direct-light-snapshot.unit.test.ts +59 -3
  289. package/src/__tests__/environment-generation.integration.test.ts +39 -0
  290. package/src/__tests__/evidence-identity.ts +13 -0
  291. package/src/__tests__/evidence-identity.unit.test.ts +24 -0
  292. package/src/__tests__/expose-renderer-errors.unit.test.ts +34 -0
  293. package/src/__tests__/extended-lighting-recovery.browser.test.ts +14 -0
  294. package/src/__tests__/extended-lighting-recovery.dawn.test.ts +14 -0
  295. package/src/__tests__/extended-lighting-recovery.integration.test.ts +81 -0
  296. package/src/__tests__/extended-lighting-resources.unit.test.ts +51 -0
  297. package/src/__tests__/extended-lighting-zero-feature.integration.test.ts +52 -0
  298. package/src/__tests__/factory-contract.integration.test.ts +154 -6
  299. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +4 -1
  300. package/src/__tests__/frame-observation.contract.test.ts +15 -0
  301. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
  302. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +1 -0
  303. package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +1 -0
  304. package/src/__tests__/gpu-driven-production.integration.test.ts +572 -9
  305. package/src/__tests__/gpu-driven-scaling.unit.test.ts +66 -2
  306. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +26 -1
  307. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +89 -2
  308. package/src/__tests__/gpu-driven-view.browser.test.ts +3 -3
  309. package/src/__tests__/gpu-driven-view.dawn.test.ts +3 -3
  310. package/src/__tests__/gpu-driven-view.unit.test.ts +50 -0
  311. package/src/__tests__/gpu-lod-evidence.ts +188 -0
  312. package/src/__tests__/gpu-lod-fallback.integration.test.ts +10 -0
  313. package/src/__tests__/gpu-lod-indirect.integration.test.ts +40 -0
  314. package/src/__tests__/gpu-lod-parity.dawn.test.ts +29 -0
  315. package/src/__tests__/gpu-lod-readiness.integration.test.ts +52 -0
  316. package/src/__tests__/gpu-lod-schema.unit.test.ts +66 -0
  317. package/src/__tests__/gpu-lod-selector.unit.test.ts +28 -0
  318. package/src/__tests__/gpu-lod-silhouette.browser.test.ts +13 -0
  319. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +66 -1
  320. package/src/__tests__/gpu-scene.dawn.test.ts +8 -1
  321. package/src/__tests__/gpu-scene.unit.test.ts +49 -3
  322. package/src/__tests__/ibl/face-uniforms.unit.test.ts +2 -0
  323. package/src/__tests__/ibl-residency-publication.unit.test.ts +113 -0
  324. package/src/__tests__/light-buffer-layout.unit.test.ts +113 -3
  325. package/src/__tests__/light-inspection.unit.test.ts +55 -0
  326. package/src/__tests__/light-resource-error.unit.test.ts +43 -0
  327. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +109 -0
  328. package/src/__tests__/lod-bounds.unit.test.ts +42 -0
  329. package/src/__tests__/lod-cpu-lane.integration.test.ts +55 -0
  330. package/src/__tests__/lod-cpu-no-change.perf.test.ts +19 -0
  331. package/src/__tests__/lod-gpu-frame-timing.unit.test.ts +49 -0
  332. package/src/__tests__/lod-multi-view.integration.test.ts +63 -0
  333. package/src/__tests__/lod-occlusion-device-loss.integration.test.ts +27 -0
  334. package/src/__tests__/lod-occlusion-final-decision.integration.test.ts +47 -0
  335. package/src/__tests__/lod-occlusion-inspection.integration.test.ts +217 -0
  336. package/src/__tests__/lod-occlusion-inspection.schema.test-d.ts +14 -0
  337. package/src/__tests__/lod-occlusion-inspection.unit.test.ts +72 -0
  338. package/src/__tests__/lod-occlusion-visual-evidence.ts +91 -0
  339. package/src/__tests__/lod-occlusion.browser.test.ts +15 -0
  340. package/src/__tests__/lod-occlusion.dawn.test.ts +20 -0
  341. package/src/__tests__/lod-selector.profile.test.ts +35 -0
  342. package/src/__tests__/lod-selector.unit.test.ts +68 -0
  343. package/src/__tests__/lod-visibility-identity.unit.test.ts +198 -0
  344. package/src/__tests__/lod-visibility-lifecycle.integration.test.ts +132 -0
  345. package/src/__tests__/ltc-resources.unit.test.ts +32 -0
  346. package/src/__tests__/material-contract-inventory.unit.test.ts +41 -9
  347. package/src/__tests__/material-cooked-projection.unit.test.ts +19 -1
  348. package/src/__tests__/material-static-dynamic-route.unit.test.ts +29 -0
  349. package/src/__tests__/material-stride-surface.unit.test.ts +7 -3
  350. package/src/__tests__/materials-standard-contract.unit.test.ts +104 -0
  351. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
  352. package/src/__tests__/occlusion-confidence.unit.test.ts +168 -0
  353. package/src/__tests__/occlusion-invalidation.integration.test.ts +37 -0
  354. package/src/__tests__/occlusion-pass-routing.unit.test.ts +16 -0
  355. package/src/__tests__/occlusion-pass.dawn.test.ts +20 -0
  356. package/src/__tests__/occlusion-pass.integration.test.ts +43 -0
  357. package/src/__tests__/occlusion-pass.rhi-null.test.ts +22 -0
  358. package/src/__tests__/occlusion-query-pool.rhi-null.test.ts +21 -0
  359. package/src/__tests__/occlusion-query-pool.unit.test.ts +95 -0
  360. package/src/__tests__/occlusion-query-ticket.integration.test.ts +47 -0
  361. package/src/__tests__/occlusion-query.dawn.test.ts +16 -0
  362. package/src/__tests__/occlusion-query.evidence.ts +178 -0
  363. package/src/__tests__/occlusion-query.rhi-null.test.ts +31 -0
  364. package/src/__tests__/occlusion-runtime.unit.test.ts +120 -0
  365. package/src/__tests__/physical-clearcoat.integration.test.ts +89 -0
  366. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
  367. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +1 -1
  368. package/src/__tests__/probe-bindings.unit.test.ts +200 -0
  369. package/src/__tests__/probe-blend-numeric.unit.test.ts +67 -0
  370. package/src/__tests__/probe-blend-oracle.unit.test.ts +136 -0
  371. package/src/__tests__/probe-capacity.integration.test.ts +97 -0
  372. package/src/__tests__/probe-recovery.integration.test.ts +104 -0
  373. package/src/__tests__/probe-scene-dirty.integration.test.ts +211 -0
  374. package/src/__tests__/profiler-phase-catalog.test.ts +4 -1
  375. package/src/__tests__/profiler-phase-token.test.ts +1 -0
  376. package/src/__tests__/recover-error-policy-owner.unit.test.ts +6 -3
  377. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +140 -0
  378. package/src/__tests__/rect-area-boundary.unit.test.ts +24 -0
  379. package/src/__tests__/reflection-fallback-graph.unit.test.ts +67 -0
  380. package/src/__tests__/reflection-fallback-inspection.unit.test.ts +77 -0
  381. package/src/__tests__/reflection-fallback-lifecycle.integration.test.ts +21 -0
  382. package/src/__tests__/reflection-fallback-projection.unit.test.ts +90 -0
  383. package/src/__tests__/reflection-fallback-source.unit.test.ts +32 -0
  384. package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
  385. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
  386. package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
  387. package/src/__tests__/render-feature-docs.unit.test.ts +12 -7
  388. package/src/__tests__/render-graph-fallback.integration.test.ts +24 -0
  389. package/src/__tests__/render-perf/extended-lighting.bench.test.ts +66 -0
  390. package/src/__tests__/render-scene-projection.unit.test.ts +447 -18
  391. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +160 -17
  392. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +47 -0
  393. package/src/__tests__/renderer-generation-assembly.unit.test.ts +77 -0
  394. package/src/__tests__/renderer-generation-failure.unit.test.ts +108 -0
  395. package/src/__tests__/renderer-producer-root-matrix.integration.test.ts +33 -0
  396. package/src/__tests__/renderer-recovery-capability-matrix.unit.test.ts +59 -0
  397. package/src/__tests__/renderer-recovery-contract.unit.test.ts +73 -0
  398. package/src/__tests__/renderer-recovery-lifecycle.unit.test.ts +216 -0
  399. package/src/__tests__/renderer-target-history-recovery.integration.test.ts +80 -0
  400. package/src/__tests__/shader-manifest-fixture.ts +13 -16
  401. package/src/__tests__/shader-stage-surface.unit.test.ts +1 -1
  402. package/src/__tests__/skin-motion-regression.unit.test.ts +22 -0
  403. package/src/__tests__/skinned-shadow-caster.test.ts +2 -2
  404. package/src/__tests__/spot-modifier-projection.unit.test.ts +70 -0
  405. package/src/__tests__/ssr-admission-matrix.integration.test.ts +206 -0
  406. package/src/__tests__/ssr-composition.unit.test.ts +46 -0
  407. package/src/__tests__/ssr-fallback-zero-work.bench.test.ts +94 -0
  408. package/src/__tests__/ssr-recovery-errors.unit.test.ts +58 -0
  409. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +67 -0
  410. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +7 -0
  411. package/src/__tests__/standard-layer-projection.unit.test.ts +23 -0
  412. package/src/__tests__/standard-lighting-inspection.integration.test.ts +1 -1
  413. package/src/__tests__/standard-lighting-write.unit.test.ts +66 -2
  414. package/src/__tests__/temporal-fallback-generation.integration.test.ts +16 -0
  415. package/src/__tests__/temporal-view.unit.test.ts +3 -3
  416. package/src/__tests__/transmission-prewarm.unit.test.ts +111 -32
  417. package/src/__tests__/visibility-budget.integration.test.ts +140 -0
  418. package/src/__tests__/visibility-budget.unit.test.ts +70 -0
  419. package/src/__tests__/visibility-extract.integration.test.ts +11 -6
  420. package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +6 -3
  421. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +31 -28
  422. package/src/__tests__/volumetric-fog-topology.unit.test.ts +3 -1
  423. package/src/assembly/backend-contract.ts +13 -0
  424. package/src/assembly/bundler-contract.ts +9 -0
  425. package/src/assembly/device-feature-admission.ts +26 -9
  426. package/src/assembly/extended-lighting-fallback.ts +216 -0
  427. package/src/assembly/factory.ts +81 -9634
  428. package/src/assembly/host-contract.ts +10 -0
  429. package/src/assembly/material/assembly.ts +18 -2
  430. package/src/assembly/material/standard-layer-projection.ts +16 -0
  431. package/src/assembly/material-shader-policy.ts +854 -0
  432. package/src/assembly/material-shader-prewarm.ts +88 -0
  433. package/src/assembly/mesh-ssbo-grow.ts +270 -0
  434. package/src/assembly/recovery/device-loss-fanout.ts +89 -0
  435. package/src/assembly/recovery/generation.ts +141 -0
  436. package/src/assembly/recovery/recovery-attempt.ts +800 -0
  437. package/src/assembly/recovery/renderer-recover.ts +906 -0
  438. package/src/assembly/renderer-facade.ts +342 -0
  439. package/src/assembly/renderer-frame-transaction.ts +45 -0
  440. package/src/assembly/renderer-helpers.ts +99 -0
  441. package/src/assembly/renderer-lifecycle.ts +159 -0
  442. package/src/assembly/shader-prewarm-policy.ts +157 -0
  443. package/src/assembly/webgpu-ready-contract.ts +14 -0
  444. package/src/assembly/webgpu-ready.ts +4079 -0
  445. package/src/assembly/webgpu-renderer.ts +4095 -0
  446. package/src/cluster-binner.ts +31 -0
  447. package/src/components/__tests__/lighting-authoring.unit.test.ts +39 -0
  448. package/src/components/__tests__/rect-area-light.unit.test.ts +33 -0
  449. package/src/components/camera.ts +1 -1
  450. package/src/components/index.ts +3 -0
  451. package/src/components/light-helpers.ts +52 -1
  452. package/src/components/light-probe.ts +13 -0
  453. package/src/components/rect-area-light.ts +15 -0
  454. package/src/components/scene-instance.ts +6 -0
  455. package/src/components/spot-light.ts +3 -0
  456. package/src/debug-draw-glue.ts +1 -1
  457. package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
  458. package/src/device/device-scope.ts +35 -6
  459. package/src/device/gpu-residency.ts +334 -35
  460. package/src/device/lifecycle-transaction.ts +12 -0
  461. package/src/environment/frame.ts +6 -0
  462. package/src/environment/inspection.ts +10 -0
  463. package/src/environment/lifecycle.ts +122 -9
  464. package/src/errors/gpu-driven.ts +92 -0
  465. package/src/errors/index.ts +1 -0
  466. package/src/errors/recover.ts +108 -5
  467. package/src/errors/render.ts +72 -1
  468. package/src/extract/camera.ts +3 -3
  469. package/src/extract/contracts.ts +974 -0
  470. package/src/extract/gpu-driven.ts +108 -0
  471. package/src/extract/visibility.ts +0 -23
  472. package/src/features/host.ts +16 -0
  473. package/src/features/prepared-gpu-work.ts +20 -2
  474. package/src/features/prepared-graphics-store.ts +17 -0
  475. package/src/gpu-driven/batch-topology.ts +206 -28
  476. package/src/gpu-driven/prepared-draw.ts +208 -0
  477. package/src/gpu-driven/production-raster.ts +1046 -39
  478. package/src/gpu-driven/view-gpu.ts +411 -29
  479. package/src/gpu-scene-schema.ts +13 -0
  480. package/src/gpu-scene.ts +137 -67
  481. package/src/gpu-usage.ts +0 -1
  482. package/src/hdrp-buffers.ts +6 -6
  483. package/src/ibl/IblPipelineCache.ts +134 -50
  484. package/src/ibl/skylight-bind-group.ts +26 -0
  485. package/src/index.ts +83 -1
  486. package/src/inspection-types.ts +220 -1
  487. package/src/internal.ts +38 -0
  488. package/src/light-buffer-layout.ts +157 -324
  489. package/src/materials.ts +278 -47
  490. package/src/mesh-material-bindings.ts +59 -0
  491. package/src/occlusion-proxy.ts +64 -0
  492. package/src/pbr-pipeline.ts +290 -60
  493. package/src/pipeline/standard-forward-lane.ts +47 -0
  494. package/src/pipeline/standard-lighting/graph.ts +2 -1
  495. package/src/pipeline/standard-lighting/light-frame.ts +3 -2
  496. package/src/pipeline/standard-lighting/topology.ts +1 -1
  497. package/src/pipeline/standard-lighting/transport.ts +2 -1
  498. package/src/pipeline/standard-pipeline.ts +2 -0
  499. package/src/pipeline-builder.ts +5 -2
  500. package/src/pipeline-spec.ts +12 -1
  501. package/src/plugin.ts +4 -0
  502. package/src/points-lines/__tests__/cache-recovery.unit.test.ts +22 -0
  503. package/src/points-lines/prepare.ts +9 -0
  504. package/src/points-lines/standard-owner.ts +403 -0
  505. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +56 -0
  506. package/src/prepare/extended-lighting/ltc-resources.ts +136 -0
  507. package/src/prepare/extended-lighting/resources.ts +389 -0
  508. package/src/prepare/extended-lighting/spot-modifiers.ts +194 -0
  509. package/src/prepare/extended-lighting/state.ts +92 -0
  510. package/src/record/__tests__/frame-targets-recovery.unit.test.ts +60 -0
  511. package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
  512. package/src/record/__tests__/main-pass-geometry.unit.test.ts +26 -1
  513. package/src/record/__tests__/mesh-ssbo.unit.test.ts +38 -0
  514. package/src/record/__tests__/recovery-pipeline.unit.test.ts +124 -0
  515. package/src/record/__tests__/sprite-material-abi.unit.test.ts +28 -13
  516. package/src/record/__tests__/standard-pbr-ubo-layout.unit.test.ts +47 -4
  517. package/src/record/__tests__/temporal-payload.unit.test.ts +29 -28
  518. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +21 -2
  519. package/src/record/frame-lighting.ts +252 -53
  520. package/src/record/frame-snapshot.ts +72 -12
  521. package/src/record/frame-targets.ts +11 -1
  522. package/src/record/frame.ts +416 -95
  523. package/src/record/gpu-timing.ts +108 -44
  524. package/src/record/helpers.ts +1 -59
  525. package/src/record/main-pass-geometry.ts +434 -44
  526. package/src/record/main-pass-material.ts +324 -210
  527. package/src/record/main-pass-sprite-draws.ts +58 -92
  528. package/src/record/main-pass.ts +94 -6
  529. package/src/record/mesh-ssbo.ts +79 -46
  530. package/src/record/recovery-pipeline.ts +695 -0
  531. package/src/record/render-context.ts +99 -7
  532. package/src/record/shadow-pass.ts +66 -40
  533. package/src/record/typed-frame-graph.ts +270 -84
  534. package/src/record/view-ubo.ts +17 -27
  535. package/src/recovery/render-system-candidate.ts +839 -0
  536. package/src/reflection/inspection.ts +67 -0
  537. package/src/reflection/projection.ts +196 -1
  538. package/src/reflection/record-owner.ts +1283 -0
  539. package/src/render-contract.ts +82 -12
  540. package/src/render-pipeline.ts +5 -0
  541. package/src/render-system-extract-tail.ts +2983 -0
  542. package/src/render-system-extract.ts +290 -2784
  543. package/src/render-system.ts +1597 -1192
  544. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +36 -0
  545. package/src/scene/probe-blend-record.ts +54 -0
  546. package/src/scene/probe-blend.ts +813 -0
  547. package/src/scene/render-scene-types.ts +0 -7
  548. package/src/scene/render-scene.ts +972 -184
  549. package/src/scene/visibility/bounds.ts +57 -0
  550. package/src/scene/visibility/budget.ts +40 -0
  551. package/src/scene/visibility/facet.ts +400 -0
  552. package/src/scene/visibility/gpu-frame-timing.ts +101 -0
  553. package/src/scene/visibility/gpu-lod.ts +119 -0
  554. package/src/scene/visibility/inspection.ts +313 -0
  555. package/src/scene/visibility/lod-selector.ts +84 -0
  556. package/src/scene/visibility/occlusion-confidence.ts +478 -0
  557. package/src/scene/visibility/occlusion-pass.ts +165 -0
  558. package/src/scene/visibility/occlusion-query-pool.ts +178 -0
  559. package/src/scene/visibility/occlusion-runtime.ts +672 -0
  560. package/src/scene/visibility/types.ts +50 -0
  561. package/src/ssr/admission.ts +451 -0
  562. package/src/ssr/composition.ts +73 -0
  563. package/src/ssr/errors.ts +76 -0
  564. package/src/ssr/identity.ts +12 -0
  565. package/src/systems/skin-palette-allocator.ts +1 -1
  566. package/src/temporal/frame-coordinator.ts +30 -1
  567. package/src/temporal/frame.ts +14 -1
  568. package/src/temporal/taa-history-store.ts +46 -2
  569. package/src/temporal/temporal-view.ts +1 -1
  570. package/src/temporal/transaction.ts +9 -0
  571. package/src/temporal/view.ts +11 -0
  572. package/src/tilemap-chunk-extract-system.ts +5 -5
  573. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +19 -12
  574. package/src/typed-render-graph-primitives.ts +48 -0
  575. package/src/volume/passes.ts +46 -49
  576. package/dist/.tsbuildinfo +0 -1
  577. package/dist/chunk-5YADUCA7.mjs.map +0 -1
  578. package/dist/chunk-6OPXDQ2E.mjs.map +0 -1
  579. package/dist/chunk-BXBQQKFQ.mjs +0 -67
  580. package/dist/chunk-BXBQQKFQ.mjs.map +0 -1
  581. package/dist/chunk-FS2KNUQH.mjs.map +0 -1
  582. package/dist/chunk-PCHBPYML.mjs.map +0 -1
  583. package/dist/chunk-VFPLTKCU.mjs +0 -192
  584. package/dist/chunk-VFPLTKCU.mjs.map +0 -1
@@ -0,0 +1,140 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { createVisibilityBudget } from '../scene/visibility/budget';
3
+ import {
4
+ primitiveKey,
5
+ primitiveKeyId,
6
+ VisibilityFacetStore,
7
+ viewKey,
8
+ viewKeyId,
9
+ } from '../scene/visibility/facet';
10
+
11
+ const view = (cameraEntity: number) =>
12
+ viewKey({
13
+ attachmentId: 'budget-scene',
14
+ cameraEntity,
15
+ viewRole: 'main',
16
+ viewGeneration: 1,
17
+ });
18
+
19
+ const primitive = (slot: number) =>
20
+ primitiveKey({
21
+ attachmentId: 'budget-scene',
22
+ worldGeneration: 1,
23
+ primitiveSlot: slot,
24
+ slotGeneration: 1,
25
+ });
26
+
27
+ describe('visibility budget integration', () => {
28
+ it('shares one derived window across views and LOD levels', () => {
29
+ const budget = createVisibilityBudget(2048);
30
+ const facets = new VisibilityFacetStore(budget);
31
+ const views = [view(1), view(2)];
32
+ for (const currentView of views) {
33
+ facets.activateView(currentView);
34
+ for (let level = 0; level < 8; level += 1) {
35
+ const currentPrimitive = primitive(currentView.cameraEntity * 10 + level);
36
+ facets.setCandidate(currentView, currentPrimitive, { level, confidence: 1 });
37
+ facets.applyConfidence(currentView, currentPrimitive, {
38
+ type: 'result',
39
+ samples: 0,
40
+ submissionGeneration: 1,
41
+ });
42
+ facets.applyConfidence(currentView, currentPrimitive, {
43
+ type: 'result',
44
+ samples: 0,
45
+ submissionGeneration: 2,
46
+ });
47
+ }
48
+ }
49
+
50
+ expect(facets.visibilityBudget()).toBe(budget);
51
+ expect(facets.visibilityBudget()).toMatchObject({
52
+ effectiveQueryBudget: 2048,
53
+ settleSubmits: 98,
54
+ retestSubmits: 44,
55
+ expirySubmits: 88,
56
+ });
57
+
58
+ facets.advanceSuccessfulSubmits(2 + budget.retestSubmits);
59
+ for (const currentView of views) {
60
+ expect(facets.shouldQuery(currentView, primitive(currentView.cameraEntity * 10))).toBe(true);
61
+ }
62
+ });
63
+
64
+ it('keeps invalidation visible and requeues the same identity without extending evidence', () => {
65
+ const budget = createVisibilityBudget(4096);
66
+ const facets = new VisibilityFacetStore(budget);
67
+ const currentView = view(3);
68
+ const currentPrimitive = primitive(3);
69
+ facets.activateView(currentView);
70
+ facets.setCandidate(currentView, currentPrimitive, { level: 2, confidence: 1 });
71
+ facets.applyConfidence(currentView, currentPrimitive, {
72
+ type: 'result',
73
+ samples: 0,
74
+ submissionGeneration: 1,
75
+ });
76
+ facets.applyConfidence(currentView, currentPrimitive, {
77
+ type: 'result',
78
+ samples: 0,
79
+ submissionGeneration: 2,
80
+ });
81
+ facets.advanceSuccessfulSubmits(2 + budget.retestSubmits, [
82
+ { view: currentView, primitive: currentPrimitive },
83
+ ]);
84
+ expect(facets.getConfidence(currentView, currentPrimitive).status).toBe('hidden');
85
+
86
+ facets.applyConfidence(currentView, currentPrimitive, {
87
+ type: 'invalidate',
88
+ reason: 'world-reorder',
89
+ });
90
+ expect(facets.getConfidence(currentView, currentPrimitive)).toMatchObject({
91
+ status: 'visible',
92
+ dirty: true,
93
+ queryable: true,
94
+ });
95
+ expect(facets.dequeueQueryCandidates(currentView, 1)).toHaveLength(1);
96
+ });
97
+
98
+ it('uses expiry-only scheduling for a due hidden row while its query is in flight', () => {
99
+ const budget = createVisibilityBudget();
100
+ const facets = new VisibilityFacetStore(budget);
101
+ const currentView = view(4);
102
+ const currentPrimitive = primitive(4);
103
+ facets.activateView(currentView);
104
+ facets.setCandidate(currentView, currentPrimitive, { level: 0, confidence: 1 });
105
+ facets.applyConfidence(currentView, currentPrimitive, {
106
+ type: 'result',
107
+ samples: 0,
108
+ submissionGeneration: 1,
109
+ });
110
+ facets.applyConfidence(currentView, currentPrimitive, {
111
+ type: 'result',
112
+ samples: 0,
113
+ submissionGeneration: 2,
114
+ });
115
+ const dueGeneration = 2 + budget.retestSubmits;
116
+ facets.advanceSuccessfulSubmits(dueGeneration);
117
+ expect(facets.dequeueQueryCandidates(currentView, 1)).toHaveLength(1);
118
+
119
+ facets.applyConfidence(currentView, currentPrimitive, {
120
+ type: 'submit',
121
+ submissionGeneration: dueGeneration,
122
+ });
123
+ expect(facets.getConfidence(currentView, currentPrimitive).successfulSubmits).toBe(
124
+ budget.retestSubmits + 1,
125
+ );
126
+ const scheduler = facets as unknown as {
127
+ confidence: { wakeByGeneration: Map<number, Set<string>> };
128
+ };
129
+ const key = `${viewKeyId(currentView)}|${primitiveKeyId(currentPrimitive)}`;
130
+ expect([...scheduler.confidence.wakeByGeneration.values()].flat()).not.toContain(key);
131
+
132
+ facets.advanceSuccessfulSubmits(
133
+ dueGeneration + budget.expirySubmits - budget.retestSubmits - 1,
134
+ );
135
+ expect(facets.getConfidence(currentView, currentPrimitive)).toMatchObject({
136
+ status: 'visible',
137
+ dirty: true,
138
+ });
139
+ });
140
+ });
@@ -0,0 +1,70 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import {
3
+ createVisibilityBudget,
4
+ DEFAULT_CONFIGURED_QUERY_BUDGET,
5
+ MAX_QUERY_BUDGET,
6
+ } from '../scene/visibility/budget';
7
+
8
+ describe('visibility budget derivation', () => {
9
+ it.each([
10
+ [
11
+ 2048,
12
+ {
13
+ effectiveQueryBudget: 2048,
14
+ oneSweepCandidates: 49,
15
+ oneSweepOccluded: 44,
16
+ settleSubmits: 98,
17
+ retestSubmits: 44,
18
+ expirySubmits: 88,
19
+ },
20
+ ],
21
+ [
22
+ 4096,
23
+ {
24
+ effectiveQueryBudget: 4096,
25
+ oneSweepCandidates: 25,
26
+ oneSweepOccluded: 22,
27
+ settleSubmits: 50,
28
+ retestSubmits: 22,
29
+ expirySubmits: 44,
30
+ },
31
+ ],
32
+ ])('derives the approved windows for Q=%d', (configuredQueryBudget, expected) => {
33
+ expect(createVisibilityBudget(configuredQueryBudget)).toMatchObject({
34
+ configuredQueryBudget,
35
+ ...expected,
36
+ });
37
+ });
38
+
39
+ it('uses the default and clamps larger configured budgets without changing page policy', () => {
40
+ expect(createVisibilityBudget()).toMatchObject({
41
+ configuredQueryBudget: DEFAULT_CONFIGURED_QUERY_BUDGET,
42
+ effectiveQueryBudget: DEFAULT_CONFIGURED_QUERY_BUDGET,
43
+ });
44
+ expect(createVisibilityBudget(MAX_QUERY_BUDGET + 1).effectiveQueryBudget).toBe(
45
+ MAX_QUERY_BUDGET,
46
+ );
47
+ });
48
+
49
+ it.each([
50
+ 0,
51
+ -1,
52
+ 1.5,
53
+ Number.NaN,
54
+ Number.POSITIVE_INFINITY,
55
+ ])('rejects invalid configured budget %s', (configuredQueryBudget) => {
56
+ expect(() => createVisibilityBudget(configuredQueryBudget)).toThrow(
57
+ 'configuredQueryBudget must be a positive safe integer',
58
+ );
59
+ });
60
+
61
+ it.each([1, 2, 3, 4, 8])('keeps derived windows independent of %d LOD levels', (levels) => {
62
+ const budget = createVisibilityBudget(2048);
63
+ expect({ levels, ...budget }).toMatchObject({
64
+ levels,
65
+ settleSubmits: 98,
66
+ retestSubmits: 44,
67
+ expirySubmits: 88,
68
+ });
69
+ });
70
+ });
@@ -1,5 +1,10 @@
1
1
  import { World } from '@forgeax/engine-ecs';
2
- import { ChildOf, registerPropagateTransforms, Transform } from '@forgeax/engine-scene';
2
+ import {
3
+ ChildOf,
4
+ GlobalTransform,
5
+ registerPropagateTransforms,
6
+ Transform,
7
+ } from '@forgeax/engine-scene';
3
8
  import { describe, expect, it, vi } from 'vitest';
4
9
  import { Fog } from '../components/fog';
5
10
  import { Visibility, VisibilityStateValue } from '../components/visibility';
@@ -67,13 +72,13 @@ describe('visibility extract orchestration', () => {
67
72
  const snapshot = frame.visibilitySnapshots[0];
68
73
  expect(snapshot?.get(parent)?.effective).toBe('visible');
69
74
  expect(snapshot?.get(child)?.effective).toBe('visible');
70
- expect(world.get(child, Transform).unwrap().world[12]).toBeCloseTo(3);
75
+ expect(world.get(child, GlobalTransform).unwrap().world[12]).toBeCloseTo(3);
71
76
  });
72
77
 
73
- it('keeps renderer extraction read-only over derived Transform.world', () => {
78
+ it('keeps renderer extraction read-only over derived GlobalTransform.world', () => {
74
79
  const { world, parent, child } = makeWorld();
75
80
  world.update(0).unwrap();
76
- const before = [...world.get(child, Transform).unwrap().world];
81
+ const before = [...world.get(child, GlobalTransform).unwrap().world];
77
82
  const beforeInspection = world.inspect();
78
83
  const beforeShape = {
79
84
  entityCount: beforeInspection.entityCount,
@@ -87,7 +92,7 @@ describe('visibility extract orchestration', () => {
87
92
  world.set(parent, Transform, { pos: [9, 0, 0] }).unwrap();
88
93
  extractFrames([world], 0);
89
94
 
90
- expect([...world.get(child, Transform).unwrap().world]).toEqual(before);
95
+ expect([...world.get(child, GlobalTransform).unwrap().world]).toEqual(before);
91
96
  const afterInspection = world.inspect();
92
97
  expect({
93
98
  entityCount: afterInspection.entityCount,
@@ -98,7 +103,7 @@ describe('visibility extract orchestration', () => {
98
103
  resourceKeys: afterInspection.resourceKeys,
99
104
  }).toEqual(beforeShape);
100
105
  world.update(0).unwrap();
101
- expect(world.get(child, Transform).unwrap().world[12]).toBeCloseTo(11);
106
+ expect(world.get(child, GlobalTransform).unwrap().world[12]).toBeCloseTo(11);
102
107
  });
103
108
 
104
109
  it('keeps direct prepared-kernel output aligned with extractFrames output', () => {
@@ -13,8 +13,10 @@ const passes = readFileSync(new URL('../volume/passes.ts', import.meta.url), 'ut
13
13
 
14
14
  describe('volumetric fog Point and Spot accumulation', () => {
15
15
  it('accumulates Point and Spot in one fixed inject stage', () => {
16
- expect(inject).toContain('pointLightsBuffer');
17
- expect(inject).toContain('spotLightsBuffer');
16
+ expect(inject).toContain('light_data');
17
+ expect(inject).toContain('cluster_uniform');
18
+ expect(inject).not.toContain('pointLightsBuffer');
19
+ expect(inject).not.toContain('spotLightsBuffer');
18
20
  expect(inject).toContain('evalVolumePoint');
19
21
  expect(inject).toContain('evalVolumeSpot');
20
22
  expect(inject).toContain('shadow_visibility');
@@ -37,7 +39,8 @@ describe('volumetric fog Point and Spot accumulation', () => {
37
39
  });
38
40
 
39
41
  it('retains falsifier hooks for off lights, occluders, and shadow visibility', () => {
40
- expect(inject).toContain('count');
42
+ expect(inject).toContain('selected_cluster_light_slot');
43
+ expect(inject).toContain('cluster_uniform.grid.w');
41
44
  expect(inject).toContain('shadowAtlasTile');
42
45
  expect(inject).toContain('return 0.0');
43
46
  expect(integrate).toContain('evalSpotAttenuation');
@@ -2,12 +2,7 @@ import type { RhiDevice, Texture, TextureView } from '@forgeax/engine-rhi';
2
2
  import { createShaderModule, rhi } from '@forgeax/engine-rhi-webgpu';
3
3
  import { buildEngineShaderManifest } from '@forgeax/engine-vite-plugin-shader';
4
4
  import { describe, expect, it } from 'vitest';
5
- import {
6
- LIGHT_ARRAY_HEADER_BYTES,
7
- LIGHT_ARRAY_MAX_SLOTS,
8
- POINT_LIGHT_STD430_BYTES,
9
- SPOT_LIGHT_STD430_BYTES,
10
- } from '../light-buffer-layout';
5
+ import { BYTES_PER_DIRECT_LIGHT_SLOT } from '../light-buffer-layout';
11
6
 
12
7
  const MAP_READ = 0x0001;
13
8
  const BUFFER_COPY_DST = 0x0008;
@@ -21,6 +16,9 @@ const SIZE = 8;
21
16
  const PACKED_LAYERS = Math.ceil(SIZE / 4);
22
17
  const BYTES_PER_ROW = 256;
23
18
  const BYTES_PER_PIXEL = 8;
19
+ const MAX_CLUSTER_LIGHTS = 256;
20
+ const CLUSTER_LIGHT_DATA_BYTES = MAX_CLUSTER_LIGHTS * BYTES_PER_DIRECT_LIGHT_SLOT;
21
+ const CLUSTER_UNIFORM_BYTES = 32;
24
22
  const engineManifest = await buildEngineShaderManifest();
25
23
 
26
24
  interface StageValues {
@@ -190,15 +188,15 @@ async function runInjectReadback(sceneDepthClear = 1): Promise<VolumeStageReadba
190
188
  size: 128,
191
189
  usage: 0x0040 | BUFFER_COPY_DST,
192
190
  });
193
- const spotLightsBuffer = device.createBuffer({
194
- label: 'stage-readback.spot-lights',
195
- size: LIGHT_ARRAY_HEADER_BYTES + LIGHT_ARRAY_MAX_SLOTS * SPOT_LIGHT_STD430_BYTES,
191
+ const lightDataBuffer = device.createBuffer({
192
+ label: 'stage-readback.cluster-light-data',
193
+ size: CLUSTER_LIGHT_DATA_BYTES,
196
194
  usage: STORAGE_BUFFER | BUFFER_COPY_DST,
197
195
  });
198
- const pointLightsBuffer = device.createBuffer({
199
- label: 'stage-readback.point-lights',
200
- size: LIGHT_ARRAY_HEADER_BYTES + LIGHT_ARRAY_MAX_SLOTS * POINT_LIGHT_STD430_BYTES,
201
- usage: STORAGE_BUFFER | BUFFER_COPY_DST,
196
+ const clusterUniformBuffer = device.createBuffer({
197
+ label: 'stage-readback.cluster-uniform',
198
+ size: CLUSTER_UNIFORM_BYTES,
199
+ usage: 0x0040 | BUFFER_COPY_DST,
202
200
  });
203
201
  const injectReadback = device.createBuffer({
204
202
  label: 'stage-readback.inject',
@@ -218,8 +216,8 @@ async function runInjectReadback(sceneDepthClear = 1): Promise<VolumeStageReadba
218
216
  if (
219
217
  !viewBuffer.ok ||
220
218
  !paramsBuffer.ok ||
221
- !spotLightsBuffer.ok ||
222
- !pointLightsBuffer.ok ||
219
+ !lightDataBuffer.ok ||
220
+ !clusterUniformBuffer.ok ||
223
221
  !injectReadback.ok ||
224
222
  !temporalReadback.ok ||
225
223
  !integrateReadback.ok
@@ -245,19 +243,22 @@ async function runInjectReadback(sceneDepthClear = 1): Promise<VolumeStageReadba
245
243
  paramsData.set([0, -1, 0, 0], 20);
246
244
  paramsData.set([1, 1, 1, 0], 24);
247
245
  paramsData.set([2, 0, 0, 0], 28);
246
+ const lightData = new Uint8Array(CLUSTER_LIGHT_DATA_BYTES);
247
+ const clusterUniformData = new Float32Array(8);
248
+ const clusterGrid = new Uint32Array(clusterUniformData.buffer);
249
+ clusterGrid[0] = 1;
250
+ clusterGrid[1] = 1;
251
+ clusterGrid[2] = 1;
252
+ clusterGrid[3] = 1;
248
253
  const viewWrite = device.queue.writeBuffer(viewBuffer.value, 0, viewData);
249
254
  const paramsWrite = device.queue.writeBuffer(paramsBuffer.value, 0, paramsData);
250
- const spotLightsWrite = device.queue.writeBuffer(
251
- spotLightsBuffer.value,
252
- 0,
253
- new Uint32Array([0, 0, 0, 0]),
254
- );
255
- const pointLightsWrite = device.queue.writeBuffer(
256
- pointLightsBuffer.value,
255
+ const lightDataWrite = device.queue.writeBuffer(lightDataBuffer.value, 0, lightData);
256
+ const clusterUniformWrite = device.queue.writeBuffer(
257
+ clusterUniformBuffer.value,
257
258
  0,
258
- new Uint32Array([0, 0, 0, 0]),
259
+ clusterUniformData,
259
260
  );
260
- if (!viewWrite.ok || !paramsWrite.ok || !spotLightsWrite.ok || !pointLightsWrite.ok)
261
+ if (!viewWrite.ok || !paramsWrite.ok || !lightDataWrite.ok || !clusterUniformWrite.ok)
261
262
  throw new Error('Dawn volume stage readback unavailable: uniform upload failed');
262
263
  const densityData = new Uint8Array((BYTES_PER_PIXEL / 2) * SIZE * SIZE * SIZE);
263
264
  densityData.fill(255);
@@ -291,6 +292,7 @@ async function runInjectReadback(sceneDepthClear = 1): Promise<VolumeStageReadba
291
292
  storageTexture: { access: 'write-only', format: 'rgba8unorm', viewDimension: '2d-array' },
292
293
  },
293
294
  { binding: 7, visibility: 4, buffer: { type: 'read-only-storage' } },
295
+ { binding: 8, visibility: 4, buffer: { type: 'uniform' } },
294
296
  ],
295
297
  });
296
298
  if (!layout.ok) throw layout.error;
@@ -354,7 +356,7 @@ async function runInjectReadback(sceneDepthClear = 1): Promise<VolumeStageReadba
354
356
  storageTexture: { access: 'write-only', format: 'rgba16float', viewDimension: '2d' },
355
357
  },
356
358
  { binding: 10, visibility: 4, buffer: { type: 'read-only-storage' } },
357
- { binding: 11, visibility: 4, buffer: { type: 'read-only-storage' } },
359
+ { binding: 11, visibility: 4, buffer: { type: 'uniform' } },
358
360
  { binding: 12, visibility: 4, texture: { sampleType: 'float', viewDimension: '2d' } },
359
361
  { binding: 13, visibility: 4, sampler: { type: 'filtering' } },
360
362
  ],
@@ -393,7 +395,8 @@ async function runInjectReadback(sceneDepthClear = 1): Promise<VolumeStageReadba
393
395
  { binding: 4, resource: { kind: 'sampler', value: comparisonSampler.value } },
394
396
  { binding: 5, resource: { kind: 'buffer', value: { buffer: paramsBuffer.value } } },
395
397
  { binding: 6, resource: { kind: 'textureView', value: outputView } },
396
- { binding: 7, resource: { kind: 'buffer', value: { buffer: spotLightsBuffer.value } } },
398
+ { binding: 7, resource: { kind: 'buffer', value: { buffer: lightDataBuffer.value } } },
399
+ { binding: 8, resource: { kind: 'buffer', value: { buffer: clusterUniformBuffer.value } } },
397
400
  ],
398
401
  });
399
402
  if (!bindings.ok) throw bindings.error;
@@ -420,8 +423,8 @@ async function runInjectReadback(sceneDepthClear = 1): Promise<VolumeStageReadba
420
423
  { binding: 7, resource: { kind: 'sampler', value: densitySampler.value } },
421
424
  { binding: 8, resource: { kind: 'textureView', value: historyView } },
422
425
  { binding: 9, resource: { kind: 'textureView', value: temporalView } },
423
- { binding: 10, resource: { kind: 'buffer', value: { buffer: spotLightsBuffer.value } } },
424
- { binding: 11, resource: { kind: 'buffer', value: { buffer: pointLightsBuffer.value } } },
426
+ { binding: 10, resource: { kind: 'buffer', value: { buffer: lightDataBuffer.value } } },
427
+ { binding: 11, resource: { kind: 'buffer', value: { buffer: clusterUniformBuffer.value } } },
425
428
  { binding: 12, resource: { kind: 'textureView', value: projectorView } },
426
429
  { binding: 13, resource: { kind: 'sampler', value: densitySampler.value } },
427
430
  ],
@@ -219,7 +219,9 @@ describe('volumetric fog RenderGraph topology', () => {
219
219
  fileURLToPath(new URL('../render-system.ts', import.meta.url)),
220
220
  'utf8',
221
221
  );
222
- const recoverStart = renderSystemSource.indexOf('resetForRecover(): void {');
222
+ const recoverStart = renderSystemSource.indexOf(
223
+ 'resetForRecover(retiringPipelineState?: PipelineState, replacementDevice?: RhiDevice): void {',
224
+ );
223
225
  expect(recoverStart).toBeGreaterThanOrEqual(0);
224
226
  const recoverEnd = renderSystemSource.indexOf(
225
227
  'restorePostProcessResources(): void',
@@ -10,6 +10,19 @@ import type {
10
10
  /** Optional host hooks for recorder and device-lifecycle capabilities. */
11
11
  export interface RhiBackendInstrumentation {
12
12
  readonly resolveSurfaceDevice?: (device: RhiDevice) => Result<RhiDevice, RhiError>;
13
+ /**
14
+ * Optional deterministic submit fault seam for backend-owned integration
15
+ * fixtures. The callback runs after `finish()` and before the queue submit;
16
+ * returning an error aborts the frame transaction without changing the
17
+ * production queue contract.
18
+ */
19
+ readonly beforeSubmit?: (device: RhiDevice) => RhiError | undefined;
20
+ /**
21
+ * Optional device-loss projection for deterministic recovery fixtures. A
22
+ * backend may compose this promise with its native `device.lost` promise;
23
+ * normal production packs leave it undefined and use the native signal.
24
+ */
25
+ readonly deviceLost?: (device: RhiDevice) => RhiDevice['lost'];
13
26
  readonly onFrameBoundary?: () => void;
14
27
  readonly onDeviceLost?: () => void;
15
28
  }
@@ -0,0 +1,9 @@
1
+ import type { ImportTransport } from '@forgeax/engine-types';
2
+
3
+ /** Build-tool inputs forwarded from the host into renderer assembly. */
4
+ export interface BundlerOptions {
5
+ readonly importTransport?: ImportTransport | undefined;
6
+ readonly shaderManifestUrl?: string | undefined;
7
+ /** Exact checkout revision emitted by the build-tool adapter. */
8
+ readonly build?: string | undefined;
9
+ }
@@ -1,4 +1,5 @@
1
1
  import type { RhiAdapter, RhiDevice } from '@forgeax/engine-rhi';
2
+ import { EXTENDED_LIGHTING_REQUIRED_SAMPLED_TEXTURES } from '../prepare/extended-lighting/resources';
2
3
 
3
4
  const COMPRESSION_FEATURES: GPUFeatureName[] = [
4
5
  'texture-compression-bc',
@@ -9,8 +10,18 @@ const COMPRESSION_FEATURES: GPUFeatureName[] = [
9
10
  // The Standard transmission fragment ABI needs 17 sampled textures across its
10
11
  // material, IBL, clustered-light, and SSAO bindings. Ordinary Standard draws
11
12
  // use the non-transmission variant and remain valid on the WebGPU minimum of
12
- // 16; only request the elevated limit when the adapter can provide it.
13
+ // 16. The extended-lighting topology reserves 20, so a device descriptor must
14
+ // request that larger limit when the adapter can provide it; adapter limits are
15
+ // not automatically inherited by requestDevice().
13
16
  export const STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES = 17;
17
+ /**
18
+ * The complete Standard physical root can declare all optional texture slots.
19
+ * Its material group therefore needs one more sampled-texture entry than the
20
+ * extended-lighting topology alone. Request this ceiling when the adapter can
21
+ * provide it; lower-capability devices remain fail-closed at material
22
+ * pipeline admission instead of receiving an invalid WebGPU layout.
23
+ */
24
+ export const STANDARD_PHYSICAL_REQUIRED_SAMPLED_TEXTURES = 21;
14
25
 
15
26
  export interface DeviceFeatureAdmissionOptions {
16
27
  readonly gpuPassTiming?: object | undefined;
@@ -36,18 +47,24 @@ export function deriveDeviceFeatureAdmission(
36
47
  if (timestampRequested && adapter.features.has('timestamp-query')) {
37
48
  requiredFeatures.push('timestamp-query');
38
49
  }
39
- const supportsTransmission =
40
- (adapter.limits?.maxSampledTexturesPerShaderStage ?? 0) >=
41
- STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES;
50
+ const adapterSampledTextureLimit = adapter.limits?.maxSampledTexturesPerShaderStage ?? 0;
51
+ const requiredSampledTextureLimit =
52
+ adapterSampledTextureLimit >= STANDARD_PHYSICAL_REQUIRED_SAMPLED_TEXTURES
53
+ ? STANDARD_PHYSICAL_REQUIRED_SAMPLED_TEXTURES
54
+ : adapterSampledTextureLimit >= EXTENDED_LIGHTING_REQUIRED_SAMPLED_TEXTURES
55
+ ? EXTENDED_LIGHTING_REQUIRED_SAMPLED_TEXTURES
56
+ : adapterSampledTextureLimit >= STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES
57
+ ? STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES
58
+ : undefined;
42
59
  return {
43
60
  requiredFeatures,
44
- ...(supportsTransmission
45
- ? {
61
+ ...(requiredSampledTextureLimit === undefined
62
+ ? {}
63
+ : {
46
64
  requiredLimits: {
47
- maxSampledTexturesPerShaderStage: STANDARD_PBR_REQUIRED_SAMPLED_TEXTURES,
65
+ maxSampledTexturesPerShaderStage: requiredSampledTextureLimit,
48
66
  },
49
- }
50
- : {}),
67
+ }),
51
68
  };
52
69
  }
53
70