@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
@@ -25,7 +25,10 @@ import {
25
25
  } from '../ibl/skylight-bind-group';
26
26
  import type { InstanceBufferCacheEntry } from '../instance-buffer-cache';
27
27
  import { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';
28
- import { SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET } from '../pbr-pipeline';
28
+ import {
29
+ isStandardPbrMaterialShader,
30
+ SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET,
31
+ } from '../pbr-pipeline';
29
32
  import {
30
33
  buildBeginRenderPassDescriptor,
31
34
  standardTopologyVariantSet,
@@ -33,6 +36,7 @@ import {
33
36
  } from '../pipeline-spec';
34
37
  import type { MaterialSnapshot, SpriteInstancesSnapshot } from '../render-system-extract';
35
38
  import { worldEntityKey } from './frame-snapshot';
39
+ import { resolveGeometryInstancesBindGroup, resolveProbeBlendBuffer } from './main-pass-geometry';
36
40
  import {
37
41
  BUILTIN_USER_REGION_TEXTURE_FIELDS,
38
42
  defaultViewForUserRegionField,
@@ -463,7 +467,7 @@ function recordSpriteTransparentPbrDraws(
463
467
  ) => BindGroup,
464
468
  meshGroup2: BindGroup | null,
465
469
  ): void {
466
- const { runtime, pipelineState, frameState, bindGroupCounts, validatedOrdered } = c;
470
+ const { runtime, pipelineState, validatedOrdered } = c;
467
471
  const isHdrTarget =
468
472
  c.tonemapActive || transparentPassColorFormat(c, pipelineState) === 'rgba16float';
469
473
  let lastPbrSubPipelineHandle: typeof pipelineState.unlitPipeline = null;
@@ -497,48 +501,6 @@ function recordSpriteTransparentPbrDraws(
497
501
  spritePass.setIndexBuffer(entry.mesh.indexBuffer.handle, entry.mesh.indexFormat);
498
502
  lastPbrSubIndexBuffer = entry.mesh.indexBuffer;
499
503
  }
500
- // Identity instance BG (instanceCount=1); reuse the per-entity cache.
501
- const identityInstBg: BindGroup = getOrCreatePerEntity(
502
- frameState.instancesBgPerEntity,
503
- worldEntityKey(entry.source.worldId, entry.source.entityKey),
504
- [pipelineState.identityInstanceBuffer],
505
- 'instances',
506
- () => {
507
- const result = runtime.device.createBindGroup({
508
- label: 'pbr-transparent-sub-instances-bg',
509
- layout: pipelineState.instancesBindGroupLayout,
510
- entries: [
511
- {
512
- binding: 0,
513
- resource: {
514
- kind: 'buffer',
515
- value: { buffer: pipelineState.identityInstanceBuffer },
516
- },
517
- },
518
- ],
519
- });
520
- if (!result.ok) throw result.error;
521
- return result.value;
522
- },
523
- bindGroupCounts,
524
- );
525
- spritePass.setBindGroup(3, identityInstBg);
526
-
527
- const subVariantSet = standardTopologyVariantSet(
528
- c.standardLighting,
529
- runtime.device.caps.storageBuffer,
530
- entry.mesh.layoutProjection.attributes.some((attribute) => attribute.key === 'color'),
531
- );
532
- const projectionVariantSetResult = variantSetFromVertexLayoutProjection(
533
- entry.mesh.layoutProjection,
534
- subVariantSet,
535
- );
536
- if (!projectionVariantSetResult.ok) {
537
- runtime.errorRegistry.fire(projectionVariantSetResult.error);
538
- continue;
539
- }
540
- const projectionVariantSet = projectionVariantSetResult.value;
541
-
542
504
  for (let smIdx = 0; smIdx < entry.mesh.submeshes.length; smIdx++) {
543
505
  const sm = entry.mesh.submeshes[smIdx];
544
506
  if (sm === undefined) continue;
@@ -549,6 +511,39 @@ function recordSpriteTransparentPbrDraws(
549
511
  if (submeshMaterial.transparent !== true) continue;
550
512
  const smShaderId = submeshMaterial.materialShaderId;
551
513
  if (smShaderId === undefined) continue;
514
+ const probeBlendAvailable =
515
+ runtime.device.caps.storageBuffer &&
516
+ entry.source.probeBlendRecord !== undefined &&
517
+ isStandardPbrMaterialShader(smShaderId);
518
+ const probeBinding = probeBlendAvailable
519
+ ? resolveProbeBlendBuffer(
520
+ c,
521
+ entry.source.probeBlendRecord,
522
+ worldEntityKey(entry.source.worldId, entry.source.entityKey),
523
+ )
524
+ : undefined;
525
+ const identityInstBg = resolveGeometryInstancesBindGroup(
526
+ c,
527
+ pipelineState.identityInstanceBuffer,
528
+ probeBinding?.buffer,
529
+ );
530
+ if (probeBinding === undefined) spritePass.setBindGroup(3, identityInstBg);
531
+ else spritePass.setBindGroup(3, identityInstBg, [probeBinding.offset]);
532
+ const subVariantSet = standardTopologyVariantSet(
533
+ c.standardLighting,
534
+ runtime.device.caps.storageBuffer,
535
+ entry.mesh.layoutProjection.attributes.some((attribute) => attribute.key === 'color'),
536
+ probeBlendAvailable,
537
+ );
538
+ const projectionVariantSetResult = variantSetFromVertexLayoutProjection(
539
+ entry.mesh.layoutProjection,
540
+ subVariantSet,
541
+ );
542
+ if (!projectionVariantSetResult.ok) {
543
+ runtime.errorRegistry.fire(projectionVariantSetResult.error);
544
+ continue;
545
+ }
546
+ const projectionVariantSet = projectionVariantSetResult.value;
552
547
  const subPipelineEntry =
553
548
  c.runtime.getMaterialShaderPipelineEntry?.(
554
549
  smShaderId,
@@ -722,12 +717,10 @@ function recordSpriteEntityDraws(
722
717
  spritePass.setVertexBuffer(0, spriteEntry.mesh.vertexBuffer.handle);
723
718
  lastSpriteVertexBuffer = spriteEntry.mesh.vertexBuffer;
724
719
  }
725
- if (
726
- spriteEntry.mesh.indexBuffer !== null &&
727
- spriteEntry.mesh.indexBuffer !== lastSpriteIndexBuffer
728
- ) {
729
- spritePass.setIndexBuffer(spriteEntry.mesh.indexBuffer.handle, spriteEntry.mesh.indexFormat);
730
- lastSpriteIndexBuffer = spriteEntry.mesh.indexBuffer;
720
+ const indexBuffer = spriteEntry.mesh.indexBuffer;
721
+ if (indexBuffer !== null && indexBuffer !== lastSpriteIndexBuffer) {
722
+ spritePass.setIndexBuffer(indexBuffer.handle, spriteEntry.mesh.indexFormat);
723
+ lastSpriteIndexBuffer = indexBuffer;
731
724
  }
732
725
 
733
726
  // Instance buffer resolution: same cap-gate logic as the geometry
@@ -837,21 +830,15 @@ function recordSpriteEntityDraws(
837
830
  );
838
831
  spriteInstanceCount = spriteInst.instanceCount;
839
832
  spriteInstanceBuffer = pipelineState.identityInstanceBuffer;
840
- const spriteInstBgResult = runtime.device.createBindGroup({
841
- label: 'sprite-pass-instances-bg',
842
- layout: pipelineState.instancesBindGroupLayout,
843
- entries: [
844
- {
845
- binding: 0,
846
- resource: {
847
- kind: 'buffer',
848
- value: { buffer: spriteInstanceBuffer },
849
- },
850
- },
851
- ],
852
- });
853
- if (!spriteInstBgResult.ok) throw spriteInstBgResult.error;
854
- spritePass.setBindGroup(3, spriteInstBgResult.value as BindGroup);
833
+ // Sprite shaders do not declare the Standard PBR Probe ABI. A
834
+ // retained scene record must therefore not change their group(3)
835
+ // bind-group shape.
836
+ const spriteInstBg = resolveGeometryInstancesBindGroup(
837
+ c,
838
+ spriteInstanceBuffer,
839
+ undefined,
840
+ );
841
+ spritePass.setBindGroup(3, spriteInstBg);
855
842
  spritePass.drawIndexed(spriteEntry.mesh.indexCount, spriteInstanceCount, 0, 0, 0);
856
843
  continue;
857
844
  }
@@ -959,35 +946,15 @@ function recordSpriteEntityDraws(
959
946
  ? c.hdrpClusterBindGroup
960
947
  : meshBindGroup;
961
948
 
962
- // M3 / w12: LDR sprite split pass per-entity instances BG cache.
963
- // Same pattern as #7.
964
- const spriteInstancesBg: BindGroup = getOrCreatePerEntity(
965
- frameState.instancesBgPerEntity,
966
- worldEntityKey(spriteEntry.source.worldId, spriteEntry.source.entityKey),
967
- [spriteInstanceBuffer],
968
- 'instances',
969
- () => {
970
- const result = runtime.device.createBindGroup({
971
- label: 'sprite-pass-instances-bg',
972
- layout: pipelineState.instancesBindGroupLayout,
973
- entries: [
974
- {
975
- binding: 0,
976
- resource: {
977
- kind: 'buffer',
978
- value: { buffer: spriteInstanceBuffer },
979
- },
980
- },
981
- ],
982
- });
983
- if (!result.ok) throw result.error;
984
- return result.value;
985
- },
986
- bindGroupCounts,
987
- );
949
+ // M3 / w12: LDR sprite split pass per-entity instances BG cache. Sprite
950
+ // shaders do not declare the Standard PBR Probe ABI, so retained probe
951
+ // records stay out of this bind-group path.
952
+ const spriteInstancesBg = resolveGeometryInstancesBindGroup(c, spriteInstanceBuffer, undefined);
988
953
 
989
954
  spritePass.setBindGroup(2, spriteGroup2 as BindGroup, [i * MESH_PER_ENTITY_STRIDE]);
990
955
 
956
+ const materialSlot = materialSlotIndices[i]?.[0] ?? 0;
957
+
991
958
  // Per-entity sprite material bind group: same standard PBR user-region
992
959
  // layout as in the geometry pass sprite branch + Skylight merged entries
993
960
  // the geometry pass sprite branch + Skylight merged entries (same
@@ -1032,7 +999,6 @@ function recordSpriteEntityDraws(
1032
999
  bindGroupCounts,
1033
1000
  );
1034
1001
 
1035
- const materialSlot = materialSlotIndices[i]?.[0] ?? 0;
1036
1002
  spritePass.setBindGroup(1, spritePassBg, [materialSlot * MATERIAL_PER_ENTITY_STRIDE]);
1037
1003
  spritePass.setBindGroup(3, spriteInstancesBg);
1038
1004
  spritePass.drawIndexed(spriteEntry.mesh.indexCount, spriteInstanceCount, 0, 0, 0);
@@ -16,6 +16,7 @@ import type { ReflectionProbeSelectionResult } from '../reflection/projection';
16
16
  import type { RenderRecordPhase } from '../render-contract';
17
17
  import type { MaterialSnapshot } from '../render-system-extract';
18
18
  import { resolveReflectionProbeBinding } from './frame-lighting';
19
+ import { getOpaqueResourceIdentity } from './frame-snapshot';
19
20
  import { recordGeometryDraws } from './main-pass-geometry';
20
21
  import {
21
22
  applyMaterialTextureUvScales,
@@ -42,6 +43,18 @@ export function standardReflectionProbeIndex(
42
43
 
43
44
  const ZERO_SKYLIGHT_PAYLOAD = new Float32Array([0, 0, 0, 0, 0, 0, 0, 1]);
44
45
 
46
+ function materialDiagnosticsEnabled(): boolean {
47
+ if (typeof globalThis !== 'object' || globalThis === null || !('process' in globalThis)) {
48
+ return false;
49
+ }
50
+ const processValue = (
51
+ globalThis as {
52
+ readonly process?: { readonly env?: Record<string, string | undefined> };
53
+ }
54
+ ).process;
55
+ return processValue?.env?.FORGEAX_MATERIAL_DIAGNOSTICS === '1';
56
+ }
57
+
45
58
  export type MainPassOptions = {
46
59
  readonly colorViews?: readonly (TextureView | null)[];
47
60
  readonly colorFormats?: readonly GPUTextureFormat[];
@@ -52,8 +65,6 @@ export type MainPassOptions = {
52
65
  readonly transmissionBackdropView?: TextureView | null;
53
66
  };
54
67
 
55
- const TRANSMISSION_VARIANT_SET = 'TRANSMISSION_AVAILABLE=true';
56
-
57
68
  function isTransmissionMaterial(material: MaterialSnapshot): boolean {
58
69
  return (
59
70
  material.materialShaderId === 'forgeax::default-standard-pbr' &&
@@ -284,10 +295,6 @@ export function recordMainPass(
284
295
  : {
285
296
  ...c,
286
297
  splitLdrSprite: recordMode === 'transparent' ? false : c.splitLdrSprite,
287
- validatedOrdered: c.validatedOrdered.map((entry) => ({
288
- ...entry,
289
- ...(recordMode === 'transmission' ? { variantSet: TRANSMISSION_VARIANT_SET } : {}),
290
- })),
291
298
  };
292
299
 
293
300
  if (clusteredBindGroupMissing) {
@@ -420,6 +427,64 @@ export function recordMainPass(
420
427
  brdfLutSampler: skylightFallback.sampler,
421
428
  intensityBuffer: skylightFallback.intensityBuffer,
422
429
  };
430
+ if (materialDiagnosticsEnabled()) {
431
+ const activeCache =
432
+ activeViews === undefined ? undefined : getOrCreateIblCache(runtime.deviceScope);
433
+ const prefilterViewMipCount =
434
+ activeCache?.prefilterFaceViewsByMip?.length ?? (activeViews === undefined ? 1 : 0);
435
+ frameState.iblBindingInspection = {
436
+ status: 'binding-chain-consistent',
437
+ frameId: frameState.frameNumber,
438
+ deviceGeneration: runtime.deviceScope.generation,
439
+ active: activeViews === undefined ? 'fallback' : 'active',
440
+ cache: {
441
+ identity: getOpaqueResourceIdentity((activeCache ?? skylightFallback) as object),
442
+ generation: runtime.deviceScope.generation,
443
+ prefilterMipCount: prefilterViewMipCount,
444
+ prefilterViewMipCount,
445
+ },
446
+ sampler: {
447
+ expected: {
448
+ magFilter: 'linear',
449
+ minFilter: 'linear',
450
+ mipmapFilter: 'linear',
451
+ addressModeU: 'clamp-to-edge',
452
+ addressModeV: 'clamp-to-edge',
453
+ addressModeW: 'clamp-to-edge',
454
+ },
455
+ identities: [
456
+ getOpaqueResourceIdentity(skylightResources.irradianceSampler as object),
457
+ getOpaqueResourceIdentity(skylightResources.prefilterSampler as object),
458
+ getOpaqueResourceIdentity(skylightResources.brdfLutSampler as object),
459
+ ],
460
+ },
461
+ resources: {
462
+ irradiance: {
463
+ viewIdentity: getOpaqueResourceIdentity(skylightResources.irradianceView as object),
464
+ samplerIdentity: getOpaqueResourceIdentity(
465
+ skylightResources.irradianceSampler as object,
466
+ ),
467
+ deviceGeneration: runtime.deviceScope.generation,
468
+ },
469
+ prefilter: {
470
+ viewIdentity: getOpaqueResourceIdentity(skylightResources.prefilterView as object),
471
+ samplerIdentity: getOpaqueResourceIdentity(
472
+ skylightResources.prefilterSampler as object,
473
+ ),
474
+ deviceGeneration: runtime.deviceScope.generation,
475
+ },
476
+ brdfLut: {
477
+ viewIdentity: getOpaqueResourceIdentity(skylightResources.brdfLutView as object),
478
+ samplerIdentity: getOpaqueResourceIdentity(skylightResources.brdfLutSampler as object),
479
+ deviceGeneration: runtime.deviceScope.generation,
480
+ },
481
+ intensityBufferIdentity: getOpaqueResourceIdentity(
482
+ skylightResources.intensityBuffer as object,
483
+ ),
484
+ },
485
+ errors: [],
486
+ };
487
+ }
423
488
  // Per-entity material uploads (D-P9 retained path).
424
489
  // feat-20260613 fix-issue-1 (D-8 channelMap split): the payload mirrors
425
490
  // the post-split sidecar paramSchema for default-standard-pbr (14 entries
@@ -490,6 +555,7 @@ export function recordMainPass(
490
555
  },
491
556
  materialBgShared: frameState.materialBgShared,
492
557
  materialBgAssemblyCache: c.materialBgAssemblyCache,
558
+ frameState,
493
559
  bindGroupCounts,
494
560
  ...(transmissionBackdropView === undefined ? {} : { transmissionBackdropView }),
495
561
  };
@@ -551,6 +617,28 @@ export function recordMainPass(
551
617
  mat.materialParamSchema ??
552
618
  (materialShaderId !== undefined ? runtime.getParamSchema?.(materialShaderId) : undefined);
553
619
  applyParamSnapshotToUbo(slotPayloadF32, schema, mat.paramSnapshot);
620
+ const processValue = (
621
+ globalThis as {
622
+ process?: { env?: Record<string, string | undefined> };
623
+ }
624
+ ).process;
625
+ if (
626
+ processValue?.env?.FORGEAX_MATERIAL_PIPELINE_DIAGNOSTICS === '1' &&
627
+ (materialShaderId === 'forgeax::default-standard-pbr' ||
628
+ materialShaderId === 'forgeax::pbr-skin')
629
+ ) {
630
+ console.error(
631
+ `[render-material] UBO receipt: ${JSON.stringify({
632
+ entityIndex: entry.renderableIndex,
633
+ materialHandle: mat.materialHandle,
634
+ materialShaderId,
635
+ clearcoat: slotPayloadF32[32],
636
+ clearcoatRoughness: slotPayloadF32[33],
637
+ clearcoatNormalScale: slotPayloadF32[34],
638
+ paramSnapshot: mat.paramSnapshot,
639
+ })}`,
640
+ );
641
+ }
554
642
  applyMaterialTextureUvScales(slotPayloadF32, mat, world);
555
643
  // Missing-texture detection: structural debug-pink fallback overrides
556
644
  // the baseColor/colorTint slot when a bound baseColorTexture handle
@@ -79,12 +79,18 @@ export function extractEntryResourceHandle(entry: {
79
79
  return v as object;
80
80
  }
81
81
 
82
+ // Object-only terminal marker keeps a shorter resource chain from colliding
83
+ // with a longer chain that shares the same prefix.
84
+ const BIND_GROUP_CHAIN_LEAF_KEY: object = {};
85
+
82
86
  /**
83
87
  * feat-20260622-handle-to-id-allocator-elimination M2 / w7: walks a nested
84
88
  * WeakMap chain to find or create a BindGroup leaf. Each handle in the
85
- * `handles` array is a chain node; the final leaf is a Map<string, BindGroup>
86
- * keyed by `variant` (D-2). Chain keys are always object references, never
87
- * numeric ids GC reclaims entries for dead handles automatically.
89
+ * `handles` array is a chain node; a dedicated object terminal marker points
90
+ * to the final Map<string, BindGroup> keyed by `variant` (D-2). The marker
91
+ * prevents variable-depth chains with a shared prefix from treating a nested
92
+ * WeakMap as a leaf. Chain keys are always object references, never numeric
93
+ * ids — GC reclaims entries for dead handles automatically.
88
94
  *
89
95
  * On cache hit returns the cached BindGroup. On miss calls `factory`,
90
96
  * bumps `bindGroupCounts.createBindGroup`, stores the result at the leaf,
@@ -99,9 +105,7 @@ export function getOrCreateFromChain(
99
105
  counts: { createBindGroup: number; keys: string[] },
100
106
  ): BindGroup {
101
107
  let node = root;
102
- for (let i = 0; i < handles.length - 1; i++) {
103
- // biome-ignore lint/style/noNonNullAssertion: handles length guards the index
104
- const h = handles[i]!;
108
+ for (const h of handles) {
105
109
  let next = node.get(h) as WeakMap<object, unknown> | undefined;
106
110
  if (next === undefined) {
107
111
  next = new WeakMap();
@@ -109,12 +113,10 @@ export function getOrCreateFromChain(
109
113
  }
110
114
  node = next;
111
115
  }
112
- // biome-ignore lint/style/noNonNullAssertion: known non-empty at call sites
113
- const last = handles[handles.length - 1]!;
114
- let leaf = node.get(last) as Map<string, BindGroup> | undefined;
116
+ let leaf = node.get(BIND_GROUP_CHAIN_LEAF_KEY) as Map<string, BindGroup> | undefined;
115
117
  if (leaf === undefined) {
116
118
  leaf = new Map();
117
- node.set(last, leaf);
119
+ node.set(BIND_GROUP_CHAIN_LEAF_KEY, leaf);
118
120
  }
119
121
  const hit = leaf.get(variant);
120
122
  if (hit !== undefined) return hit;
@@ -125,6 +127,26 @@ export function getOrCreateFromChain(
125
127
  return bg;
126
128
  }
127
129
 
130
+ /**
131
+ * Read a cached bind group using the same variable-depth chain contract as
132
+ * `getOrCreateFromChain`. Readers must traverse the terminal marker instead
133
+ * of assuming that the last handle directly stores the variant map.
134
+ */
135
+ export function findFromChain(
136
+ root: WeakMap<object, unknown>,
137
+ handles: readonly object[],
138
+ variant: string,
139
+ ): BindGroup | undefined {
140
+ let node = root;
141
+ for (const handle of handles) {
142
+ const next = node.get(handle);
143
+ if (next === undefined) return undefined;
144
+ node = next as WeakMap<object, unknown>;
145
+ }
146
+ const leaf = node.get(BIND_GROUP_CHAIN_LEAF_KEY) as Map<string, BindGroup> | undefined;
147
+ return leaf?.get(variant);
148
+ }
149
+
128
150
  /**
129
151
  * feat-20260622-handle-to-id-allocator-elimination M2 / w8: per-entity bind
130
152
  * group lookup-or-create helper (D-2). Two-step lookup: outer Map.get(outerKey)
@@ -325,6 +347,8 @@ export function isMeshSsboDevMode(): boolean {
325
347
  * @internal
326
348
  */
327
349
  let _meshSsboScratch = new Uint8Array(0);
350
+ /** @internal */
351
+ let _meshSsboScratchFloats = new Float32Array(0);
328
352
 
329
353
  /**
330
354
  * feat-20260704 M3/w21: per-renderable `entity_world` upload (batched). All N
@@ -358,60 +382,69 @@ export function uploadMeshSsboBatch(
358
382
  // Grow the module-scoped scratch monotonically; zero the used range.
359
383
  if (_meshSsboScratch.length < neededBytes) {
360
384
  _meshSsboScratch = new Uint8Array(neededBytes);
385
+ _meshSsboScratchFloats = new Float32Array(_meshSsboScratch.buffer);
361
386
  } else {
362
387
  _meshSsboScratch.fill(0, 0, neededBytes);
363
388
  }
364
389
  const normalMatrixScratch = mat3.create();
390
+ const strideFloats = MESH_PER_ENTITY_STRIDE / Float32Array.BYTES_PER_ELEMENT;
365
391
  for (let i = 0; i < slotCount; i++) {
366
392
  const entry = validatedOrdered[i];
367
393
  if (entry === undefined) continue;
368
- // Float32Array view into this entity's 256-byte slot (current world,
369
- // normal, previous world, and reactive metadata use 45 floats; the
370
- // remaining padding stays zero). Byte offset i*256 is always
371
- // 4-byte aligned since MESH_PER_ENTITY_STRIDE=256 is divisible by 4.
372
- const slot = new Float32Array(_meshSsboScratch.buffer, i * MESH_PER_ENTITY_STRIDE, 48);
394
+ // Address the reusable flat view directly. Constructing one typed-array
395
+ // wrapper per visible entity made this otherwise contiguous upload create
396
+ // tens of thousands of short-lived JS objects every frame.
397
+ const slot = i * strideFloats;
373
398
  const isFoldHead = foldDispatchPlan?.headBuckets.has(i) === true;
374
399
  if (isFoldHead) {
375
400
  // identity mat4
376
- slot[0] = 1;
377
- slot[5] = 1;
378
- slot[10] = 1;
379
- slot[15] = 1;
401
+ _meshSsboScratchFloats[slot] = 1;
402
+ _meshSsboScratchFloats[slot + 5] = 1;
403
+ _meshSsboScratchFloats[slot + 10] = 1;
404
+ _meshSsboScratchFloats[slot + 15] = 1;
380
405
  // identity mat3 normal (cols at slot offsets 16/20/24)
381
- slot[16] = 1;
382
- slot[20] = 1;
383
- slot[24] = 1;
406
+ _meshSsboScratchFloats[slot + 16] = 1;
407
+ _meshSsboScratchFloats[slot + 20] = 1;
408
+ _meshSsboScratchFloats[slot + 24] = 1;
384
409
  // Fold heads use the instance storage path; keep the mesh temporal
385
410
  // fields deterministic for shader variants that still read the slot.
386
- slot[28] = 1;
387
- slot[33] = 1;
388
- slot[38] = 1;
389
- slot[43] = 1;
390
- slot[44] = 1;
411
+ _meshSsboScratchFloats[slot + 28] = 1;
412
+ _meshSsboScratchFloats[slot + 33] = 1;
413
+ _meshSsboScratchFloats[slot + 38] = 1;
414
+ _meshSsboScratchFloats[slot + 43] = 1;
415
+ _meshSsboScratchFloats[slot + 44] = 1;
391
416
  } else {
392
417
  const worldFromLocal = entry.source.transform.world;
393
- for (let k = 0; k < 16; k++) slot[k] = worldFromLocal[k] ?? 0;
418
+ for (let k = 0; k < 16; k++) _meshSsboScratchFloats[slot + k] = worldFromLocal[k] ?? 0;
394
419
  const normal = mat3.normalMatrix(normalMatrixScratch, worldFromLocal);
395
- slot[16] = normal[0] ?? 0;
396
- slot[17] = normal[1] ?? 0;
397
- slot[18] = normal[2] ?? 0;
398
- slot[20] = normal[3] ?? 0;
399
- slot[21] = normal[4] ?? 0;
400
- slot[22] = normal[5] ?? 0;
401
- slot[24] = normal[6] ?? 0;
402
- slot[25] = normal[7] ?? 0;
403
- slot[26] = normal[8] ?? 0;
420
+ _meshSsboScratchFloats[slot + 16] = normal[0] ?? 0;
421
+ _meshSsboScratchFloats[slot + 17] = normal[1] ?? 0;
422
+ _meshSsboScratchFloats[slot + 18] = normal[2] ?? 0;
423
+ _meshSsboScratchFloats[slot + 20] = normal[3] ?? 0;
424
+ _meshSsboScratchFloats[slot + 21] = normal[4] ?? 0;
425
+ _meshSsboScratchFloats[slot + 22] = normal[5] ?? 0;
426
+ _meshSsboScratchFloats[slot + 24] = normal[6] ?? 0;
427
+ _meshSsboScratchFloats[slot + 25] = normal[7] ?? 0;
428
+ _meshSsboScratchFloats[slot + 26] = normal[8] ?? 0;
404
429
  const previousWorld = entry.source.temporal?.previousTransform.world ?? worldFromLocal;
405
- for (let k = 0; k < 16; k++) slot[28 + k] = previousWorld[k] ?? 0;
406
- const reactiveMaterial = entry.source.materials.some(
407
- (material) =>
430
+ for (let k = 0; k < 16; k++) {
431
+ _meshSsboScratchFloats[slot + 28 + k] = previousWorld[k] ?? 0;
432
+ }
433
+ let reactiveMaterial = false;
434
+ for (const material of entry.source.materials) {
435
+ const shader = material.materialShaderId;
436
+ if (
408
437
  material.transparent === true ||
409
- material.materialShaderId === 'forgeax::sprite' ||
410
- material.materialShaderId === 'forgeax::sprite-lit' ||
411
- (material.materialShaderId !== undefined &&
412
- !material.materialShaderId.startsWith('forgeax::')),
413
- );
414
- slot[44] = entry.source.temporal?.reactive === true || reactiveMaterial ? 1 : 0;
438
+ shader === 'forgeax::sprite' ||
439
+ shader === 'forgeax::sprite-lit' ||
440
+ (shader !== undefined && !shader.startsWith('forgeax::'))
441
+ ) {
442
+ reactiveMaterial = true;
443
+ break;
444
+ }
445
+ }
446
+ _meshSsboScratchFloats[slot + 44] =
447
+ entry.source.temporal?.reactive === true || reactiveMaterial ? 1 : 0;
415
448
  }
416
449
  }
417
450
  if (neededBytes > 0) {