@forgeax/engine-render 0.1.33 → 0.1.34

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 (518) hide show
  1. package/README.md +1010 -124
  2. package/dist/assembly/backend-contract.d.ts +2 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
  5. package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
  6. package/dist/assembly/canvas-draw-guard.d.ts +3 -0
  7. package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
  8. package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
  9. package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
  10. package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
  11. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  12. package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
  13. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
  14. package/dist/assembly/factory.d.ts +1 -1
  15. package/dist/assembly/factory.d.ts.map +1 -1
  16. package/dist/assembly/host-contract.d.ts +3 -3
  17. package/dist/assembly/host-contract.d.ts.map +1 -1
  18. package/dist/assembly/material/assembly.d.ts.map +1 -1
  19. package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
  20. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
  21. package/dist/assembly/material-shader-policy.d.ts +16 -2
  22. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  23. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
  24. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  25. package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
  26. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  27. package/dist/assembly/render-feature-post-processes.d.ts +6 -0
  28. package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
  29. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  30. package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
  31. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
  32. package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
  33. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  34. package/dist/assembly/renderer-inspection.d.ts +11 -0
  35. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  36. package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
  37. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
  38. package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
  39. package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
  40. package/dist/assembly/webgpu-ready.d.ts +1 -1
  41. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  42. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
  43. package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
  44. package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
  45. package/dist/assembly/webgpu-renderer.d.ts +1 -1
  46. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  47. package/dist/authoring.mjs +1 -1
  48. package/dist/barrel-distortion.d.ts +47 -0
  49. package/dist/barrel-distortion.d.ts.map +1 -0
  50. package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
  51. package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
  52. package/dist/{chunk-ZDQWGQW7.mjs → chunk-HEB564WF.mjs} +4 -4
  53. package/dist/{chunk-ZDQWGQW7.mjs.map → chunk-HEB564WF.mjs.map} +1 -1
  54. package/dist/{chunk-VOZWDM3L.mjs → chunk-MKDIT2EM.mjs} +1307 -188
  55. package/dist/chunk-MKDIT2EM.mjs.map +1 -0
  56. package/dist/{chunk-LEAXOMYJ.mjs → chunk-OCDLEI6I.mjs} +3 -3
  57. package/dist/{chunk-LEAXOMYJ.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
  58. package/dist/chunk-ODZWR6JQ.mjs +4927 -0
  59. package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
  60. package/dist/{chunk-3RTCJTH4.mjs → chunk-SHFUFJ5N.mjs} +184 -13
  61. package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
  62. package/dist/{chunk-OO3DRYK7.mjs → chunk-UI5SFODX.mjs} +176 -96
  63. package/dist/chunk-UI5SFODX.mjs.map +1 -0
  64. package/dist/{chunk-PLAXOOX5.mjs → chunk-UINHLCZA.mjs} +561 -79
  65. package/dist/chunk-UINHLCZA.mjs.map +1 -0
  66. package/dist/{chunk-NB2S7ZRX.mjs → chunk-WEX45HKH.mjs} +127 -386
  67. package/dist/chunk-WEX45HKH.mjs.map +1 -0
  68. package/dist/cloud/density.d.ts +55 -0
  69. package/dist/cloud/density.d.ts.map +1 -0
  70. package/dist/cloud/extract.d.ts +25 -0
  71. package/dist/cloud/extract.d.ts.map +1 -0
  72. package/dist/cloud/feature.d.ts +57 -0
  73. package/dist/cloud/feature.d.ts.map +1 -0
  74. package/dist/cloud/frame-context.d.ts +8 -0
  75. package/dist/cloud/frame-context.d.ts.map +1 -0
  76. package/dist/cloud/inspection.d.ts +59 -0
  77. package/dist/cloud/inspection.d.ts.map +1 -0
  78. package/dist/cloud/optics.d.ts +56 -0
  79. package/dist/cloud/optics.d.ts.map +1 -0
  80. package/dist/cloud/parameters.d.ts +73 -0
  81. package/dist/cloud/parameters.d.ts.map +1 -0
  82. package/dist/cloud/resources.d.ts +60 -0
  83. package/dist/cloud/resources.d.ts.map +1 -0
  84. package/dist/cloud/shadow.d.ts +42 -0
  85. package/dist/cloud/shadow.d.ts.map +1 -0
  86. package/dist/cloud/temporal.d.ts +74 -0
  87. package/dist/cloud/temporal.d.ts.map +1 -0
  88. package/dist/components/barrel-distortion.d.ts +13 -0
  89. package/dist/components/barrel-distortion.d.ts.map +1 -0
  90. package/dist/components/cloud-layer.d.ts +29 -0
  91. package/dist/components/cloud-layer.d.ts.map +1 -0
  92. package/dist/components/index.d.ts +2 -0
  93. package/dist/components/index.d.ts.map +1 -1
  94. package/dist/components/instances.d.ts +20 -6
  95. package/dist/components/instances.d.ts.map +1 -1
  96. package/dist/construct-renderer.d.ts +1 -1
  97. package/dist/construct-renderer.d.ts.map +1 -1
  98. package/dist/construct-renderer.mjs +6759 -2875
  99. package/dist/construct-renderer.mjs.map +1 -1
  100. package/dist/dynamic-geometry.d.ts +5 -1
  101. package/dist/dynamic-geometry.d.ts.map +1 -1
  102. package/dist/errors/cloud.d.ts +59 -0
  103. package/dist/errors/cloud.d.ts.map +1 -0
  104. package/dist/errors/render.d.ts +18 -4
  105. package/dist/errors/render.d.ts.map +1 -1
  106. package/dist/examples/single-layer-medium-surface.d.ts +47 -0
  107. package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
  108. package/dist/extract/camera.d.ts.map +1 -1
  109. package/dist/extract/contracts.d.ts +5 -1
  110. package/dist/extract/contracts.d.ts.map +1 -1
  111. package/dist/features/barrel-distortion.d.ts +29 -0
  112. package/dist/features/barrel-distortion.d.ts.map +1 -0
  113. package/dist/features/error-reporting.d.ts +6 -2
  114. package/dist/features/error-reporting.d.ts.map +1 -1
  115. package/dist/features/host.d.ts +10 -0
  116. package/dist/features/host.d.ts.map +1 -1
  117. package/dist/features/plan.d.ts +8 -0
  118. package/dist/features/plan.d.ts.map +1 -1
  119. package/dist/features/render-graph-contribution.d.ts +5 -0
  120. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  121. package/dist/features/render-graph-raster.d.ts +1 -0
  122. package/dist/features/render-graph-raster.d.ts.map +1 -1
  123. package/dist/features/targets.d.ts +2 -0
  124. package/dist/features/targets.d.ts.map +1 -1
  125. package/dist/features/types.d.ts +44 -0
  126. package/dist/features/types.d.ts.map +1 -1
  127. package/dist/fullscreen-post-process-pass.d.ts +15 -7
  128. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  129. package/dist/gpu-dirty-ranges.d.ts +11 -0
  130. package/dist/gpu-dirty-ranges.d.ts.map +1 -0
  131. package/dist/gpu-driven/batch-topology.d.ts +17 -0
  132. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  133. package/dist/gpu-driven/material-artifacts.d.ts +6 -0
  134. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  135. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  136. package/dist/gpu-driven/production-raster-material.d.ts +178 -0
  137. package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
  138. package/dist/gpu-driven/production-raster.d.ts +47 -3
  139. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  140. package/dist/gpu-driven/resource-allocation.d.ts +31 -0
  141. package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
  142. package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
  143. package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
  144. package/dist/gpu-driven/view-gpu.d.ts +26 -2
  145. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  146. package/dist/gpu-scene.d.ts +5 -0
  147. package/dist/gpu-scene.d.ts.map +1 -1
  148. package/dist/hdrp-buffers.d.ts +2 -2
  149. package/dist/hdrp-buffers.d.ts.map +1 -1
  150. package/dist/ibl/skylight-bind-group.d.ts +10 -1
  151. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  152. package/dist/index.d.ts +27 -7
  153. package/dist/index.d.ts.map +1 -1
  154. package/dist/index.mjs +258 -8
  155. package/dist/index.mjs.map +1 -1
  156. package/dist/inspection-types.d.ts +135 -1
  157. package/dist/inspection-types.d.ts.map +1 -1
  158. package/dist/instance-buffer-cache.d.ts +4 -4
  159. package/dist/instance-buffer-cache.d.ts.map +1 -1
  160. package/dist/instances.d.ts +48 -100
  161. package/dist/instances.d.ts.map +1 -1
  162. package/dist/internal.mjs +7 -7
  163. package/dist/pbr-pipeline.d.ts +19 -1
  164. package/dist/pbr-pipeline.d.ts.map +1 -1
  165. package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
  166. package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
  167. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  168. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  169. package/dist/pipeline/standard-output/types.d.ts +4 -2
  170. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  171. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  172. package/dist/pipeline/standard-post.d.ts.map +1 -1
  173. package/dist/pipeline-builder.d.ts +1 -1
  174. package/dist/pipeline-builder.d.ts.map +1 -1
  175. package/dist/plugin.d.ts.map +1 -1
  176. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
  177. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  178. package/dist/record/barrel-distortion-frame.d.ts +15 -0
  179. package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
  180. package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
  181. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
  182. package/dist/record/fold-buckets.d.ts +95 -0
  183. package/dist/record/fold-buckets.d.ts.map +1 -0
  184. package/dist/record/fold-instance-buffer.d.ts +6 -0
  185. package/dist/record/fold-instance-buffer.d.ts.map +1 -0
  186. package/dist/record/frame-lighting.d.ts +1 -0
  187. package/dist/record/frame-lighting.d.ts.map +1 -1
  188. package/dist/record/frame-snapshot.d.ts +37 -3
  189. package/dist/record/frame-snapshot.d.ts.map +1 -1
  190. package/dist/record/frame.d.ts +10 -61
  191. package/dist/record/frame.d.ts.map +1 -1
  192. package/dist/record/gpu-draw-receipts.d.ts +11 -0
  193. package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
  194. package/dist/record/gpu-timing.d.ts +8 -0
  195. package/dist/record/gpu-timing.d.ts.map +1 -1
  196. package/dist/record/main-pass-geometry.d.ts +21 -5
  197. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  198. package/dist/record/main-pass-material.d.ts +7 -1
  199. package/dist/record/main-pass-material.d.ts.map +1 -1
  200. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  201. package/dist/record/main-pass.d.ts +13 -2
  202. package/dist/record/main-pass.d.ts.map +1 -1
  203. package/dist/record/motion-blur-receipt.d.ts +11 -0
  204. package/dist/record/motion-blur-receipt.d.ts.map +1 -0
  205. package/dist/record/probe-blend-buffer.d.ts +16 -0
  206. package/dist/record/probe-blend-buffer.d.ts.map +1 -0
  207. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  208. package/dist/record/render-context.d.ts +22 -3
  209. package/dist/record/render-context.d.ts.map +1 -1
  210. package/dist/record/shadow-pass.d.ts +2 -0
  211. package/dist/record/shadow-pass.d.ts.map +1 -1
  212. package/dist/record/skybox-post-pass.d.ts +1 -1
  213. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  214. package/dist/record/typed-frame-graph.d.ts +22 -2
  215. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  216. package/dist/record/view-ubo.d.ts +11 -3
  217. package/dist/record/view-ubo.d.ts.map +1 -1
  218. package/dist/record/volume-params.d.ts +9 -0
  219. package/dist/record/volume-params.d.ts.map +1 -0
  220. package/dist/recovery/render-system-candidate.d.ts +10 -0
  221. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  222. package/dist/reflection/record-owner.d.ts.map +1 -1
  223. package/dist/render-contract.d.ts +42 -4
  224. package/dist/render-contract.d.ts.map +1 -1
  225. package/dist/render-graph-primitives.d.ts.map +1 -1
  226. package/dist/render-pipeline.d.ts +103 -2
  227. package/dist/render-pipeline.d.ts.map +1 -1
  228. package/dist/render-system-extract-tail.d.ts +3 -2
  229. package/dist/render-system-extract-tail.d.ts.map +1 -1
  230. package/dist/render-system-extract.d.ts +16 -9
  231. package/dist/render-system-extract.d.ts.map +1 -1
  232. package/dist/render-system-presentation.d.ts +23 -0
  233. package/dist/render-system-presentation.d.ts.map +1 -0
  234. package/dist/render-system-producer-roots.d.ts +10 -0
  235. package/dist/render-system-producer-roots.d.ts.map +1 -0
  236. package/dist/render-system-residency.d.ts +12 -0
  237. package/dist/render-system-residency.d.ts.map +1 -0
  238. package/dist/render-system.d.ts +19 -14
  239. package/dist/render-system.d.ts.map +1 -1
  240. package/dist/scene/probe-blend.d.ts +27 -0
  241. package/dist/scene/probe-blend.d.ts.map +1 -1
  242. package/dist/scene/render-scene.d.ts +12 -5
  243. package/dist/scene/render-scene.d.ts.map +1 -1
  244. package/dist/ssao-buffers.d.ts +9 -0
  245. package/dist/ssao-buffers.d.ts.map +1 -1
  246. package/dist/surface/dynamic-input.d.ts +133 -0
  247. package/dist/surface/dynamic-input.d.ts.map +1 -0
  248. package/dist/surface/gpu-driven.d.ts +41 -0
  249. package/dist/surface/gpu-driven.d.ts.map +1 -0
  250. package/dist/surface/submission-observation.d.ts +136 -0
  251. package/dist/surface/submission-observation.d.ts.map +1 -0
  252. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  253. package/dist/temporal/gpu.d.ts +13 -1
  254. package/dist/temporal/gpu.d.ts.map +1 -1
  255. package/dist/temporal/index.mjs +5 -5
  256. package/dist/temporal/inspection.d.ts.map +1 -1
  257. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  258. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
  259. package/dist/transmission/single-layer-medium.d.ts +89 -0
  260. package/dist/transmission/single-layer-medium.d.ts.map +1 -0
  261. package/dist/typed-render-graph-primitives.d.ts +14 -2
  262. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  263. package/dist/volume/component.d.ts +9 -4
  264. package/dist/volume/component.d.ts.map +1 -1
  265. package/dist/volume/extract.d.ts +1 -1
  266. package/dist/volume/extract.d.ts.map +1 -1
  267. package/dist/volume/inspection.d.ts +2 -0
  268. package/dist/volume/inspection.d.ts.map +1 -1
  269. package/dist/volume/passes.d.ts +4 -1
  270. package/dist/volume/passes.d.ts.map +1 -1
  271. package/dist/volume/resources.d.ts.map +1 -1
  272. package/package.json +22 -21
  273. package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
  274. package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
  275. package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
  276. package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
  277. package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
  278. package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
  279. package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
  280. package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
  281. package/src/__tests__/factory-contract.integration.test.ts +295 -45
  282. package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
  283. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
  284. package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
  285. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
  286. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
  287. package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
  288. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
  289. package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
  290. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +6 -5
  291. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +94 -6
  292. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
  293. package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
  294. package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
  295. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
  296. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
  297. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
  298. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
  299. package/src/__tests__/gpu-scene.unit.test.ts +119 -9
  300. package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
  301. package/src/__tests__/instances-culling.integration.test.ts +10 -36
  302. package/src/__tests__/instances-store.unit.test.ts +97 -305
  303. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  304. package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
  305. package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
  306. package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
  307. package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
  308. package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
  309. package/src/__tests__/motion-blur-compute.dawn.test.ts +13 -7
  310. package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
  311. package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
  312. package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
  313. package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
  314. package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
  315. package/src/__tests__/probe-bindings.unit.test.ts +582 -1
  316. package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
  317. package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
  318. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
  319. package/src/__tests__/render-error-code-owner.test-d.ts +7 -0
  320. package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
  321. package/src/__tests__/render-feature-error-reporting.unit.test.ts +21 -1
  322. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
  323. package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
  324. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
  325. package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
  326. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +20 -20
  327. package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
  328. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
  329. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
  330. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
  331. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
  332. package/src/__tests__/renderer-frame-transaction.integration.test.ts +26 -10
  333. package/src/__tests__/resource-allocation.unit.test.ts +123 -0
  334. package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
  335. package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
  336. package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
  337. package/src/__tests__/skinned-shadow-caster.test.ts +15 -0
  338. package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
  339. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
  340. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
  341. package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
  342. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
  343. package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
  344. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
  345. package/src/__tests__/standard-pipeline.integration.test.ts +182 -1
  346. package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
  347. package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
  348. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
  349. package/src/__tests__/temporal-performance.integration.test.ts +3 -3
  350. package/src/__tests__/visibility-instances.integration.test.ts +7 -19
  351. package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
  352. package/src/__tests__/volume-optics-oracle.unit.test.ts +4 -2
  353. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +30 -20
  354. package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
  355. package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
  356. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
  357. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +113 -9
  358. package/src/__tests__/volumetric-fog-topology.unit.test.ts +5 -3
  359. package/src/assembly/backend-contract.ts +30 -0
  360. package/src/assembly/barrel-distortion-inspection.ts +22 -0
  361. package/src/assembly/canvas-draw-guard.ts +11 -0
  362. package/src/assembly/cloud-shadow-entry.ts +22 -0
  363. package/src/assembly/dynamic-geometry-host.ts +65 -37
  364. package/src/assembly/dynamic-geometry-runtime.ts +7 -1
  365. package/src/assembly/factory.ts +2 -30
  366. package/src/assembly/host-contract.ts +3 -3
  367. package/src/assembly/material/assembly.ts +25 -13
  368. package/src/assembly/material/pipeline-helpers.ts +53 -12
  369. package/src/assembly/material-shader-policy.ts +55 -0
  370. package/src/assembly/material-shader-prewarm.ts +21 -10
  371. package/src/assembly/recovery/device-loss-fanout.ts +13 -0
  372. package/src/assembly/recovery/renderer-recover.ts +41 -18
  373. package/src/assembly/render-feature-post-processes.ts +54 -0
  374. package/src/assembly/renderer-facade.ts +4 -1
  375. package/src/assembly/renderer-feature-inspection.ts +8 -2
  376. package/src/assembly/renderer-frame-transaction.ts +23 -0
  377. package/src/assembly/renderer-inspection.ts +28 -0
  378. package/src/assembly/skin-palette-owner.ts +1 -1
  379. package/src/assembly/temporal-post-process-prewarm.ts +3 -3
  380. package/src/assembly/webgpu-pbr-ready.ts +9 -1
  381. package/src/assembly/webgpu-ready-per-pass.ts +104 -0
  382. package/src/assembly/webgpu-ready.ts +115 -61
  383. package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
  384. package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
  385. package/src/assembly/webgpu-renderer.ts +214 -252
  386. package/src/assembly/webgpu-vertex-layouts.ts +1 -1
  387. package/src/barrel-distortion.ts +247 -0
  388. package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
  389. package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
  390. package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
  391. package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
  392. package/src/cloud/density.ts +600 -0
  393. package/src/cloud/extract.ts +110 -0
  394. package/src/cloud/feature.ts +1810 -0
  395. package/src/cloud/frame-context.ts +42 -0
  396. package/src/cloud/inspection.ts +130 -0
  397. package/src/cloud/optics.ts +285 -0
  398. package/src/cloud/parameters.ts +255 -0
  399. package/src/cloud/resources.ts +122 -0
  400. package/src/cloud/shadow.ts +167 -0
  401. package/src/cloud/temporal.ts +226 -0
  402. package/src/components/barrel-distortion.ts +46 -0
  403. package/src/components/cloud-layer.ts +47 -0
  404. package/src/components/index.ts +2 -0
  405. package/src/components/instances.ts +18 -45
  406. package/src/components/sprite-instances.ts +1 -1
  407. package/src/construct-renderer.ts +1 -1
  408. package/src/dynamic-geometry.ts +12 -1
  409. package/src/errors/cloud.ts +103 -0
  410. package/src/errors/render.ts +44 -7
  411. package/src/examples/single-layer-medium-surface.ts +59 -0
  412. package/src/extract/camera.ts +15 -1
  413. package/src/extract/contracts.ts +5 -0
  414. package/src/features/barrel-distortion.ts +172 -0
  415. package/src/features/error-reporting.ts +26 -6
  416. package/src/features/host.ts +115 -14
  417. package/src/features/plan.ts +8 -0
  418. package/src/features/render-graph-contribution.ts +9 -0
  419. package/src/features/render-graph-raster.ts +45 -3
  420. package/src/features/targets.ts +66 -0
  421. package/src/features/types.ts +47 -0
  422. package/src/fullscreen-post-process-pass.ts +41 -9
  423. package/src/gpu-dirty-ranges.ts +48 -0
  424. package/src/gpu-driven/batch-topology.ts +53 -0
  425. package/src/gpu-driven/material-artifacts.ts +33 -25
  426. package/src/gpu-driven/prepared-draw.ts +12 -4
  427. package/src/gpu-driven/production-raster-material.ts +1894 -0
  428. package/src/gpu-driven/production-raster.ts +825 -784
  429. package/src/gpu-driven/resource-allocation.ts +142 -0
  430. package/src/gpu-driven/shadow-ownership.ts +71 -0
  431. package/src/gpu-driven/view-gpu.ts +164 -10
  432. package/src/gpu-scene.ts +75 -84
  433. package/src/hdrp-buffers.ts +4 -3
  434. package/src/ibl/skylight-bind-group.ts +49 -7
  435. package/src/index.ts +196 -9
  436. package/src/inspection-types.ts +162 -0
  437. package/src/instance-buffer-cache.ts +4 -4
  438. package/src/instances.ts +149 -569
  439. package/src/pbr-pipeline.ts +219 -13
  440. package/src/pipeline/single-layer-medium-passes.ts +267 -0
  441. package/src/pipeline/standard-forward-lane.ts +313 -57
  442. package/src/pipeline/standard-output/graph.ts +8 -2
  443. package/src/pipeline/standard-output/types.ts +12 -1
  444. package/src/pipeline/standard-pipeline.ts +291 -18
  445. package/src/pipeline/standard-post.ts +90 -24
  446. package/src/pipeline-builder.ts +1 -1
  447. package/src/plugin.ts +4 -0
  448. package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
  449. package/src/prepare/prepared-graphics-resolver.ts +2 -0
  450. package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
  451. package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
  452. package/src/record/__tests__/temporal-payload.unit.test.ts +1 -1
  453. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
  454. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
  455. package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
  456. package/src/record/barrel-distortion-frame.ts +110 -0
  457. package/src/record/dynamic-geometry-consumption.ts +39 -9
  458. package/src/record/fold-buckets.ts +852 -0
  459. package/src/record/fold-instance-buffer.ts +51 -0
  460. package/src/record/frame-lighting.ts +36 -2
  461. package/src/record/frame-snapshot.ts +39 -3
  462. package/src/record/frame.ts +217 -1084
  463. package/src/record/gpu-draw-receipts.ts +38 -0
  464. package/src/record/gpu-timing.ts +48 -5
  465. package/src/record/main-pass-geometry.ts +251 -82
  466. package/src/record/main-pass-material.ts +66 -4
  467. package/src/record/main-pass-sprite-draws.ts +7 -65
  468. package/src/record/main-pass.ts +156 -20
  469. package/src/record/motion-blur-receipt.ts +91 -0
  470. package/src/record/probe-blend-buffer.ts +180 -0
  471. package/src/record/recovery-pipeline.ts +35 -3
  472. package/src/record/render-context.ts +39 -3
  473. package/src/record/shadow-pass.ts +30 -1
  474. package/src/record/skybox-post-pass.ts +28 -4
  475. package/src/record/typed-frame-graph.ts +770 -134
  476. package/src/record/view-ubo.ts +26 -3
  477. package/src/record/volume-params.ts +225 -0
  478. package/src/recovery/render-system-candidate.ts +235 -42
  479. package/src/reflection/record-owner.ts +7 -3
  480. package/src/render-contract.ts +48 -4
  481. package/src/render-graph-primitives.ts +7 -1
  482. package/src/render-pipeline.ts +130 -0
  483. package/src/render-system-extract-tail.ts +57 -61
  484. package/src/render-system-extract.ts +74 -76
  485. package/src/render-system-presentation.ts +56 -0
  486. package/src/render-system-producer-roots.ts +96 -0
  487. package/src/render-system-residency.ts +159 -0
  488. package/src/render-system.ts +347 -363
  489. package/src/scene/probe-blend.ts +96 -4
  490. package/src/scene/render-scene.ts +349 -280
  491. package/src/ssao-buffers.ts +95 -2
  492. package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
  493. package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
  494. package/src/surface/dynamic-input.ts +658 -0
  495. package/src/surface/gpu-driven.ts +147 -0
  496. package/src/surface/submission-observation.ts +517 -0
  497. package/src/systems/skin-palette-allocator.ts +4 -1
  498. package/src/temporal/gpu.ts +101 -17
  499. package/src/temporal/inspection.ts +7 -1
  500. package/src/temporal/standard-scene-data.ts +5 -0
  501. package/src/temporal/target-coverage-attachment.ts +4 -0
  502. package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
  503. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
  504. package/src/transmission/single-layer-medium.ts +322 -0
  505. package/src/typed-render-graph-primitives.ts +70 -2
  506. package/src/volume/component.ts +10 -9
  507. package/src/volume/extract.ts +11 -5
  508. package/src/volume/inspection.ts +3 -0
  509. package/src/volume/passes.ts +87 -4
  510. package/src/volume/resources.ts +2 -1
  511. package/dist/chunk-3RTCJTH4.mjs.map +0 -1
  512. package/dist/chunk-NB2S7ZRX.mjs.map +0 -1
  513. package/dist/chunk-NNQL7CB3.mjs +0 -1713
  514. package/dist/chunk-NNQL7CB3.mjs.map +0 -1
  515. package/dist/chunk-OO3DRYK7.mjs.map +0 -1
  516. package/dist/chunk-PA5DRJNI.mjs.map +0 -1
  517. package/dist/chunk-PLAXOOX5.mjs.map +0 -1
  518. package/dist/chunk-VOZWDM3L.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
- import { RenderIntentInvalidError, DynamicResolutionRequiresTaaError, ShadowInvalidConfigError, EnvironmentSourceConflictError, FogCardinalityError, VolumeOwnerConflictError, VolumeDensityShapeMismatchError, VolumeInvalidBoundsError, VolumeInvalidParametersError, DynamicResolutionInvalidParameterError, AtmosphereInvalidParameterError } from './chunk-NB2S7ZRX.mjs';
2
- import { defineComponent, Entity } from '@forgeax/engine-ecs';
3
- import { TONEMAP_SHADER_MODE } from '@forgeax/engine-shader';
1
+ import { RenderIntentInvalidError, DynamicResolutionRequiresTaaError, ShadowInvalidConfigError, VolumeDensityShapeMismatchError, VolumeInvalidBoundsError, VolumeInvalidParametersError, EnvironmentSourceConflictError, FogCardinalityError, VolumeOwnerConflictError, BarrelDistortionInvalidParameterError, DynamicResolutionInvalidParameterError, AtmosphereInvalidParameterError } from './chunk-WEX45HKH.mjs';
2
+ import { defineComponent, Entity, Time } from '@forgeax/engine-ecs';
4
3
  import { R_MIN, err, ok } from '@forgeax/engine-types';
4
+ import { TONEMAP_SHADER_MODE } from '@forgeax/engine-shader';
5
5
  import { SpawnLightInvalidBoundsError } from '@forgeax/engine-ecs/projection';
6
6
  import { Transform, projectHierarchy } from '@forgeax/engine-scene';
7
7
  import { mat4 } from '@forgeax/engine-math';
@@ -17,6 +17,35 @@ var Atmosphere = defineComponent("Atmosphere", {
17
17
  /** Relative angular width of the analytic circumsolar lobe. */
18
18
  circumsolarWidth: { type: "f32", default: 1 }
19
19
  });
20
+ var BarrelDistortion = defineComponent("BarrelDistortion", {
21
+ strength: { type: "f32", default: 0 },
22
+ centerX: { type: "f32", default: 0.5 },
23
+ centerY: { type: "f32", default: 0.5 }
24
+ });
25
+ var DEFAULT_BARREL_DISTORTION = Object.freeze({
26
+ strength: 0,
27
+ centerX: 0.5,
28
+ centerY: 0.5
29
+ });
30
+ function invalid(field, value, expected) {
31
+ return new BarrelDistortionInvalidParameterError({ field, value, expected });
32
+ }
33
+ function validateBarrelDistortionParameters(input) {
34
+ const value = input ?? {};
35
+ const strength = value.strength ?? DEFAULT_BARREL_DISTORTION.strength;
36
+ const centerX = value.centerX ?? DEFAULT_BARREL_DISTORTION.centerX;
37
+ const centerY = value.centerY ?? DEFAULT_BARREL_DISTORTION.centerY;
38
+ if (!Number.isFinite(strength) || strength < 0 || strength > 0.35) {
39
+ return err(invalid("strength", strength, "finite and in [0, 0.35]"));
40
+ }
41
+ if (!Number.isFinite(centerX) || centerX < 0 || centerX > 1) {
42
+ return err(invalid("centerX", centerX, "finite and in [0, 1]"));
43
+ }
44
+ if (!Number.isFinite(centerY) || centerY < 0 || centerY > 1) {
45
+ return err(invalid("centerY", centerY, "finite and in [0, 1]"));
46
+ }
47
+ return ok(Object.freeze({ strength, centerX, centerY }));
48
+ }
20
49
  var CAMERA_PROJECTION_PERSPECTIVE = 0;
21
50
  var CAMERA_PROJECTION_ORTHOGRAPHIC = 1;
22
51
  var CAMERA_EXPOSURE_MODE_MANUAL = 0;
@@ -403,6 +432,37 @@ function orthographic(opts) {
403
432
  ...cameraColorGradingColumns(opts)
404
433
  };
405
434
  }
