@forgeax/engine-render 0.1.28 → 0.1.30

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 (768) hide show
  1. package/README.md +856 -126
  2. package/dist/assembly/atmosphere-shader-prewarm.d.ts +6 -0
  3. package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -0
  4. package/dist/assembly/device-feature-admission.d.ts +4 -3
  5. package/dist/assembly/device-feature-admission.d.ts.map +1 -1
  6. package/dist/assembly/dynamic-geometry-host.d.ts +27 -0
  7. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  8. package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
  9. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
  10. package/dist/assembly/factory.d.ts +3 -1
  11. package/dist/assembly/factory.d.ts.map +1 -1
  12. package/dist/assembly/gpu-driven-owner.d.ts +10 -0
  13. package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
  14. package/dist/assembly/host-contract.d.ts +14 -0
  15. package/dist/assembly/host-contract.d.ts.map +1 -1
  16. package/dist/assembly/material/assembly.d.ts +31 -1
  17. package/dist/assembly/material/assembly.d.ts.map +1 -1
  18. package/dist/assembly/material/pipeline-helpers.d.ts +24 -0
  19. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -0
  20. package/dist/assembly/material-shader-policy.d.ts +3 -1
  21. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  22. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  23. package/dist/assembly/recovery/failure-location.d.ts +12 -0
  24. package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
  25. package/dist/assembly/recovery/recovery-attempt.d.ts +1 -6
  26. package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -1
  27. package/dist/assembly/recovery/renderer-recover.d.ts +7 -4
  28. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  29. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  30. package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
  31. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
  32. package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
  33. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  34. package/dist/assembly/renderer-helpers.d.ts +3 -0
  35. package/dist/assembly/renderer-helpers.d.ts.map +1 -1
  36. package/dist/assembly/renderer-inspection.d.ts +4 -0
  37. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  38. package/dist/assembly/shader-prewarm-policy.d.ts +7 -1
  39. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
  40. package/dist/assembly/skin-palette-owner.d.ts +8 -0
  41. package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
  42. package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
  43. package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
  44. package/dist/assembly/webgpu-device-loss.d.ts +15 -0
  45. package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
  47. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
  48. package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
  49. package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
  50. package/dist/assembly/webgpu-ready.d.ts +7 -3
  51. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  52. package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
  53. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
  54. package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
  55. package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
  56. package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
  57. package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
  58. package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
  59. package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
  60. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
  61. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
  62. package/dist/assembly/webgpu-renderer.d.ts +7 -141
  63. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  64. package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
  65. package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
  66. package/dist/authoring.mjs +2 -2
  67. package/dist/capture/scene-projection.d.ts +41 -0
  68. package/dist/capture/scene-projection.d.ts.map +1 -0
  69. package/dist/{chunk-J52NMQKR.mjs → chunk-7MQ3XBSP.mjs} +1098 -844
  70. package/dist/chunk-7MQ3XBSP.mjs.map +1 -0
  71. package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
  72. package/dist/chunk-BLXGONR2.mjs.map +1 -0
  73. package/dist/{chunk-VSL23LZE.mjs → chunk-C3DDSXYK.mjs} +1188 -463
  74. package/dist/chunk-C3DDSXYK.mjs.map +1 -0
  75. package/dist/{chunk-IQMKJLNU.mjs → chunk-FUUO4UND.mjs} +443 -30
  76. package/dist/chunk-FUUO4UND.mjs.map +1 -0
  77. package/dist/{chunk-J6KACNOH.mjs → chunk-JRBDO2KB.mjs} +617 -7
  78. package/dist/chunk-JRBDO2KB.mjs.map +1 -0
  79. package/dist/{chunk-GE3SDD72.mjs → chunk-MDQJPY3T.mjs} +20 -40
  80. package/dist/chunk-MDQJPY3T.mjs.map +1 -0
  81. package/dist/{chunk-MYJ5RPJO.mjs → chunk-NO4WZCAH.mjs} +3 -3
  82. package/dist/chunk-NO4WZCAH.mjs.map +1 -0
  83. package/dist/{chunk-RBDBZ5R7.mjs → chunk-PA5DRJNI.mjs} +2 -2
  84. package/dist/chunk-PA5DRJNI.mjs.map +1 -0
  85. package/dist/{chunk-MBU4ZVE7.mjs → chunk-PSEQ6QPH.mjs} +4655 -892
  86. package/dist/chunk-PSEQ6QPH.mjs.map +1 -0
  87. package/dist/{chunk-JAASCMXA.mjs → chunk-S5UE2T5P.mjs} +289 -41
  88. package/dist/chunk-S5UE2T5P.mjs.map +1 -0
  89. package/dist/components/camera.d.ts +62 -2
  90. package/dist/components/camera.d.ts.map +1 -1
  91. package/dist/components/directional-light.d.ts +2 -2
  92. package/dist/components/dynamic-resolution.d.ts +15 -0
  93. package/dist/components/dynamic-resolution.d.ts.map +1 -0
  94. package/dist/components/index.d.ts +2 -0
  95. package/dist/components/index.d.ts.map +1 -1
  96. package/dist/components/instances.d.ts +6 -20
  97. package/dist/components/instances.d.ts.map +1 -1
  98. package/dist/components/light-helpers.d.ts.map +1 -1
  99. package/dist/components/reflection-probe.d.ts +1 -0
  100. package/dist/components/reflection-probe.d.ts.map +1 -1
  101. package/dist/components/scene-instance.d.ts +2 -1
  102. package/dist/components/scene-instance.d.ts.map +1 -1
  103. package/dist/components/screen-space-reflection.d.ts +14 -0
  104. package/dist/components/screen-space-reflection.d.ts.map +1 -0
  105. package/dist/components/skylight.d.ts +4 -1
  106. package/dist/components/skylight.d.ts.map +1 -1
  107. package/dist/construct-renderer.mjs +14809 -7570
  108. package/dist/construct-renderer.mjs.map +1 -1
  109. package/dist/device/device-scope.d.ts +2 -0
  110. package/dist/device/device-scope.d.ts.map +1 -1
  111. package/dist/device/gpu-residency.d.ts +3 -14
  112. package/dist/device/gpu-residency.d.ts.map +1 -1
  113. package/dist/dynamic-geometry.d.ts.map +1 -1
  114. package/dist/environment/background.d.ts +7 -0
  115. package/dist/environment/background.d.ts.map +1 -0
  116. package/dist/environment/ibl.d.ts +11 -0
  117. package/dist/environment/ibl.d.ts.map +1 -0
  118. package/dist/environment/storage.d.ts +14 -0
  119. package/dist/environment/storage.d.ts.map +1 -0
  120. package/dist/errors/gpu-driven.d.ts +6 -3
  121. package/dist/errors/gpu-driven.d.ts.map +1 -1
  122. package/dist/errors/render.d.ts +41 -4
  123. package/dist/errors/render.d.ts.map +1 -1
  124. package/dist/extract/camera.d.ts.map +1 -1
  125. package/dist/extract/contracts.d.ts +7 -0
  126. package/dist/extract/contracts.d.ts.map +1 -1
  127. package/dist/extract/gpu-driven.d.ts +50 -3
  128. package/dist/extract/gpu-driven.d.ts.map +1 -1
  129. package/dist/features/host.d.ts +23 -1
  130. package/dist/features/host.d.ts.map +1 -1
  131. package/dist/features/noise-texture.d.ts +17 -0
  132. package/dist/features/noise-texture.d.ts.map +1 -0
  133. package/dist/features/plan.d.ts +83 -2
  134. package/dist/features/plan.d.ts.map +1 -1
  135. package/dist/features/prepared-gpu-work.d.ts +37 -4
  136. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  137. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  138. package/dist/features/prepared-graphics.d.ts +5 -0
  139. package/dist/features/prepared-graphics.d.ts.map +1 -1
  140. package/dist/features/render-graph-compute.d.ts +5 -3
  141. package/dist/features/render-graph-compute.d.ts.map +1 -1
  142. package/dist/features/render-graph-contribution.d.ts +11 -3
  143. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  144. package/dist/features/render-graph-raster.d.ts +19 -3
  145. package/dist/features/render-graph-raster.d.ts.map +1 -1
  146. package/dist/features/types.d.ts +11 -0
  147. package/dist/features/types.d.ts.map +1 -1
  148. package/dist/fullscreen-post-process-pass.d.ts +2 -0
  149. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  150. package/dist/gpu-driven/batch-topology.d.ts +34 -1
  151. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  152. package/dist/gpu-driven/material-artifacts.d.ts +24 -0
  153. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -0
  154. package/dist/gpu-driven/material-bindings.d.ts +7 -0
  155. package/dist/gpu-driven/material-bindings.d.ts.map +1 -0
  156. package/dist/gpu-driven/pbr-program.d.ts +10 -0
  157. package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
  158. package/dist/gpu-driven/prepared-draw.d.ts +2 -0
  159. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  160. package/dist/gpu-driven/production-raster.d.ts +169 -27
  161. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  162. package/dist/gpu-driven/shadow-views.d.ts +126 -0
  163. package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
  164. package/dist/gpu-driven/view-gpu.d.ts +18 -2
  165. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  166. package/dist/gpu-resource.d.ts +5 -2
  167. package/dist/gpu-resource.d.ts.map +1 -1
  168. package/dist/gpu-scene-schema.d.ts +2 -8
  169. package/dist/gpu-scene-schema.d.ts.map +1 -1
  170. package/dist/gpu-scene.d.ts +14 -0
  171. package/dist/gpu-scene.d.ts.map +1 -1
  172. package/dist/gpu-texture-usage.d.ts +1 -0
  173. package/dist/gpu-texture-usage.d.ts.map +1 -1
  174. package/dist/hdrp-buffers.d.ts +9 -0
  175. package/dist/hdrp-buffers.d.ts.map +1 -1
  176. package/dist/ibl/IblPipelineCache.d.ts +2 -0
  177. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  178. package/dist/ibl/frame-resources.d.ts +8 -0
  179. package/dist/ibl/frame-resources.d.ts.map +1 -0
  180. package/dist/ibl/skylight-bind-group.d.ts +3 -1
  181. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  182. package/dist/index.d.ts +87 -75
  183. package/dist/index.d.ts.map +1 -1
  184. package/dist/index.mjs +10 -8
  185. package/dist/index.mjs.map +1 -1
  186. package/dist/inspection-types.d.ts +180 -1
  187. package/dist/inspection-types.d.ts.map +1 -1
  188. package/dist/instances-derived-bounds.d.ts +11 -0
  189. package/dist/instances-derived-bounds.d.ts.map +1 -1
  190. package/dist/instances.d.ts +89 -44
  191. package/dist/instances.d.ts.map +1 -1
  192. package/dist/internal.d.ts +3 -0
  193. package/dist/internal.d.ts.map +1 -1
  194. package/dist/internal.mjs +117 -9
  195. package/dist/internal.mjs.map +1 -1
  196. package/dist/lifecycle.d.ts +2 -1
  197. package/dist/lifecycle.d.ts.map +1 -1
  198. package/dist/material-row.d.ts +15 -0
  199. package/dist/material-row.d.ts.map +1 -0
  200. package/dist/materials.d.ts +15 -0
  201. package/dist/materials.d.ts.map +1 -1
  202. package/dist/pbr-pipeline.d.ts +23 -5
  203. package/dist/pbr-pipeline.d.ts.map +1 -1
  204. package/dist/pipeline/render-extent.d.ts +51 -0
  205. package/dist/pipeline/render-extent.d.ts.map +1 -0
  206. package/dist/pipeline/standard-build-context.d.ts +7 -0
  207. package/dist/pipeline/standard-build-context.d.ts.map +1 -0
  208. package/dist/pipeline/standard-forward-lane.d.ts +3 -2
  209. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  210. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
  211. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
  212. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
  213. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
  214. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
  215. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
  216. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
  217. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
  218. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
  219. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
  220. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
  221. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
  222. package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
  223. package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
  224. package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
  225. package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
  226. package/dist/pipeline/standard-output/graph.d.ts +15 -0
  227. package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
  228. package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
  229. package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
  230. package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
  231. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
  232. package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
  233. package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
  234. package/dist/pipeline/standard-output/resources.d.ts +10 -0
  235. package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
  236. package/dist/pipeline/standard-output/types.d.ts +39 -0
  237. package/dist/pipeline/standard-output/types.d.ts.map +1 -0
  238. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  239. package/dist/pipeline/standard-post.d.ts +2 -2
  240. package/dist/pipeline/standard-post.d.ts.map +1 -1
  241. package/dist/pipeline/standard-profile.d.ts +2 -1
  242. package/dist/pipeline/standard-profile.d.ts.map +1 -1
  243. package/dist/pipeline-builder.d.ts +5 -2
  244. package/dist/pipeline-builder.d.ts.map +1 -1
  245. package/dist/pipeline-spec-types.d.ts +4 -0
  246. package/dist/pipeline-spec-types.d.ts.map +1 -1
  247. package/dist/pipeline-spec.d.ts +1 -9
  248. package/dist/pipeline-spec.d.ts.map +1 -1
  249. package/dist/plugin.d.ts.map +1 -1
  250. package/dist/points-lines/standard-owner.d.ts +1 -1
  251. package/dist/points-lines/standard-owner.d.ts.map +1 -1
  252. package/dist/post-process-errors.d.ts +9 -2
  253. package/dist/post-process-errors.d.ts.map +1 -1
  254. package/dist/prepare/extended-lighting/resources.d.ts +3 -3
  255. package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
  256. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  257. package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
  258. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
  259. package/dist/record/frame-lighting.d.ts +3 -3
  260. package/dist/record/frame-lighting.d.ts.map +1 -1
  261. package/dist/record/frame-snapshot.d.ts +109 -13
  262. package/dist/record/frame-snapshot.d.ts.map +1 -1
  263. package/dist/record/frame-targets.d.ts.map +1 -1
  264. package/dist/record/frame.d.ts +41 -5
  265. package/dist/record/frame.d.ts.map +1 -1
  266. package/dist/record/main-pass-geometry.d.ts +13 -9
  267. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  268. package/dist/record/main-pass-material.d.ts +43 -3
  269. package/dist/record/main-pass-material.d.ts.map +1 -1
  270. package/dist/record/main-pass-sprite-draws.d.ts +2 -10
  271. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  272. package/dist/record/main-pass.d.ts +14 -2
  273. package/dist/record/main-pass.d.ts.map +1 -1
  274. package/dist/record/mesh-ssbo.d.ts +15 -6
  275. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  276. package/dist/record/prepared-material-bindings.d.ts +19 -0
  277. package/dist/record/prepared-material-bindings.d.ts.map +1 -0
  278. package/dist/record/recovery-pipeline.d.ts +1 -0
  279. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  280. package/dist/record/render-context.d.ts +101 -22
  281. package/dist/record/render-context.d.ts.map +1 -1
  282. package/dist/record/shadow-pass.d.ts +62 -7
  283. package/dist/record/shadow-pass.d.ts.map +1 -1
  284. package/dist/record/skybox-post-pass.d.ts +1 -1
  285. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  286. package/dist/record/typed-frame-graph.d.ts +39 -8
  287. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  288. package/dist/record/view-ubo.d.ts +1 -0
  289. package/dist/record/view-ubo.d.ts.map +1 -1
  290. package/dist/recovery/render-system-candidate.d.ts +10 -2
  291. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  292. package/dist/recovery/render-system-roots.d.ts +11 -0
  293. package/dist/recovery/render-system-roots.d.ts.map +1 -0
  294. package/dist/recovery/types.d.ts +76 -0
  295. package/dist/recovery/types.d.ts.map +1 -0
  296. package/dist/reflection/background.d.ts +14 -0
  297. package/dist/reflection/background.d.ts.map +1 -0
  298. package/dist/reflection/filter.d.ts.map +1 -1
  299. package/dist/reflection/projection.d.ts +1 -0
  300. package/dist/reflection/projection.d.ts.map +1 -1
  301. package/dist/reflection/record-owner.d.ts +4 -4
  302. package/dist/reflection/record-owner.d.ts.map +1 -1
  303. package/dist/render-contract.d.ts +211 -53
  304. package/dist/render-contract.d.ts.map +1 -1
  305. package/dist/render-graph-primitives.d.ts +1 -0
  306. package/dist/render-graph-primitives.d.ts.map +1 -1
  307. package/dist/render-pipeline.d.ts +81 -6
  308. package/dist/render-pipeline.d.ts.map +1 -1
  309. package/dist/render-system-extract-tail.d.ts +15 -6
  310. package/dist/render-system-extract-tail.d.ts.map +1 -1
  311. package/dist/render-system-extract.d.ts +128 -41
  312. package/dist/render-system-extract.d.ts.map +1 -1
  313. package/dist/render-system-projections.d.ts +22 -0
  314. package/dist/render-system-projections.d.ts.map +1 -0
  315. package/dist/render-system.d.ts +27 -77
  316. package/dist/render-system.d.ts.map +1 -1
  317. package/dist/scene/render-scene-types.d.ts +14 -7
  318. package/dist/scene/render-scene-types.d.ts.map +1 -1
  319. package/dist/scene/render-scene.d.ts +31 -11
  320. package/dist/scene/render-scene.d.ts.map +1 -1
  321. package/dist/scene/shadow-visibility.d.ts +5 -0
  322. package/dist/scene/shadow-visibility.d.ts.map +1 -0
  323. package/dist/ssao-config.d.ts +8 -6
  324. package/dist/ssao-config.d.ts.map +1 -1
  325. package/dist/ssr/admission.d.ts +70 -1
  326. package/dist/ssr/admission.d.ts.map +1 -1
  327. package/dist/ssr/compose.d.ts +13 -0
  328. package/dist/ssr/compose.d.ts.map +1 -0
  329. package/dist/ssr/errors.d.ts +35 -0
  330. package/dist/ssr/errors.d.ts.map +1 -1
  331. package/dist/ssr/graph.d.ts +60 -0
  332. package/dist/ssr/graph.d.ts.map +1 -0
  333. package/dist/ssr/history.d.ts +97 -0
  334. package/dist/ssr/history.d.ts.map +1 -0
  335. package/dist/ssr/hiz.d.ts +37 -0
  336. package/dist/ssr/hiz.d.ts.map +1 -0
  337. package/dist/ssr/inspection.d.ts +42 -0
  338. package/dist/ssr/inspection.d.ts.map +1 -0
  339. package/dist/ssr/resources.d.ts +58 -0
  340. package/dist/ssr/resources.d.ts.map +1 -0
  341. package/dist/ssr/temporal.d.ts +38 -0
  342. package/dist/ssr/temporal.d.ts.map +1 -0
  343. package/dist/systems/skin-palette-allocator.d.ts +32 -10
  344. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  345. package/dist/systems/skin-palette-types.d.ts +15 -0
  346. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  347. package/dist/systems/transparent-dispatch.d.ts +9 -0
  348. package/dist/systems/transparent-dispatch.d.ts.map +1 -0
  349. package/dist/targets/material-source.d.ts +7 -0
  350. package/dist/targets/material-source.d.ts.map +1 -1
  351. package/dist/temporal/frame-coordinator.d.ts +7 -0
  352. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  353. package/dist/temporal/gpu.d.ts +8 -0
  354. package/dist/temporal/gpu.d.ts.map +1 -1
  355. package/dist/temporal/history.d.ts.map +1 -1
  356. package/dist/temporal/index.mjs +6 -6
  357. package/dist/temporal/inspection.d.ts.map +1 -1
  358. package/dist/temporal/standard-scene-data.d.ts +4 -2
  359. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  360. package/dist/temporal/target-coverage-attachment.d.ts +15 -0
  361. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -0
  362. package/dist/temporal/temporal-view.d.ts +6 -0
  363. package/dist/temporal/temporal-view.d.ts.map +1 -1
  364. package/dist/temporal/view.d.ts +6 -0
  365. package/dist/temporal/view.d.ts.map +1 -1
  366. package/dist/typed-render-graph-primitives.d.ts +41 -1
  367. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  368. package/dist/typed-shadow-passes.d.ts +3 -1
  369. package/dist/typed-shadow-passes.d.ts.map +1 -1
  370. package/dist/volume/component.d.ts +1 -0
  371. package/dist/volume/component.d.ts.map +1 -1
  372. package/dist/volume/temporal.d.ts +6 -0
  373. package/dist/volume/temporal.d.ts.map +1 -1
  374. package/package.json +21 -20
  375. package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
  376. package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
  377. package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
  378. package/src/__tests__/auto-exposure.browser.test.ts +33 -0
  379. package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
  380. package/src/__tests__/capture-scene-projection.unit.test.ts +24 -0
  381. package/src/__tests__/detached-inspection.integration.test.ts +5 -0
  382. package/src/__tests__/device-feature-admission.unit.test.ts +15 -24
  383. package/src/__tests__/device-loss-fanout.unit.test.ts +43 -0
  384. package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
  385. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
  386. package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
  387. package/src/__tests__/dynamic-geometry-batch.unit.test.ts +157 -0
  388. package/src/__tests__/dynamic-geometry.unit.test.ts +36 -0
  389. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +81 -0
  390. package/src/__tests__/factory-contract.integration.test.ts +231 -9
  391. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
  392. package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
  393. package/src/__tests__/feature-noise.unit.test.ts +38 -0
  394. package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
  395. package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
  396. package/src/__tests__/frame-observation.contract.test.ts +21 -0
  397. package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
  398. package/src/__tests__/frame-targets.unit.test.ts +24 -0
  399. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
  400. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
  401. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +307 -7
  402. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
  403. package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
  404. package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +261 -0
  405. package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +346 -0
  406. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1422 -0
  407. package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
  408. package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
  409. package/src/__tests__/gpu-driven-production.integration.test.ts +1076 -106
  410. package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
  411. package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
  412. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
  413. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
  414. package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
  415. package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
  416. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
  417. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
  418. package/src/__tests__/gpu-driven-view.unit.test.ts +160 -52
  419. package/src/__tests__/gpu-pass-timing-browser-runner.ts +15 -0
  420. package/src/__tests__/gpu-pass-timing.browser.test.ts +20 -2
  421. package/src/__tests__/gpu-resource-scope.unit.test.ts +71 -0
  422. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
  423. package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
  424. package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
  425. package/src/__tests__/gpu-scene.unit.test.ts +613 -33
  426. package/src/__tests__/instances-culling.integration.test.ts +36 -10
  427. package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
  428. package/src/__tests__/instances-store.unit.test.ts +242 -39
  429. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
  430. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
  431. package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
  432. package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
  433. package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
  434. package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
  435. package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
  436. package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
  437. package/src/__tests__/material-texture-source.unit.test.ts +87 -0
  438. package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
  439. package/src/__tests__/materials-standard-contract.unit.test.ts +57 -3
  440. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
  441. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +8 -0
  442. package/src/__tests__/morph-neutral-admission.unit.test.ts +19 -0
  443. package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
  444. package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
  445. package/src/__tests__/physical-clearcoat.integration.test.ts +42 -3
  446. package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
  447. package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
  448. package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -5
  449. package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
  450. package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
  451. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +251 -9
  452. package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
  453. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
  454. package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
  455. package/src/__tests__/public-surface.test-d.ts +3 -0
  456. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
  457. package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +171 -0
  458. package/src/__tests__/reflection-probe-authoring.unit.test.ts +12 -10
  459. package/src/__tests__/reflection-probe-box.dawn.test.ts +71 -0
  460. package/src/__tests__/reflection-probe-filter.unit.test.ts +9 -0
  461. package/src/__tests__/reflection-probe-orientation.dawn.test.ts +294 -0
  462. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +5 -14
  463. package/src/__tests__/reflection-probe-updates.unit.test.ts +129 -0
  464. package/src/__tests__/render-error-code-owner.test-d.ts +7 -0
  465. package/src/__tests__/render-error-detail-ssot.test-d.ts +27 -1
  466. package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
  467. package/src/__tests__/render-extent.unit.test.ts +63 -0
  468. package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
  469. package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
  470. package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
  471. package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
  472. package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
  473. package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
  474. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
  475. package/src/__tests__/render-scene-projection.unit.test.ts +915 -23
  476. package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
  477. package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
  478. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
  479. package/src/__tests__/render-target-material-source.test-d.ts +27 -3
  480. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +233 -9
  481. package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
  482. package/src/__tests__/shader-manifest-fixture.ts +45 -0
  483. package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
  484. package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
  485. package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
  486. package/src/__tests__/skinned-shadow-caster.test.ts +125 -14
  487. package/src/__tests__/specular-environment-scale.dawn.test.ts +158 -0
  488. package/src/__tests__/ssao-config.unit.test.ts +7 -0
  489. package/src/__tests__/ssao-surface.dawn.test.ts +252 -0
  490. package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
  491. package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
  492. package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
  493. package/src/__tests__/ssr-cube-silhouette.dawn.test.ts +270 -0
  494. package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
  495. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +99 -0
  496. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +116 -0
  497. package/src/__tests__/ssr-gpu-dispatch.ts +951 -0
  498. package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
  499. package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
  500. package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
  501. package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
  502. package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
  503. package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
  504. package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
  505. package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
  506. package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
  507. package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
  508. package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
  509. package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
  510. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
  511. package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
  512. package/src/__tests__/ssr-reprojection-probe.ts +90 -0
  513. package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
  514. package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
  515. package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
  516. package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
  517. package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
  518. package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
  519. package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
  520. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +84 -12
  521. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
  522. package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
  523. package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
  524. package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
  525. package/src/__tests__/standard-output.browser.test.ts +15 -0
  526. package/src/__tests__/standard-output.dawn.test.ts +15 -0
  527. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +275 -0
  528. package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
  529. package/src/__tests__/standard-profile-oracle.unit.test.ts +49 -0
  530. package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
  531. package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
  532. package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
  533. package/src/__tests__/taa-coverage-edge.dawn.test.ts +199 -0
  534. package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
  535. package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +782 -0
  536. package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
  537. package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
  538. package/src/__tests__/taa-stability-feedback.ts +342 -0
  539. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
  540. package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
  541. package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
  542. package/src/__tests__/temporal-view.unit.test.ts +17 -0
  543. package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
  544. package/src/__tests__/transmission-prewarm.unit.test.ts +57 -0
  545. package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
  546. package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
  547. package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
  548. package/src/__tests__/visibility-extract.perf.test.ts +20 -8
  549. package/src/__tests__/visibility-instances.integration.test.ts +19 -7
  550. package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
  551. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +62 -13
  552. package/src/__tests__/volumetric-fog-topology.unit.test.ts +7 -7
  553. package/src/assembly/atmosphere-shader-prewarm.ts +39 -0
  554. package/src/assembly/device-feature-admission.ts +9 -4
  555. package/src/assembly/dynamic-geometry-host.ts +284 -163
  556. package/src/assembly/dynamic-geometry-runtime.ts +71 -0
  557. package/src/assembly/factory.ts +4 -0
  558. package/src/assembly/gpu-driven-owner.ts +29 -0
  559. package/src/assembly/host-contract.ts +19 -0
  560. package/src/assembly/material/assembly.ts +383 -1
  561. package/src/assembly/material/pipeline-helpers.ts +100 -0
  562. package/src/assembly/material-shader-policy.ts +110 -46
  563. package/src/assembly/recovery/device-loss-fanout.ts +5 -0
  564. package/src/assembly/recovery/failure-location.ts +62 -0
  565. package/src/assembly/recovery/recovery-attempt.ts +2 -29
  566. package/src/assembly/recovery/renderer-recover.ts +16 -17
  567. package/src/assembly/renderer-facade.ts +34 -1
  568. package/src/assembly/renderer-feature-inspection.ts +13 -0
  569. package/src/assembly/renderer-frame-transaction.ts +63 -0
  570. package/src/assembly/renderer-helpers.ts +26 -0
  571. package/src/assembly/renderer-inspection.ts +6 -0
  572. package/src/assembly/shader-prewarm-policy.ts +46 -1
  573. package/src/assembly/skin-palette-owner.ts +21 -0
  574. package/src/assembly/ssr-shader-prewarm.ts +41 -0
  575. package/src/assembly/webgpu-device-loss.ts +75 -0
  576. package/src/assembly/webgpu-pbr-ready.ts +232 -0
  577. package/src/assembly/webgpu-ready-mipmap.ts +26 -0
  578. package/src/assembly/webgpu-ready.ts +161 -131
  579. package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
  580. package/src/assembly/webgpu-renderer-contract.ts +69 -0
  581. package/src/assembly/webgpu-renderer-guards.ts +32 -0
  582. package/src/assembly/webgpu-renderer-observation.ts +43 -0
  583. package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
  584. package/src/assembly/webgpu-renderer.ts +744 -730
  585. package/src/assembly/webgpu-vertex-layouts.ts +233 -87
  586. package/src/capture/scene-projection.ts +37 -0
  587. package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
  588. package/src/components/__tests__/dynamic-resolution-schema.unit.test.ts +65 -0
  589. package/src/components/__tests__/light-radius.integration.test.ts +59 -0
  590. package/src/components/camera.ts +287 -7
  591. package/src/components/directional-light.ts +3 -3
  592. package/src/components/dynamic-resolution.ts +67 -0
  593. package/src/components/index.ts +2 -0
  594. package/src/components/instances.ts +45 -18
  595. package/src/components/light-helpers.ts +6 -1
  596. package/src/components/reflection-probe.ts +1 -0
  597. package/src/components/scene-instance.ts +2 -1
  598. package/src/components/screen-space-reflection.ts +21 -0
  599. package/src/components/skylight.ts +4 -1
  600. package/src/components/sprite-animation.ts +2 -2
  601. package/src/components/sprite-instances.ts +1 -1
  602. package/src/device/device-scope.ts +13 -7
  603. package/src/device/gpu-residency.ts +45 -42
  604. package/src/dynamic-geometry.ts +13 -8
  605. package/src/environment/background.ts +281 -0
  606. package/src/environment/ibl.ts +211 -0
  607. package/src/environment/storage.ts +63 -0
  608. package/src/errors/gpu-driven.ts +49 -8
  609. package/src/errors/render.ts +91 -3
  610. package/src/extract/camera.ts +37 -1
  611. package/src/extract/contracts.ts +10 -0
  612. package/src/extract/gpu-driven.ts +240 -10
  613. package/src/features/host.ts +237 -19
  614. package/src/features/noise-texture.ts +91 -0
  615. package/src/features/plan.ts +553 -24
  616. package/src/features/prepared-gpu-work.ts +631 -49
  617. package/src/features/prepared-graphics-store.ts +31 -0
  618. package/src/features/prepared-graphics.ts +5 -0
  619. package/src/features/render-graph-compute.ts +41 -8
  620. package/src/features/render-graph-contribution.ts +141 -3
  621. package/src/features/render-graph-raster.ts +143 -30
  622. package/src/features/types.ts +11 -0
  623. package/src/fullscreen-post-process-pass.ts +3 -0
  624. package/src/gpu-driven/batch-topology.ts +452 -108
  625. package/src/gpu-driven/material-artifacts.ts +179 -0
  626. package/src/gpu-driven/material-bindings.ts +41 -0
  627. package/src/gpu-driven/pbr-program.ts +31 -0
  628. package/src/gpu-driven/prepared-draw.ts +42 -6
  629. package/src/gpu-driven/production-raster.ts +2806 -716
  630. package/src/gpu-driven/shadow-views.ts +539 -0
  631. package/src/gpu-driven/view-gpu.ts +188 -41
  632. package/src/gpu-resource.ts +21 -2
  633. package/src/gpu-scene-schema.ts +61 -11
  634. package/src/gpu-scene.ts +197 -99
  635. package/src/gpu-texture-usage.ts +1 -0
  636. package/src/hdrp-buffers.ts +141 -36
  637. package/src/ibl/IblPipelineCache.ts +5 -0
  638. package/src/ibl/frame-resources.ts +38 -0
  639. package/src/ibl/skylight-bind-group.ts +32 -21
  640. package/src/index.ts +194 -75
  641. package/src/inspection-types.ts +207 -1
  642. package/src/instances-derived-bounds.ts +258 -34
  643. package/src/instances.ts +459 -150
  644. package/src/internal.ts +22 -0
  645. package/src/lifecycle.ts +2 -0
  646. package/src/material-row.ts +194 -0
  647. package/src/materials.ts +44 -8
  648. package/src/pbr-pipeline.ts +172 -19
  649. package/src/pipeline/render-extent.ts +111 -0
  650. package/src/pipeline/standard-build-context.ts +7 -0
  651. package/src/pipeline/standard-forward-lane.ts +74 -29
  652. package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
  653. package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
  654. package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
  655. package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
  656. package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
  657. package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
  658. package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
  659. package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
  660. package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
  661. package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
  662. package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
  663. package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
  664. package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
  665. package/src/pipeline/standard-output/color-transform.ts +124 -0
  666. package/src/pipeline/standard-output/graph.ts +139 -0
  667. package/src/pipeline/standard-output/lut-admission.ts +121 -0
  668. package/src/pipeline/standard-output/lut-gpu.ts +399 -0
  669. package/src/pipeline/standard-output/lut-state.ts +176 -0
  670. package/src/pipeline/standard-output/resources.ts +121 -0
  671. package/src/pipeline/standard-output/types.ts +58 -0
  672. package/src/pipeline/standard-pipeline.ts +232 -70
  673. package/src/pipeline/standard-post.ts +190 -27
  674. package/src/pipeline/standard-profile.ts +2 -1
  675. package/src/pipeline-builder.ts +28 -9
  676. package/src/pipeline-spec-types.ts +4 -0
  677. package/src/pipeline-spec.ts +37 -29
  678. package/src/plugin.ts +4 -0
  679. package/src/points-lines/standard-owner.ts +6 -14
  680. package/src/post-process-errors.ts +26 -18
  681. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +2 -2
  682. package/src/prepare/extended-lighting/resources.ts +3 -3
  683. package/src/prepare/prepared-graphics-resolver.ts +9 -2
  684. package/src/record/__tests__/main-pass-geometry.unit.test.ts +68 -0
  685. package/src/record/__tests__/material-bg-cache.unit.test.ts +45 -0
  686. package/src/record/__tests__/material-slot-plan.unit.test.ts +57 -0
  687. package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
  688. package/src/record/__tests__/recovery-pipeline.unit.test.ts +20 -1
  689. package/src/record/__tests__/sprite-material-abi.unit.test.ts +41 -6
  690. package/src/record/__tests__/temporal-payload.unit.test.ts +2 -0
  691. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
  692. package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
  693. package/src/record/dynamic-geometry-consumption.ts +59 -0
  694. package/src/record/frame-lighting.ts +15 -12
  695. package/src/record/frame-snapshot.ts +146 -34
  696. package/src/record/frame-targets.ts +9 -0
  697. package/src/record/frame.ts +838 -170
  698. package/src/record/main-pass-geometry.ts +209 -103
  699. package/src/record/main-pass-material.ts +157 -40
  700. package/src/record/main-pass-sprite-draws.ts +16 -107
  701. package/src/record/main-pass.ts +141 -12
  702. package/src/record/material-uniforms.ts +1 -1
  703. package/src/record/mesh-ssbo.ts +59 -15
  704. package/src/record/prepared-material-bindings.ts +238 -0
  705. package/src/record/recovery-pipeline.ts +69 -90
  706. package/src/record/render-context.ts +123 -24
  707. package/src/record/shadow-pass.ts +1389 -230
  708. package/src/record/skybox-post-pass.ts +14 -3
  709. package/src/record/typed-frame-graph.ts +1064 -47
  710. package/src/record/view-ubo.ts +12 -1
  711. package/src/recovery/render-system-candidate.ts +135 -68
  712. package/src/recovery/render-system-roots.ts +113 -0
  713. package/src/recovery/types.ts +77 -0
  714. package/src/reflection/background.ts +151 -0
  715. package/src/reflection/filter.ts +3 -0
  716. package/src/reflection/projection.ts +16 -6
  717. package/src/reflection/record-owner.ts +308 -140
  718. package/src/render-contract.ts +237 -49
  719. package/src/render-graph-primitives.ts +34 -5
  720. package/src/render-pipeline.ts +90 -2
  721. package/src/render-system-extract-tail.ts +431 -162
  722. package/src/render-system-extract.ts +478 -119
  723. package/src/render-system-projections.ts +241 -0
  724. package/src/render-system.ts +715 -828
  725. package/src/scene/render-scene-types.ts +13 -4
  726. package/src/scene/render-scene.ts +577 -355
  727. package/src/scene/shadow-visibility.ts +21 -0
  728. package/src/ssao-config.ts +25 -8
  729. package/src/ssr/admission.ts +380 -14
  730. package/src/ssr/compose.ts +144 -0
  731. package/src/ssr/errors.ts +48 -0
  732. package/src/ssr/graph.ts +797 -0
  733. package/src/ssr/history.ts +436 -0
  734. package/src/ssr/hiz.ts +124 -0
  735. package/src/ssr/inspection.ts +124 -0
  736. package/src/ssr/resources.ts +202 -0
  737. package/src/ssr/temporal.ts +164 -0
  738. package/src/systems/skin-palette-allocator.ts +495 -148
  739. package/src/systems/skin-palette-types.ts +17 -0
  740. package/src/systems/transparent-dispatch.ts +90 -0
  741. package/src/targets/material-source.ts +34 -0
  742. package/src/temporal/coverage.ts +1 -1
  743. package/src/temporal/frame-coordinator.ts +23 -2
  744. package/src/temporal/gpu.ts +79 -12
  745. package/src/temporal/history.ts +3 -1
  746. package/src/temporal/inspection.ts +2 -1
  747. package/src/temporal/standard-scene-data.ts +10 -2
  748. package/src/temporal/target-coverage-attachment.ts +72 -0
  749. package/src/temporal/temporal-view.ts +11 -2
  750. package/src/temporal/view.ts +12 -2
  751. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +219 -139
  752. package/src/typed-render-graph-primitives.ts +304 -74
  753. package/src/typed-shadow-passes.ts +122 -12
  754. package/src/volume/component.ts +1 -0
  755. package/src/volume/passes.ts +3 -3
  756. package/src/volume/temporal.ts +10 -0
  757. package/dist/chunk-GE3SDD72.mjs.map +0 -1
  758. package/dist/chunk-GF523LHF.mjs.map +0 -1
  759. package/dist/chunk-IQMKJLNU.mjs.map +0 -1
  760. package/dist/chunk-J52NMQKR.mjs.map +0 -1
  761. package/dist/chunk-J6KACNOH.mjs.map +0 -1
  762. package/dist/chunk-JAASCMXA.mjs.map +0 -1
  763. package/dist/chunk-MBU4ZVE7.mjs.map +0 -1
  764. package/dist/chunk-MYJ5RPJO.mjs.map +0 -1
  765. package/dist/chunk-RBDBZ5R7.mjs.map +0 -1
  766. package/dist/chunk-VSL23LZE.mjs.map +0 -1
  767. package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
  768. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
