@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
@@ -62,6 +62,7 @@ import type {
62
62
  } from '../render-pipeline';
63
63
  import type { ExtractedLights, ExtractedVolumetricFog } from '../render-system-extract';
64
64
  import { SHADOW_ATLAS_DEFAULT_FACE_SIZE, SHADOW_ATLAS_DEFAULT_LAYERS } from '../shadow-atlas';
65
+ import type { SsrAdmissionResult } from '../ssr/admission';
65
66
  import type { RenderTarget } from '../targets/contracts';
66
67
  import type { RenderTargetPhysical } from '../targets/physical';
67
68
  import {
@@ -82,7 +83,7 @@ import { buildPerFrameBindGroups } from './frame-lighting';
82
83
  import { getTextureIdentity, type RenderFrameState } from './frame-snapshot';
83
84
  import type { GpuPassTimingPassIdentity } from './gpu-pass-timing/contract.js';
84
85
  import type { GpuPassTimingCapture, GpuPassTimingSession } from './gpu-pass-timing/session.js';
85
- import type { GpuTimingCapture, VolumeTimingTimestampWrites } from './gpu-timing';
86
+ import type { GpuTimingCapture } from './gpu-timing';
86
87
  import { encodeMainPass } from './main-pass';
87
88
  import type {
88
89
  _InternalRenderPipelineContext,
@@ -104,6 +105,97 @@ export interface TemporalGraphRoster {
104
105
  readonly uploads: number;
105
106
  }
106
107
 
108
+ export interface ReflectionFallbackGraphRoster {
109
+ readonly enabled: boolean;
110
+ readonly attachments: readonly string[];
111
+ readonly passes: readonly string[];
112
+ readonly bindings: readonly string[];
113
+ readonly historyCount: 0;
114
+ readonly temporalDemand: 0;
115
+ }
116
+
117
+ export interface ReflectionFallbackGraphCandidate {
118
+ readonly generation: number;
119
+ readonly source: 'probe' | 'skylight' | 'neutral';
120
+ readonly roster: ReflectionFallbackGraphRoster;
121
+ }
122
+
123
+ export interface SsrAdmissionGraphRoster {
124
+ readonly enabled: boolean;
125
+ readonly attachments: readonly string[];
126
+ readonly passes: readonly string[];
127
+ readonly bindings: readonly string[];
128
+ readonly historyCount: 0;
129
+ readonly temporalDemand: 0;
130
+ }
131
+
132
+ /**
133
+ * Admission is the sole switch for parent SSR graph work. A blocked result
134
+ * projects to an empty roster, so missing receipts cannot allocate or bind
135
+ * any SSR resource.
136
+ */
137
+ export function createSsrAdmissionGraphRoster(
138
+ admission: Pick<SsrAdmissionResult, 'status'>,
139
+ ): SsrAdmissionGraphRoster {
140
+ if (admission.status !== 'admitted') {
141
+ return {
142
+ enabled: false,
143
+ attachments: [],
144
+ passes: [],
145
+ bindings: [],
146
+ historyCount: 0,
147
+ temporalDemand: 0,
148
+ };
149
+ }
150
+ return {
151
+ enabled: true,
152
+ attachments: ['ssr-reflection-admission'],
153
+ passes: ['ssr-m0-admission'],
154
+ bindings: ['ssr-reflection-admission'],
155
+ historyCount: 0,
156
+ temporalDemand: 0,
157
+ };
158
+ }
159
+
160
+ export type ReflectionFallbackGraphFailure = 'compile-failed' | 'encode-failed' | 'submit-failed';
161
+
162
+ export function createReflectionFallbackGraphRoster(input: {
163
+ readonly fallbackDemand: boolean;
164
+ }): ReflectionFallbackGraphRoster {
165
+ if (!input.fallbackDemand) {
166
+ return {
167
+ enabled: false,
168
+ attachments: [],
169
+ passes: [],
170
+ bindings: [],
171
+ historyCount: 0,
172
+ temporalDemand: 0,
173
+ };
174
+ }
175
+ return {
176
+ enabled: true,
177
+ attachments: ['reflection-fallback-linear-hdr'],
178
+ passes: ['standard-main'],
179
+ bindings: ['reflection-fallback-output'],
180
+ historyCount: 0,
181
+ temporalDemand: 0,
182
+ };
183
+ }
184
+
185
+ export function commitReflectionFallbackGraph(
186
+ candidate: ReflectionFallbackGraphCandidate,
187
+ result:
188
+ | { readonly ok: true }
189
+ | { readonly ok: false; readonly reason: ReflectionFallbackGraphFailure },
190
+ ): {
191
+ readonly visible: boolean;
192
+ readonly generation: number;
193
+ readonly source?: ReflectionFallbackGraphCandidate['source'];
194
+ } {
195
+ if (!result.ok || !candidate.roster.enabled) return { visible: false, generation: 0 };
196
+ return { visible: true, generation: candidate.generation, source: candidate.source };
197
+ }
198
+
107
199
  function importTemporalHistoryTarget(
108
200
  graph: RenderGraphBuilder<RenderPipelineFrame>,
109
201
  label: string,
@@ -719,6 +811,7 @@ export interface RenderFeatureGraphCandidate {
719
811
  }
720
812
 
721
813
  const featureGraphStates = new WeakMap<RenderSystemInternals, RenderFeatureGraphRuntimeState>();
814
+ const graphDeviceGenerations = new WeakMap<object, number>();
722
815
 
723
816
  interface TimingInstrumentationState {
724
817
  readonly instrumentation: RenderGraphPassInstrumentation<RenderPipelineFrame>;
@@ -730,16 +823,6 @@ const timingInstrumentationStates = new WeakMap<
730
823
  TimingInstrumentationState
731
824
  >();
732
825
 
733
- interface VolumeTimingInstrumentationState {
734
- readonly instrumentation: RenderGraphPassInstrumentation<RenderPipelineFrame>;
735
- setCapture(capture: GpuTimingCapture | undefined): void;
736
- }
737
-
738
- const volumeTimingInstrumentationStates = new WeakMap<
739
- RenderSystemInternals,
740
- VolumeTimingInstrumentationState
741
- >();
742
-
743
826
  type CompiledGraphTargetAccess = CompiledRenderGraph<RenderPipelineFrame> & {
744
827
  readonly getColorTargetDescriptor: (
745
828
  name: string,
@@ -930,6 +1013,7 @@ function topologyOf(
930
1013
  standardProfile: internals.standardProfile,
931
1014
  config,
932
1015
  clearOnly,
1016
+ reflectionFallback: { enabled: frameState.reflectionFallbackDemand === true },
933
1017
  surface: {
934
1018
  width,
935
1019
  height,
@@ -1262,9 +1346,11 @@ export function ensureCompiledFrameGraph(
1262
1346
  cubeCaptureState?: CubeCaptureGraphState,
1263
1347
  clearOnly = false,
1264
1348
  transmissionDemand?: TransmissionDemand,
1349
+ occlusion?: import('../scene/visibility/occlusion-runtime').OcclusionFrameProjection,
1265
1350
  volumetricFog?: ExtractedVolumetricFog,
1266
1351
  volumeTopologyCandidate = false,
1267
1352
  standardLighting?: StandardTopologyInputValue,
1353
+ onRecoveryError?: (error: unknown) => void,
1268
1354
  ): CompiledRenderGraph<RenderPipelineFrame> | null {
1269
1355
  const requestedStandardLightingSignature = standardLightingTopologySignature(standardLighting);
1270
1356
  const lastKnownGood = (): CompiledRenderGraph<RenderPipelineFrame> | null =>
@@ -1277,6 +1363,7 @@ export function ensureCompiledFrameGraph(
1277
1363
  const featurePlans = featureGraphCandidate?.plans ?? getRenderFeatureGraphState(internals).plans;
1278
1364
  const projectedFeaturePlans = validateRenderFeaturePlans(featurePlans);
1279
1365
  if (!projectedFeaturePlans.ok) {
1366
+ onRecoveryError?.(projectedFeaturePlans.error);
1280
1367
  reportRenderFeatureGraphError(internals, projectedFeaturePlans.error);
1281
1368
  featureGraphCandidate?.onRejected?.();
1282
1369
  return volumeTopologyCandidate ? null : lastKnownGood();
@@ -1299,6 +1386,7 @@ export function ensureCompiledFrameGraph(
1299
1386
  standardLighting,
1300
1387
  );
1301
1388
  if (!topologyResult.ok) {
1389
+ onRecoveryError?.(topologyResult.error);
1302
1390
  internals.errorRegistry.fire(topologyResult.error);
1303
1391
  featureGraphCandidate?.onRejected?.();
1304
1392
  return volumeTopologyCandidate ? null : lastKnownGood();
@@ -1354,6 +1442,17 @@ export function ensureCompiledFrameGraph(
1354
1442
  : topologyResult.value;
1355
1443
  const key = JSON.stringify({
1356
1444
  topology,
1445
+ // GPU-driven residency can become available after the first record pass
1446
+ // (custom mesh handles are resolved into the per-frame projection). The
1447
+ // topology signature alone is intentionally stable across that lifecycle,
1448
+ // so include the prepared projection's presence to invalidate a cached
1449
+ // CPU-only graph when the GPU owner becomes ready, and vice versa.
1450
+ gpuDrivenProjectionActive: gpuDriven !== undefined,
1451
+ // Query reservations are frame-local transport state. The projection is
1452
+ // renderer-owned and read dynamically by the compiled pass, so a page
1453
+ // rotation must not invalidate the graph or its cached bind groups.
1454
+ occlusionQuery:
1455
+ occlusion === undefined ? undefined : { active: true, sampleCount: occlusion.sampleCount },
1357
1456
  cubeCaptureSlots: cubeCaptureState?.work.length ?? 0,
1358
1457
  reflectionProbeSlots: cubeCaptureState?.reflectionProbes?.work.map((work) => [
1359
1458
  work.probeIndex,
@@ -1385,6 +1484,7 @@ export function ensureCompiledFrameGraph(
1385
1484
  graph: builder,
1386
1485
  ...(standardLighting === undefined ? {} : { standardLighting }),
1387
1486
  capabilities: { rgba16floatRenderable: internals.device.caps.rgba16floatRenderable },
1487
+ ...(occlusion === undefined ? {} : { occlusion }),
1388
1488
  ...(taaHistory === undefined ? {} : { taaHistory }),
1389
1489
  encodeTransmissionMip: ({ pass, resources, source }) => {
1390
1490
  const sourceView = resources.textureView(source);
@@ -1425,6 +1525,7 @@ export function ensureCompiledFrameGraph(
1425
1525
  topology,
1426
1526
  );
1427
1527
  if (!built.ok) {
1528
+ onRecoveryError?.(built.error);
1428
1529
  internals.errorRegistry.fire(built.error);
1429
1530
  featureGraphCandidate?.onRejected?.();
1430
1531
  return volumeTopologyCandidate ? null : lastKnownGood();
@@ -1434,6 +1535,7 @@ export function ensureCompiledFrameGraph(
1434
1535
  surfaceSize: { width: surfaceWidth, height: surfaceHeight },
1435
1536
  });
1436
1537
  if (!compiled.ok) {
1538
+ onRecoveryError?.(compiled.error);
1437
1539
  internals.errorRegistry.fire(compiled.error);
1438
1540
  featureGraphCandidate?.onRejected?.();
1439
1541
  return lastKnownGood();
@@ -1456,6 +1558,10 @@ export function ensureCompiledFrameGraph(
1456
1558
  getColorTargetTexture: (name) => compiledTargets.getColorTargetTexture(name),
1457
1559
  graphGeneration: frameState.graphGeneration,
1458
1560
  };
1561
+ const deviceGeneration = internals.deviceScope?.generation;
1562
+ if (deviceGeneration !== undefined) {
1563
+ graphDeviceGenerations.set(compiled.value, deviceGeneration);
1564
+ }
1459
1565
  gpuDriven?._commitResourceReplacement();
1460
1566
  if (featureGraphCandidate !== undefined && !postProcessAdmission.pending) {
1461
1567
  commitFeatureCandidate(internals, featureGraphCandidate);
@@ -1472,6 +1578,11 @@ export function executeCompiledFrameGraph(
1472
1578
  frame: RenderPipelineFrame,
1473
1579
  encoder: RhiCommandEncoder,
1474
1580
  runPass?: import('@forgeax/engine-render-graph').RenderGraphPassRunner,
1581
+ frameHooks?: {
1582
+ readonly afterGraphExecute?: () => Result<void, RhiError>;
1583
+ readonly onSubmitted?: () => void;
1584
+ readonly onAborted?: () => void;
1585
+ },
1475
1586
  readbackFaces?: readonly number[],
1476
1587
  onSubmitted?: (completed: Promise<unknown>) => void,
1477
1588
  timingCapture?: GpuTimingCapture,
@@ -1494,6 +1605,8 @@ export function executeCompiledFrameGraph(
1494
1605
  rejectTemporalFrame();
1495
1606
  return false;
1496
1607
  }
1608
+ const legacyTimingInstrumentation =
1609
+ timingCapture === undefined ? undefined : createTimingInstrumentation(timingCapture);
1497
1610
  const timingHost = internals as RenderSystemInternals & {
1498
1611
  gpuPassTimingSession?: GpuPassTimingSession | undefined;
1499
1612
  gpuPassTimingCapture?: GpuPassTimingCapture | undefined;
@@ -1525,19 +1638,54 @@ export function executeCompiledFrameGraph(
1525
1638
  ? getTimingInstrumentationState(internals, passTimingCapture)
1526
1639
  : timingCapture === undefined
1527
1640
  ? undefined
1528
- : getVolumeTimingInstrumentationState(internals, timingCapture);
1641
+ : undefined;
1642
+ const graphInstrumentation =
1643
+ passTimingCapture !== undefined
1644
+ ? timingInstrumentationState?.instrumentation
1645
+ : legacyTimingInstrumentation;
1529
1646
  type PreparedCommand = { readonly command: CommandBuffer };
1530
1647
  let preparedCommand: PreparedCommand = { command: undefined as never };
1648
+ const deviceScope = internals.deviceScope;
1649
+ const graphDeviceGeneration = graphDeviceGenerations.get(graph);
1650
+ if (
1651
+ graphDeviceGeneration !== undefined &&
1652
+ deviceScope !== undefined &&
1653
+ graphDeviceGeneration !== deviceScope.generation
1654
+ ) {
1655
+ internals.errorRegistry.fire(
1656
+ new RhiError({
1657
+ code: 'webgpu-runtime-error',
1658
+ expected: 'the compiled frame graph belongs to the active device generation',
1659
+ hint: 'discard the stale graph and rebuild it from the retained logical frame plan',
1660
+ detail: {
1661
+ error: {
1662
+ code: 'stale-frame-graph-generation',
1663
+ message: `graph=${graphDeviceGeneration}; current=${deviceScope.generation}`,
1664
+ },
1665
+ },
1666
+ }),
1667
+ );
1668
+ return false;
1669
+ }
1670
+ const capturedGeneration = deviceScope?.generation;
1531
1671
  const transaction = executeRendererFrameTransaction<PreparedCommand>({
1532
1672
  build: () => ({ ok: true, value: { command: undefined as never } }),
1533
1673
  execute: () => {
1534
- const executed = graph.execute(frame, runPass, timingInstrumentationState?.instrumentation);
1674
+ const executed = graph.execute(frame, runPass, graphInstrumentation);
1535
1675
  timingInstrumentationState?.setCapture(undefined);
1536
1676
  if (!executed.ok) {
1537
1677
  passTimingCapture?.abort({ code: executed.error.code });
1538
1678
  internals.errorRegistry.fire(executed.error);
1539
1679
  return { ok: false, stage: 'execute' };
1540
1680
  }
1681
+ const afterGraphExecute = frameHooks?.afterGraphExecute;
1682
+ if (afterGraphExecute !== undefined) {
1683
+ const recorded = afterGraphExecute();
1684
+ if (!recorded.ok) {
1685
+ internals.errorRegistry.fire(recorded.error);
1686
+ return { ok: false, stage: 'execute' };
1687
+ }
1688
+ }
1541
1689
  return { ok: true, value: undefined };
1542
1690
  },
1543
1691
  finish: () => {
@@ -1547,7 +1695,7 @@ export function executeCompiledFrameGraph(
1547
1695
  const graphAccess = frameState.perFrameGraph;
1548
1696
  const graphTexture = graphAccess?.getColorTargetTexture(graphCapture.name);
1549
1697
  const descriptor = graphAccess?.getColorTargetDescriptor(graphCapture.name);
1550
- const frameId = frameState.frameNumber - 1;
1698
+ const frameId = frameState.frameNumber;
1551
1699
  const captureFailure = (message: string): void => {
1552
1700
  internals.errorRegistry.fire(
1553
1701
  new RhiError({
@@ -1664,6 +1812,43 @@ export function executeCompiledFrameGraph(
1664
1812
  );
1665
1813
  }
1666
1814
  }
1815
+ const fallbackReadback = frameState.reflectionFallbackReadback;
1816
+ frameState.reflectionFallbackReadback = undefined;
1817
+ if (fallbackReadback !== undefined) {
1818
+ const graphAccess = frameState.perFrameGraph;
1819
+ const graphTexture = graphAccess?.getColorTargetTexture(fallbackReadback.name);
1820
+ const descriptor = graphAccess?.getColorTargetDescriptor(fallbackReadback.name);
1821
+ const matches =
1822
+ graphAccess !== undefined &&
1823
+ graphAccess !== null &&
1824
+ graphTexture !== undefined &&
1825
+ descriptor !== undefined &&
1826
+ descriptor.format === fallbackReadback.expected.format &&
1827
+ descriptor.size.width === fallbackReadback.expected.width &&
1828
+ descriptor.size.height === fallbackReadback.expected.height &&
1829
+ descriptor.sample === 1 &&
1830
+ (descriptor.usage & fallbackReadback.expected.usage) ===
1831
+ fallbackReadback.expected.usage &&
1832
+ graphAccess.graphGeneration === fallbackReadback.expected.graphGeneration &&
1833
+ frameState.frameNumber === fallbackReadback.expected.frameId &&
1834
+ getTextureIdentity(graphTexture) === fallbackReadback.expected.textureIdentity;
1835
+ if (matches && graphTexture !== undefined) {
1836
+ encoder.copyTextureToBuffer(
1837
+ { texture: graphTexture },
1838
+ {
1839
+ buffer: fallbackReadback.buffer,
1840
+ bytesPerRow: fallbackReadback.bytesPerRow,
1841
+ rowsPerImage: fallbackReadback.height,
1842
+ },
1843
+ {
1844
+ width: fallbackReadback.width,
1845
+ height: fallbackReadback.height,
1846
+ depthOrArrayLayers: 1,
1847
+ },
1848
+ );
1849
+ fallbackReadback.encoded = true;
1850
+ }
1851
+ }
1667
1852
  internals.encodeRenderTargetReadbacks?.(encoder, readbackFaces);
1668
1853
  const stagedGpuState = frameState.temporalGpuState;
1669
1854
  if (stagedGpuState !== undefined && !hasPendingTemporalGpuSubmit(stagedGpuState)) {
@@ -1696,6 +1881,13 @@ export function executeCompiledFrameGraph(
1696
1881
  return { ok: true, value: undefined };
1697
1882
  },
1698
1883
  submit: () => {
1884
+ const injectedFailure = internals.beforeSubmit?.(internals.device);
1885
+ if (injectedFailure !== undefined) {
1886
+ passTimingCapture?.abort({ code: injectedFailure.code });
1887
+ timingCapture?.discard();
1888
+ internals.errorRegistry.fire(injectedFailure);
1889
+ return { ok: false, stage: 'submit' };
1890
+ }
1699
1891
  const submitted = internals.device.queue.submit([preparedCommand.command]);
1700
1892
  if (!submitted.ok) {
1701
1893
  passTimingCapture?.abort({ code: submitted.error.code });
@@ -1706,7 +1898,35 @@ export function executeCompiledFrameGraph(
1706
1898
  timingCapture?.markSubmitted();
1707
1899
  return { ok: true, value: undefined };
1708
1900
  },
1901
+ ...(capturedGeneration === undefined || deviceScope === undefined
1902
+ ? {}
1903
+ : {
1904
+ generationFence: {
1905
+ capturedGeneration,
1906
+ // Read the owner at submit time. Recovery publishes a replacement
1907
+ // scope synchronously between finish and submit; retaining the
1908
+ // entry scope here would make that race invisible to the fence.
1909
+ currentGeneration: () => internals.deviceScope?.generation ?? -1,
1910
+ },
1911
+ }),
1709
1912
  commit: () => {
1913
+ frameHooks?.onSubmitted?.();
1914
+ if (frameState.temporalFrameInput !== undefined) {
1915
+ const temporal = frameState.temporalFrameTransaction.commit({ accepted: true });
1916
+ if (temporal.ok) {
1917
+ frameState.temporalFrame = temporal.value;
1918
+ } else {
1919
+ internals.errorRegistry.fire(
1920
+ new RhiError({
1921
+ code: 'webgpu-runtime-error',
1922
+ expected: 'the staged temporal frame to commit after queue submission',
1923
+ hint: 'discard the temporal candidate and retry the next frame',
1924
+ detail: { error: temporal.error },
1925
+ }),
1926
+ );
1927
+ }
1928
+ frameState.temporalFrameInput = undefined;
1929
+ }
1710
1930
  if (passTimingCapture !== undefined) {
1711
1931
  const completion = internals.device.queue.onSubmittedWorkDone();
1712
1932
  timingHost.gpuPassTimingSubmittedWork = completion;
@@ -1783,6 +2003,7 @@ export function executeCompiledFrameGraph(
1783
2003
  onSubmitted?.(internals.device.queue.onSubmittedWorkDone());
1784
2004
  },
1785
2005
  abort: (failure) => {
2006
+ frameHooks?.onAborted?.();
1786
2007
  passTimingCapture?.abort({ code: failure.stage });
1787
2008
  timingHost.gpuPassTimingCapture = undefined;
1788
2009
  timingHost.gpuPassTimingSubmittedWork = undefined;
@@ -1814,6 +2035,41 @@ export function executeCompiledFrameGraph(
1814
2035
  return transaction.ok;
1815
2036
  }
1816
2037
 
2038
+ function createTimingInstrumentation(
2039
+ capture: GpuTimingCapture,
2040
+ ): RenderGraphPassInstrumentation<RenderPipelineFrame> {
2041
+ return {
2042
+ begin: (pass): RenderGraphPassInstrumentationScope | undefined => {
2043
+ // WebGPU has no portable timestamp boundary for a copy pass. Do not
2044
+ // pretend a command-encoder marker exists; frame timing remains valid
2045
+ // when at least one raster/compute pass is present.
2046
+ if (pass.kind === 'copy') return undefined;
2047
+ const writes = capture.beginPass(pass.name, pass.kind, pass.executionIndex);
2048
+ if (writes === undefined) return undefined;
2049
+ if (pass.kind === 'raster') {
2050
+ return {
2051
+ renderPassDescriptor: (descriptor) => {
2052
+ if (descriptor.timestampWrites !== undefined) {
2053
+ capture.markOwnerConflict(pass.name);
2054
+ return descriptor;
2055
+ }
2056
+ return { ...descriptor, timestampWrites: writes };
2057
+ },
2058
+ };
2059
+ }
2060
+ return {
2061
+ computePassDescriptor: (descriptor) => {
2062
+ if (descriptor.timestampWrites !== undefined) {
2063
+ capture.markOwnerConflict(pass.name);
2064
+ return descriptor;
2065
+ }
2066
+ return { ...descriptor, timestampWrites: writes };
2067
+ },
2068
+ };
2069
+ },
2070
+ };
2071
+ }
2072
+
1817
2073
  function getTimingInstrumentationState(
1818
2074
  internals: RenderSystemInternals,
1819
2075
  capture: GpuPassTimingCapture,
@@ -1912,73 +2168,3 @@ function getTimingInstrumentationState(
1912
2168
  timingInstrumentationStates.set(internals, state);
1913
2169
  return state;
1914
2170
  }
1915
-
1916
- function getVolumeTimingInstrumentationState(
1917
- internals: RenderSystemInternals,
1918
- capture: GpuTimingCapture,
1919
- ): VolumeTimingInstrumentationState {
1920
- const existing = volumeTimingInstrumentationStates.get(internals);
1921
- if (existing !== undefined) {
1922
- existing.setCapture(capture);
1923
- return existing;
1924
- }
1925
- let activeCapture: GpuTimingCapture | undefined = capture;
1926
- let activePassName: string | undefined;
1927
- let activeWrites: VolumeTimingTimestampWrites | undefined;
1928
- const rasterScope: RenderGraphPassInstrumentationScope = {
1929
- renderPassDescriptor: (descriptor) => {
1930
- const currentCapture = activeCapture;
1931
- const passName = activePassName;
1932
- const writes = activeWrites;
1933
- if (currentCapture === undefined || passName === undefined || writes === undefined) {
1934
- return descriptor;
1935
- }
1936
- if (descriptor.timestampWrites !== undefined) {
1937
- currentCapture.skipPass(passName);
1938
- activeWrites = undefined;
1939
- return descriptor;
1940
- }
1941
- return { ...descriptor, timestampWrites: writes };
1942
- },
1943
- };
1944
- const computeScope: RenderGraphPassInstrumentationScope = {
1945
- computePassDescriptor: (descriptor) => {
1946
- const currentCapture = activeCapture;
1947
- const passName = activePassName;
1948
- const writes = activeWrites;
1949
- if (currentCapture === undefined || passName === undefined || writes === undefined) {
1950
- return descriptor;
1951
- }
1952
- if (descriptor.timestampWrites !== undefined) {
1953
- currentCapture.skipPass(passName);
1954
- activeWrites = undefined;
1955
- return descriptor;
1956
- }
1957
- return { ...descriptor, timestampWrites: writes };
1958
- },
1959
- };
1960
- const instrumentation: RenderGraphPassInstrumentation<RenderPipelineFrame> = {
1961
- begin: (pass) => {
1962
- const currentCapture = activeCapture;
1963
- if (currentCapture === undefined) return undefined;
1964
- activePassName = pass.name;
1965
- activeWrites = currentCapture.recordPass(pass.name);
1966
- if (activeWrites === undefined) return undefined;
1967
- if (pass.kind === 'raster') return rasterScope;
1968
- if (pass.kind === 'compute') return computeScope;
1969
- currentCapture.skipPass(pass.name);
1970
- activeWrites = undefined;
1971
- return undefined;
1972
- },
1973
- };
1974
- const state: VolumeTimingInstrumentationState = {
1975
- instrumentation,
1976
- setCapture: (nextCapture) => {
1977
- activeCapture = nextCapture;
1978
- activePassName = undefined;
1979
- activeWrites = undefined;
1980
- },
1981
- };
1982
- volumeTimingInstrumentationStates.set(internals, state);
1983
- return state;
1984
- }
@@ -9,7 +9,6 @@
9
9
  import { mat4 } from '@forgeax/engine-math';
10
10
  import type { Buffer, RhiQueue } from '@forgeax/engine-rhi';
11
11
  import type { DirectionalShadowQuality } from '../components/directional-shadow-filter';
12
- import type { FogFrame } from '../extract/environment';
13
12
  import type { PointsLinesStyle } from '../points-lines/snapshot';
14
13
  import type { CameraSnapshot } from '../render-contract';
15
14
  import type {
@@ -140,18 +139,11 @@ export function writeViewUbo(
140
139
  light: DirectionalLightSnapshot,
141
140
  lights: ExtractedLights,
142
141
  spotShadowSnapshots: readonly SpotLightSnapshot[],
143
- fogOrTemporalOrOffset?: FogFrame | TemporalView | LegacyTemporalView | number,
144
- temporal?: TemporalView,
142
+ temporalOrOffset?: TemporalView | LegacyTemporalView | number,
145
143
  projectorSpotIndex?: number,
146
144
  ): void {
147
- const byteOffset = typeof fogOrTemporalOrOffset === 'number' ? fogOrTemporalOrOffset : 0;
148
- const fogOrTemporal =
149
- typeof fogOrTemporalOrOffset === 'number' ? undefined : fogOrTemporalOrOffset;
150
- const isTemporal =
151
- fogOrTemporal !== undefined &&
152
- ('currentJitterUv' in fogOrTemporal || 'currentUnjitteredViewProjection' in fogOrTemporal);
153
- const fog = isTemporal ? undefined : fogOrTemporal;
154
- const resolvedTemporal = temporal ?? (isTemporal ? fogOrTemporal : undefined);
145
+ const byteOffset = typeof temporalOrOffset === 'number' ? temporalOrOffset : 0;
146
+ const resolvedTemporal = typeof temporalOrOffset === 'number' ? undefined : temporalOrOffset;
155
147
  // Compose worldViewProj once per frame (view * proj).
156
148
  const projMatrix = computeProjectionMatrix(camera);
157
149
  const viewMatrix = computeViewMatrix(camera);
@@ -172,9 +164,9 @@ export function writeViewUbo(
172
164
  const VIEW_PAYLOAD_FLOATS = 240;
173
165
  const viewPayload = new Float32Array(VIEW_PAYLOAD_FLOATS);
174
166
  for (let i = 0; i < 16; i++) viewPayload[i] = mainProjection[i] ?? 0;
175
- viewPayload[16] = (light.direction[0] ?? 0) * light.intensity;
176
- viewPayload[17] = (light.direction[1] ?? -1) * light.intensity;
177
- viewPayload[18] = (light.direction[2] ?? 0) * light.intensity;
167
+ viewPayload[16] = light.direction[0] ?? 0;
168
+ viewPayload[17] = light.direction[1] ?? -1;
169
+ viewPayload[18] = light.direction[2] ?? 0;
178
170
  viewPayload[20] = light.color[0] ?? 0;
179
171
  viewPayload[21] = light.color[1] ?? 0;
180
172
  viewPayload[22] = light.color[2] ?? 0;
@@ -216,6 +208,16 @@ export function writeViewUbo(
216
208
  viewPayload[228] = camera.near;
217
209
  viewPayload[229] = camera.far;
218
210
  viewPayload[230] = camera.projection === 'orthographic' ? 1 : 0;
211
+ const previousCameraPosition =
212
+ resolvedTemporal !== undefined && 'previousCameraPosition' in resolvedTemporal
213
+ ? resolvedTemporal.previousCameraPosition
214
+ : undefined;
215
+ if (previousCameraPosition !== undefined) {
216
+ viewPayload[232] = previousCameraPosition[0] ?? 0;
217
+ viewPayload[233] = previousCameraPosition[1] ?? 0;
218
+ viewPayload[234] = previousCameraPosition[2] ?? 0;
219
+ viewPayload[235] = 1;
220
+ }
219
221
  // splitPlanes at [108..123] (four vec4 lanes: split/world texel/depth span/reserved).
220
222
  if (lights.splitPlanes !== undefined) {
221
223
  for (let s = 0; s < 4; s++) {
@@ -248,7 +250,7 @@ export function writeViewUbo(
248
250
  // spot index, not by a negative shadow tile: a projector-only spot publishes
249
251
  // its matrix in lane 0 so the shader never samples a zero matrix. Shadowed
250
252
  // projector spots keep their shadow tile lane and carry the projector bit in
251
- // the LightSlot identity word.
253
+ // the DirectLightSlot identity word.
252
254
  // Folded from the former standalone binding 9 UBO to keep the WebGL2
253
255
  // fallback fragment uniform-buffer count <= 11 (GLES 3.0).
254
256
  {
@@ -272,18 +274,6 @@ export function writeViewUbo(
272
274
  }
273
275
  }
274
276
 
275
- // Fog is a resource-owner semantic carried by the shared View ABI. Keep the
276
- // disabled payload zeroed and write only the selected frame facts so both
277
- // direct and clustered lanes consume the same owner projection.
278
- if (fog !== undefined) {
279
- viewPayload[232] = fog.color[0] ?? 0;
280
- viewPayload[233] = fog.color[1] ?? 0;
281
- viewPayload[234] = fog.color[2] ?? 0;
282
- viewPayload[235] = fog.density;
283
- viewPayload[236] = fog.heightFalloff;
284
- viewPayload[237] = fog.maxOpacity;
285
- }
286
-
287
277
  const viewUploadResult = queue.writeBuffer(viewUniformBuffer, byteOffset, viewPayload);
288
278
  if (!viewUploadResult.ok) throw viewUploadResult.error;
289
279