435
+ var CloudQualityValue = Object.freeze({
436
+ low: 0,
437
+ medium: 1,
438
+ high: 2
439
+ });
440
+ var CloudLayer = defineComponent("CloudLayer", {
441
+ /** Stable integer seed for the periodic 3D density field. */
442
+ seed: { type: "u32", default: 1337 },
443
+ /** World-space lower edge of the layer, in metres. */
444
+ baseHeight: { type: "f32", default: 120 },
445
+ /** World-space thickness of the layer, in metres. */
446
+ thickness: { type: "f32", default: 80 },
447
+ /** Horizontal noise scale, in cycles per metre. */
448
+ scale: { type: "f32", default: 4e-3 },
449
+ /** Coverage threshold in [0, 1]. */
450
+ coverage: { type: "f32", default: 0.48 },
451
+ /** Extinction multiplier in inverse metres. */
452
+ density: { type: "f32", default: 1 },
453
+ /** World-space wind velocity in metres per second. */
454
+ wind: { type: "array<f32, 3>", default: new Float32Array([8, 0, 2]) },
455
+ /** Quality controls cache resolution and bounded ray steps. */
456
+ quality: { type: "f32", default: CloudQualityValue.medium },
457
+ /** Maximum world-space distance represented by the light-space shadow map. */
458
+ shadowRange: { type: "f32", default: 512 }
459
+ });
460
+ function cloudQualityFromF32(value) {
461
+ if (value === CloudQualityValue.low) return "low";
462
+ if (value === CloudQualityValue.medium) return "medium";
463
+ if (value === CloudQualityValue.high) return "high";
464
+ return void 0;
465
+ }
406
466
  var CUBE_CAMERA_UPDATE_ONCE = 0;