@@ -9,6 +9,8 @@ import type {
9
9
  TextureFormat,
10
10
  TextureView,
11
11
  } from '@forgeax/engine-rhi';
12
+ import { RhiError } from '@forgeax/engine-rhi';
13
+ import { toShared } from '@forgeax/engine-types';
12
14
  import { buildCubeCameraFaceViews } from '../capture/cube-views';
13
15
  import {
14
16
  createFaceUniformsBuffer,
@@ -30,7 +32,6 @@ import {
30
32
  createIblPipelines,
31
33
  getOrCreateIblCache,
32
34
  PREFILTER_MIP_LEVELS,
33
- PREFILTER_SIZE,
34
35
  } from '../ibl/IblPipelineCache';
35
36
  import type {
36
37
  ReflectionFallbackReadbackReceipt,
@@ -42,7 +43,8 @@ import type { ReflectionProbeRecordState, RenderSystemInternals } from '../recor
42
43
  import type { ReflectionProbeGraphWork } from '../record/typed-frame-graph';
43
44
  import { REFLECTION_PROBE_VIEW_SLOT_BASE, VIEW_UNIFORM_SLOT_STRIDE } from '../record/view-ubo';
44
45
  import type { CameraSnapshot } from '../render-contract';
45
- import type { SkylightSnapshot } from '../render-system-extract';
46
+ import type { SkyboxSnapshot, SkylightSnapshot } from '../render-system-extract';
47
+ import { createProbeBackgroundResources, type ProbeBackgroundResources } from './background';
46
48
  import {
47
49
  advanceProbeFilter,
48
50
  commitProbeFilterStep,
@@ -76,6 +78,12 @@ type ProbeCubeSet = {
76
78
 
77
79
  type ProbeGpuResource = {
78
80
  fact: ReflectionProbeFact;
81
+ captureFact: ReflectionProbeFact;
82
+ diffusePayload: readonly number[];
83
+ captureSceneRevision: string;
84
+ captureStartedFrame: number;
85
+ lastCompletedFrame: number;
86
+ activeFact?: ReflectionProbeFact;
79
87
  index: number;
80
88
  filter: ProbeFilterState;
81
89
  rawFaceCursor: number;
@@ -93,6 +101,7 @@ type ProbeGpuResource = {
93
101
  };
94
102
 
95
103
  type ProbeSharedResources = {
104
+ readonly background: ProbeBackgroundResources | undefined;
96
105
  readonly faceUniforms: Buffer;
97
106
  readonly prefilterUniforms: Buffer;
98
107
  readonly vertexBuffer: Buffer;
@@ -126,16 +135,16 @@ export class ReflectionProbeRecordOwner {
126
135
  private lastAcceptedCount = 0;
127
136
  private lastScheduledRawFaces = 0;
128
137
  private lastScheduledFilteredSteps = 0;
138
+ private workCursor = 0;
139
+ private currentFrame = 0;
129
140
  private lastSelection: ReflectionProbeSelectionInspection = { kind: 'skylight' };
130
141
  private outputFormat: TextureFormat;
131
142
  private fallbackFormatAvailable: boolean;
132
143
  private nextFallbackTicket = 0;
133
- // Readback completion is asynchronous and can overlap the next frame's
134
- // prepare. Key tickets by immutable id and retain only the latest ticket
135
- // per renderable; an older completion is stale by definition once a newer
136
- // candidate has been staged, but cannot erase the newer ticket.
137
- private pendingFallback = new Map<number, PendingFallback>();
138
- private latestFallbackTickets = new Map<string, number>();
144
+ // Submitted frames own their immutable candidates until completion. Keep
145
+ // only the current projection here: preparing a source-identical frame
146
+ // must not starve an earlier asynchronous readback of publication.
147
+ private latestFallbackTickets = new Map<string, PendingFallback>();
139
148
  private fallbackRetiredFrames = new Map<string, number>();
140
149
  private fallbackCommittedFrames = new Map<string, number>();
141
150
  private fallbackGenerations = new Map<
@@ -173,6 +182,22 @@ export class ReflectionProbeRecordOwner {
173
182
  if (resource.active !== undefined) activeCount += 1;
174
183
  }
175
184
  return {
185
+ updates: [...this.resources.values()].map((resource) => ({
186
+ worldId: resource.fact.worldId,
187
+ entityKey: resource.fact.entityKey,
188
+ intent: resource.fact.updateIntent ?? 'once',
189
+ activeGeneration: resource.filter.activeGeneration,
190
+ requestedRevision: resource.fact.revision,
191
+ capturedRevision: resource.captureFact.revision,
192
+ pending: resource.filter.cursor < resource.filter.faceCount * resource.filter.mipCount,
193
+ captureStartedFrame: resource.captureStartedFrame,
194
+ lastCompletedFrame: resource.lastCompletedFrame,
195
+ latencyFrames:
196
+ resource.lastCompletedFrame < resource.captureStartedFrame
197
+ ? undefined
198
+ : resource.lastCompletedFrame - resource.captureStartedFrame,
199
+ })),
200
+ workBudgetPerFrame: 1,
176
201
  selection: this.lastSelection,
177
202
  factCount: this.lastFactCount,
178
203
  acceptedCount: this.lastAcceptedCount,
@@ -283,14 +308,13 @@ export class ReflectionProbeRecordOwner {
283
308
  }
284
309
 
285
310
  private retireFallbackState(frameId: number): void {
286
- for (const pending of this.pendingFallback.values()) {
311
+ for (const pending of this.latestFallbackTickets.values()) {
287
312
  const key = pending.projection.renderableKey;
288
313
  if (key !== undefined) this.fallbackRetiredFrames.set(key, frameId);
289
314
  }
290
315
  for (const key of this.fallbackReceipts.keys()) {
291
316
  this.fallbackRetiredFrames.set(key, frameId);
292
317
  }
293
- this.pendingFallback.clear();
294
318
  this.latestFallbackTickets.clear();
295
319
  this.fallbackReceipts.clear();
296
320
  this.fallbackSignatures.clear();
@@ -307,7 +331,8 @@ export class ReflectionProbeRecordOwner {
307
331
  if (factory === undefined) return;
308
332
  const attempt = this.pipelineWarmupAttempts + 1;
309
333
  this.pipelineWarmupAttempts = attempt;
310
- this.pipelineWarmup = createIblPipelines(
334
+ const device = this.internals.device;
335
+ const warmup = createIblPipelines(
311
336
  this.internals.deviceScope,
312
337
  this.internals.device,
313
338
  (device, descriptor) => {
@@ -320,20 +345,42 @@ export class ReflectionProbeRecordOwner {
320
345
  : this.internals.createShaderModule(device, labeled);
321
346
  },
322
347
  this.outputFormat,
323
- ).then((result) => {
324
- if (!result.ok) {
325
- this.pipelineWarmupFailure = `${result.error.code}: ${result.error.hint}`;
326
- console.warn('[forgeax] ReflectionProbe IBL warmup retry', this.pipelineWarmupFailure);
327
- this.pipelineWarmup = undefined;
328
- return;
329
- }
330
- this.shared = this.createSharedResources(result.value.prefilterPipeline);
331
- if (this.shared === undefined) {
332
- this.pipelineWarmupFailure = 'renderer-owned IBL resources could not be allocated';
333
- console.warn('[forgeax] ReflectionProbe IBL resource allocation retry');
348
+ )
349
+ .then(async (result) => {
350
+ if (this.pipelineWarmup !== warmup) return;
351
+ if (!result.ok) {
352
+ this.pipelineWarmupFailure = `${result.error.code}: ${result.error.hint}`;
353
+ console.warn('[forgeax] ReflectionProbe IBL warmup retry', this.pipelineWarmupFailure);
354
+ this.pipelineWarmup = undefined;
355
+ return;
356
+ }
357
+ const background = await createProbeBackgroundResources(this.internals, this.outputFormat);
358
+ if (this.pipelineWarmup !== warmup) {
359
+ if (background !== undefined) device.destroyBuffer(background.uniform);
360
+ return;
361
+ }
362
+ this.shared = this.createSharedResources(result.value.prefilterPipeline, background);
363
+ if (this.shared === undefined) {
364
+ this.pipelineWarmupFailure = 'renderer-owned IBL resources could not be allocated';
365
+ console.warn('[forgeax] ReflectionProbe IBL resource allocation retry');
366
+ this.pipelineWarmup = undefined;
367
+ }
368
+ })
369
+ .catch((cause: unknown) => {
370
+ if (this.pipelineWarmup !== warmup) return;
371
+ this.pipelineWarmupFailure = cause instanceof Error ? cause.message : String(cause);
334
372
  this.pipelineWarmup = undefined;
335
- }
336
- });
373
+ this.internals.errorRegistry.fire(
374
+ cause instanceof RhiError
375
+ ? cause
376
+ : new RhiError({
377
+ code: 'shader-compile-failed',
378
+ expected: 'complete reflection probe background and IBL pipelines',
379
+ hint: `inspect the shader manifest and device error: ${this.pipelineWarmupFailure}`,
380
+ }),
381
+ );
382
+ });
383
+ this.pipelineWarmup = warmup;
337
384
  }
338
385
 
339
386
  prepare(
@@ -342,7 +389,10 @@ export class ReflectionProbeRecordOwner {
342
389
  displayCamera: CameraSnapshot | undefined,
343
390
  frameId = this.nextFallbackTicket + 1,
344
391
  skylight: SkylightSnapshot | undefined = undefined,
392
+ sceneRevision = '',
393
+ skybox?: SkyboxSnapshot,
345
394
  ): ReflectionProbeRecordState {
395
+ this.currentFrame = frameId;
346
396
  this.refreshFallbackCapabilities(frameId);
347
397
  this.lastFactCount = facts.length;
348
398
  this.lastScheduledRawFaces = 0;
@@ -374,7 +424,7 @@ export class ReflectionProbeRecordOwner {
374
424
  );
375
425
  if (!admission.ok) continue;
376
426
  const key = `${fact.worldId}:${fact.entityKey}`;
377
- const resource = this.resourceFor(key, fact, acceptedCount);
427
+ const resource = this.resourceFor(key, fact, acceptedCount, sceneRevision, skylight);
378
428
  if (resource === undefined) continue;
379
429
  acceptedCount += 1;
380
430
  acceptedBytes = admission.acceptedBytes;
@@ -392,7 +442,9 @@ export class ReflectionProbeRecordOwner {
392
442
  }
393
443
  const rows = [...accepted.values()]
394
444
  .map((resource) => {
395
- const active = resource.active;
445
+ const active = resource.activeFact?.center.every((v, i) => v === resource.fact.center[i])
446
+ ? resource.active
447
+ : undefined;
396
448
  if (active === undefined) return undefined;
397
449
  return {
398
450
  primitiveKey: `${resource.fact.worldId}:${resource.fact.entityKey}`,
@@ -411,7 +463,23 @@ export class ReflectionProbeRecordOwner {
411
463
  .filter((row): row is NonNullable<typeof row> => row !== undefined);
412
464
  const table = buildReflectionProbeTable(rows);
413
465
  const work: ReflectionProbeGraphWork[] = [];
414
- for (const resource of accepted.values()) {
466
+ const environmentReady = [skylight?.equirectHandle, skybox?.equirectHandle].every(
467
+ (handle) =>
468
+ handle === undefined ||
469
+ handle === 0 ||
470
+ this.internals.gpuStore.getCubemapGpuView(toShared<'EquirectAsset'>(handle)) !== undefined,
471
+ );
472
+ const candidates = [...accepted.values()];
473
+ const captureTickets: Array<{
474
+ resource: ProbeGpuResource;
475
+ pending: NonNullable<ProbeGpuResource['pending']>;
476
+ }> = [];
477
+ const deviceGeneration = this.internals.deviceScope.generation;
478
+ for (let offset = 0; offset < candidates.length; offset++) {
479
+ const candidateIndex = (this.workCursor + offset) % candidates.length;
480
+ const resource = candidates[candidateIndex];
481
+ if (resource === undefined) continue;
482
+ if (resource.pending !== undefined) continue;
415
483
  const rawCaptureFace =
416
484
  resource.rawFaceCursor < resource.raw.faceViews.length ? resource.rawFaceCursor : undefined;
417
485
  const step =
@@ -419,7 +487,7 @@ export class ReflectionProbeRecordOwner {
419
487
  ? advanceProbeFilter(resource.filter)
420
488
  : undefined;
421
489
  if (this.shared === undefined) continue;
422
- if (rawCaptureFace === undefined && step === undefined) continue;
490
+ if (!environmentReady || (rawCaptureFace === undefined && step === undefined)) continue;
423
491
  const filterGroup0 =
424
492
  step === undefined
425
493
  ? undefined
@@ -452,15 +520,15 @@ export class ReflectionProbeRecordOwner {
452
520
  ],
453
521
  });
454
522
  if (filterGroup0 !== undefined && !filterGroup0.ok) continue;
455
- if (resource.pending !== undefined) continue;
456
523
  resource.pending = { rawCaptureFace, step };
524
+ captureTickets.push({ resource, pending: resource.pending });
457
525
  if (rawCaptureFace !== undefined) this.lastScheduledRawFaces += 1;
458
526
  if (step !== undefined) this.lastScheduledFilteredSteps += 1;
459
527
  const face =
460
528
  rawCaptureFace === undefined
461
529
  ? undefined
462
530
  : buildCubeCameraFaceViews({
463
- position: resource.fact.center,
531
+ position: resource.captureFact.center,
464
532
  near: 0.1,
465
533
  far: 100,
466
534
  })[rawCaptureFace];
@@ -470,9 +538,9 @@ export class ReflectionProbeRecordOwner {
470
538
  : {
471
539
  ...displayCamera,
472
540
  position: vec3.create(
473
- resource.fact.center[0] ?? 0,
474
- resource.fact.center[1] ?? 0,
475
- resource.fact.center[2] ?? 0,
541
+ resource.captureFact.center[0] ?? 0,
542
+ resource.captureFact.center[1] ?? 0,
543
+ resource.captureFact.center[2] ?? 0,
476
544
  ),
477
545
  world: mat4.invert(mat4.create(), face.view),
478
546
  fov: Math.PI / 2,
@@ -493,6 +561,7 @@ export class ReflectionProbeRecordOwner {
493
561
  outputFormat: this.outputFormat,
494
562
  sampler: resource.sampler,
495
563
  filterPipeline: this.shared.filterPipeline,
564
+ ...(this.shared.background === undefined ? {} : { background: this.shared.background }),
496
565
  filterGroup0: filterGroup0?.value,
497
566
  filterGroup1: resource.filterGroup1,
498
567
  cubeVertexBuffer: this.shared.vertexBuffer,
@@ -509,6 +578,8 @@ export class ReflectionProbeRecordOwner {
509
578
  filteredSize: resource.candidate.size,
510
579
  step,
511
580
  });
581
+ this.workCursor = (candidateIndex + 1) % candidates.length;
582
+ break;
512
583
  }
513
584
  return {
514
585
  table,
@@ -533,6 +604,9 @@ export class ReflectionProbeRecordOwner {
533
604
  completed,
534
605
  fallbackOutput,
535
606
  fallbackRequested,
607
+ captureTickets,
608
+ deviceGeneration,
609
+ frameId,
536
610
  ),
537
611
  };
538
612
  }
@@ -555,15 +629,13 @@ export class ReflectionProbeRecordOwner {
555
629
  }>;
556
630
  },
557
631
  fallbackRequested = true,
632
+ captureTickets: readonly {
633
+ resource: ProbeGpuResource;
634
+ pending: NonNullable<ProbeGpuResource['pending']>;
635
+ }[] = [],
636
+ deviceGeneration = this.internals.deviceScope.generation,
637
+ submittedFrame = this.currentFrame,
558
638
  ): Promise<void> {
559
- if (!fallbackRequested) {
560
- // The scene has no Standard PBR renderable that can consume the
561
- // producer's second output, so the graph intentionally omits the MRT.
562
- // Retire only this frame's candidate tickets; keep any previously
563
- // committed LKG receipt without manufacturing a readback failure.
564
- this.discardFallbackTickets(fallbackTickets);
565
- return;
566
- }
567
639
  let completionFailure: ReflectionFallbackFailureInput | undefined;
568
640
  if (completed !== undefined) {
569
641
  try {
@@ -577,14 +649,20 @@ export class ReflectionProbeRecordOwner {
577
649
  };
578
650
  }
579
651
  }
580
- await this.completeFallbackSubmission(
581
- submitted,
582
- fallbackTickets,
583
- fallbackOutput,
584
- completionFailure,
585
- );
586
- for (const resource of this.resources.values()) {
587
- const pending = resource.pending;
652
+ if (fallbackRequested)
653
+ await this.completeFallbackSubmission(
654
+ submitted,
655
+ fallbackTickets,
656
+ fallbackOutput,
657
+ completionFailure,
658
+ );
659
+ if (deviceGeneration !== this.internals.deviceScope.generation) return;
660
+ for (const { resource, pending } of captureTickets) {
661
+ if (
662
+ resource.pending !== pending ||
663
+ this.resources.get(`${resource.fact.worldId}:${resource.fact.entityKey}`) !== resource
664
+ )
665
+ continue;
588
666
  delete resource.pending;
589
667
  if (!submitted || pending === undefined) continue;
590
668
  if (pending.rawCaptureFace !== undefined) {
@@ -599,6 +677,8 @@ export class ReflectionProbeRecordOwner {
599
677
  if (resource.filter.cursor >= resource.filter.faceCount * resource.filter.mipCount) {
600
678
  const previous = resource.active;
601
679
  resource.active = resource.candidate;
680
+ resource.activeFact = resource.captureFact;
681
+ resource.lastCompletedFrame = submittedFrame;
602
682
  resource.candidate = resource.spare ?? previous ?? resource.candidate;
603
683
  resource.spare = undefined;
604
684
  }
@@ -622,18 +702,29 @@ export class ReflectionProbeRecordOwner {
622
702
  facts.length === 0 && skylight === undefined
623
703
  ? new Map([['__frame__', { kind: 'skylight' as const }]])
624
704
  : selections;
705
+ const skylightSignature =
706
+ skylight === undefined
707
+ ? ''
708
+ : `:${JSON.stringify([skylight.equirectHandle, skylight.intensity, ...skylight.color, ...skylight.rotation])}`;
625
709
  for (const [renderableKey, selection] of stagedSelections) {
626
710
  const probeKey =
627
711
  selection.kind === 'probe' ? `${selection.worldId}:${selection.entityKey}` : undefined;
628
712
  const resource = probeKey === undefined ? undefined : accepted.get(probeKey);
629
713
  const source = resolveReflectionFallbackSource(
630
714
  selection,
631
- resource?.active !== undefined,
715
+ resource?.active !== undefined &&
716
+ resource.activeFact?.center.every((v, i) => v === resource.fact.center[i]) === true,
632
717
  skylight !== undefined,
633
718
  );
634
719
  const projection = deriveReflectionFallbackProjection({
635
720
  renderableKey,
636
- sourceKey: reflectionFallbackSourceKey(source, selection, skylight),
721
+ sourceKey:
722
+ reflectionFallbackSourceKey(source, selection, skylight) +
723
+ (source === 'probe' && resource !== undefined
724
+ ? `@${resource.filter.activeGeneration}:${resource.fact.boxProjection === true}:${resource.fact.intensity}`
725
+ : '') +
726
+ skylightSignature +
727
+ (source === 'neutral' ? '' : `:catalog:${this.internals.assets.catalogEpoch}`),
637
728
  source,
638
729
  coverage: reflectionFallbackCoverage(source, resource?.fact, selection),
639
730
  ...(resource === undefined ? {} : { extent: resource.fact.halfExtents }),
@@ -650,6 +741,13 @@ export class ReflectionProbeRecordOwner {
650
741
  continue;
651
742
  }
652
743
  const signature = reflectionFallbackProjectionSignature(projection.value);
744
+ const previousCandidate = this.latestFallbackTickets.get(renderableKey);
745
+ if (
746
+ previousCandidate !== undefined &&
747
+ reflectionFallbackProjectionSignature(previousCandidate.projection) !== signature
748
+ ) {
749
+ this.fallbackRetiredFrames.set(renderableKey, frameId);
750
+ }
653
751
  const previousSignature = this.fallbackSignatures.get(renderableKey);
654
752
  if (previousSignature !== undefined && previousSignature !== signature) {
655
753
  // A changed source, coverage, extent, or BRDF is not a compatible LKG.
@@ -668,11 +766,8 @@ export class ReflectionProbeRecordOwner {
668
766
  deviceGeneration: this.internals.deviceScope.generation,
669
767
  projection: projection.value,
670
768
  };
671
- const previousTicket = this.latestFallbackTickets.get(renderableKey);
672
- if (previousTicket !== undefined) this.pendingFallback.delete(previousTicket);
673
769
  tickets.set(renderableKey, pending);
674
- this.pendingFallback.set(pending.ticket, pending);
675
- this.latestFallbackTickets.set(renderableKey, pending.ticket);
770
+ this.latestFallbackTickets.set(renderableKey, pending);
676
771
  }
677
772
  // Retire rows that disappeared from this frame's main-pass selection.
678
773
  // Keeping them would make a detached inspection row outlive its source.
@@ -688,23 +783,12 @@ export class ReflectionProbeRecordOwner {
688
783
  for (const renderableKey of this.fallbackGenerations.keys()) {
689
784
  if (!tickets.has(renderableKey)) this.fallbackGenerations.delete(renderableKey);
690
785
  }
691
- // An in-flight ticket for a row that disappeared is no longer admissible.
692
- // Remove it eagerly so the map remains bounded; completion still sees the
693
- // missing ticket and safely rejects it as stale.
694
- for (const [ticket, pending] of this.pendingFallback) {
695
- const key = pending.projection.renderableKey;
696
- const current = key === undefined ? undefined : tickets.get(key);
697
- if (
698
- key !== undefined &&
699
- pending.frameId < frameId &&
700
- (current === undefined ||
701
- current.projection.source === 'neutral' ||
702
- reflectionFallbackProjectionSignature(current.projection) !==
703
- reflectionFallbackProjectionSignature(pending.projection))
704
- ) {
705
- this.pendingFallback.delete(ticket);
706
- if (current === undefined) this.fallbackRetiredFrames.set(key, frameId);
707
- }
786
+ // Retire even uncommitted rows, so disappear/reappear cannot revive an
787
+ // old completion. Storage stays bounded by current renderables.
788
+ for (const key of this.latestFallbackTickets.keys()) {
789
+ if (tickets.has(key)) continue;
790
+ this.latestFallbackTickets.delete(key);
791
+ this.fallbackRetiredFrames.set(key, frameId);
708
792
  }
709
793
  if (tickets.size === 0 && facts.length === 0) {
710
794
  const neutralKey = '__frame__';
@@ -723,11 +807,8 @@ export class ReflectionProbeRecordOwner {
723
807
  deviceGeneration: this.internals.deviceScope.generation,
724
808
  projection: projection.value,
725
809
  };
726
- const previousTicket = this.latestFallbackTickets.get(neutralKey);
727
- if (previousTicket !== undefined) this.pendingFallback.delete(previousTicket);
728
810
  tickets.set(neutralKey, pending);
729
- this.pendingFallback.set(pending.ticket, pending);
730
- this.latestFallbackTickets.set(neutralKey, pending.ticket);
811
+ this.latestFallbackTickets.set(neutralKey, pending);
731
812
  }
732
813
  }
733
814
  this.selectFallbackReceiptKey(tickets, skylight !== undefined);
@@ -762,7 +843,8 @@ export class ReflectionProbeRecordOwner {
762
843
  let sourceMatch: string | undefined;
763
844
  for (const [key, pending] of tickets) {
764
845
  const matches =
765
- pending.projection.sourceKey === selectedSourceKey ||
846
+ (selectedSourceKey !== undefined &&
847
+ pending.projection.sourceKey?.startsWith(`${selectedSourceKey}@`) === true) ||
766
848
  (selectedSourceKey === undefined && pending.projection.source === 'skylight');
767
849
  if (matches && (sourceMatch === undefined || key < sourceMatch)) sourceMatch = key;
768
850
  }
@@ -778,19 +860,13 @@ export class ReflectionProbeRecordOwner {
778
860
  this.fallbackReceiptKey = firstKey;
779
861
  }
780
862
 
781
- private discardFallbackTickets(fallbackTickets: ReadonlyMap<string, PendingFallback>): void {
782
- for (const pending of fallbackTickets.values()) {
783
- this.pendingFallback.delete(pending.ticket);
784
- }
785
- }
786
-
787
863
  /** Commit exact-zero neutral rows even when a non-neutral MRT readback fails. */
788
864
  private commitNeutralFallbacks(fallbackTickets: ReadonlyMap<string, PendingFallback>): number {
789
865
  let committed = 0;
790
866
  for (const [renderableKey, pending] of fallbackTickets) {
791
867
  if (
792
868
  pending.projection.source === 'neutral' &&
793
- this.latestFallbackTickets.get(renderableKey) === pending.ticket &&
869
+ this.latestFallbackTickets.get(renderableKey) === pending &&
794
870
  pending.deviceGeneration === this.internals.deviceScope.generation
795
871
  ) {
796
872
  this.commitFallbackProjection(renderableKey, pending, 'neutral');
@@ -813,8 +889,9 @@ export class ReflectionProbeRecordOwner {
813
889
  source: previous?.sourceGeneration ?? 0,
814
890
  projection: previous?.projectionGeneration ?? 0,
815
891
  };
892
+ const { linearHdr: _referencePixel, ...projection } = pending.projection;
816
893
  const receipt = Object.freeze({
817
- ...pending.projection,
894
+ ...projection,
818
895
  rendererId: this.internals.deviceScope.owner,
819
896
  producerId: REFLECTION_PROBE_PRODUCER_ID,
820
897
  ...(this.internals.ssrIdentity === undefined ? {} : { identity: this.internals.ssrIdentity }),
@@ -839,7 +916,7 @@ export class ReflectionProbeRecordOwner {
839
916
  /** Retain only a source-identical committed row after candidate failure. */
840
917
  private preserveFallbackLkg(fallbackTickets: ReadonlyMap<string, PendingFallback>): void {
841
918
  for (const [renderableKey, pending] of fallbackTickets) {
842
- if (this.latestFallbackTickets.get(renderableKey) !== pending.ticket) continue;
919
+ if (this.latestFallbackTickets.get(renderableKey) !== pending) continue;
843
920
  const previous = this.fallbackReceipts.get(renderableKey);
844
921
  const signature = reflectionFallbackProjectionSignature(pending.projection);
845
922
  const compatible =
@@ -887,14 +964,10 @@ export class ReflectionProbeRecordOwner {
887
964
  // fallback attachment probe. The prepare phase already published the
888
965
  // structured capability failure and retired all current rows.
889
966
  if (!this.fallbackFormatAvailable) {
890
- this.discardFallbackTickets(fallbackTickets);
891
967
  return;
892
968
  }
893
- // A graph attachment descriptor is not a producer receipt. Until the
894
- // completed frame has supplied mapped bytes and their digest, discard the
895
- // pending ticket and keep the last committed row (if any) as LKG. This
896
- // prevents the projection's zero quartet from becoming false active
897
- // evidence when the copy/readback owner has not run.
969
+ // Source/coverage publication follows real graph execution and GPU completion.
970
+ // Pixel validation is a separate, explicitly requested diagnostic capability.
898
971
  if (!submitted || fallbackTickets.size === 0) {
899
972
  if (!submitted) {
900
973
  this.recordFallbackFailure(
@@ -906,13 +979,14 @@ export class ReflectionProbeRecordOwner {
906
979
  );
907
980
  this.preserveFallbackLkg(fallbackTickets);
908
981
  }
909
- this.discardFallbackTickets(fallbackTickets);
910
982
  return;
911
983
  }
912
- if (fallbackOutput?.readback === undefined) {
913
- // Neutral is an exact producer-owned zero and does not need an MRT
914
- // sample. A successfully submitted frame may commit those rows even
915
- // when the non-neutral rows have no mapped readback and must stay LKG.
984
+ if (
985
+ fallbackOutput === undefined ||
986
+ (this.internals.captureReflectionFallbackReadback === true &&
987
+ fallbackOutput.readback === undefined)
988
+ ) {
989
+ // Neutral rows require no attachment; non-neutral rows need an executed output.
916
990
  const committedNeutral = this.commitNeutralFallbacks(fallbackTickets);
917
991
  const nonNeutral = new Map(
918
992
  [...fallbackTickets].filter(([, pending]) => pending.projection.source !== 'neutral'),
@@ -924,21 +998,25 @@ export class ReflectionProbeRecordOwner {
924
998
  if (nonNeutral.size > 0) {
925
999
  this.recordFallbackFailure({
926
1000
  stage: 'completion',
927
- code: 'reflection-fallback-readback-missing',
928
- expected: 'a mapped fallback MRT readback for every non-neutral source',
1001
+ code:
1002
+ fallbackOutput === undefined
1003
+ ? 'reflection-fallback-output-missing'
1004
+ : 'reflection-fallback-readback-missing',
1005
+ expected: 'a completed fallback MRT output and, when requested, mapped diagnostic bytes',
929
1006
  detail: { frameId: fallbackTickets.values().next().value?.frameId },
930
1007
  });
931
1008
  }
932
1009
  this.preserveFallbackLkg(nonNeutral);
933
- this.discardFallbackTickets(fallbackTickets);
934
1010
  return;
935
1011
  }
936
- let readback: {
937
- readonly linearHdr: readonly [number, number, number, number];
938
- readonly hash: string;
939
- readonly graphGeneration: number;
940
- readonly textureIdentity: number;
941
- };
1012
+ let readback:
1013
+ | {
1014
+ readonly linearHdr: readonly [number, number, number, number];
1015
+ readonly hash: string;
1016
+ readonly graphGeneration: number;
1017
+ readonly textureIdentity: number;
1018
+ }
1019
+ | undefined;
942
1020
  try {
943
1021
  readback = await fallbackOutput.readback;
944
1022
  } catch (cause) {
@@ -954,12 +1032,12 @@ export class ReflectionProbeRecordOwner {
954
1032
  [...fallbackTickets].filter(([, pending]) => pending.projection.source !== 'neutral'),
955
1033
  ),
956
1034
  );
957
- this.discardFallbackTickets(fallbackTickets);
958
1035
  return;
959
1036
  }
960
1037
  if (
961
- readback.graphGeneration !== fallbackOutput.graphGeneration ||
962
- readback.textureIdentity !== fallbackOutput.textureIdentity
1038
+ readback !== undefined &&
1039
+ (readback.graphGeneration !== fallbackOutput.graphGeneration ||
1040
+ readback.textureIdentity !== fallbackOutput.textureIdentity)
963
1041
  ) {
964
1042
  this.recordFallbackFailure({
965
1043
  stage: 'completion',
@@ -979,25 +1057,23 @@ export class ReflectionProbeRecordOwner {
979
1057
  [...fallbackTickets].filter(([, pending]) => pending.projection.source !== 'neutral'),
980
1058
  ),
981
1059
  );
982
- this.discardFallbackTickets(fallbackTickets);
983
1060
  return;
984
1061
  }
985
1062
  const eligible: Array<[string, PendingFallback]> = [];
986
1063
  let staleCount = 0;
987
1064
  for (const [renderableKey, pending] of fallbackTickets) {
988
- const staged = this.pendingFallback.get(pending.ticket);
989
1065
  const latest = this.latestFallbackTickets.get(renderableKey);
990
1066
  const retiredAt = this.fallbackRetiredFrames.get(renderableKey);
991
1067
  const committedFrame = this.fallbackCommittedFrames.get(renderableKey);
992
1068
  if (
993
- staged !== pending ||
994
- latest !== pending.ticket ||
1069
+ latest === undefined ||
1070
+ reflectionFallbackProjectionSignature(latest.projection) !==
1071
+ reflectionFallbackProjectionSignature(pending.projection) ||
995
1072
  pending.frameId !== fallbackOutput.frameId ||
996
1073
  pending.deviceGeneration !== this.internals.deviceScope.generation ||
997
1074
  (retiredAt !== undefined && pending.frameId < retiredAt) ||
998
1075
  (committedFrame !== undefined && pending.frameId <= committedFrame)
999
1076
  ) {
1000
- this.pendingFallback.delete(pending.ticket);
1001
1077
  staleCount += 1;
1002
1078
  continue;
1003
1079
  }
@@ -1009,7 +1085,7 @@ export class ReflectionProbeRecordOwner {
1009
1085
  stage: 'completion',
1010
1086
  code: 'reflection-fallback-stale-ticket',
1011
1087
  expected:
1012
- 'the fallback completion ticket to match the latest frame and device generation',
1088
+ 'the completed fallback to match the current projection and device without rolling back a committed frame',
1013
1089
  detail: { staleCount },
1014
1090
  });
1015
1091
  }
@@ -1020,6 +1096,7 @@ export class ReflectionProbeRecordOwner {
1020
1096
  const previousReadback = this.fallbackReadback;
1021
1097
  if (
1022
1098
  hasNonNeutral &&
1099
+ readback !== undefined &&
1023
1100
  (previousReadback === undefined || fallbackOutput.frameId >= previousReadback.frameId)
1024
1101
  ) {
1025
1102
  this.fallbackReadback = Object.freeze({
@@ -1041,8 +1118,8 @@ export class ReflectionProbeRecordOwner {
1041
1118
  readbackStatus: 'complete',
1042
1119
  });
1043
1120
  }
1121
+ if (readback === undefined) this.fallbackReadback = undefined;
1044
1122
  for (const [renderableKey, pending] of eligible) {
1045
- this.pendingFallback.delete(pending.ticket);
1046
1123
  this.commitFallbackProjection(
1047
1124
  renderableKey,
1048
1125
  pending,
@@ -1058,7 +1135,6 @@ export class ReflectionProbeRecordOwner {
1058
1135
  this.destroyProbeResource(resource);
1059
1136
  }
1060
1137
  this.resources.clear();
1061
- this.pendingFallback.clear();
1062
1138
  this.latestFallbackTickets.clear();
1063
1139
  this.fallbackRetiredFrames.clear();
1064
1140
  this.fallbackCommittedFrames.clear();
@@ -1071,6 +1147,8 @@ export class ReflectionProbeRecordOwner {
1071
1147
  this.fallbackFormatAvailable = this.internals.device.caps.rgba16floatRenderable === true;
1072
1148
  this.fallbackReceipt = this.createFallbackReceipt('unavailable');
1073
1149
  if (this.shared !== undefined) {
1150
+ if (this.shared.background !== undefined)
1151
+ this.internals.device.destroyBuffer(this.shared.background.uniform);
1074
1152
  this.internals.device.destroyBuffer(this.shared.faceUniforms);
1075
1153
  this.internals.device.destroyBuffer(this.shared.prefilterUniforms);
1076
1154
  this.internals.device.destroyBuffer(this.shared.vertexBuffer);
@@ -1096,35 +1174,92 @@ export class ReflectionProbeRecordOwner {
1096
1174
  key: string,
1097
1175
  fact: ReflectionProbeFact,
1098
1176
  index: number,
1177
+ sceneRevision = '',
1178
+ skylight?: SkylightSnapshot,
1099
1179
  ): ProbeGpuResource | undefined {
1100
- const existing = this.resources.get(key);
1180
+ const diffuse =
1181
+ skylight === undefined
1182
+ ? [0, 0, 0, 0, 0, 0, 0, 1]
1183
+ : [...skylight.color.map((value) => value * skylight.intensity), 0, ...skylight.rotation];
1184
+ let existing = this.resources.get(key);
1185
+ if (
1186
+ existing !== undefined &&
1187
+ existing.raw.size !== fact.resolution &&
1188
+ existing.pending === undefined
1189
+ ) {
1190
+ this.destroyProbeResource(existing);
1191
+ this.resources.delete(key);
1192
+ existing = undefined;
1193
+ }
1101
1194
  if (existing !== undefined) {
1102
- if (existing.fact.revision !== fact.revision) {
1103
- existing.fact = fact;
1195
+ const previous = existing.fact;
1196
+ const settled =
1197
+ existing.filter.cursor >= existing.filter.faceCount * existing.filter.mipCount;
1198
+ const moved = existing.captureFact.center.some((value, axis) => value !== fact.center[axis]);
1199
+ const requested =
1200
+ existing.captureFact.revision !== fact.revision ||
1201
+ moved ||
1202
+ fact.updateIntent === 'continuous' ||
1203
+ (fact.updateIntent === 'on-change' && existing.captureSceneRevision !== sceneRevision);
1204
+ // Finish the current bounded cycle. Coalesce newer changes into the next
1205
+ // cycle instead of continuously restarting face zero under motion.
1206
+ if (settled && existing.pending === undefined && requested) {
1207
+ existing.captureFact = fact;
1208
+ existing.captureSceneRevision = sceneRevision;
1209
+ existing.captureStartedFrame = this.currentFrame;
1104
1210
  existing.filter = createProbeFilterState({
1105
1211
  probeIndex: index,
1106
1212
  mipCount: PREFILTER_MIP_LEVELS,
1107
1213
  activeGeneration: existing.filter.activeGeneration,
1108
1214
  });
1109
1215
  existing.rawFaceCursor = 0;
1110
- } else {
1111
- existing.fact = fact;
1112
- existing.index = index;
1216
+ }
1217
+ existing.fact = fact;
1218
+ existing.index = index;
1219
+ if (
1220
+ previous.intensity !== fact.intensity ||
1221
+ previous.boxProjection !== fact.boxProjection ||
1222
+ previous.center.some((v, i) => v !== fact.center[i]) ||
1223
+ previous.halfExtents.some((v, i) => v !== fact.halfExtents[i]) ||
1224
+ existing.diffusePayload.some((v, i) => v !== diffuse[i])
1225
+ ) {
1226
+ const written = this.internals.device.queue.writeBuffer(
1227
+ existing.uniformBuffer,
1228
+ 0,
1229
+ new Float32Array([
1230
+ -(Math.max(0, fact.intensity) + PROBE_INTENSITY_SENTINEL_OFFSET),
1231
+ ...fact.center,
1232
+ ...fact.halfExtents,
1233
+ fact.boxProjection === true ? 1 : 0,
1234
+ ...diffuse,
1235
+ ]),
1236
+ );
1237
+ if (!written.ok) this.internals.errorRegistry.fire(written.error);
1238
+ else existing.diffusePayload = diffuse;
1113
1239
  }
1114
1240
  return existing;
1115
1241
  }
1116
1242
  if (this.shared === undefined) return undefined;
1117
- const raw = this.createCubeSet(`reflection-probe-${index}-raw`, fact.resolution);
1243
+ const raw = this.createCubeSet(`reflection-probe-${index}-raw`, fact.resolution, 1);
1118
1244
  const candidate = this.createCubeSet(`reflection-probe-${index}-candidate`, fact.resolution);
1119
1245
  const spare = this.createCubeSet(`reflection-probe-${index}-spare`, fact.resolution);
1120
- if (raw === undefined || candidate === undefined || spare === undefined) return undefined;
1246
+ const releaseSets = () => {
1247
+ for (const set of [raw, candidate, spare]) if (set !== undefined) this.destroyCubeSet(set);
1248
+ };
1249
+ if (raw === undefined || candidate === undefined || spare === undefined) {
1250
+ releaseSets();
1251
+ return undefined;
1252
+ }
1121
1253
  const uniformBuffer = this.internals.device.createBuffer({
1122
1254
  label: `reflection-probe-${index}-uniforms`,
1123
- size: 32,
1255
+ size: 64,
1124
1256
  usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,
1125
1257
  mappedAtCreation: false,
1126
1258
  });
1127
- if (!uniformBuffer.ok) return undefined;
1259
+ if (!uniformBuffer.ok) {
1260
+ releaseSets();
1261
+ return undefined;
1262
+ }
1128
1263
  const payload = new Float32Array([
1129
1264
  -(Math.max(0, fact.intensity) + PROBE_INTENSITY_SENTINEL_OFFSET),
1130
1265
  fact.center[0],
@@ -1133,10 +1268,15 @@ export class ReflectionProbeRecordOwner {
1133
1268
  fact.halfExtents[0],
1134
1269
  fact.halfExtents[1],
1135
1270
  fact.halfExtents[2],
1136
- 0,
1271
+ fact.boxProjection === true ? 1 : 0,
1272
+ ...diffuse,
1137
1273
  ]);
1138
1274
  const written = this.internals.device.queue.writeBuffer(uniformBuffer.value, 0, payload);
1139
- if (!written.ok) return undefined;
1275
+ if (!written.ok) {
1276
+ releaseSets();
1277
+ this.internals.device.destroyBuffer(uniformBuffer.value);
1278
+ return undefined;
1279
+ }
1140
1280
  const filterGroup1 = this.internals.device.createBindGroup({
1141
1281
  label: `reflection-probe-${index}-filter-input`,
1142
1282
  layout: this.shared.cubeGroup1Bgl,
@@ -1145,11 +1285,20 @@ export class ReflectionProbeRecordOwner {
1145
1285
  { binding: 1, resource: { kind: 'sampler', value: this.shared.sampler } },
1146
1286
  ],
1147
1287
  });
1148
- if (!filterGroup1.ok) return undefined;
1288
+ if (!filterGroup1.ok) {
1289
+ releaseSets();
1290
+ this.internals.device.destroyBuffer(uniformBuffer.value);
1291
+ return undefined;
1292
+ }
1149
1293
  const resource: ProbeGpuResource = {
1150
1294
  fact,
1295
+ captureFact: fact,
1296
+ diffusePayload: diffuse,
1297
+ captureSceneRevision: sceneRevision,
1298
+ captureStartedFrame: this.currentFrame,
1299
+ lastCompletedFrame: 0,
1151
1300
  index,
1152
- filter: createProbeFilterState({ probeIndex: index, mipCount: PREFILTER_MIP_LEVELS }),
1301
+ filter: createProbeFilterState({ probeIndex: index, mipCount: candidate.mipViews.length }),
1153
1302
  rawFaceCursor: 0,
1154
1303
  raw,
1155
1304
  active: undefined,
@@ -1163,12 +1312,15 @@ export class ReflectionProbeRecordOwner {
1163
1312
  return resource;
1164
1313
  }
1165
1314
 
1166
- private createSharedResources(filterPipeline: RenderPipeline): ProbeSharedResources | undefined {
1315
+ private createSharedResources(
1316
+ filterPipeline: RenderPipeline,
1317
+ background?: ProbeBackgroundResources,
1318
+ ): ProbeSharedResources | undefined {
1167
1319
  const faceUniforms = createFaceUniformsBuffer(this.internals.device);
1168
1320
  const prefilterUniforms = createPrefilterUniformsBuffer(this.internals.device);
1169
1321
  if (!faceUniforms.ok || !prefilterUniforms.ok) return undefined;
1170
1322
  if (!writeAllFaceUniforms(this.internals.device, faceUniforms.value).ok) return undefined;
1171
- if (!writeAllPrefilterUniforms(this.internals.device, prefilterUniforms.value).ok)
1323
+ if (!writeAllPrefilterUniforms(this.internals.device, prefilterUniforms.value, 1, 'camera').ok)
1172
1324
  return undefined;
1173
1325
  const vertexBuffer = this.internals.device.createBuffer({
1174
1326
  label: 'reflection-probe-capture-cube-vertices',
@@ -1201,6 +1353,7 @@ export class ReflectionProbeRecordOwner {
1201
1353
  return undefined;
1202
1354
  }
1203
1355
  return {
1356
+ background,
1204
1357
  faceUniforms: faceUniforms.value,
1205
1358
  prefilterUniforms: prefilterUniforms.value,
1206
1359
  vertexBuffer: vertexBuffer.value,
@@ -1211,9 +1364,11 @@ export class ReflectionProbeRecordOwner {
1211
1364
  };
1212
1365
  }
1213
1366
 
1214
- private createCubeSet(label: string, requestedSize: number): ProbeCubeSet | undefined {
1215
- const size = Math.min(Math.max(1, Math.floor(requestedSize)), PREFILTER_SIZE);
1216
- const mipCount = Math.min(PREFILTER_MIP_LEVELS, Math.floor(Math.log2(size)) + 1);
1367
+ private createCubeSet(
1368
+ label: string,
1369
+ size: number,
1370
+ mipCount = PREFILTER_MIP_LEVELS,
1371
+ ): ProbeCubeSet | undefined {
1217
1372
  const texture = this.internals.device.createTexture({
1218
1373
  label,
1219
1374
  size: { width: size, height: size, depthOrArrayLayers: 6 },
@@ -1233,7 +1388,10 @@ export class ReflectionProbeRecordOwner {
1233
1388
  mipLevelCount: mipCount,
1234
1389
  arrayLayerCount: 6,
1235
1390
  });
1236
- if (!cubeView.ok) return undefined;
1391
+ if (!cubeView.ok) {
1392
+ this.internals.device.destroyTexture(texture.value);
1393
+ return undefined;
1394
+ }
1237
1395
  const faceViews: TextureView[] = [];
1238
1396
  const mipViews: TextureView[][] = [];
1239
1397
  for (let mip = 0; mip < mipCount; mip += 1) {
@@ -1247,7 +1405,10 @@ export class ReflectionProbeRecordOwner {
1247
1405
  baseArrayLayer: face,
1248
1406
  arrayLayerCount: 1,
1249
1407
  });
1250
- if (!view.ok) return undefined;
1408
+ if (!view.ok) {
1409
+ this.internals.device.destroyTexture(texture.value);
1410
+ return undefined;
1411
+ }
1251
1412
  if (mip === 0) faceViews.push(view.value);
1252
1413
  faces.push(view.value);
1253
1414
  }
@@ -1264,12 +1425,19 @@ export class ReflectionProbeRecordOwner {
1264
1425
  viewFormats: [],
1265
1426
  textureBindingViewDimension: undefined,
1266
1427
  });
1267
- if (!depthTexture.ok) return undefined;
1428
+ if (!depthTexture.ok) {
1429
+ this.internals.device.destroyTexture(texture.value);
1430
+ return undefined;
1431
+ }
1268
1432
  const depthView = this.internals.device.createTextureView(depthTexture.value, {
1269
1433
  label: `${label}-depth-view`,
1270
1434
  dimension: '2d',
1271
1435
  });
1272
- if (!depthView.ok) return undefined;
1436
+ if (!depthView.ok) {
1437
+ this.internals.device.destroyTexture(texture.value);
1438
+ this.internals.device.destroyTexture(depthTexture.value);
1439
+ return undefined;
1440
+ }
1273
1441
  return {
1274
1442
  texture: texture.value,
1275
1443
  cubeView: cubeView.value,