@forgeax/engine-render 0.1.32 → 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 (624) hide show
  1. package/README.md +1374 -142
  2. package/dist/assembly/analytic-fog-registration.d.ts +3 -0
  3. package/dist/assembly/analytic-fog-registration.d.ts.map +1 -0
  4. package/dist/assembly/backend-contract.d.ts +2 -0
  5. package/dist/assembly/backend-contract.d.ts.map +1 -1
  6. package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
  7. package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
  8. package/dist/assembly/canvas-draw-guard.d.ts +3 -0
  9. package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
  10. package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
  11. package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
  12. package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
  13. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  14. package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
  15. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
  16. package/dist/assembly/factory.d.ts +1 -1
  17. package/dist/assembly/factory.d.ts.map +1 -1
  18. package/dist/assembly/fxaa-registration.d.ts +4 -0
  19. package/dist/assembly/fxaa-registration.d.ts.map +1 -0
  20. package/dist/assembly/host-contract.d.ts +3 -3
  21. package/dist/assembly/host-contract.d.ts.map +1 -1
  22. package/dist/assembly/lod-observation.d.ts +4 -0
  23. package/dist/assembly/lod-observation.d.ts.map +1 -0
  24. package/dist/assembly/material/assembly.d.ts.map +1 -1
  25. package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
  26. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
  27. package/dist/assembly/material-shader-policy.d.ts +16 -2
  28. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  29. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
  30. package/dist/assembly/motion-blur-registration.d.ts +3 -0
  31. package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
  32. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  33. package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
  34. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  35. package/dist/assembly/render-feature-post-processes.d.ts +6 -0
  36. package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
  37. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  38. package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
  39. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
  40. package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
  41. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  42. package/dist/assembly/renderer-inspection.d.ts +11 -0
  43. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  44. package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
  45. package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
  47. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
  48. package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
  49. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
  50. package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
  51. package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
  52. package/dist/assembly/webgpu-ready.d.ts +2 -2
  53. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  54. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
  55. package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
  56. package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
  57. package/dist/assembly/webgpu-renderer.d.ts +1 -1
  58. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  59. package/dist/authoring.mjs +1 -1
  60. package/dist/barrel-distortion.d.ts +47 -0
  61. package/dist/barrel-distortion.d.ts.map +1 -0
  62. package/dist/bloom-admission.d.ts +13 -0
  63. package/dist/bloom-admission.d.ts.map +1 -0
  64. package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
  65. package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
  66. package/dist/{chunk-JCIRYQ4V.mjs → chunk-HEB564WF.mjs} +10 -4
  67. package/dist/chunk-HEB564WF.mjs.map +1 -0
  68. package/dist/{chunk-JRIPCMYC.mjs → chunk-MKDIT2EM.mjs} +1584 -375
  69. package/dist/chunk-MKDIT2EM.mjs.map +1 -0
  70. package/dist/{chunk-S665NJNF.mjs → chunk-OCDLEI6I.mjs} +3 -3
  71. package/dist/{chunk-S665NJNF.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
  72. package/dist/chunk-ODZWR6JQ.mjs +4927 -0
  73. package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
  74. package/dist/{chunk-DRR7D3KX.mjs → chunk-SHFUFJ5N.mjs} +192 -18
  75. package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
  76. package/dist/{chunk-4NNZQCL3.mjs → chunk-UI5SFODX.mjs} +223 -277
  77. package/dist/chunk-UI5SFODX.mjs.map +1 -0
  78. package/dist/{chunk-GWCEMDVR.mjs → chunk-UINHLCZA.mjs} +787 -80
  79. package/dist/chunk-UINHLCZA.mjs.map +1 -0
  80. package/dist/{chunk-6TFBXLRJ.mjs → chunk-WEX45HKH.mjs} +222 -337
  81. package/dist/chunk-WEX45HKH.mjs.map +1 -0
  82. package/dist/cloud/density.d.ts +55 -0
  83. package/dist/cloud/density.d.ts.map +1 -0
  84. package/dist/cloud/extract.d.ts +25 -0
  85. package/dist/cloud/extract.d.ts.map +1 -0
  86. package/dist/cloud/feature.d.ts +57 -0
  87. package/dist/cloud/feature.d.ts.map +1 -0
  88. package/dist/cloud/frame-context.d.ts +8 -0
  89. package/dist/cloud/frame-context.d.ts.map +1 -0
  90. package/dist/cloud/inspection.d.ts +59 -0
  91. package/dist/cloud/inspection.d.ts.map +1 -0
  92. package/dist/cloud/optics.d.ts +56 -0
  93. package/dist/cloud/optics.d.ts.map +1 -0
  94. package/dist/cloud/parameters.d.ts +73 -0
  95. package/dist/cloud/parameters.d.ts.map +1 -0
  96. package/dist/cloud/resources.d.ts +60 -0
  97. package/dist/cloud/resources.d.ts.map +1 -0
  98. package/dist/cloud/shadow.d.ts +42 -0
  99. package/dist/cloud/shadow.d.ts.map +1 -0
  100. package/dist/cloud/temporal.d.ts +74 -0
  101. package/dist/cloud/temporal.d.ts.map +1 -0
  102. package/dist/components/atmosphere.d.ts +2 -0
  103. package/dist/components/atmosphere.d.ts.map +1 -1
  104. package/dist/components/barrel-distortion.d.ts +13 -0
  105. package/dist/components/barrel-distortion.d.ts.map +1 -0
  106. package/dist/components/camera.d.ts +20 -4
  107. package/dist/components/camera.d.ts.map +1 -1
  108. package/dist/components/cloud-layer.d.ts +29 -0
  109. package/dist/components/cloud-layer.d.ts.map +1 -0
  110. package/dist/components/index.d.ts +2 -0
  111. package/dist/components/index.d.ts.map +1 -1
  112. package/dist/components/instances.d.ts +20 -6
  113. package/dist/components/instances.d.ts.map +1 -1
  114. package/dist/components/mesh-filter.d.ts +6 -5
  115. package/dist/components/mesh-filter.d.ts.map +1 -1
  116. package/dist/components/motion-blur.d.ts +1 -0
  117. package/dist/components/motion-blur.d.ts.map +1 -1
  118. package/dist/construct-renderer.d.ts +1 -1
  119. package/dist/construct-renderer.d.ts.map +1 -1
  120. package/dist/construct-renderer.mjs +9751 -3528
  121. package/dist/construct-renderer.mjs.map +1 -1
  122. package/dist/device/gpu-residency.d.ts +6 -0
  123. package/dist/device/gpu-residency.d.ts.map +1 -1
  124. package/dist/dynamic-geometry.d.ts +5 -1
  125. package/dist/dynamic-geometry.d.ts.map +1 -1
  126. package/dist/environment/analytic-fog.d.ts +6 -0
  127. package/dist/environment/analytic-fog.d.ts.map +1 -0
  128. package/dist/errors/cloud.d.ts +59 -0
  129. package/dist/errors/cloud.d.ts.map +1 -0
  130. package/dist/errors/render.d.ts +23 -5
  131. package/dist/errors/render.d.ts.map +1 -1
  132. package/dist/examples/single-layer-medium-surface.d.ts +47 -0
  133. package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
  134. package/dist/extract/camera.d.ts.map +1 -1
  135. package/dist/extract/contracts.d.ts +12 -1
  136. package/dist/extract/contracts.d.ts.map +1 -1
  137. package/dist/extract/environment.d.ts +2 -0
  138. package/dist/extract/environment.d.ts.map +1 -1
  139. package/dist/features/barrel-distortion.d.ts +29 -0
  140. package/dist/features/barrel-distortion.d.ts.map +1 -0
  141. package/dist/features/error-reporting.d.ts +17 -0
  142. package/dist/features/error-reporting.d.ts.map +1 -0
  143. package/dist/features/host.d.ts +15 -0
  144. package/dist/features/host.d.ts.map +1 -1
  145. package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
  146. package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
  147. package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
  148. package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
  149. package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
  150. package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
  151. package/dist/features/plan.d.ts +15 -4
  152. package/dist/features/plan.d.ts.map +1 -1
  153. package/dist/features/prepared-gpu-work.d.ts +9 -5
  154. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  155. package/dist/features/render-graph-compute.d.ts.map +1 -1
  156. package/dist/features/render-graph-contribution.d.ts +5 -0
  157. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  158. package/dist/features/render-graph-raster.d.ts +1 -0
  159. package/dist/features/render-graph-raster.d.ts.map +1 -1
  160. package/dist/features/targets.d.ts +2 -0
  161. package/dist/features/targets.d.ts.map +1 -1
  162. package/dist/features/types.d.ts +44 -0
  163. package/dist/features/types.d.ts.map +1 -1
  164. package/dist/fullscreen-post-process-pass.d.ts +15 -7
  165. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  166. package/dist/gpu-dirty-ranges.d.ts +11 -0
  167. package/dist/gpu-dirty-ranges.d.ts.map +1 -0
  168. package/dist/gpu-driven/batch-topology.d.ts +17 -0
  169. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  170. package/dist/gpu-driven/material-artifacts.d.ts +6 -0
  171. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  172. package/dist/gpu-driven/prepared-draw.d.ts +7 -0
  173. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  174. package/dist/gpu-driven/production-raster-material.d.ts +178 -0
  175. package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
  176. package/dist/gpu-driven/production-raster.d.ts +50 -4
  177. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  178. package/dist/gpu-driven/resource-allocation.d.ts +31 -0
  179. package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
  180. package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
  181. package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
  182. package/dist/gpu-driven/view-gpu.d.ts +35 -2
  183. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  184. package/dist/gpu-scene.d.ts +11 -1
  185. package/dist/gpu-scene.d.ts.map +1 -1
  186. package/dist/hdrp-buffers.d.ts +2 -2
  187. package/dist/hdrp-buffers.d.ts.map +1 -1
  188. package/dist/ibl/skylight-bind-group.d.ts +10 -1
  189. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  190. package/dist/index.d.ts +31 -8
  191. package/dist/index.d.ts.map +1 -1
  192. package/dist/index.mjs +258 -8
  193. package/dist/index.mjs.map +1 -1
  194. package/dist/inspection-types.d.ts +178 -3
  195. package/dist/inspection-types.d.ts.map +1 -1
  196. package/dist/instance-buffer-cache.d.ts +4 -4
  197. package/dist/instance-buffer-cache.d.ts.map +1 -1
  198. package/dist/instances.d.ts +49 -94
  199. package/dist/instances.d.ts.map +1 -1
  200. package/dist/internal.mjs +7 -7
  201. package/dist/pbr-pipeline.d.ts +19 -1
  202. package/dist/pbr-pipeline.d.ts.map +1 -1
  203. package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
  204. package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
  205. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  206. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  207. package/dist/pipeline/standard-output/types.d.ts +4 -2
  208. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  209. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  210. package/dist/pipeline/standard-post.d.ts +28 -19
  211. package/dist/pipeline/standard-post.d.ts.map +1 -1
  212. package/dist/pipeline-builder.d.ts +1 -1
  213. package/dist/pipeline-builder.d.ts.map +1 -1
  214. package/dist/pipeline-spec.d.ts +2 -2
  215. package/dist/plugin.d.ts.map +1 -1
  216. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
  217. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  218. package/dist/record/barrel-distortion-frame.d.ts +15 -0
  219. package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
  220. package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
  221. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
  222. package/dist/record/fold-buckets.d.ts +95 -0
  223. package/dist/record/fold-buckets.d.ts.map +1 -0
  224. package/dist/record/fold-instance-buffer.d.ts +6 -0
  225. package/dist/record/fold-instance-buffer.d.ts.map +1 -0
  226. package/dist/record/frame-lighting.d.ts +1 -0
  227. package/dist/record/frame-lighting.d.ts.map +1 -1
  228. package/dist/record/frame-snapshot.d.ts +40 -3
  229. package/dist/record/frame-snapshot.d.ts.map +1 -1
  230. package/dist/record/frame-targets.d.ts.map +1 -1
  231. package/dist/record/frame.d.ts +14 -62
  232. package/dist/record/frame.d.ts.map +1 -1
  233. package/dist/record/gpu-draw-receipts.d.ts +11 -0
  234. package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
  235. package/dist/record/gpu-timing.d.ts +8 -0
  236. package/dist/record/gpu-timing.d.ts.map +1 -1
  237. package/dist/record/main-pass-geometry.d.ts +21 -5
  238. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  239. package/dist/record/main-pass-material.d.ts +7 -1
  240. package/dist/record/main-pass-material.d.ts.map +1 -1
  241. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  242. package/dist/record/main-pass.d.ts +13 -2
  243. package/dist/record/main-pass.d.ts.map +1 -1
  244. package/dist/record/mesh-ssbo.d.ts +6 -5
  245. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  246. package/dist/record/motion-blur-receipt.d.ts +11 -0
  247. package/dist/record/motion-blur-receipt.d.ts.map +1 -0
  248. package/dist/record/probe-blend-buffer.d.ts +16 -0
  249. package/dist/record/probe-blend-buffer.d.ts.map +1 -0
  250. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  251. package/dist/record/render-context.d.ts +34 -31
  252. package/dist/record/render-context.d.ts.map +1 -1
  253. package/dist/record/shadow-pass.d.ts +2 -0
  254. package/dist/record/shadow-pass.d.ts.map +1 -1
  255. package/dist/record/skybox-post-pass.d.ts +6 -4
  256. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  257. package/dist/record/typed-frame-graph.d.ts +22 -2
  258. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  259. package/dist/record/view-ubo.d.ts +11 -3
  260. package/dist/record/view-ubo.d.ts.map +1 -1
  261. package/dist/record/volume-params.d.ts +9 -0
  262. package/dist/record/volume-params.d.ts.map +1 -0
  263. package/dist/recovery/render-system-candidate.d.ts +10 -0
  264. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  265. package/dist/reflection/record-owner.d.ts.map +1 -1
  266. package/dist/render-contract.d.ts +66 -8
  267. package/dist/render-contract.d.ts.map +1 -1
  268. package/dist/render-graph-primitives.d.ts.map +1 -1
  269. package/dist/render-pipeline.d.ts +106 -3
  270. package/dist/render-pipeline.d.ts.map +1 -1
  271. package/dist/render-system-extract-tail.d.ts +3 -2
  272. package/dist/render-system-extract-tail.d.ts.map +1 -1
  273. package/dist/render-system-extract.d.ts +24 -10
  274. package/dist/render-system-extract.d.ts.map +1 -1
  275. package/dist/render-system-presentation.d.ts +23 -0
  276. package/dist/render-system-presentation.d.ts.map +1 -0
  277. package/dist/render-system-producer-roots.d.ts +10 -0
  278. package/dist/render-system-producer-roots.d.ts.map +1 -0
  279. package/dist/render-system-residency.d.ts +12 -0
  280. package/dist/render-system-residency.d.ts.map +1 -0
  281. package/dist/render-system.d.ts +26 -15
  282. package/dist/render-system.d.ts.map +1 -1
  283. package/dist/scene/probe-blend.d.ts +27 -0
  284. package/dist/scene/probe-blend.d.ts.map +1 -1
  285. package/dist/scene/render-scene.d.ts +14 -5
  286. package/dist/scene/render-scene.d.ts.map +1 -1
  287. package/dist/ssao-buffers.d.ts +9 -0
  288. package/dist/ssao-buffers.d.ts.map +1 -1
  289. package/dist/surface/dynamic-input.d.ts +133 -0
  290. package/dist/surface/dynamic-input.d.ts.map +1 -0
  291. package/dist/surface/gpu-driven.d.ts +41 -0
  292. package/dist/surface/gpu-driven.d.ts.map +1 -0
  293. package/dist/surface/submission-observation.d.ts +136 -0
  294. package/dist/surface/submission-observation.d.ts.map +1 -0
  295. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  296. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  297. package/dist/temporal/frame.d.ts +7 -0
  298. package/dist/temporal/frame.d.ts.map +1 -1
  299. package/dist/temporal/gpu.d.ts +13 -1
  300. package/dist/temporal/gpu.d.ts.map +1 -1
  301. package/dist/temporal/index.mjs +5 -5
  302. package/dist/temporal/inspection.d.ts.map +1 -1
  303. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  304. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
  305. package/dist/temporal/view.d.ts +6 -1
  306. package/dist/temporal/view.d.ts.map +1 -1
  307. package/dist/transmission/single-layer-medium.d.ts +89 -0
  308. package/dist/transmission/single-layer-medium.d.ts.map +1 -0
  309. package/dist/typed-render-graph-primitives.d.ts +24 -9
  310. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  311. package/dist/volume/component.d.ts +9 -5
  312. package/dist/volume/component.d.ts.map +1 -1
  313. package/dist/volume/extract.d.ts +1 -1
  314. package/dist/volume/extract.d.ts.map +1 -1
  315. package/dist/volume/inspection.d.ts +2 -0
  316. package/dist/volume/inspection.d.ts.map +1 -1
  317. package/dist/volume/passes.d.ts +4 -1
  318. package/dist/volume/passes.d.ts.map +1 -1
  319. package/dist/volume/resources.d.ts.map +1 -1
  320. package/dist/volume/temporal.d.ts +3 -1
  321. package/dist/volume/temporal.d.ts.map +1 -1
  322. package/package.json +22 -21
  323. package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
  324. package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
  325. package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
  326. package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
  327. package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
  328. package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
  329. package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
  330. package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
  331. package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
  332. package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
  333. package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
  334. package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
  335. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
  336. package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
  337. package/src/__tests__/environment-selection.unit.test.ts +12 -0
  338. package/src/__tests__/factory-contract.integration.test.ts +626 -113
  339. package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
  340. package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
  341. package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
  342. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
  343. package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
  344. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
  345. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
  346. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
  347. package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
  348. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
  349. package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
  350. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +7 -6
  351. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
  352. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +103 -4
  353. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
  354. package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
  355. package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
  356. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
  357. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
  358. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
  359. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
  360. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
  361. package/src/__tests__/gpu-scene.unit.test.ts +210 -9
  362. package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
  363. package/src/__tests__/instances-culling.integration.test.ts +10 -36
  364. package/src/__tests__/instances-store.unit.test.ts +105 -238
  365. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  366. package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
  367. package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
  368. package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
  369. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
  370. package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
  371. package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
  372. package/src/__tests__/motion-blur-compute.dawn.test.ts +589 -0
  373. package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
  374. package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
  375. package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
  376. package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
  377. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +21 -0
  378. package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
  379. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
  380. package/src/__tests__/probe-bindings.unit.test.ts +582 -1
  381. package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
  382. package/src/__tests__/public-surface.test-d.ts +8 -0
  383. package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
  384. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
  385. package/src/__tests__/render-error-code-owner.test-d.ts +9 -0
  386. package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
  387. package/src/__tests__/render-feature-error-reporting.unit.test.ts +44 -0
  388. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
  389. package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
  390. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
  391. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
  392. package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
  393. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +37 -6
  394. package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
  395. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
  396. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
  397. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
  398. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
  399. package/src/__tests__/renderer-frame-transaction.integration.test.ts +33 -11
  400. package/src/__tests__/resource-allocation.unit.test.ts +123 -0
  401. package/src/__tests__/shader-manifest-fixture.ts +4 -4
  402. package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
  403. package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
  404. package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
  405. package/src/__tests__/skinned-shadow-caster.test.ts +17 -0
  406. package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
  407. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
  408. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
  409. package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
  410. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
  411. package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
  412. package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
  413. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
  414. package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
  415. package/src/__tests__/standard-pipeline.integration.test.ts +200 -9
  416. package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
  417. package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
  418. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
  419. package/src/__tests__/temporal-performance.integration.test.ts +3 -3
  420. package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
  421. package/src/__tests__/temporal-view.unit.test.ts +2 -1
  422. package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
  423. package/src/__tests__/visibility-instances.integration.test.ts +7 -19
  424. package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
  425. package/src/__tests__/volume-optics-oracle.unit.test.ts +7 -3
  426. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +189 -15
  427. package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
  428. package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
  429. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
  430. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +558 -68
  431. package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
  432. package/src/__tests__/volumetric-fog-topology.unit.test.ts +23 -5
  433. package/src/assembly/analytic-fog-registration.ts +14 -0
  434. package/src/assembly/backend-contract.ts +30 -0
  435. package/src/assembly/barrel-distortion-inspection.ts +22 -0
  436. package/src/assembly/canvas-draw-guard.ts +11 -0
  437. package/src/assembly/cloud-shadow-entry.ts +22 -0
  438. package/src/assembly/dynamic-geometry-host.ts +65 -37
  439. package/src/assembly/dynamic-geometry-runtime.ts +7 -1
  440. package/src/assembly/factory.ts +2 -30
  441. package/src/assembly/fxaa-registration.ts +17 -0
  442. package/src/assembly/host-contract.ts +3 -3
  443. package/src/assembly/lod-observation.ts +12 -0
  444. package/src/assembly/material/assembly.ts +25 -13
  445. package/src/assembly/material/pipeline-helpers.ts +53 -12
  446. package/src/assembly/material-shader-policy.ts +55 -0
  447. package/src/assembly/material-shader-prewarm.ts +21 -10
  448. package/src/assembly/motion-blur-registration.ts +17 -0
  449. package/src/assembly/recovery/device-loss-fanout.ts +13 -0
  450. package/src/assembly/recovery/renderer-recover.ts +41 -18
  451. package/src/assembly/render-feature-post-processes.ts +54 -0
  452. package/src/assembly/renderer-facade.ts +6 -1
  453. package/src/assembly/renderer-feature-inspection.ts +8 -2
  454. package/src/assembly/renderer-frame-transaction.ts +23 -0
  455. package/src/assembly/renderer-inspection.ts +28 -0
  456. package/src/assembly/skin-palette-owner.ts +1 -1
  457. package/src/assembly/temporal-post-process-prewarm.ts +40 -0
  458. package/src/assembly/webgpu-pbr-ready.ts +9 -1
  459. package/src/assembly/webgpu-ready-contract.ts +8 -3
  460. package/src/assembly/webgpu-ready-per-pass.ts +104 -0
  461. package/src/assembly/webgpu-ready.ts +296 -306
  462. package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
  463. package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
  464. package/src/assembly/webgpu-renderer.ts +228 -281
  465. package/src/assembly/webgpu-vertex-layouts.ts +1 -1
  466. package/src/barrel-distortion.ts +247 -0
  467. package/src/bloom-admission.ts +21 -0
  468. package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
  469. package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
  470. package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
  471. package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
  472. package/src/cloud/density.ts +600 -0
  473. package/src/cloud/extract.ts +110 -0
  474. package/src/cloud/feature.ts +1810 -0
  475. package/src/cloud/frame-context.ts +42 -0
  476. package/src/cloud/inspection.ts +130 -0
  477. package/src/cloud/optics.ts +285 -0
  478. package/src/cloud/parameters.ts +255 -0
  479. package/src/cloud/resources.ts +122 -0
  480. package/src/cloud/shadow.ts +167 -0
  481. package/src/cloud/temporal.ts +226 -0
  482. package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
  483. package/src/components/atmosphere.ts +4 -0
  484. package/src/components/barrel-distortion.ts +46 -0
  485. package/src/components/camera.ts +66 -10
  486. package/src/components/cloud-layer.ts +47 -0
  487. package/src/components/index.ts +2 -0
  488. package/src/components/instances.ts +18 -45
  489. package/src/components/mesh-filter.ts +11 -9
  490. package/src/components/motion-blur.ts +1 -0
  491. package/src/components/sprite-instances.ts +1 -1
  492. package/src/construct-renderer.ts +1 -1
  493. package/src/device/gpu-residency.ts +56 -12
  494. package/src/dynamic-geometry.ts +12 -1
  495. package/src/environment/analytic-fog.ts +44 -0
  496. package/src/environment/background.ts +2 -2
  497. package/src/errors/cloud.ts +103 -0
  498. package/src/errors/render.ts +58 -8
  499. package/src/examples/single-layer-medium-surface.ts +59 -0
  500. package/src/extract/camera.ts +35 -8
  501. package/src/extract/contracts.ts +12 -0
  502. package/src/extract/environment.ts +4 -0
  503. package/src/features/barrel-distortion.ts +172 -0
  504. package/src/features/error-reporting.ts +98 -0
  505. package/src/features/host.ts +138 -24
  506. package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
  507. package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
  508. package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
  509. package/src/features/motion-blur/motion-blur-params.ts +70 -2
  510. package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
  511. package/src/features/plan.ts +33 -8
  512. package/src/features/prepared-gpu-work.ts +86 -35
  513. package/src/features/render-graph-compute.ts +13 -5
  514. package/src/features/render-graph-contribution.ts +11 -0
  515. package/src/features/render-graph-raster.ts +45 -3
  516. package/src/features/targets.ts +66 -0
  517. package/src/features/types.ts +47 -0
  518. package/src/fullscreen-post-process-pass.ts +41 -9
  519. package/src/gpu-dirty-ranges.ts +48 -0
  520. package/src/gpu-driven/batch-topology.ts +53 -0
  521. package/src/gpu-driven/material-artifacts.ts +35 -32
  522. package/src/gpu-driven/prepared-draw.ts +27 -14
  523. package/src/gpu-driven/production-raster-material.ts +1894 -0
  524. package/src/gpu-driven/production-raster.ts +904 -787
  525. package/src/gpu-driven/resource-allocation.ts +142 -0
  526. package/src/gpu-driven/shadow-ownership.ts +71 -0
  527. package/src/gpu-driven/view-gpu.ts +181 -10
  528. package/src/gpu-scene.ts +259 -101
  529. package/src/hdrp-buffers.ts +4 -3
  530. package/src/ibl/skylight-bind-group.ts +49 -7
  531. package/src/index.ts +228 -9
  532. package/src/inspection-types.ts +222 -2
  533. package/src/instance-buffer-cache.ts +4 -4
  534. package/src/instances.ts +151 -492
  535. package/src/pbr-pipeline.ts +219 -13
  536. package/src/pipeline/single-layer-medium-passes.ts +267 -0
  537. package/src/pipeline/standard-forward-lane.ts +313 -57
  538. package/src/pipeline/standard-output/graph.ts +8 -2
  539. package/src/pipeline/standard-output/types.ts +12 -1
  540. package/src/pipeline/standard-pipeline.ts +291 -18
  541. package/src/pipeline/standard-post.ts +397 -102
  542. package/src/pipeline-builder.ts +1 -1
  543. package/src/pipeline-spec.ts +5 -5
  544. package/src/plugin.ts +4 -0
  545. package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
  546. package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
  547. package/src/prepare/prepared-graphics-resolver.ts +2 -0
  548. package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
  549. package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
  550. package/src/record/__tests__/temporal-payload.unit.test.ts +3 -2
  551. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
  552. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
  553. package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
  554. package/src/record/barrel-distortion-frame.ts +110 -0
  555. package/src/record/dynamic-geometry-consumption.ts +39 -9
  556. package/src/record/fold-buckets.ts +852 -0
  557. package/src/record/fold-instance-buffer.ts +51 -0
  558. package/src/record/frame-lighting.ts +36 -2
  559. package/src/record/frame-snapshot.ts +44 -4
  560. package/src/record/frame-targets.ts +10 -6
  561. package/src/record/frame.ts +373 -1099
  562. package/src/record/gpu-draw-receipts.ts +38 -0
  563. package/src/record/gpu-timing.ts +48 -5
  564. package/src/record/main-pass-geometry.ts +281 -83
  565. package/src/record/main-pass-material.ts +66 -4
  566. package/src/record/main-pass-sprite-draws.ts +13 -66
  567. package/src/record/main-pass.ts +156 -20
  568. package/src/record/mesh-ssbo.ts +43 -6
  569. package/src/record/motion-blur-receipt.ts +91 -0
  570. package/src/record/probe-blend-buffer.ts +180 -0
  571. package/src/record/recovery-pipeline.ts +35 -3
  572. package/src/record/render-context.ts +51 -31
  573. package/src/record/shadow-pass.ts +36 -2
  574. package/src/record/skybox-post-pass.ts +150 -200
  575. package/src/record/typed-frame-graph.ts +824 -44
  576. package/src/record/view-ubo.ts +26 -3
  577. package/src/record/volume-params.ts +225 -0
  578. package/src/recovery/render-system-candidate.ts +257 -52
  579. package/src/reflection/record-owner.ts +7 -3
  580. package/src/render-contract.ts +71 -8
  581. package/src/render-graph-primitives.ts +7 -1
  582. package/src/render-pipeline.ts +136 -1
  583. package/src/render-system-extract-tail.ts +72 -60
  584. package/src/render-system-extract.ts +117 -87
  585. package/src/render-system-presentation.ts +56 -0
  586. package/src/render-system-producer-roots.ts +96 -0
  587. package/src/render-system-residency.ts +159 -0
  588. package/src/render-system.ts +601 -482
  589. package/src/scene/probe-blend.ts +96 -4
  590. package/src/scene/render-scene.ts +431 -281
  591. package/src/ssao-buffers.ts +95 -2
  592. package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
  593. package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
  594. package/src/surface/dynamic-input.ts +658 -0
  595. package/src/surface/gpu-driven.ts +147 -0
  596. package/src/surface/submission-observation.ts +517 -0
  597. package/src/systems/skin-palette-allocator.ts +4 -1
  598. package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
  599. package/src/temporal/frame-coordinator.ts +8 -1
  600. package/src/temporal/frame.ts +20 -0
  601. package/src/temporal/gpu.ts +101 -17
  602. package/src/temporal/inspection.ts +7 -1
  603. package/src/temporal/standard-scene-data.ts +5 -0
  604. package/src/temporal/target-coverage-attachment.ts +4 -0
  605. package/src/temporal/view.ts +13 -2
  606. package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
  607. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
  608. package/src/transmission/single-layer-medium.ts +322 -0
  609. package/src/typed-render-graph-primitives.ts +191 -50
  610. package/src/volume/component.ts +10 -10
  611. package/src/volume/extract.ts +11 -5
  612. package/src/volume/inspection.ts +3 -0
  613. package/src/volume/passes.ts +95 -8
  614. package/src/volume/resources.ts +2 -1
  615. package/src/volume/temporal.ts +11 -0
  616. package/dist/chunk-4NNZQCL3.mjs.map +0 -1
  617. package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
  618. package/dist/chunk-DRR7D3KX.mjs.map +0 -1
  619. package/dist/chunk-GWCEMDVR.mjs.map +0 -1
  620. package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
  621. package/dist/chunk-JRIPCMYC.mjs.map +0 -1
  622. package/dist/chunk-LULCA3OF.mjs +0 -1713
  623. package/dist/chunk-LULCA3OF.mjs.map +0 -1
  624. package/dist/chunk-PA5DRJNI.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
- import { RenderIntentInvalidError, DynamicResolutionRequiresTaaError, ShadowInvalidConfigError, VolumeOwnerConflictError, VolumeDensityShapeMismatchError, VolumeInvalidBoundsError, VolumeInvalidParametersError, DynamicResolutionInvalidParameterError } from './chunk-6TFBXLRJ.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';
@@ -11,8 +11,41 @@ var Atmosphere = defineComponent("Atmosphere", {
11
11
  rayleigh: { type: "f32", default: 1 },
12
12
  mieCoefficient: { type: "f32", default: 5e-3 },
13
13
  mieDirectionalG: { type: "f32", default: 0.8 },
14
- sunAngularRadius: { type: "f32", default: 4675e-6 }
14
+ sunAngularRadius: { type: "f32", default: 4675e-6 },
15
+ /** Independent multiplier for the analytic circumsolar lobe. */
16
+ circumsolarStrength: { type: "f32", default: 1 },
17
+ /** Relative angular width of the analytic circumsolar lobe. */
18
+ circumsolarWidth: { type: "f32", default: 1 }
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
15
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
+ }
16
49
  var CAMERA_PROJECTION_PERSPECTIVE = 0;
17
50
  var CAMERA_PROJECTION_ORTHOGRAPHIC = 1;
18
51
  var CAMERA_EXPOSURE_MODE_MANUAL = 0;
@@ -199,6 +232,14 @@ function antialiasFromF32(value) {
199
232
  }
200
233
  var BLOOM_DISABLED = 0;
201
234
  var BLOOM_ENABLED = 1;
235
+ var CAMERA_BLOOM_INTENSITY_MIN = 0;
236
+ var CAMERA_BLOOM_INTENSITY_MAX = 8;
237
+ var CAMERA_BLOOM_THRESHOLD_MIN = 0;
238
+ var CAMERA_BLOOM_THRESHOLD_MAX = 65504;
239
+ var CAMERA_BLOOM_SOFT_KNEE_MIN = 0;
240
+ var CAMERA_BLOOM_SOFT_KNEE_MAX = 1;
241
+ var CAMERA_BLOOM_SCATTER_MIN = 0;
242
+ var CAMERA_BLOOM_SCATTER_MAX = 0.95;
202
243
  function bloomEnabledFromF32(value) {
203
244
  if (value === BLOOM_DISABLED) return "off";
204
245
  if (value === BLOOM_ENABLED) return "on";
@@ -210,6 +251,40 @@ function bloomEnabledFromF32(value) {
210
251
  "select Camera bloom off or on"
211
252
  );
212
253
  }
254
+ function validateBloomRange(field, value, min, max) {
255
+ if (!Number.isFinite(value) || value < min || value > max) {
256
+ throw cameraError(
257
+ "camera-bloom-invalid",
258
+ field,
259
+ value,
260
+ `a finite value in [${min}, ${max}]`,
261
+ `set Camera.${field} to a finite value in [${min}, ${max}]`
262
+ );
263
+ }
264
+ }
265
+ function validateCameraBloom(bloom, threshold, intensity, softKnee, scatter) {
266
+ const enabled = bloomEnabledFromF32(bloom);
267
+ validateBloomRange(
268
+ "bloomThreshold",
269
+ threshold,
270
+ CAMERA_BLOOM_THRESHOLD_MIN,
271
+ CAMERA_BLOOM_THRESHOLD_MAX
272
+ );
273
+ validateBloomRange(
274
+ "bloomIntensity",
275
+ intensity,
276
+ CAMERA_BLOOM_INTENSITY_MIN,
277
+ CAMERA_BLOOM_INTENSITY_MAX
278
+ );
279
+ validateBloomRange(
280
+ "bloomSoftKnee",
281
+ softKnee,
282
+ CAMERA_BLOOM_SOFT_KNEE_MIN,
283
+ CAMERA_BLOOM_SOFT_KNEE_MAX
284
+ );
285
+ validateBloomRange("bloomScatter", scatter, CAMERA_BLOOM_SCATTER_MIN, CAMERA_BLOOM_SCATTER_MAX);
286
+ return enabled;
287
+ }
213
288
  var Camera = defineComponent("Camera", {
214
289
  fov: { type: "f32" },
215
290
  aspect: { type: "f32" },
@@ -236,7 +311,8 @@ var Camera = defineComponent("Camera", {
236
311
  bloom: { type: "f32", default: 0 },
237
312
  bloomThreshold: { type: "f32", default: 1 },
238
313
  bloomIntensity: { type: "f32", default: 1 },
239
- bloomBlurRadius: { type: "f32", default: 4 },
314
+ bloomSoftKnee: { type: "f32", default: 0.5 },
315
+ bloomScatter: { type: "f32", default: 0.7 },
240
316
  // M1 target camera role: zero means this camera is eligible for display;
241
317
  // non-zero shared targets are auxiliary producers whose views and receipt
242
318
  // promotion remain owned by Renderer.
@@ -356,6 +432,37 @@ function orthographic(opts) {
356
432
  ...cameraColorGradingColumns(opts)
357
433
  };
358
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
+ }
359
466
  var CUBE_CAMERA_UPDATE_ONCE = 0;
360
467
  var CUBE_CAMERA_UPDATE_ON_DEMAND = 1;
361
468
  var CUBE_CAMERA_UPDATE_CONTINUOUS = 2;
@@ -496,7 +603,7 @@ var DEFAULT_DYNAMIC_RESOLUTION = Object.freeze({
496
603
  minScale: 0.67,
497
604
  maxScale: 1
498
605
  });
499
- function invalid(field, value, expected) {
606
+ function invalid2(field, value, expected) {
500
607
  return new DynamicResolutionInvalidParameterError({ field, value, expected });
501
608
  }
502
609
  function validateDynamicResolutionParameters(input) {
@@ -505,16 +612,16 @@ function validateDynamicResolutionParameters(input) {
505
612
  const minScale = value.minScale ?? DEFAULT_DYNAMIC_RESOLUTION.minScale;
506
613
  const maxScale = value.maxScale ?? DEFAULT_DYNAMIC_RESOLUTION.maxScale;
507
614
  if (!Number.isFinite(targetGpuMs) || targetGpuMs <= 0) {
508
- return err(invalid("targetGpuMs", targetGpuMs, "finite and greater than 0"));
615
+ return err(invalid2("targetGpuMs", targetGpuMs, "finite and greater than 0"));
509
616
  }
510
617
  if (!Number.isFinite(minScale) || minScale < 0.5 || minScale > 1) {
511
- 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]"));
512
619
  }
513
620
  if (!Number.isFinite(maxScale) || maxScale < 0.5 || maxScale > 1) {
514
- 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]"));
515
622
  }
516
623
  if (minScale > maxScale) {
517
- return err(invalid("minScale", minScale, "less than or equal to maxScale"));
624
+ return err(invalid2("minScale", minScale, "less than or equal to maxScale"));
518
625
  }
519
626
  return ok(Object.freeze({ targetGpuMs, minScale, maxScale }));
520
627
  }
@@ -534,7 +641,7 @@ var Fog = defineComponent("Fog", {
534
641
  maxOpacity: { type: "f32", default: 1 }
535
642
  });
536
643
  var Instances = defineComponent("Instances", {
537
- collectionId: { type: "u32", default: 0 }
644
+ transforms: { type: "array<f32>" }
538
645
  });
539
646
  var Layer = defineComponent("Layer", {
540
647
  value: { type: "i32", default: 0 }
@@ -777,7 +884,8 @@ var MeshRenderer = defineComponent("MeshRenderer", {
777
884
  var MotionBlur = defineComponent("MotionBlur", {
778
885
  shutterAngle: { type: "f32", default: 180 },
779
886
  maxRadiusPixels: { type: "f32", default: 32 },
780
- sampleCount: { type: "f32", default: 8 }
887
+ sampleCount: { type: "f32", default: 8 },
888
+ targetFps: { type: "f32", default: 60 }
781
889
  });
782
890
  var PointLight = defineComponent("PointLight", {
783
891
  // color carries an explicit layer-2 default [1,1,1] (white); the array
@@ -973,6 +1081,576 @@ var Visibility = defineComponent(
973
1081
  }
974
1082
  }
975
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
+ }
1477
+
1478
+ // src/environment/signature.ts
1479
+ function sorted(items) {
1480
+ return [...items].sort((left, right) => left.entityKey - right.entityKey);
1481
+ }
1482
+ function environmentSignature(input) {
1483
+ return JSON.stringify({
1484
+ environments: sorted(input.environments),
1485
+ fogs: sorted(input.fogs),
1486
+ suns: sorted(input.suns)
1487
+ });
1488
+ }
1489
+ function environmentOnlySignature(input) {
1490
+ return JSON.stringify({
1491
+ environments: sorted(input.environments),
1492
+ suns: sorted(input.suns)
1493
+ });
1494
+ }
1495
+ function fogOnlySignature(input) {
1496
+ return JSON.stringify({ fogs: sorted(input.fogs) });
1497
+ }
1498
+ function environmentFactSignatures(input) {
1499
+ return {
1500
+ environmentSignature: environmentOnlySignature(input),
1501
+ fogSignature: fogOnlySignature(input),
1502
+ signature: environmentSignature(input)
1503
+ };
1504
+ }
1505
+
1506
+ // src/extract/environment.ts
1507
+ var ATMOSPHERE_PARAMETER_RANGES = Object.freeze({
1508
+ turbidity: Object.freeze({ min: 1, max: 20 }),
1509
+ rayleigh: Object.freeze({ min: 0, max: Number.POSITIVE_INFINITY }),
1510
+ mieCoefficient: Object.freeze({ min: 0, max: Number.POSITIVE_INFINITY }),
1511
+ mieDirectionalG: Object.freeze({ min: 0, max: 0.999 }),
1512
+ sunAngularRadius: Object.freeze({ min: 0, max: Number.POSITIVE_INFINITY }),
1513
+ circumsolarStrength: Object.freeze({ min: 0, max: 4 }),
1514
+ circumsolarWidth: Object.freeze({ min: 0.25, max: 4 })
1515
+ });
1516
+ function validateFogParameters(candidate) {
1517
+ if (candidate.color.length !== 3) {
1518
+ return {
1519
+ field: "color",
1520
+ value: candidate.color.length,
1521
+ expected: "exactly three finite channels in [0, 1]"
1522
+ };
1523
+ }
1524
+ for (let index = 0; index < candidate.color.length; index += 1) {
1525
+ const value = candidate.color[index];
1526
+ if (value === void 0 || !Number.isFinite(value) || value < 0 || value > 1) {
1527
+ return {
1528
+ field: `color[${index}]`,
1529
+ value: value ?? Number.NaN,
1530
+ expected: "a finite number in [0, 1]"
1531
+ };
1532
+ }
1533
+ }
1534
+ if (!Number.isFinite(candidate.density) || candidate.density < 0) {
1535
+ return { field: "density", value: candidate.density, expected: "a finite number >= 0" };
1536
+ }
1537
+ if (!Number.isFinite(candidate.heightFalloff) || candidate.heightFalloff < 0) {
1538
+ return {
1539
+ field: "heightFalloff",
1540
+ value: candidate.heightFalloff,
1541
+ expected: "a finite number >= 0"
1542
+ };
1543
+ }
1544
+ if (!Number.isFinite(candidate.maxOpacity) || candidate.maxOpacity < 0 || candidate.maxOpacity > 1) {
1545
+ return {
1546
+ field: "maxOpacity",
1547
+ value: candidate.maxOpacity,
1548
+ expected: "a finite number in [0, 1]"
1549
+ };
1550
+ }
1551
+ return void 0;
1552
+ }
1553
+ function validateAtmosphereParameters(parameters) {
1554
+ for (const field of Object.keys(ATMOSPHERE_PARAMETER_RANGES)) {
1555
+ const value = parameters[field];
1556
+ const range = ATMOSPHERE_PARAMETER_RANGES[field];
1557
+ if (!Number.isFinite(value) || value < range.min || value > range.max) {
1558
+ return new AtmosphereInvalidParameterError(field, value, range);
1559
+ }
1560
+ }
1561
+ return void 0;
1562
+ }
1563
+
1564
+ // src/environment/frame.ts
1565
+ var SKYLIGHT_RECOVERY_FALLBACK = Object.freeze({
1566
+ kind: "skylight",
1567
+ active: false
1568
+ });
1569
+ var EnvironmentSelectionParameterError = class extends Error {
1570
+ code = "environment-selection-invalid";
1571
+ expected;
1572
+ hint;
1573
+ detail;
1574
+ constructor(field, value, expected) {
1575
+ super(`environment selection field ${field} is invalid`);
1576
+ this.name = "EnvironmentSelectionParameterError";
1577
+ this.expected = expected;
1578
+ this.hint = `set ${field} to a finite value satisfying ${expected}`;
1579
+ this.detail = { field, value };
1580
+ }
1581
+ };
1582
+ var SunCardinalityError = class extends Error {
1583
+ code = "sun-cardinality";
1584
+ expected = "atmosphere has exactly one sun owner";
1585
+ hint = "add exactly one DirectionalLight sun for the atmosphere owner";
1586
+ detail;
1587
+ constructor(value) {
1588
+ super(`atmosphere sun cardinality is ${value}`);
1589
+ this.name = "SunCardinalityError";
1590
+ this.detail = { field: "sun", value };
1591
+ }
1592
+ };
1593
+ function freezeCandidate(candidate) {
1594
+ return Object.freeze(candidate);
1595
+ }
1596
+ function freezeFog(candidate) {
1597
+ return Object.freeze({
1598
+ ...candidate,
1599
+ color: Object.freeze([...candidate.color])
1600
+ });
1601
+ }
1602
+ function selectEnvironment(input) {
1603
+ if (input.environments.length > 1) {
1604
+ return err(
1605
+ new EnvironmentSourceConflictError(
1606
+ [...input.environments].sort((left, right) => left.entityKey - right.entityKey).map(({ kind, entityKey, sourceKey }) => ({ kind, entityKey, sourceKey }))
1607
+ )
1608
+ );
1609
+ }
1610
+ if (input.fogs.length > 1) return err(new FogCardinalityError(input.fogs.length));
1611
+ const selectedFog = input.fogs[0];
1612
+ if (selectedFog !== void 0) {
1613
+ const issue = validateFogParameters(selectedFog);
1614
+ if (issue !== void 0) {
1615
+ return err(new EnvironmentSelectionParameterError(issue.field, issue.value, issue.expected));
1616
+ }
1617
+ }
1618
+ const selected = input.environments[0];
1619
+ if (selected?.kind === "atmosphere") {
1620
+ const invalid5 = validateAtmosphereParameters(selected.atmosphere);
1621
+ if (invalid5 !== void 0) return err(invalid5);
1622
+ }
1623
+ if (selected?.kind === "atmosphere" && input.suns.length !== 1) {
1624
+ return err(new SunCardinalityError(input.suns.length));
1625
+ }
1626
+ const source = selected === void 0 ? { kind: "none" } : selected.kind === "atmosphere" ? {
1627
+ kind: "atmosphere",
1628
+ entityKey: selected.entityKey,
1629
+ sourceKey: selected.sourceKey,
1630
+ atmosphere: Object.freeze({ ...selected.atmosphere })
1631
+ } : {
1632
+ kind: "image",
1633
+ entityKey: selected.entityKey,
1634
+ sourceKey: selected.sourceKey
1635
+ };
1636
+ const sun = input.suns[0] === void 0 ? void 0 : freezeCandidate({ ...input.suns[0] });
1637
+ const fog = selectedFog === void 0 ? void 0 : freezeFog(selectedFog);
1638
+ const signatureInput = {
1639
+ environments: selected === void 0 ? [] : [selected],
1640
+ fogs: selectedFog === void 0 ? [] : [selectedFog],
1641
+ suns: input.suns
1642
+ };
1643
+ const signatures = environmentFactSignatures(signatureInput);
1644
+ const result = {
1645
+ source: Object.freeze(source),
1646
+ fog,
1647
+ ...signatures,
1648
+ revision: 0,
1649
+ sun
1650
+ };
1651
+ Object.defineProperty(result, "lane", { value: input.lane, enumerable: false });
1652
+ return ok(Object.freeze(result));
1653
+ }
976
1654
  var DEPTH_OF_FIELD_PARAMS_BYTE_SIZE = 64;
977
1655
  var MIN_F_STOP = Math.fround(0.7);
978
1656
  var MAX_F_STOP = Math.fround(32);
@@ -1018,7 +1696,7 @@ function resolveDepthOfFieldFrameParams(requested, requestFailure, accepted) {
1018
1696
  }
1019
1697
  return accepted;
1020
1698
  }
1021
- function invalid2(field, value, expected, bound) {
1699
+ function invalid4(field, value, expected, bound) {
1022
1700
  return new DepthOfFieldValidationError(
1023
1701
  "depth-of-field-invalid-params",
1024
1702
  { field, value, expected, ...bound === void 0 ? {} : { bound } },
@@ -1053,31 +1731,31 @@ function resolveDepthOfFieldFrameValues(params, input) {
1053
1731
  ];
1054
1732
  for (const [field, value, raw] of finitePositiveFields) {
1055
1733
  if (!Number.isFinite(value) || value <= 0) {
1056
- return err(invalid2(field, raw, "a finite positive f32 value"));
1734
+ return err(invalid4(field, raw, "a finite positive f32 value"));
1057
1735
  }
1058
1736
  }
1059
1737
  if (!Number.isFinite(fStop) || fStop < MIN_F_STOP || fStop > MAX_F_STOP) {
1060
1738
  return err(
1061
- 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])
1062
1740
  );
1063
1741
  }
1064
1742
  if (!Number.isFinite(maxRadiusPixels) || maxRadiusPixels < 0 || maxRadiusPixels > 32) {
1065
1743
  return err(
1066
- 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])
1067
1745
  );
1068
1746
  }
1069
1747
  if (!Number.isFinite(outputHeight) || outputHeight <= 0) {
1070
- return err(invalid2("outputHeight", input.outputHeight, "a finite positive f32 value"));
1748
+ return err(invalid4("outputHeight", input.outputHeight, "a finite positive f32 value"));
1071
1749
  }
1072
1750
  if (far <= near) {
1073
- 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"));
1074
1752
  }
1075
1753
  if (focusDistance <= focal) {
1076
- return err(invalid2("focusDistance", params.focusDistance, "greater than focalLength in f32"));
1754
+ return err(invalid4("focusDistance", params.focusDistance, "greater than focalLength in f32"));
1077
1755
  }
1078
1756
  const depthRatio = quantizeF32(near / far);
1079
1757
  if (!Number.isFinite(depthRatio) || depthRatio <= 0) {
1080
- 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"));
1081
1759
  }
1082
1760
  for (const raw of [quantizeF32(2 ** -149), 0.5, MAX_LINEAR_DEPTH_RAW]) {
1083
1761
  const oneMinusRaw = quantizeF32(1 - raw);
@@ -1085,7 +1763,7 @@ function resolveDepthOfFieldFrameValues(params, input) {
1085
1763
  const denominator = quantizeF32(oneMinusRaw + weightedRatio);
1086
1764
  const distance = quantizeF32(near / denominator);
1087
1765
  if (!Number.isFinite(oneMinusRaw) || oneMinusRaw <= 0 || !Number.isFinite(weightedRatio) || !Number.isFinite(denominator) || denominator <= 0 || !Number.isFinite(distance) || distance <= 0) {
1088
- return err(invalid2("linearDepth", distance, "finite positive f32 reconstruction"));
1766
+ return err(invalid4("linearDepth", distance, "finite positive f32 reconstruction"));
1089
1767
  }
1090
1768
  }
1091
1769
  const cocCoefficient = frameCocCoefficient(
@@ -1099,7 +1777,7 @@ function resolveDepthOfFieldFrameValues(params, input) {
1099
1777
  );
1100
1778
  if (!Number.isFinite(cocCoefficient) || cocCoefficient <= 0) {
1101
1779
  return err(
1102
- invalid2("cocCoefficient", cocCoefficient, "a finite positive value representable as f32")
1780
+ invalid4("cocCoefficient", cocCoefficient, "a finite positive value representable as f32")
1103
1781
  );
1104
1782
  }
1105
1783
  for (const [field, depth] of [
@@ -1110,7 +1788,7 @@ function resolveDepthOfFieldFrameValues(params, input) {
1110
1788
  const depthFactor = quantizeF32(1 - focusOverDepth);
1111
1789
  const radius = quantizeF32(cocCoefficient * depthFactor);
1112
1790
  if (!Number.isFinite(focusOverDepth) || !Number.isFinite(depthFactor) || !Number.isFinite(radius)) {
1113
- 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"));
1114
1792
  }
1115
1793
  }
1116
1794
  return ok({
@@ -1153,16 +1831,16 @@ function validateDepthOfFieldParams(input, camera) {
1153
1831
  );
1154
1832
  const qualityValue = quantizeF32(value.quality ?? DepthOfFieldQualityValue.medium);
1155
1833
  const blurSideValue = quantizeF32(value.blurSide ?? DepthOfFieldSideValue.both);
1156
- const quality = depthOfFieldQualityFromF32(qualityValue);
1834
+ const quality2 = depthOfFieldQualityFromF32(qualityValue);
1157
1835
  const blurSide = depthOfFieldSideFromF32(blurSideValue);
1158
1836
  if (!Number.isFinite(focusDistance) || focusDistance <= 0) {
1159
1837
  return err(
1160
- invalid2("focusDistance", value.focusDistance ?? focusDistance, "a finite positive f32 value")
1838
+ invalid4("focusDistance", value.focusDistance ?? focusDistance, "a finite positive f32 value")
1161
1839
  );
1162
1840
  }
1163
1841
  if (!Number.isFinite(fStop) || fStop < MIN_F_STOP || fStop > MAX_F_STOP) {
1164
1842
  return err(
1165
- 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]", [
1166
1844
  MIN_F_STOP,
1167
1845
  MAX_F_STOP
1168
1846
  ])
@@ -1170,12 +1848,12 @@ function validateDepthOfFieldParams(input, camera) {
1170
1848
  }
1171
1849
  if (!Number.isFinite(sensorHeight) || sensorHeight <= 0) {
1172
1850
  return err(
1173
- invalid2("sensorHeight", value.sensorHeight ?? sensorHeight, "a finite positive f32 value")
1851
+ invalid4("sensorHeight", value.sensorHeight ?? sensorHeight, "a finite positive f32 value")
1174
1852
  );
1175
1853
  }
1176
1854
  if (!Number.isFinite(maxRadiusPixels) || maxRadiusPixels < 0 || maxRadiusPixels > 32) {
1177
1855
  return err(
1178
- invalid2(
1856
+ invalid4(
1179
1857
  "maxRadiusPixels",
1180
1858
  value.maxRadiusPixels ?? maxRadiusPixels,
1181
1859
  "a finite f32 value in [0, 32]",
@@ -1183,11 +1861,11 @@ function validateDepthOfFieldParams(input, camera) {
1183
1861
  )
1184
1862
  );
1185
1863
  }
1186
- if (quality === void 0) {
1187
- 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"));
1188
1866
  }
1189
1867
  if (blurSide === void 0) {
1190
- return err(invalid2("blurSide", blurSideValue, "DepthOfFieldSideValue.both, near, or far"));
1868
+ return err(invalid4("blurSide", blurSideValue, "DepthOfFieldSideValue.both, near, or far"));
1191
1869
  }
1192
1870
  let focal = DEFAULT_DEPTH_OF_FIELD_PARAMS.focalLength;
1193
1871
  if (camera !== void 0) {
@@ -1195,25 +1873,25 @@ function validateDepthOfFieldParams(input, camera) {
1195
1873
  const near = quantizeF32(camera.near);
1196
1874
  const far = quantizeF32(camera.far);
1197
1875
  if (!Number.isFinite(fov) || fov <= 0 || fov >= Math.PI) {
1198
- 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)"));
1199
1877
  }
1200
1878
  if (!Number.isFinite(near) || !Number.isFinite(far) || near <= 0 || far <= near) {
1201
1879
  return err(
1202
- 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")
1203
1881
  );
1204
1882
  }
1205
1883
  focal = quantizeF32(focalLength(sensorHeight, fov));
1206
1884
  if (!Number.isFinite(focal) || focal <= 0) {
1207
- return err(invalid2("focalLength", focal, "a finite positive f32 value"));
1885
+ return err(invalid4("focalLength", focal, "a finite positive f32 value"));
1208
1886
  }
1209
1887
  if (focusDistance < near || focusDistance > far) {
1210
1888
  return err(
1211
- invalid2("focusDistance", focusDistance, `a value in [${near}, ${far}]`, [near, far])
1889
+ invalid4("focusDistance", focusDistance, `a value in [${near}, ${far}]`, [near, far])
1212
1890
  );
1213
1891
  }
1214
1892
  if (focusDistance <= focal) {
1215
1893
  return err(
1216
- invalid2("focusDistance", focusDistance, `greater than focalLength in f32 (${focal})`)
1894
+ invalid4("focusDistance", focusDistance, `greater than focalLength in f32 (${focal})`)
1217
1895
  );
1218
1896
  }
1219
1897
  }
@@ -1223,7 +1901,7 @@ function validateDepthOfFieldParams(input, camera) {
1223
1901
  fStop,
1224
1902
  sensorHeight,
1225
1903
  maxRadiusPixels,
1226
- quality,
1904
+ quality: quality2,
1227
1905
  blurSide,
1228
1906
  focalLength: focal
1229
1907
  })
@@ -1233,8 +1911,8 @@ function resolveDepthOfFieldParams(input, camera) {
1233
1911
  if (input === void 0) return ok(void 0);
1234
1912
  return validateDepthOfFieldParams(input, camera);
1235
1913
  }
1236
- function depthOfFieldTapCount(quality) {
1237
- switch (quality) {
1914
+ function depthOfFieldTapCount(quality2) {
1915
+ switch (quality2) {
1238
1916
  case "low":
1239
1917
  return 16;
1240
1918
  case "medium":
@@ -1253,8 +1931,8 @@ function depthOfFieldSideCode(side) {
1253
1931
  return DepthOfFieldSideValue.far;
1254
1932
  }
1255
1933
  }
1256
- function depthOfFieldQualityCode(quality) {
1257
- switch (quality) {
1934
+ function depthOfFieldQualityCode(quality2) {
1935
+ switch (quality2) {
1258
1936
  case "low":
1259
1937
  return DepthOfFieldQualityValue.low;
1260
1938
  case "medium":
@@ -1633,50 +2311,79 @@ function resolveVisibility(world, hierarchy = projectHierarchy(world)) {
1633
2311
  };
1634
2312
  return snapshot;
1635
2313
  }
1636
- var VolumetricFog = defineComponent("VolumetricFog", {
1637
- light: { type: "entity" },
1638
- spotLight: { type: "entity" },
1639
- density: { type: "shared<TextureAsset>", simulationTransient: true },
1640
- boundsMin: { type: "array<f32, 3>" },
1641
- boundsMax: { type: "array<f32, 3>" },
1642
- extinction: { type: "array<f32, 3>" },
1643
- albedo: { type: "array<f32, 3>" },
1644
- emission: { type: "array<f32, 3>" },
1645
- anisotropy: { type: "f32", default: 0 },
1646
- maxDistance: { type: "f32", default: 100 }
1647
- });
1648
- function finiteVector(value) {
1649
- return value.every(Number.isFinite);
1650
- }
1651
- function validBounds(bounds) {
1652
- if (!finiteVector(bounds.min) || !finiteVector(bounds.max)) return false;
1653
- return bounds.max.every((value, index) => value > (bounds.min[index] ?? value));
1654
- }
1655
- function validRange(value, min, max = Infinity) {
1656
- 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
+ );
1657
2333
  }
1658
- function validateVolumetricFog(input) {
1659
- const ownerCount = input.ownerCount ?? 1;
1660
- if (ownerCount !== 1) return err(new VolumeOwnerConflictError(ownerCount));
1661
- if (input.density.shape.viewDimension !== "3d" || input.density.colorSpace === "srgb") {
1662
- return err(
1663
- new VolumeDensityShapeMismatchError(input.density.guid, input.density.shape.viewDimension)
1664
- );
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);
1665
2343
  }
1666
- if (!validBounds(input.bounds)) return err(new VolumeInvalidBoundsError(input.bounds));
1667
- 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) {
1668
- 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 {
1669
2366
  }
1670
- return ok({ ...input, ownerCount: 1 });
2367
+ return selectCloudLayerFrame(
2368
+ candidates,
2369
+ world.getResource(Time).elapsed,
2370
+ sunDirection,
2371
+ sunRadiance
2372
+ );
1671
2373
  }
1672
2374
  function extractVolumetricFog(inputs) {
1673
2375
  if (inputs.length === 0) return ok({ status: "off" });
1674
- if (inputs.length !== 1) return err(new VolumeOwnerConflictError(inputs.length));
1675
- const validated = validateVolumetricFog(inputs[0]);
1676
- if (!validated.ok) return validated;
1677
- 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 });
1678
2385
  }
1679
2386
 
1680
- export { ANTIALIAS_FXAA, ANTIALIAS_MSAA, ANTIALIAS_NONE, ANTIALIAS_TAA, Atmosphere, BLOOM_DISABLED, BLOOM_ENABLED, 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, SceneInstance, ScreenSpaceReflection, SkyboxBackground, Skylight, SortKey, SpotLight, TONEMAP_ACES_FILMIC, TONEMAP_AGX, TONEMAP_CINEON, TONEMAP_LINEAR, TONEMAP_NEUTRAL, TONEMAP_NONE, TONEMAP_REINHARD, TONEMAP_REINHARD_EXTENDED, Visibility, VisibilityStateValue, VolumetricFog, antialiasFromF32, bloomEnabledFromF32, 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, signedDepthOfFieldCoC, summarizeMeshMaterialBindings, tonemapFromF32, tonemapToU32, validateCameraColorGrading, validateCameraExposure, validateDepthOfFieldFrameParams, validateDepthOfFieldParams, validateDirection, validateDirectionalLightData, validateDynamicResolutionCamera, validateDynamicResolutionParameters, validateLightProbeData, validatePointLightData, validatePointLightShadowData, validateRectAreaLightData, validateSpotLightData, validateVolumetricFog, visibilityStateFromU32 };
1681
- //# sourceMappingURL=chunk-GWCEMDVR.mjs.map
1682
- //# sourceMappingURL=chunk-GWCEMDVR.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