407
467
  var CUBE_CAMERA_UPDATE_ON_DEMAND = 1;
408
468
  var CUBE_CAMERA_UPDATE_CONTINUOUS = 2;
@@ -543,7 +603,7 @@ var DEFAULT_DYNAMIC_RESOLUTION = Object.freeze({
543
603
  minScale: 0.67,
544
604
  maxScale: 1
545
605
  });
546
- function invalid(field, value, expected) {
606
+ function invalid2(field, value, expected) {
547
607
  return new DynamicResolutionInvalidParameterError({ field, value, expected });
548
608
  }
549
609
  function validateDynamicResolutionParameters(input) {
@@ -552,16 +612,16 @@ function validateDynamicResolutionParameters(input) {
552
612
  const minScale = value.minScale ?? DEFAULT_DYNAMIC_RESOLUTION.minScale;
553
613
  const maxScale = value.maxScale ?? DEFAULT_DYNAMIC_RESOLUTION.maxScale;
554
614
  if (!Number.isFinite(targetGpuMs) || targetGpuMs <= 0) {
555
- return err(invalid("targetGpuMs", targetGpuMs, "finite and greater than 0"));
615
+ return err(invalid2("targetGpuMs", targetGpuMs, "finite and greater than 0"));
556
616
  }
557
617
  if (!Number.isFinite(minScale) || minScale < 0.5 || minScale > 1) {
558
- return err(invalid("minScale", minScale, "finite and in [0.5, 1.0]"));
618
+ return err(invalid2("minScale", minScale, "finite and in [0.5, 1.0]"));
559
619
  }
560
620
  if (!Number.isFinite(maxScale) || maxScale < 0.5 || maxScale > 1) {
561
- return err(invalid("maxScale", maxScale, "finite and in [0.5, 1.0]"));
621
+ return err(invalid2("maxScale", maxScale, "finite and in [0.5, 1.0]"));
562
622
  }
563
623
  if (minScale > maxScale) {
564
- return err(invalid("minScale", minScale, "less than or equal to maxScale"));
624
+ return err(invalid2("minScale", minScale, "less than or equal to maxScale"));
565
625
  }
566
626
  return ok(Object.freeze({ targetGpuMs, minScale, maxScale }));
567
627
  }
@@ -581,7 +641,7 @@ var Fog = defineComponent("Fog", {
581
641
  maxOpacity: { type: "f32", default: 1 }
582
642
  });
583
643
  var Instances = defineComponent("Instances", {
584
- collectionId: { type: "u32", default: 0 }
644
+ transforms: { type: "array<f32>" }
585
645
  });
586
646
  var Layer = defineComponent("Layer", {
587
647
  value: { type: "i32", default: 0 }
@@ -1021,6 +1081,399 @@ var Visibility = defineComponent(
1021
1081
  }
1022
1082
  }
1023
1083
  );
1084
+ var COMPUTED_UV_BOUNDARY_EPSILON = Number.EPSILON * 16;
1085
+ function freezeBarrelDistortionMapping(mapping) {
1086
+ const camera = mapping.camera;
1087
+ return Object.freeze({
1088
+ ...mapping,
1089
+ ...camera === void 0 ? {} : {
1090
+ camera: Object.freeze({
1091
+ projection: camera.projection,
1092
+ far: camera.far,
1093
+ viewMatrix: Object.freeze(Array.from(camera.viewMatrix)),
1094
+ projectionMatrix: Object.freeze(Array.from(camera.projectionMatrix))
1095
+ })
1096
+ }
1097
+ });
1098
+ }
1099
+ function attachBarrelDistortionCameraFrame(mapping, camera) {
1100
+ return freezeBarrelDistortionMapping({
1101
+ ...mapping,
1102
+ camera: {
1103
+ projection: camera.projection,
1104
+ far: camera.far,
1105
+ viewMatrix: camera.viewMatrix,
1106
+ projectionMatrix: camera.projectionMatrix
1107
+ }
1108
+ });
1109
+ }
1110
+ function invalidExtent(field, value) {
1111
+ return new BarrelDistortionInvalidParameterError({
1112
+ field,
1113
+ value,
1114
+ expected: "finite and greater than 0"
1115
+ });
1116
+ }
1117
+ function createBarrelDistortionMapping(width, height, input) {
1118
+ if (!Number.isFinite(width) || width <= 0) return err(invalidExtent("width", width));
1119
+ if (!Number.isFinite(height) || height <= 0) return err(invalidExtent("height", height));
1120
+ const parameters = validateBarrelDistortionParameters(input);
1121
+ if (!parameters.ok) return parameters;
1122
+ const { strength, centerX, centerY } = parameters.value;
1123
+ const aspect = width / height;
1124
+ const radiusSquared = 4 * (aspect * aspect * Math.max(centerX, 1 - centerX) ** 2 + Math.max(centerY, 1 - centerY) ** 2);
1125
+ return ok(
1126
+ Object.freeze({
1127
+ width,
1128
+ height,
1129
+ aspect,
1130
+ strength,
1131
+ centerX,
1132
+ centerY,
1133
+ radiusSquared
1134
+ })
1135
+ );
1136
+ }
1137
+ function displayToSceneScale(mapping, ux, uy) {
1138
+ const px = 2 * mapping.aspect * (ux - mapping.centerX);
1139
+ const py = 2 * (uy - mapping.centerY);
1140
+ const t = (px * px + py * py) / mapping.radiusSquared;
1141
+ return (1 - mapping.strength) / (1 - mapping.strength * t);
1142
+ }
1143
+ function normalizeComputedUv(out, x, y) {
1144
+ if (!Number.isFinite(x) || !Number.isFinite(y)) return false;
1145
+ if (x < -COMPUTED_UV_BOUNDARY_EPSILON || x > 1 + COMPUTED_UV_BOUNDARY_EPSILON || y < -COMPUTED_UV_BOUNDARY_EPSILON || y > 1 + COMPUTED_UV_BOUNDARY_EPSILON) {
1146
+ return false;
1147
+ }
1148
+ out.x = Math.min(1, Math.max(0, x));
1149
+ out.y = Math.min(1, Math.max(0, y));
1150
+ return true;
1151
+ }
1152
+ function mapDisplayUvToSceneUv(out, mapping, ux, uy) {
1153
+ if (!Number.isFinite(ux) || !Number.isFinite(uy) || ux < 0 || ux > 1 || uy < 0 || uy > 1)
1154
+ return false;
1155
+ if (mapping.strength === 0) {
1156
+ out.x = ux;
1157
+ out.y = uy;
1158
+ return ux >= 0 && ux <= 1 && uy >= 0 && uy <= 1;
1159
+ }
1160
+ const scale = displayToSceneScale(mapping, ux, uy);
1161
+ return normalizeComputedUv(
1162
+ out,
1163
+ mapping.centerX + (ux - mapping.centerX) * scale,
1164
+ mapping.centerY + (uy - mapping.centerY) * scale
1165
+ );
1166
+ }
1167
+ function mapSceneUvToDisplayUv(out, mapping, ux, uy) {
1168
+ if (!Number.isFinite(ux) || !Number.isFinite(uy) || ux < 0 || ux > 1 || uy < 0 || uy > 1)
1169
+ return false;
1170
+ if (mapping.strength === 0) {
1171
+ out.x = ux;
1172
+ out.y = uy;
1173
+ return ux >= 0 && ux <= 1 && uy >= 0 && uy <= 1;
1174
+ }
1175
+ const px = 2 * mapping.aspect * (ux - mapping.centerX);
1176
+ const py = 2 * (uy - mapping.centerY);
1177
+ const sourceRadius = Math.hypot(px, py);
1178
+ if (sourceRadius === 0) {
1179
+ out.x = mapping.centerX;
1180
+ out.y = mapping.centerY;
1181
+ return true;
1182
+ }
1183
+ const discriminant = (1 - mapping.strength) ** 2 + 4 * mapping.strength * sourceRadius * sourceRadius / mapping.radiusSquared;
1184
+ const displayRadius = 2 * sourceRadius / (1 - mapping.strength + Math.sqrt(Math.max(0, discriminant)));
1185
+ const scale = displayRadius / sourceRadius;
1186
+ return normalizeComputedUv(
1187
+ out,
1188
+ mapping.centerX + (ux - mapping.centerX) * scale,
1189
+ mapping.centerY + (uy - mapping.centerY) * scale
1190
+ );
1191
+ }
1192
+ function validPixel(point) {
1193
+ return Number.isFinite(point.x) && Number.isFinite(point.y);
1194
+ }
1195
+ function mapDisplayToScene(out, mapping, displayX, displayY) {
1196
+ if (!Number.isFinite(displayX) || !Number.isFinite(displayY)) return false;
1197
+ if (displayX < 0 || displayX > mapping.width || displayY < 0 || displayY > mapping.height) {
1198
+ return false;
1199
+ }
1200
+ const scene = { x: 0, y: 0 };
1201
+ if (!mapDisplayUvToSceneUv(scene, mapping, displayX / mapping.width, displayY / mapping.height)) {
1202
+ return false;
1203
+ }
1204
+ out.x = scene.x * mapping.width;
1205
+ out.y = scene.y * mapping.height;
1206
+ return validPixel(out);
1207
+ }
1208
+ function mapSceneToDisplay(out, mapping, sceneX, sceneY) {
1209
+ if (!Number.isFinite(sceneX) || !Number.isFinite(sceneY)) return false;
1210
+ if (sceneX < 0 || sceneX > mapping.width || sceneY < 0 || sceneY > mapping.height) {
1211
+ return false;
1212
+ }
1213
+ const display = { x: 0, y: 0 };
1214
+ if (!mapSceneUvToDisplayUv(display, mapping, sceneX / mapping.width, sceneY / mapping.height)) {
1215
+ return false;
1216
+ }
1217
+ out.x = display.x * mapping.width;
1218
+ out.y = display.y * mapping.height;
1219
+ return validPixel(out);
1220
+ }
1221
+
1222
+ // src/errors/cloud.ts
1223
+ var CloudLayerInvalidParameterError = class extends Error {
1224
+ code = "cloud-layer-invalid-parameter";
1225
+ expected;
1226
+ hint;
1227
+ detail;
1228
+ constructor(field, value, expected) {
1229
+ super(`CloudLayer.${field} is invalid`);
1230
+ this.name = "CloudLayerInvalidParameterError";
1231
+ this.expected = `CloudLayer.${field} must be ${expected}`;
1232
+ this.hint = `set CloudLayer.${field} to ${expected}`;
1233
+ this.detail = { field, value, expected };
1234
+ }
1235
+ };
1236
+ var CloudLayerOwnerConflictError = class extends Error {
1237
+ code = "cloud-layer-owner-conflict";
1238
+ expected = "at most one CloudLayer owns a World frame";
1239
+ hint = "remove additional CloudLayer owners before extraction";
1240
+ detail;
1241
+ constructor(count) {
1242
+ super(`CloudLayer owner cardinality is ${count}`);
1243
+ this.name = "CloudLayerOwnerConflictError";
1244
+ this.detail = { count };
1245
+ }
1246
+ };
1247
+ var CloudLayerCacheInvalidError = class extends Error {
1248
+ code = "cloud-layer-cache-invalid";
1249
+ expected = "the density cache payload matches its reconstructible source";
1250
+ hint = "discard the derived cache and rebuild it from CloudLayer source facts";
1251
+ detail;
1252
+ constructor(sourceKey, reason) {
1253
+ super(`CloudLayer cache is invalid: ${reason}`);
1254
+ this.name = "CloudLayerCacheInvalidError";
1255
+ this.detail = { sourceKey, reason };
1256
+ }
1257
+ };
1258
+ var CloudLayerCapabilityMissingError = class extends Error {
1259
+ code = "cloud-layer-capability-missing";
1260
+ expected = "the selected backend exposes the capability required by the cloud lane";
1261
+ hint = "inspect the capability report, disable the cloud lane on this backend, or retry on a backend with the required capability";
1262
+ detail;
1263
+ constructor(capability) {
1264
+ super(`CloudLayer capability is unavailable: ${capability}`);
1265
+ this.name = "CloudLayerCapabilityMissingError";
1266
+ this.detail = { capability };
1267
+ }
1268
+ };
1269
+ var CloudLayerResourceFailureError = class extends Error {
1270
+ code = "cloud-layer-resource-failed";
1271
+ expected = "cloud resources are created, submitted and retired as one generation";
1272
+ hint = "keep the last-known-good cloud generation and retry after recovery";
1273
+ detail;
1274
+ constructor(detail) {
1275
+ super(`CloudLayer ${detail.stage} resource failed at generation ${detail.generation}`);
1276
+ this.name = "CloudLayerResourceFailureError";
1277
+ this.detail = detail;
1278
+ }
1279
+ };
1280
+ var CLOUD_QUALITY_PROFILES = Object.freeze({
1281
+ low: Object.freeze({
1282
+ // Preserve low-profile ray counts while keeping separate puffs from
1283
+ // collapsing into one bilinear cache smear.
1284
+ cacheResolution: 32,
1285
+ viewSteps: 40,
1286
+ shadowSteps: 12,
1287
+ historyWeight: 0.82,
1288
+ viewDistance: 1600
1289
+ }),
1290
+ medium: Object.freeze({
1291
+ cacheResolution: 40,
1292
+ viewSteps: 64,
1293
+ shadowSteps: 20,
1294
+ historyWeight: 0.9,
1295
+ viewDistance: 2400
1296
+ }),
1297
+ high: Object.freeze({
1298
+ cacheResolution: 64,
1299
+ viewSteps: 64,
1300
+ shadowSteps: 32,
1301
+ historyWeight: 0.94,
1302
+ viewDistance: 4e3
1303
+ })
1304
+ });
1305
+ function cloudShadowResolutionForQuality(qualityValue) {
1306
+ return CLOUD_QUALITY_PROFILES[qualityValue].cacheResolution * 4;
1307
+ }
1308
+ function cloudViewDistanceForQuality(qualityValue) {
1309
+ return CLOUD_QUALITY_PROFILES[qualityValue].viewDistance;
1310
+ }
1311
+ var CLOUD_EXTINCTION_COEFFICIENT = 0.03;
1312
+ var DEFAULT_CLOUD_LAYER = Object.freeze({
1313
+ seed: 1337,
1314
+ baseHeight: 120,
1315
+ thickness: 80,
1316
+ scale: 4e-3,
1317
+ coverage: 0.48,
1318
+ density: 1,
1319
+ wind: Object.freeze([8, 0, 2]),
1320
+ quality: "medium",
1321
+ shadowRange: 512
1322
+ });
1323
+ function invalid3(field, value, expected) {
1324
+ return err(new CloudLayerInvalidParameterError(field, value, expected));
1325
+ }
1326
+ function finiteRange(field, value, min, max = Number.POSITIVE_INFINITY) {
1327
+ if (typeof value !== "number" || !Number.isFinite(value) || value < min || value > max) {
1328
+ const expected = Number.isFinite(max) ? `finite and in [${min}, ${max}]` : `finite and >= ${min}`;
1329
+ return invalid3(field, value, expected);
1330
+ }
1331
+ return ok(value);
1332
+ }
1333
+ function quality(value) {
1334
+ if (typeof value === "string" && (value === "low" || value === "medium" || value === "high")) {
1335
+ return ok(value);
1336
+ }
1337
+ if (typeof value === "number") {
1338
+ const resolved = cloudQualityFromF32(value);
1339
+ if (resolved !== void 0) return ok(resolved);
1340
+ }
1341
+ return invalid3(
1342
+ "quality",
1343
+ value,
1344
+ `one of low, medium, high (codes ${CloudQualityValue.low}, ${CloudQualityValue.medium}, ${CloudQualityValue.high})`
1345
+ );
1346
+ }
1347
+ function wind(value) {
1348
+ if (value === void 0 || value === null || typeof value !== "object") {
1349
+ return invalid3("wind", value, "three finite world-space components");
1350
+ }
1351
+ const source = value;
1352
+ if (source.length !== 3) return invalid3("wind", value, "three finite world-space components");
1353
+ const result = [
1354
+ source[0] ?? Number.NaN,
1355
+ source[1] ?? Number.NaN,
1356
+ source[2] ?? Number.NaN
1357
+ ];
1358
+ if (result.some((entry) => !Number.isFinite(entry) || Math.abs(entry) > 1e3)) {
1359
+ return invalid3("wind", value, "three finite components in [-1000, 1000]");
1360
+ }
1361
+ return ok(Object.freeze(result));
1362
+ }
1363
+ function validateCloudLayer(input) {
1364
+ const value = input ?? {};
1365
+ const seed = value.seed ?? DEFAULT_CLOUD_LAYER.seed;
1366
+ if (typeof seed !== "number" || !Number.isInteger(seed) || seed < 0 || seed > 4294967295) {
1367
+ return invalid3("seed", seed, "an integer in [0, 4294967295]");
1368
+ }
1369
+ const baseHeight = finiteRange(
1370
+ "baseHeight",
1371
+ value.baseHeight ?? DEFAULT_CLOUD_LAYER.baseHeight,
1372
+ -1e5,
1373
+ 1e6
1374
+ );
1375
+ if (!baseHeight.ok) return baseHeight;
1376
+ const thickness = finiteRange(
1377
+ "thickness",
1378
+ value.thickness ?? DEFAULT_CLOUD_LAYER.thickness,
1379
+ 1e-3,
1380
+ 1e6
1381
+ );
1382
+ if (!thickness.ok) return thickness;
1383
+ const scale = finiteRange("scale", value.scale ?? DEFAULT_CLOUD_LAYER.scale, 1e-6, 10);
1384
+ if (!scale.ok) return scale;
1385
+ const coverage = finiteRange("coverage", value.coverage ?? DEFAULT_CLOUD_LAYER.coverage, 0, 1);
1386
+ if (!coverage.ok) return coverage;
1387
+ const density = finiteRange("density", value.density ?? DEFAULT_CLOUD_LAYER.density, 0, 32);
1388
+ if (!density.ok) return density;
1389
+ const resolvedWind = wind(value.wind ?? DEFAULT_CLOUD_LAYER.wind);
1390
+ if (!resolvedWind.ok) return resolvedWind;
1391
+ const resolvedQuality = quality(value.quality ?? DEFAULT_CLOUD_LAYER.quality);
1392
+ if (!resolvedQuality.ok) return resolvedQuality;
1393
+ const shadowRange = finiteRange(
1394
+ "shadowRange",
1395
+ value.shadowRange ?? DEFAULT_CLOUD_LAYER.shadowRange,
1396
+ 1e-3,
1397
+ 1e7
1398
+ );
1399
+ if (!shadowRange.ok) return shadowRange;
1400
+ return ok(
1401
+ Object.freeze({
1402
+ seed,
1403
+ baseHeight: baseHeight.value,
1404
+ thickness: thickness.value,
1405
+ scale: scale.value,
1406
+ coverage: coverage.value,
1407
+ density: density.value,
1408
+ wind: resolvedWind.value,
1409
+ quality: resolvedQuality.value,
1410
+ shadowRange: shadowRange.value
1411
+ })
1412
+ );
1413
+ }
1414
+ function cloudLayerSourceKey(params) {
1415
+ return [
1416
+ "cloud-layer-v1",
1417
+ params.seed,
1418
+ params.baseHeight,
1419
+ params.thickness,
1420
+ params.scale,
1421
+ params.coverage,
1422
+ params.density,
1423
+ params.wind[0],
1424
+ params.wind[1],
1425
+ params.wind[2],
1426
+ params.quality,
1427
+ params.shadowRange
1428
+ ].join(":");
1429
+ }
1430
+ function cloudLayerFormationKey(params) {
1431
+ return [
1432
+ "cloud-formation-v5",
1433
+ params.seed,
1434
+ params.baseHeight,
1435
+ params.thickness,
1436
+ params.scale,
1437
+ params.quality
1438
+ ].join(":");
1439
+ }
1440
+ var MAX_VOLUMETRIC_FOG_OWNERS = 8;
1441
+ var VolumetricFogSamplingValue = { noise: 0, density: 1 };
1442
+ var VolumetricFog = defineComponent("VolumetricFog", {
1443
+ light: { type: "entity" },
1444
+ spotLight: { type: "entity" },
1445
+ density: { type: "shared<TextureAsset>", simulationTransient: true },
1446
+ boundsMin: { type: "array<f32, 3>" },
1447
+ boundsMax: { type: "array<f32, 3>" },
1448
+ extinction: { type: "array<f32, 3>" },
1449
+ albedo: { type: "array<f32, 3>" },
1450
+ emission: { type: "array<f32, 3>" },
1451
+ anisotropy: { type: "f32", default: 0 },
1452
+ maxDistance: { type: "f32", default: 100 },
1453
+ sampling: { type: "enum", labels: VolumetricFogSamplingValue, default: 0 }
1454
+ });
1455
+ function finiteVector(value) {
1456
+ return value.every(Number.isFinite);
1457
+ }
1458
+ function validBounds(bounds) {
1459
+ if (!finiteVector(bounds.min) || !finiteVector(bounds.max)) return false;
1460
+ return bounds.max.every((value, index) => value > (bounds.min[index] ?? value));
1461
+ }
1462
+ function validRange(value, min, max = Infinity) {
1463
+ return value.every((entry) => Number.isFinite(entry) && entry >= min && entry <= max);
1464
+ }
1465
+ function validateVolumetricFog(input) {
1466
+ if (input.density.shape.viewDimension !== "3d" || input.density.colorSpace === "srgb") {
1467
+ return err(
1468
+ new VolumeDensityShapeMismatchError(input.density.guid, input.density.shape.viewDimension)
1469
+ );
1470
+ }
1471
+ if (!validBounds(input.bounds)) return err(new VolumeInvalidBoundsError(input.bounds));
1472
+ if (!validRange(input.extinction, 0) || !validRange(input.albedo, 0, 1) || !validRange(input.emission, 0) || !Number.isFinite(input.anisotropy) || input.anisotropy <= -1 || input.anisotropy >= 1 || !Number.isFinite(input.maxDistance) || input.maxDistance <= 0 || input.sampling !== void 0 && input.sampling !== "noise" && input.sampling !== "density") {
1473
+ return err(new VolumeInvalidParametersError(input));
1474
+ }
1475
+ return ok(input);
1476
+ }
1024
1477
 
1025
1478
  // src/environment/signature.ts
1026
1479
  function sorted(items) {
@@ -1164,8 +1617,8 @@ function selectEnvironment(input) {
1164
1617
  }
1165
1618
  const selected = input.environments[0];
1166
1619
  if (selected?.kind === "atmosphere") {
1167
- const invalid3 = validateAtmosphereParameters(selected.atmosphere);
1168
- if (invalid3 !== void 0) return err(invalid3);
1620
+ const invalid5 = validateAtmosphereParameters(selected.atmosphere);
1621
+ if (invalid5 !== void 0) return err(invalid5);
1169
1622
  }
1170
1623
  if (selected?.kind === "atmosphere" && input.suns.length !== 1) {
1171
1624
  return err(new SunCardinalityError(input.suns.length));
@@ -1243,7 +1696,7 @@ function resolveDepthOfFieldFrameParams(requested, requestFailure, accepted) {
1243
1696
  }
1244
1697
  return accepted;
1245
1698
  }
1246
- function invalid2(field, value, expected, bound) {
1699
+ function invalid4(field, value, expected, bound) {
1247
1700
  return new DepthOfFieldValidationError(
1248
1701
  "depth-of-field-invalid-params",
1249
1702
  { field, value, expected, ...bound === void 0 ? {} : { bound } },
@@ -1278,31 +1731,31 @@ function resolveDepthOfFieldFrameValues(params, input) {
1278
1731
  ];
1279
1732
  for (const [field, value, raw] of finitePositiveFields) {
1280
1733
  if (!Number.isFinite(value) || value <= 0) {
1281
- return err(invalid2(field, raw, "a finite positive f32 value"));
1734
+ return err(invalid4(field, raw, "a finite positive f32 value"));
1282
1735
  }
1283
1736
  }
1284
1737
  if (!Number.isFinite(fStop) || fStop < MIN_F_STOP || fStop > MAX_F_STOP) {
1285
1738
  return err(
1286
- invalid2("fStop", params.fStop, "a finite f32 value in [0.7, 32]", [MIN_F_STOP, MAX_F_STOP])
1739
+ invalid4("fStop", params.fStop, "a finite f32 value in [0.7, 32]", [MIN_F_STOP, MAX_F_STOP])
1287
1740
  );
1288
1741
  }
1289
1742
  if (!Number.isFinite(maxRadiusPixels) || maxRadiusPixels < 0 || maxRadiusPixels > 32) {
1290
1743
  return err(
1291
- invalid2("maxRadiusPixels", params.maxRadiusPixels, "a finite f32 value in [0, 32]", [0, 32])
1744
+ invalid4("maxRadiusPixels", params.maxRadiusPixels, "a finite f32 value in [0, 32]", [0, 32])
1292
1745
  );
1293
1746
  }
1294
1747
  if (!Number.isFinite(outputHeight) || outputHeight <= 0) {
1295
- return err(invalid2("outputHeight", input.outputHeight, "a finite positive f32 value"));
1748
+ return err(invalid4("outputHeight", input.outputHeight, "a finite positive f32 value"));
1296
1749
  }
1297
1750
  if (far <= near) {
1298
- return err(invalid2("near/far", [input.near, input.far], "finite f32 near > 0 and far > near"));
1751
+ return err(invalid4("near/far", [input.near, input.far], "finite f32 near > 0 and far > near"));
1299
1752
  }
1300
1753
  if (focusDistance <= focal) {
1301
- return err(invalid2("focusDistance", params.focusDistance, "greater than focalLength in f32"));
1754
+ return err(invalid4("focusDistance", params.focusDistance, "greater than focalLength in f32"));
1302
1755
  }
1303
1756
  const depthRatio = quantizeF32(near / far);
1304
1757
  if (!Number.isFinite(depthRatio) || depthRatio <= 0) {
1305
- return err(invalid2("near/far ratio", depthRatio, "a finite positive f32 value"));
1758
+ return err(invalid4("near/far ratio", depthRatio, "a finite positive f32 value"));
1306
1759
  }
1307
1760
  for (const raw of [quantizeF32(2 ** -149), 0.5, MAX_LINEAR_DEPTH_RAW]) {
1308
1761
  const oneMinusRaw = quantizeF32(1 - raw);
@@ -1310,7 +1763,7 @@ function resolveDepthOfFieldFrameValues(params, input) {
1310
1763
  const denominator = quantizeF32(oneMinusRaw + weightedRatio);
1311
1764
  const distance = quantizeF32(near / denominator);
1312
1765
  if (!Number.isFinite(oneMinusRaw) || oneMinusRaw <= 0 || !Number.isFinite(weightedRatio) || !Number.isFinite(denominator) || denominator <= 0 || !Number.isFinite(distance) || distance <= 0) {
1313
- return err(invalid2("linearDepth", distance, "finite positive f32 reconstruction"));
1766
+ return err(invalid4("linearDepth", distance, "finite positive f32 reconstruction"));
1314
1767
  }
1315
1768
  }
1316
1769
  const cocCoefficient = frameCocCoefficient(
@@ -1324,7 +1777,7 @@ function resolveDepthOfFieldFrameValues(params, input) {
1324
1777
  );
1325
1778
  if (!Number.isFinite(cocCoefficient) || cocCoefficient <= 0) {
1326
1779
  return err(
1327
- invalid2("cocCoefficient", cocCoefficient, "a finite positive value representable as f32")
1780
+ invalid4("cocCoefficient", cocCoefficient, "a finite positive value representable as f32")
1328
1781
  );
1329
1782
  }
1330
1783
  for (const [field, depth] of [
@@ -1335,7 +1788,7 @@ function resolveDepthOfFieldFrameValues(params, input) {
1335
1788
  const depthFactor = quantizeF32(1 - focusOverDepth);
1336
1789
  const radius = quantizeF32(cocCoefficient * depthFactor);
1337
1790
  if (!Number.isFinite(focusOverDepth) || !Number.isFinite(depthFactor) || !Number.isFinite(radius)) {
1338
- return err(invalid2(`coc.${field}`, radius, "a finite value representable as f32"));
1791
+ return err(invalid4(`coc.${field}`, radius, "a finite value representable as f32"));
1339
1792
  }
1340
1793
  }
1341
1794
  return ok({
@@ -1378,16 +1831,16 @@ function validateDepthOfFieldParams(input, camera) {
1378
1831
  );
1379
1832
  const qualityValue = quantizeF32(value.quality ?? DepthOfFieldQualityValue.medium);
1380
1833
  const blurSideValue = quantizeF32(value.blurSide ?? DepthOfFieldSideValue.both);
1381
- const quality = depthOfFieldQualityFromF32(qualityValue);
1834
+ const quality2 = depthOfFieldQualityFromF32(qualityValue);
1382
1835
  const blurSide = depthOfFieldSideFromF32(blurSideValue);
1383
1836
  if (!Number.isFinite(focusDistance) || focusDistance <= 0) {
1384
1837
  return err(
1385
- invalid2("focusDistance", value.focusDistance ?? focusDistance, "a finite positive f32 value")
1838
+ invalid4("focusDistance", value.focusDistance ?? focusDistance, "a finite positive f32 value")
1386
1839
  );
1387
1840
  }
1388
1841
  if (!Number.isFinite(fStop) || fStop < MIN_F_STOP || fStop > MAX_F_STOP) {
1389
1842
  return err(
1390
- invalid2("fStop", value.fStop ?? fStop, "a finite f32 value in [0.7, 32]", [
1843
+ invalid4("fStop", value.fStop ?? fStop, "a finite f32 value in [0.7, 32]", [
1391
1844
  MIN_F_STOP,
1392
1845
  MAX_F_STOP
1393
1846
  ])
@@ -1395,12 +1848,12 @@ function validateDepthOfFieldParams(input, camera) {
1395
1848
  }
1396
1849
  if (!Number.isFinite(sensorHeight) || sensorHeight <= 0) {
1397
1850
  return err(
1398
- invalid2("sensorHeight", value.sensorHeight ?? sensorHeight, "a finite positive f32 value")
1851
+ invalid4("sensorHeight", value.sensorHeight ?? sensorHeight, "a finite positive f32 value")
1399
1852
  );
1400
1853
  }
1401
1854
  if (!Number.isFinite(maxRadiusPixels) || maxRadiusPixels < 0 || maxRadiusPixels > 32) {
1402
1855
  return err(
1403
- invalid2(
1856
+ invalid4(
1404
1857
  "maxRadiusPixels",
1405
1858
  value.maxRadiusPixels ?? maxRadiusPixels,
1406
1859
  "a finite f32 value in [0, 32]",
@@ -1408,11 +1861,11 @@ function validateDepthOfFieldParams(input, camera) {
1408
1861
  )
1409
1862
  );
1410
1863
  }
1411
- if (quality === void 0) {
1412
- return err(invalid2("quality", qualityValue, "DepthOfFieldQualityValue.low, medium, or high"));
1864
+ if (quality2 === void 0) {
1865
+ return err(invalid4("quality", qualityValue, "DepthOfFieldQualityValue.low, medium, or high"));
1413
1866
  }
1414
1867
  if (blurSide === void 0) {
1415
- return err(invalid2("blurSide", blurSideValue, "DepthOfFieldSideValue.both, near, or far"));
1868
+ return err(invalid4("blurSide", blurSideValue, "DepthOfFieldSideValue.both, near, or far"));
1416
1869
  }
1417
1870
  let focal = DEFAULT_DEPTH_OF_FIELD_PARAMS.focalLength;
1418
1871
  if (camera !== void 0) {
@@ -1420,25 +1873,25 @@ function validateDepthOfFieldParams(input, camera) {
1420
1873
  const near = quantizeF32(camera.near);
1421
1874
  const far = quantizeF32(camera.far);
1422
1875
  if (!Number.isFinite(fov) || fov <= 0 || fov >= Math.PI) {
1423
- return err(invalid2("fov", camera.fov, "a finite f32 value in (0, PI)"));
1876
+ return err(invalid4("fov", camera.fov, "a finite f32 value in (0, PI)"));
1424
1877
  }
1425
1878
  if (!Number.isFinite(near) || !Number.isFinite(far) || near <= 0 || far <= near) {
1426
1879
  return err(
1427
- invalid2("near/far", [camera.near, camera.far], "finite f32 near > 0 and far > near")
1880
+ invalid4("near/far", [camera.near, camera.far], "finite f32 near > 0 and far > near")
1428
1881
  );
1429
1882
  }
1430
1883
  focal = quantizeF32(focalLength(sensorHeight, fov));
1431
1884
  if (!Number.isFinite(focal) || focal <= 0) {
1432
- return err(invalid2("focalLength", focal, "a finite positive f32 value"));
1885
+ return err(invalid4("focalLength", focal, "a finite positive f32 value"));
1433
1886
  }
1434
1887
  if (focusDistance < near || focusDistance > far) {
1435
1888
  return err(
1436
- invalid2("focusDistance", focusDistance, `a value in [${near}, ${far}]`, [near, far])
1889
+ invalid4("focusDistance", focusDistance, `a value in [${near}, ${far}]`, [near, far])
1437
1890
  );
1438
1891
  }
1439
1892
  if (focusDistance <= focal) {
1440
1893
  return err(
1441
- invalid2("focusDistance", focusDistance, `greater than focalLength in f32 (${focal})`)
1894
+ invalid4("focusDistance", focusDistance, `greater than focalLength in f32 (${focal})`)
1442
1895
  );
1443
1896
  }
1444
1897
  }
@@ -1448,7 +1901,7 @@ function validateDepthOfFieldParams(input, camera) {
1448
1901
  fStop,
1449
1902
  sensorHeight,
1450
1903
  maxRadiusPixels,
1451
- quality,
1904
+ quality: quality2,
1452
1905
  blurSide,
1453
1906
  focalLength: focal
1454
1907
  })
@@ -1458,8 +1911,8 @@ function resolveDepthOfFieldParams(input, camera) {
1458
1911
  if (input === void 0) return ok(void 0);
1459
1912
  return validateDepthOfFieldParams(input, camera);
1460
1913
  }
1461
- function depthOfFieldTapCount(quality) {
1462
- switch (quality) {
1914
+ function depthOfFieldTapCount(quality2) {
1915
+ switch (quality2) {
1463
1916
  case "low":
1464
1917
  return 16;
1465
1918
  case "medium":
@@ -1478,8 +1931,8 @@ function depthOfFieldSideCode(side) {
1478
1931
  return DepthOfFieldSideValue.far;
1479
1932
  }
1480
1933
  }
1481
- function depthOfFieldQualityCode(quality) {
1482
- switch (quality) {
1934
+ function depthOfFieldQualityCode(quality2) {
1935
+ switch (quality2) {
1483
1936
  case "low":
1484
1937
  return DepthOfFieldQualityValue.low;
1485
1938
  case "medium":
@@ -1858,50 +2311,79 @@ function resolveVisibility(world, hierarchy = projectHierarchy(world)) {
1858
2311
  };
1859
2312
  return snapshot;
1860
2313
  }
1861
- var VolumetricFog = defineComponent("VolumetricFog", {
1862
- light: { type: "entity" },
1863
- spotLight: { type: "entity" },
1864
- density: { type: "shared<TextureAsset>", simulationTransient: true },
1865
- boundsMin: { type: "array<f32, 3>" },
1866
- boundsMax: { type: "array<f32, 3>" },
1867
- extinction: { type: "array<f32, 3>" },
1868
- albedo: { type: "array<f32, 3>" },
1869
- emission: { type: "array<f32, 3>" },
1870
- anisotropy: { type: "f32", default: 0 },
1871
- maxDistance: { type: "f32", default: 100 }
1872
- });
1873
- function finiteVector(value) {
1874
- return value.every(Number.isFinite);
1875
- }
1876
- function validBounds(bounds) {
1877
- if (!finiteVector(bounds.min) || !finiteVector(bounds.max)) return false;
1878
- return bounds.max.every((value, index) => value > (bounds.min[index] ?? value));
1879
- }
1880
- function validRange(value, min, max = Infinity) {
1881
- return value.every((entry) => Number.isFinite(entry) && entry >= min && entry <= max);
2314
+ function selectCloudLayerFrame(candidates, worldTimeSeconds = 0, sunDirection = void 0, sunRadiance = void 0) {
2315
+ if (candidates.length === 0) return ok(void 0);
2316
+ if (candidates.length > 1) return err(new CloudLayerOwnerConflictError(candidates.length));
2317
+ const candidate = candidates[0];
2318
+ if (candidate === void 0) return ok(void 0);
2319
+ const validated = validateCloudLayer(candidate.data);
2320
+ if (!validated.ok) return validated;
2321
+ return ok(
2322
+ Object.freeze({
2323
+ status: "available",
2324
+ entityKey: candidate.entityKey,
2325
+ sourceKey: cloudLayerSourceKey(validated.value),
2326
+ params: validated.value,
2327
+ worldTimeSeconds: Number.isFinite(worldTimeSeconds) ? Math.max(0, worldTimeSeconds) : 0,
2328
+ sunDirection: sunDirection === void 0 ? void 0 : Object.freeze([...sunDirection]),
2329
+ sunRadiance: sunRadiance === void 0 ? void 0 : Object.freeze([...sunRadiance]),
2330
+ revision: 1
2331
+ })
2332
+ );
1882
2333
  }
1883
- function validateVolumetricFog(input) {
1884
- const ownerCount = input.ownerCount ?? 1;
1885
- if (ownerCount !== 1) return err(new VolumeOwnerConflictError(ownerCount));
1886
- if (input.density.shape.viewDimension !== "3d" || input.density.colorSpace === "srgb") {
1887
- return err(
1888
- new VolumeDensityShapeMismatchError(input.density.guid, input.density.shape.viewDimension)
1889
- );
2334
+ function extractCloudLayer(world) {
2335
+ const candidates = [];
2336
+ try {
2337
+ const query = world.query({ read: [CloudLayer] });
2338
+ if (!query.ok) return ok(void 0);
2339
+ for (const row of query.value)
2340
+ candidates.push({ entityKey: row.entity, data: row.get(CloudLayer) });
2341
+ } catch {
2342
+ return ok(void 0);
1890
2343
  }
1891
- if (!validBounds(input.bounds)) return err(new VolumeInvalidBoundsError(input.bounds));
1892
- if (!validRange(input.extinction, 0) || !validRange(input.albedo, 0, 1) || !validRange(input.emission, 0) || !Number.isFinite(input.anisotropy) || input.anisotropy <= -1 || input.anisotropy >= 1 || !Number.isFinite(input.maxDistance) || input.maxDistance <= 0) {
1893
- return err(new VolumeInvalidParametersError(input));
2344
+ let sunDirection;
2345
+ let sunRadiance;
2346
+ try {
2347
+ const query = world.query({ read: [DirectionalLight] });
2348
+ if (query.ok) {
2349
+ for (const row of query.value) {
2350
+ const light = row.get(DirectionalLight);
2351
+ const intensity = Number.isFinite(light.intensity) ? Math.max(0, light.intensity) : 0;
2352
+ sunDirection = [
2353
+ -(light.direction[0] ?? 0),
2354
+ -(light.direction[1] ?? -1),
2355
+ -(light.direction[2] ?? 0)
2356
+ ];
2357
+ sunRadiance = [
2358
+ (light.color[0] ?? 1) * intensity,
2359
+ (light.color[1] ?? 1) * intensity,
2360
+ (light.color[2] ?? 1) * intensity
2361
+ ];
2362
+ break;
2363
+ }
2364
+ }
2365
+ } catch {
1894
2366
  }
1895
- return ok({ ...input, ownerCount: 1 });
2367
+ return selectCloudLayerFrame(
2368
+ candidates,
2369
+ world.getResource(Time).elapsed,
2370
+ sunDirection,
2371
+ sunRadiance
2372
+ );
1896
2373
  }
1897
2374
  function extractVolumetricFog(inputs) {
1898
2375
  if (inputs.length === 0) return ok({ status: "off" });
1899
- if (inputs.length !== 1) return err(new VolumeOwnerConflictError(inputs.length));
1900
- const validated = validateVolumetricFog(inputs[0]);
1901
- if (!validated.ok) return validated;
1902
- return ok({ status: "available", fog: validated.value });
2376
+ if (inputs.length > MAX_VOLUMETRIC_FOG_OWNERS)
2377
+ return err(new VolumeOwnerConflictError(inputs.length));
2378
+ const fogs = [];
2379
+ for (const input of inputs) {
2380
+ const validated = validateVolumetricFog(input);
2381
+ if (!validated.ok) return validated;
2382
+ fogs.push(validated.value);
2383
+ }
2384
+ return ok({ status: "available", fogs });
1903
2385
  }
1904
2386
 
1905
- export { ANTIALIAS_FXAA, ANTIALIAS_MSAA, ANTIALIAS_NONE, ANTIALIAS_TAA, Atmosphere, BLOOM_DISABLED, BLOOM_ENABLED, CAMERA_BLOOM_INTENSITY_MAX, CAMERA_BLOOM_INTENSITY_MIN, CAMERA_BLOOM_SCATTER_MAX, CAMERA_BLOOM_SCATTER_MIN, CAMERA_BLOOM_SOFT_KNEE_MAX, CAMERA_BLOOM_SOFT_KNEE_MIN, CAMERA_BLOOM_THRESHOLD_MAX, CAMERA_BLOOM_THRESHOLD_MIN, CAMERA_EXPOSURE_MODE_AUTO, CAMERA_EXPOSURE_MODE_MANUAL, CAMERA_PROJECTION_ORTHOGRAPHIC, CAMERA_PROJECTION_PERSPECTIVE, CAMERA_TEMPERATURE_MAX, CAMERA_TEMPERATURE_MIN, CAMERA_TINT_MAX, CAMERA_TINT_MIN, CUBE_CAMERA_FACE_ORDER, CUBE_CAMERA_UPDATE_CONTINUOUS, CUBE_CAMERA_UPDATE_ONCE, CUBE_CAMERA_UPDATE_ON_DEMAND, Camera, CameraError, CubeCamera, DEFAULT_DEPTH_OF_FIELD_PARAMS, DEPTH_OF_FIELD_PARAMS_BYTE_SIZE, DepthOfField, DepthOfFieldQualityValue, DepthOfFieldSideValue, DepthOfFieldValidationError, DirectionalLight, DirectionalShadowFilterValue, DynamicResolution, Fog, Instances, Layer, LightProbe, Lines, MeshFilter, MeshRenderer, MotionBlur, PointLight, PointLightShadow, PointShapeValue, Points, PostProcessParams, REFLECTION_PROBE_UPDATE_CONTINUOUS, REFLECTION_PROBE_UPDATE_ONCE, REFLECTION_PROBE_UPDATE_ON_CHANGE, RectAreaLight, ReflectionProbe, SKYBOX_MODE_CUBEMAP, SKYLIGHT_RECOVERY_FALLBACK, SceneInstance, ScreenSpaceReflection, SkyboxBackground, Skylight, SortKey, SpotLight, SunCardinalityError, TONEMAP_ACES_FILMIC, TONEMAP_AGX, TONEMAP_CINEON, TONEMAP_LINEAR, TONEMAP_NEUTRAL, TONEMAP_NONE, TONEMAP_REINHARD, TONEMAP_REINHARD_EXTENDED, Visibility, VisibilityStateValue, VolumetricFog, antialiasFromF32, buildCubeCameraFaceViews, cameraExposureFromColumns, cameraProjectionFromF32, computeInvRangeSquared, cubeCameraUpdateIntentFromF32, cubeCameraUpdateIntentToF32, degToCos, depthOfFieldQualityCode, depthOfFieldQualityFromF32, depthOfFieldRequestFailure, depthOfFieldSideCode, depthOfFieldSideFromF32, depthOfFieldTapCount, directionalShadowQualityFromF32, extractVolumetricFog, hasVolumetricFogCapability, orthographic, packDepthOfFieldParams, perspective, pointShapeFromU32, projectMeshMaterialBindingObservation, reflectionProbeUpdateIntentFromF32, reflectionProbeUpdateIntentToF32, resolveDepthOfFieldFrameParams, resolveDepthOfFieldParams, resolveIntegratedVolumeConsumer, resolveMeshMaterialBindings, resolveSelectedVolumetricLight, resolveVisibility, resolveVolumetricFogLightPair, selectEnvironment, signedDepthOfFieldCoC, summarizeMeshMaterialBindings, tonemapFromF32, tonemapToU32, validateCameraBloom, validateCameraColorGrading, validateCameraExposure, validateDepthOfFieldFrameParams, validateDepthOfFieldParams, validateDirection, validateDirectionalLightData, validateDynamicResolutionCamera, validateDynamicResolutionParameters, validateLightProbeData, validatePointLightData, validatePointLightShadowData, validateRectAreaLightData, validateSpotLightData, validateVolumetricFog, visibilityStateFromU32 };
1906
- //# sourceMappingURL=chunk-PLAXOOX5.mjs.map
1907
- //# sourceMappingURL=chunk-PLAXOOX5.mjs.map
2387
+ export { ANTIALIAS_FXAA, ANTIALIAS_MSAA, ANTIALIAS_NONE, ANTIALIAS_TAA, Atmosphere, BLOOM_DISABLED, BLOOM_ENABLED, BarrelDistortion, CAMERA_BLOOM_INTENSITY_MAX, CAMERA_BLOOM_INTENSITY_MIN, CAMERA_BLOOM_SCATTER_MAX, CAMERA_BLOOM_SCATTER_MIN, CAMERA_BLOOM_SOFT_KNEE_MAX, CAMERA_BLOOM_SOFT_KNEE_MIN, CAMERA_BLOOM_THRESHOLD_MAX, CAMERA_BLOOM_THRESHOLD_MIN, CAMERA_EXPOSURE_MODE_AUTO, CAMERA_EXPOSURE_MODE_MANUAL, CAMERA_PROJECTION_ORTHOGRAPHIC, CAMERA_PROJECTION_PERSPECTIVE, CAMERA_TEMPERATURE_MAX, CAMERA_TEMPERATURE_MIN, CAMERA_TINT_MAX, CAMERA_TINT_MIN, CLOUD_EXTINCTION_COEFFICIENT, CLOUD_QUALITY_PROFILES, CUBE_CAMERA_FACE_ORDER, CUBE_CAMERA_UPDATE_CONTINUOUS, CUBE_CAMERA_UPDATE_ONCE, CUBE_CAMERA_UPDATE_ON_DEMAND, Camera, CameraError, CloudLayer, CloudLayerCacheInvalidError, CloudLayerCapabilityMissingError, CloudLayerInvalidParameterError, CloudLayerOwnerConflictError, CloudLayerResourceFailureError, CloudQualityValue, CubeCamera, DEFAULT_CLOUD_LAYER, DEFAULT_DEPTH_OF_FIELD_PARAMS, DEPTH_OF_FIELD_PARAMS_BYTE_SIZE, DepthOfField, DepthOfFieldQualityValue, DepthOfFieldSideValue, DepthOfFieldValidationError, DirectionalLight, DirectionalShadowFilterValue, DynamicResolution, Fog, Instances, Layer, LightProbe, Lines, MAX_VOLUMETRIC_FOG_OWNERS, MeshFilter, MeshRenderer, MotionBlur, PointLight, PointLightShadow, PointShapeValue, Points, PostProcessParams, REFLECTION_PROBE_UPDATE_CONTINUOUS, REFLECTION_PROBE_UPDATE_ONCE, REFLECTION_PROBE_UPDATE_ON_CHANGE, RectAreaLight, ReflectionProbe, SKYBOX_MODE_CUBEMAP, SKYLIGHT_RECOVERY_FALLBACK, SceneInstance, ScreenSpaceReflection, SkyboxBackground, Skylight, SortKey, SpotLight, SunCardinalityError, TONEMAP_ACES_FILMIC, TONEMAP_AGX, TONEMAP_CINEON, TONEMAP_LINEAR, TONEMAP_NEUTRAL, TONEMAP_NONE, TONEMAP_REINHARD, TONEMAP_REINHARD_EXTENDED, Visibility, VisibilityStateValue, VolumetricFog, VolumetricFogSamplingValue, antialiasFromF32, attachBarrelDistortionCameraFrame, buildCubeCameraFaceViews, cameraExposureFromColumns, cameraProjectionFromF32, cloudLayerFormationKey, cloudLayerSourceKey, cloudQualityFromF32, cloudShadowResolutionForQuality, cloudViewDistanceForQuality, computeInvRangeSquared, createBarrelDistortionMapping, cubeCameraUpdateIntentFromF32, cubeCameraUpdateIntentToF32, degToCos, depthOfFieldQualityCode, depthOfFieldQualityFromF32, depthOfFieldRequestFailure, depthOfFieldSideCode, depthOfFieldSideFromF32, depthOfFieldTapCount, directionalShadowQualityFromF32, extractCloudLayer, extractVolumetricFog, freezeBarrelDistortionMapping, hasVolumetricFogCapability, mapDisplayToScene, mapDisplayUvToSceneUv, mapSceneToDisplay, mapSceneUvToDisplayUv, orthographic, packDepthOfFieldParams, perspective, pointShapeFromU32, projectMeshMaterialBindingObservation, reflectionProbeUpdateIntentFromF32, reflectionProbeUpdateIntentToF32, resolveDepthOfFieldFrameParams, resolveDepthOfFieldParams, resolveIntegratedVolumeConsumer, resolveMeshMaterialBindings, resolveSelectedVolumetricLight, resolveVisibility, resolveVolumetricFogLightPair, selectCloudLayerFrame, selectEnvironment, signedDepthOfFieldCoC, summarizeMeshMaterialBindings, tonemapFromF32, tonemapToU32, validateBarrelDistortionParameters, validateCameraBloom, validateCameraColorGrading, validateCameraExposure, validateCloudLayer, validateDepthOfFieldFrameParams, validateDepthOfFieldParams, validateDirection, validateDirectionalLightData, validateDynamicResolutionCamera, validateDynamicResolutionParameters, validateLightProbeData, validatePointLightData, validatePointLightShadowData, validateRectAreaLightData, validateSpotLightData, validateVolumetricFog, visibilityStateFromU32 };
2388
+ //# sourceMappingURL=chunk-UINHLCZA.mjs.map
2389
+ //# sourceMappingURL=chunk-UINHLCZA.mjs.map