@forgeax/engine-render 0.1.31 → 0.1.33

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 (293) hide show
  1. package/README.md +447 -34
  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/fxaa-registration.d.ts +4 -0
  5. package/dist/assembly/fxaa-registration.d.ts.map +1 -0
  6. package/dist/assembly/lod-observation.d.ts +4 -0
  7. package/dist/assembly/lod-observation.d.ts.map +1 -0
  8. package/dist/assembly/motion-blur-registration.d.ts +3 -0
  9. package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
  10. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  11. package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
  12. package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
  13. package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
  14. package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
  15. package/dist/assembly/webgpu-ready.d.ts +3 -2
  16. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  17. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  18. package/dist/bloom-admission.d.ts +13 -0
  19. package/dist/bloom-admission.d.ts.map +1 -0
  20. package/dist/{chunk-FUUO4UND.mjs → chunk-3RTCJTH4.mjs} +12 -9
  21. package/dist/chunk-3RTCJTH4.mjs.map +1 -0
  22. package/dist/{chunk-NO4WZCAH.mjs → chunk-LEAXOMYJ.mjs} +3 -3
  23. package/dist/{chunk-NO4WZCAH.mjs.map → chunk-LEAXOMYJ.mjs.map} +1 -1
  24. package/dist/{chunk-JRBDO2KB.mjs → chunk-NB2S7ZRX.mjs} +166 -10
  25. package/dist/chunk-NB2S7ZRX.mjs.map +1 -0
  26. package/dist/{chunk-7MQ3XBSP.mjs → chunk-NNQL7CB3.mjs} +4 -4
  27. package/dist/{chunk-7MQ3XBSP.mjs.map → chunk-NNQL7CB3.mjs.map} +1 -1
  28. package/dist/{chunk-C3DDSXYK.mjs → chunk-OO3DRYK7.mjs} +171 -230
  29. package/dist/chunk-OO3DRYK7.mjs.map +1 -0
  30. package/dist/{chunk-S5UE2T5P.mjs → chunk-PLAXOOX5.mjs} +608 -7
  31. package/dist/chunk-PLAXOOX5.mjs.map +1 -0
  32. package/dist/{chunk-PSEQ6QPH.mjs → chunk-VOZWDM3L.mjs} +295 -198
  33. package/dist/chunk-VOZWDM3L.mjs.map +1 -0
  34. package/dist/{chunk-MDQJPY3T.mjs → chunk-ZDQWGQW7.mjs} +10 -4
  35. package/dist/chunk-ZDQWGQW7.mjs.map +1 -0
  36. package/dist/components/atmosphere.d.ts +2 -0
  37. package/dist/components/atmosphere.d.ts.map +1 -1
  38. package/dist/components/camera.d.ts +20 -4
  39. package/dist/components/camera.d.ts.map +1 -1
  40. package/dist/components/depth-of-field.d.ts +28 -0
  41. package/dist/components/depth-of-field.d.ts.map +1 -0
  42. package/dist/components/directional-light.d.ts +2 -1
  43. package/dist/components/directional-light.d.ts.map +1 -1
  44. package/dist/components/index.d.ts +1 -0
  45. package/dist/components/index.d.ts.map +1 -1
  46. package/dist/components/mesh-filter.d.ts +6 -5
  47. package/dist/components/mesh-filter.d.ts.map +1 -1
  48. package/dist/components/motion-blur.d.ts +1 -0
  49. package/dist/components/motion-blur.d.ts.map +1 -1
  50. package/dist/construct-renderer.mjs +3746 -837
  51. package/dist/construct-renderer.mjs.map +1 -1
  52. package/dist/device/gpu-residency.d.ts +6 -0
  53. package/dist/device/gpu-residency.d.ts.map +1 -1
  54. package/dist/environment/analytic-fog.d.ts +6 -0
  55. package/dist/environment/analytic-fog.d.ts.map +1 -0
  56. package/dist/errors/render.d.ts +6 -2
  57. package/dist/errors/render.d.ts.map +1 -1
  58. package/dist/extract/camera.d.ts.map +1 -1
  59. package/dist/extract/contracts.d.ts +7 -0
  60. package/dist/extract/contracts.d.ts.map +1 -1
  61. package/dist/extract/environment.d.ts +2 -0
  62. package/dist/extract/environment.d.ts.map +1 -1
  63. package/dist/features/depth-of-field/depth-of-field-assembly.d.ts +19 -0
  64. package/dist/features/depth-of-field/depth-of-field-assembly.d.ts.map +1 -0
  65. package/dist/features/depth-of-field/depth-of-field-feature.d.ts +43 -0
  66. package/dist/features/depth-of-field/depth-of-field-feature.d.ts.map +1 -0
  67. package/dist/features/depth-of-field/depth-of-field-inspection.d.ts +34 -0
  68. package/dist/features/depth-of-field/depth-of-field-inspection.d.ts.map +1 -0
  69. package/dist/features/depth-of-field/depth-of-field-params.d.ts +83 -0
  70. package/dist/features/depth-of-field/depth-of-field-params.d.ts.map +1 -0
  71. package/dist/features/error-reporting.d.ts +13 -0
  72. package/dist/features/error-reporting.d.ts.map +1 -0
  73. package/dist/features/host.d.ts +5 -0
  74. package/dist/features/host.d.ts.map +1 -1
  75. package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
  76. package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
  77. package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
  78. package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
  79. package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
  80. package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
  81. package/dist/features/plan.d.ts +7 -4
  82. package/dist/features/plan.d.ts.map +1 -1
  83. package/dist/features/prepared-gpu-work.d.ts +9 -5
  84. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  85. package/dist/features/render-graph-compute.d.ts.map +1 -1
  86. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  87. package/dist/features/types.d.ts +19 -1
  88. package/dist/features/types.d.ts.map +1 -1
  89. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  90. package/dist/gpu-driven/prepared-draw.d.ts +7 -0
  91. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  92. package/dist/gpu-driven/production-raster.d.ts +3 -1
  93. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  94. package/dist/gpu-driven/view-gpu.d.ts +9 -0
  95. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  96. package/dist/gpu-scene.d.ts +6 -1
  97. package/dist/gpu-scene.d.ts.map +1 -1
  98. package/dist/index.d.ts +8 -3
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.mjs +6 -5
  101. package/dist/index.mjs.map +1 -1
  102. package/dist/inspection-types.d.ts +78 -2
  103. package/dist/inspection-types.d.ts.map +1 -1
  104. package/dist/instances.d.ts +15 -1
  105. package/dist/instances.d.ts.map +1 -1
  106. package/dist/internal.mjs +6 -6
  107. package/dist/mesh-material-bindings.d.ts +3 -0
  108. package/dist/mesh-material-bindings.d.ts.map +1 -1
  109. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  110. package/dist/pipeline/standard-output/types.d.ts +4 -2
  111. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  112. package/dist/pipeline/standard-post.d.ts +28 -19
  113. package/dist/pipeline/standard-post.d.ts.map +1 -1
  114. package/dist/pipeline-spec.d.ts +2 -2
  115. package/dist/plugin.d.ts.map +1 -1
  116. package/dist/record/frame-snapshot.d.ts +24 -1
  117. package/dist/record/frame-snapshot.d.ts.map +1 -1
  118. package/dist/record/frame-targets.d.ts.map +1 -1
  119. package/dist/record/frame.d.ts +5 -2
  120. package/dist/record/frame.d.ts.map +1 -1
  121. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  122. package/dist/record/main-pass.d.ts.map +1 -1
  123. package/dist/record/mesh-ssbo.d.ts +6 -5
  124. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  125. package/dist/record/render-context.d.ts +12 -28
  126. package/dist/record/render-context.d.ts.map +1 -1
  127. package/dist/record/shadow-pass.d.ts.map +1 -1
  128. package/dist/record/skybox-post-pass.d.ts +5 -3
  129. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  130. package/dist/record/typed-frame-graph.d.ts +8 -1
  131. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  132. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  133. package/dist/render-contract.d.ts +32 -5
  134. package/dist/render-contract.d.ts.map +1 -1
  135. package/dist/render-graph-primitives.d.ts +2 -0
  136. package/dist/render-graph-primitives.d.ts.map +1 -1
  137. package/dist/render-pipeline.d.ts +15 -1
  138. package/dist/render-pipeline.d.ts.map +1 -1
  139. package/dist/render-system-extract-tail.d.ts.map +1 -1
  140. package/dist/render-system-extract.d.ts +26 -5
  141. package/dist/render-system-extract.d.ts.map +1 -1
  142. package/dist/render-system.d.ts +9 -2
  143. package/dist/render-system.d.ts.map +1 -1
  144. package/dist/scene/render-scene.d.ts +2 -0
  145. package/dist/scene/render-scene.d.ts.map +1 -1
  146. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  147. package/dist/temporal/frame.d.ts +7 -0
  148. package/dist/temporal/frame.d.ts.map +1 -1
  149. package/dist/temporal/index.mjs +5 -5
  150. package/dist/temporal/view.d.ts +6 -1
  151. package/dist/temporal/view.d.ts.map +1 -1
  152. package/dist/typed-render-graph-primitives.d.ts +10 -7
  153. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  154. package/dist/volume/component.d.ts +0 -1
  155. package/dist/volume/component.d.ts.map +1 -1
  156. package/dist/volume/passes.d.ts.map +1 -1
  157. package/dist/volume/temporal.d.ts +3 -1
  158. package/dist/volume/temporal.d.ts.map +1 -1
  159. package/package.json +21 -21
  160. package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
  161. package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
  162. package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
  163. package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
  164. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
  165. package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
  166. package/src/__tests__/environment-selection.unit.test.ts +12 -0
  167. package/src/__tests__/factory-contract.integration.test.ts +331 -68
  168. package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
  169. package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
  170. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +12 -0
  171. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
  172. package/src/__tests__/gpu-driven-production.integration.test.ts +27 -1
  173. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +1 -1
  174. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
  175. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +11 -0
  176. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
  177. package/src/__tests__/gpu-scene.unit.test.ts +91 -0
  178. package/src/__tests__/instances-store.unit.test.ts +90 -0
  179. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
  180. package/src/__tests__/motion-blur-compute.dawn.test.ts +583 -0
  181. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +49 -0
  182. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
  183. package/src/__tests__/public-surface.test-d.ts +8 -0
  184. package/src/__tests__/render-error-code-owner.test-d.ts +2 -0
  185. package/src/__tests__/render-feature-error-reporting.unit.test.ts +24 -0
  186. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
  187. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +31 -0
  188. package/src/__tests__/renderer-frame-transaction.integration.test.ts +7 -1
  189. package/src/__tests__/shader-manifest-fixture.ts +4 -4
  190. package/src/__tests__/skinned-shadow-caster.test.ts +2 -0
  191. package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
  192. package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
  193. package/src/__tests__/standard-pipeline.integration.test.ts +18 -8
  194. package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
  195. package/src/__tests__/temporal-view.unit.test.ts +2 -1
  196. package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
  197. package/src/__tests__/volume-optics-oracle.unit.test.ts +3 -1
  198. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +177 -13
  199. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +447 -61
  200. package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
  201. package/src/__tests__/volumetric-fog-topology.unit.test.ts +19 -3
  202. package/src/assembly/analytic-fog-registration.ts +14 -0
  203. package/src/assembly/fxaa-registration.ts +17 -0
  204. package/src/assembly/lod-observation.ts +12 -0
  205. package/src/assembly/motion-blur-registration.ts +17 -0
  206. package/src/assembly/renderer-facade.ts +2 -0
  207. package/src/assembly/temporal-post-process-prewarm.ts +40 -0
  208. package/src/assembly/webgpu-ready-contract.ts +8 -3
  209. package/src/assembly/webgpu-ready.ts +186 -250
  210. package/src/assembly/webgpu-renderer.ts +30 -45
  211. package/src/bloom-admission.ts +21 -0
  212. package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
  213. package/src/components/atmosphere.ts +4 -0
  214. package/src/components/camera.ts +66 -10
  215. package/src/components/depth-of-field.ts +45 -0
  216. package/src/components/directional-light.ts +2 -1
  217. package/src/components/index.ts +1 -0
  218. package/src/components/mesh-filter.ts +11 -9
  219. package/src/components/motion-blur.ts +1 -0
  220. package/src/device/gpu-residency.ts +56 -12
  221. package/src/environment/analytic-fog.ts +44 -0
  222. package/src/environment/background.ts +2 -2
  223. package/src/errors/render.ts +14 -1
  224. package/src/extract/camera.ts +42 -9
  225. package/src/extract/contracts.ts +7 -0
  226. package/src/extract/environment.ts +4 -0
  227. package/src/features/depth-of-field/__tests__/depth-of-field-params.unit.test.ts +943 -0
  228. package/src/features/depth-of-field/depth-of-field-assembly.ts +100 -0
  229. package/src/features/depth-of-field/depth-of-field-feature.ts +295 -0
  230. package/src/features/depth-of-field/depth-of-field-inspection.ts +237 -0
  231. package/src/features/depth-of-field/depth-of-field-params.ts +556 -0
  232. package/src/features/error-reporting.ts +78 -0
  233. package/src/features/host.ts +26 -13
  234. package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
  235. package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
  236. package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
  237. package/src/features/motion-blur/motion-blur-params.ts +70 -2
  238. package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
  239. package/src/features/plan.ts +25 -8
  240. package/src/features/prepared-gpu-work.ts +86 -35
  241. package/src/features/render-graph-compute.ts +13 -5
  242. package/src/features/render-graph-contribution.ts +2 -0
  243. package/src/features/types.ts +18 -1
  244. package/src/gpu-driven/material-artifacts.ts +2 -7
  245. package/src/gpu-driven/prepared-draw.ts +15 -10
  246. package/src/gpu-driven/production-raster.ts +83 -7
  247. package/src/gpu-driven/view-gpu.ts +17 -0
  248. package/src/gpu-scene.ts +188 -21
  249. package/src/index.ts +64 -0
  250. package/src/inspection-types.ts +98 -2
  251. package/src/instances.ts +93 -0
  252. package/src/mesh-material-bindings.ts +4 -0
  253. package/src/pipeline/standard-output/graph.ts +3 -0
  254. package/src/pipeline/standard-output/types.ts +4 -1
  255. package/src/pipeline/standard-post.ts +324 -76
  256. package/src/pipeline-spec.ts +5 -5
  257. package/src/plugin.ts +2 -0
  258. package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
  259. package/src/record/__tests__/temporal-payload.unit.test.ts +2 -1
  260. package/src/record/frame-snapshot.ts +31 -2
  261. package/src/record/frame-targets.ts +10 -6
  262. package/src/record/frame.ts +202 -28
  263. package/src/record/main-pass-geometry.ts +30 -1
  264. package/src/record/main-pass-sprite-draws.ts +6 -1
  265. package/src/record/main-pass.ts +1 -5
  266. package/src/record/mesh-ssbo.ts +43 -6
  267. package/src/record/render-context.ts +12 -28
  268. package/src/record/shadow-pass.ts +6 -1
  269. package/src/record/skybox-post-pass.ts +122 -196
  270. package/src/record/typed-frame-graph.ts +259 -15
  271. package/src/recovery/render-system-candidate.ts +28 -10
  272. package/src/render-contract.ts +34 -4
  273. package/src/render-graph-primitives.ts +8 -1
  274. package/src/render-pipeline.ts +22 -1
  275. package/src/render-system-extract-tail.ts +103 -13
  276. package/src/render-system-extract.ts +148 -38
  277. package/src/render-system.ts +332 -119
  278. package/src/scene/render-scene.ts +85 -4
  279. package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
  280. package/src/temporal/frame-coordinator.ts +8 -1
  281. package/src/temporal/frame.ts +20 -0
  282. package/src/temporal/view.ts +13 -2
  283. package/src/typed-render-graph-primitives.ts +124 -48
  284. package/src/volume/component.ts +0 -1
  285. package/src/volume/passes.ts +8 -4
  286. package/src/volume/resources.ts +1 -1
  287. package/src/volume/temporal.ts +11 -0
  288. package/dist/chunk-C3DDSXYK.mjs.map +0 -1
  289. package/dist/chunk-FUUO4UND.mjs.map +0 -1
  290. package/dist/chunk-JRBDO2KB.mjs.map +0 -1
  291. package/dist/chunk-MDQJPY3T.mjs.map +0 -1
  292. package/dist/chunk-PSEQ6QPH.mjs.map +0 -1
  293. package/dist/chunk-S5UE2T5P.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { RenderIntentInvalidError, DynamicResolutionRequiresTaaError, ShadowInvalidConfigError, VolumeOwnerConflictError, VolumeDensityShapeMismatchError, VolumeInvalidBoundsError, VolumeInvalidParametersError, DynamicResolutionInvalidParameterError } from './chunk-JRBDO2KB.mjs';
1
+ import { RenderIntentInvalidError, DynamicResolutionRequiresTaaError, ShadowInvalidConfigError, EnvironmentSourceConflictError, FogCardinalityError, VolumeOwnerConflictError, VolumeDensityShapeMismatchError, VolumeInvalidBoundsError, VolumeInvalidParametersError, DynamicResolutionInvalidParameterError, AtmosphereInvalidParameterError } from './chunk-NB2S7ZRX.mjs';
2
2
  import { defineComponent, Entity } from '@forgeax/engine-ecs';
3
3
  import { TONEMAP_SHADER_MODE } from '@forgeax/engine-shader';
4
4
  import { R_MIN, err, ok } from '@forgeax/engine-types';
@@ -11,7 +11,11 @@ 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 }
15
19
  });
16
20
  var CAMERA_PROJECTION_PERSPECTIVE = 0;
17
21
  var CAMERA_PROJECTION_ORTHOGRAPHIC = 1;
@@ -199,6 +203,14 @@ function antialiasFromF32(value) {
199
203
  }
200
204
  var BLOOM_DISABLED = 0;
201
205
  var BLOOM_ENABLED = 1;
206
+ var CAMERA_BLOOM_INTENSITY_MIN = 0;
207
+ var CAMERA_BLOOM_INTENSITY_MAX = 8;
208
+ var CAMERA_BLOOM_THRESHOLD_MIN = 0;
209
+ var CAMERA_BLOOM_THRESHOLD_MAX = 65504;
210
+ var CAMERA_BLOOM_SOFT_KNEE_MIN = 0;
211
+ var CAMERA_BLOOM_SOFT_KNEE_MAX = 1;
212
+ var CAMERA_BLOOM_SCATTER_MIN = 0;
213
+ var CAMERA_BLOOM_SCATTER_MAX = 0.95;
202
214
  function bloomEnabledFromF32(value) {
203
215
  if (value === BLOOM_DISABLED) return "off";
204
216
  if (value === BLOOM_ENABLED) return "on";
@@ -210,6 +222,40 @@ function bloomEnabledFromF32(value) {
210
222
  "select Camera bloom off or on"
211
223
  );
212
224
  }
225
+ function validateBloomRange(field, value, min, max) {
226
+ if (!Number.isFinite(value) || value < min || value > max) {
227
+ throw cameraError(
228
+ "camera-bloom-invalid",
229
+ field,
230
+ value,
231
+ `a finite value in [${min}, ${max}]`,
232
+ `set Camera.${field} to a finite value in [${min}, ${max}]`
233
+ );
234
+ }
235
+ }
236
+ function validateCameraBloom(bloom, threshold, intensity, softKnee, scatter) {
237
+ const enabled = bloomEnabledFromF32(bloom);
238
+ validateBloomRange(
239
+ "bloomThreshold",
240
+ threshold,
241
+ CAMERA_BLOOM_THRESHOLD_MIN,
242
+ CAMERA_BLOOM_THRESHOLD_MAX
243
+ );
244
+ validateBloomRange(
245
+ "bloomIntensity",
246
+ intensity,
247
+ CAMERA_BLOOM_INTENSITY_MIN,
248
+ CAMERA_BLOOM_INTENSITY_MAX
249
+ );
250
+ validateBloomRange(
251
+ "bloomSoftKnee",
252
+ softKnee,
253
+ CAMERA_BLOOM_SOFT_KNEE_MIN,
254
+ CAMERA_BLOOM_SOFT_KNEE_MAX
255
+ );
256
+ validateBloomRange("bloomScatter", scatter, CAMERA_BLOOM_SCATTER_MIN, CAMERA_BLOOM_SCATTER_MAX);
257
+ return enabled;
258
+ }
213
259
  var Camera = defineComponent("Camera", {
214
260
  fov: { type: "f32" },
215
261
  aspect: { type: "f32" },
@@ -236,7 +282,8 @@ var Camera = defineComponent("Camera", {
236
282
  bloom: { type: "f32", default: 0 },
237
283
  bloomThreshold: { type: "f32", default: 1 },
238
284
  bloomIntensity: { type: "f32", default: 1 },
239
- bloomBlurRadius: { type: "f32", default: 4 },
285
+ bloomSoftKnee: { type: "f32", default: 0.5 },
286
+ bloomScatter: { type: "f32", default: 0.7 },
240
287
  // M1 target camera role: zero means this camera is eligible for display;
241
288
  // non-zero shared targets are auxiliary producers whose views and receipt
242
289
  // promotion remain owned by Renderer.
@@ -390,6 +437,36 @@ var CubeCamera = defineComponent("CubeCamera", {
390
437
  requestVersion: { type: "u32", default: 0 },
391
438
  faceBudget: { type: "u32", default: 1 }
392
439
  });
440
+ var DepthOfFieldQualityValue = Object.freeze({
441
+ low: 0,
442
+ medium: 1,
443
+ high: 2
444
+ });
445
+ var DepthOfFieldSideValue = Object.freeze({
446
+ both: 0,
447
+ near: 1,
448
+ far: 2
449
+ });
450
+ var DepthOfField = defineComponent("DepthOfField", {
451
+ focusDistance: { type: "f32", default: 8 },
452
+ fStop: { type: "f32", default: 2.8 },
453
+ sensorHeight: { type: "f32", default: 0.024 },
454
+ maxRadiusPixels: { type: "f32", default: 16 },
455
+ quality: { type: "f32", default: DepthOfFieldQualityValue.medium },
456
+ blurSide: { type: "f32", default: DepthOfFieldSideValue.both }
457
+ });
458
+ function depthOfFieldQualityFromF32(value) {
459
+ if (value === DepthOfFieldQualityValue.low) return "low";
460
+ if (value === DepthOfFieldQualityValue.medium) return "medium";
461
+ if (value === DepthOfFieldQualityValue.high) return "high";
462
+ return void 0;
463
+ }
464
+ function depthOfFieldSideFromF32(value) {
465
+ if (value === DepthOfFieldSideValue.both) return "both";
466
+ if (value === DepthOfFieldSideValue.near) return "near";
467
+ if (value === DepthOfFieldSideValue.far) return "far";
468
+ return void 0;
469
+ }
393
470
 
394
471
  // src/components/directional-shadow-filter.ts
395
472
  var DirectionalShadowFilterValue = Object.freeze({
@@ -747,7 +824,8 @@ var MeshRenderer = defineComponent("MeshRenderer", {
747
824
  var MotionBlur = defineComponent("MotionBlur", {
748
825
  shutterAngle: { type: "f32", default: 180 },
749
826
  maxRadiusPixels: { type: "f32", default: 32 },
750
- sampleCount: { type: "f32", default: 8 }
827
+ sampleCount: { type: "f32", default: 8 },
828
+ targetFps: { type: "f32", default: 60 }
751
829
  });
752
830
  var PointLight = defineComponent("PointLight", {
753
831
  // color carries an explicit layer-2 default [1,1,1] (white); the array
@@ -943,6 +1021,528 @@ var Visibility = defineComponent(
943
1021
  }
944
1022
  }
945
1023
  );
1024
+
1025
+ // src/environment/signature.ts
1026
+ function sorted(items) {
1027
+ return [...items].sort((left, right) => left.entityKey - right.entityKey);
1028
+ }
1029
+ function environmentSignature(input) {
1030
+ return JSON.stringify({
1031
+ environments: sorted(input.environments),
1032
+ fogs: sorted(input.fogs),
1033
+ suns: sorted(input.suns)
1034
+ });
1035
+ }
1036
+ function environmentOnlySignature(input) {
1037
+ return JSON.stringify({
1038
+ environments: sorted(input.environments),
1039
+ suns: sorted(input.suns)
1040
+ });
1041
+ }
1042
+ function fogOnlySignature(input) {
1043
+ return JSON.stringify({ fogs: sorted(input.fogs) });
1044
+ }
1045
+ function environmentFactSignatures(input) {
1046
+ return {
1047
+ environmentSignature: environmentOnlySignature(input),
1048
+ fogSignature: fogOnlySignature(input),
1049
+ signature: environmentSignature(input)
1050
+ };
1051
+ }
1052
+
1053
+ // src/extract/environment.ts
1054
+ var ATMOSPHERE_PARAMETER_RANGES = Object.freeze({
1055
+ turbidity: Object.freeze({ min: 1, max: 20 }),
1056
+ rayleigh: Object.freeze({ min: 0, max: Number.POSITIVE_INFINITY }),
1057
+ mieCoefficient: Object.freeze({ min: 0, max: Number.POSITIVE_INFINITY }),
1058
+ mieDirectionalG: Object.freeze({ min: 0, max: 0.999 }),
1059
+ sunAngularRadius: Object.freeze({ min: 0, max: Number.POSITIVE_INFINITY }),
1060
+ circumsolarStrength: Object.freeze({ min: 0, max: 4 }),
1061
+ circumsolarWidth: Object.freeze({ min: 0.25, max: 4 })
1062
+ });
1063
+ function validateFogParameters(candidate) {
1064
+ if (candidate.color.length !== 3) {
1065
+ return {
1066
+ field: "color",
1067
+ value: candidate.color.length,
1068
+ expected: "exactly three finite channels in [0, 1]"
1069
+ };
1070
+ }
1071
+ for (let index = 0; index < candidate.color.length; index += 1) {
1072
+ const value = candidate.color[index];
1073
+ if (value === void 0 || !Number.isFinite(value) || value < 0 || value > 1) {
1074
+ return {
1075
+ field: `color[${index}]`,
1076
+ value: value ?? Number.NaN,
1077
+ expected: "a finite number in [0, 1]"
1078
+ };
1079
+ }
1080
+ }
1081
+ if (!Number.isFinite(candidate.density) || candidate.density < 0) {
1082
+ return { field: "density", value: candidate.density, expected: "a finite number >= 0" };
1083
+ }
1084
+ if (!Number.isFinite(candidate.heightFalloff) || candidate.heightFalloff < 0) {
1085
+ return {
1086
+ field: "heightFalloff",
1087
+ value: candidate.heightFalloff,
1088
+ expected: "a finite number >= 0"
1089
+ };
1090
+ }
1091
+ if (!Number.isFinite(candidate.maxOpacity) || candidate.maxOpacity < 0 || candidate.maxOpacity > 1) {
1092
+ return {
1093
+ field: "maxOpacity",
1094
+ value: candidate.maxOpacity,
1095
+ expected: "a finite number in [0, 1]"
1096
+ };
1097
+ }
1098
+ return void 0;
1099
+ }
1100
+ function validateAtmosphereParameters(parameters) {
1101
+ for (const field of Object.keys(ATMOSPHERE_PARAMETER_RANGES)) {
1102
+ const value = parameters[field];
1103
+ const range = ATMOSPHERE_PARAMETER_RANGES[field];
1104
+ if (!Number.isFinite(value) || value < range.min || value > range.max) {
1105
+ return new AtmosphereInvalidParameterError(field, value, range);
1106
+ }
1107
+ }
1108
+ return void 0;
1109
+ }
1110
+
1111
+ // src/environment/frame.ts
1112
+ var SKYLIGHT_RECOVERY_FALLBACK = Object.freeze({
1113
+ kind: "skylight",
1114
+ active: false
1115
+ });
1116
+ var EnvironmentSelectionParameterError = class extends Error {
1117
+ code = "environment-selection-invalid";
1118
+ expected;
1119
+ hint;
1120
+ detail;
1121
+ constructor(field, value, expected) {
1122
+ super(`environment selection field ${field} is invalid`);
1123
+ this.name = "EnvironmentSelectionParameterError";
1124
+ this.expected = expected;
1125
+ this.hint = `set ${field} to a finite value satisfying ${expected}`;
1126
+ this.detail = { field, value };
1127
+ }
1128
+ };
1129
+ var SunCardinalityError = class extends Error {
1130
+ code = "sun-cardinality";
1131
+ expected = "atmosphere has exactly one sun owner";
1132
+ hint = "add exactly one DirectionalLight sun for the atmosphere owner";
1133
+ detail;
1134
+ constructor(value) {
1135
+ super(`atmosphere sun cardinality is ${value}`);
1136
+ this.name = "SunCardinalityError";
1137
+ this.detail = { field: "sun", value };
1138
+ }
1139
+ };
1140
+ function freezeCandidate(candidate) {
1141
+ return Object.freeze(candidate);
1142
+ }
1143
+ function freezeFog(candidate) {
1144
+ return Object.freeze({
1145
+ ...candidate,
1146
+ color: Object.freeze([...candidate.color])
1147
+ });
1148
+ }
1149
+ function selectEnvironment(input) {
1150
+ if (input.environments.length > 1) {
1151
+ return err(
1152
+ new EnvironmentSourceConflictError(
1153
+ [...input.environments].sort((left, right) => left.entityKey - right.entityKey).map(({ kind, entityKey, sourceKey }) => ({ kind, entityKey, sourceKey }))
1154
+ )
1155
+ );
1156
+ }
1157
+ if (input.fogs.length > 1) return err(new FogCardinalityError(input.fogs.length));
1158
+ const selectedFog = input.fogs[0];
1159
+ if (selectedFog !== void 0) {
1160
+ const issue = validateFogParameters(selectedFog);
1161
+ if (issue !== void 0) {
1162
+ return err(new EnvironmentSelectionParameterError(issue.field, issue.value, issue.expected));
1163
+ }
1164
+ }
1165
+ const selected = input.environments[0];
1166
+ if (selected?.kind === "atmosphere") {
1167
+ const invalid3 = validateAtmosphereParameters(selected.atmosphere);
1168
+ if (invalid3 !== void 0) return err(invalid3);
1169
+ }
1170
+ if (selected?.kind === "atmosphere" && input.suns.length !== 1) {
1171
+ return err(new SunCardinalityError(input.suns.length));
1172
+ }
1173
+ const source = selected === void 0 ? { kind: "none" } : selected.kind === "atmosphere" ? {
1174
+ kind: "atmosphere",
1175
+ entityKey: selected.entityKey,
1176
+ sourceKey: selected.sourceKey,
1177
+ atmosphere: Object.freeze({ ...selected.atmosphere })
1178
+ } : {
1179
+ kind: "image",
1180
+ entityKey: selected.entityKey,
1181
+ sourceKey: selected.sourceKey
1182
+ };
1183
+ const sun = input.suns[0] === void 0 ? void 0 : freezeCandidate({ ...input.suns[0] });
1184
+ const fog = selectedFog === void 0 ? void 0 : freezeFog(selectedFog);
1185
+ const signatureInput = {
1186
+ environments: selected === void 0 ? [] : [selected],
1187
+ fogs: selectedFog === void 0 ? [] : [selectedFog],
1188
+ suns: input.suns
1189
+ };
1190
+ const signatures = environmentFactSignatures(signatureInput);
1191
+ const result = {
1192
+ source: Object.freeze(source),
1193
+ fog,
1194
+ ...signatures,
1195
+ revision: 0,
1196
+ sun
1197
+ };
1198
+ Object.defineProperty(result, "lane", { value: input.lane, enumerable: false });
1199
+ return ok(Object.freeze(result));
1200
+ }
1201
+ var DEPTH_OF_FIELD_PARAMS_BYTE_SIZE = 64;
1202
+ var MIN_F_STOP = Math.fround(0.7);
1203
+ var MAX_F_STOP = Math.fround(32);
1204
+ var MAX_LINEAR_DEPTH_RAW = Math.fround(1 - 2 ** -24);
1205
+ var DEFAULT_DEPTH_OF_FIELD_PARAMS = Object.freeze({
1206
+ focusDistance: 8,
1207
+ fStop: 2.8,
1208
+ sensorHeight: 0.024,
1209
+ maxRadiusPixels: 16,
1210
+ quality: "medium",
1211
+ blurSide: "both",
1212
+ focalLength: 0
1213
+ });
1214
+ function quantizeF32(value) {
1215
+ return Math.fround(value);
1216
+ }
1217
+ var DepthOfFieldValidationError = class extends Error {
1218
+ code;
1219
+ expected;
1220
+ hint;
1221
+ detail;
1222
+ constructor(code, detail, expected, hint) {
1223
+ super(`${code}: ${expected}`);
1224
+ this.name = "DepthOfFieldValidationError";
1225
+ this.code = code;
1226
+ this.expected = expected;
1227
+ this.hint = hint;
1228
+ this.detail = detail;
1229
+ }
1230
+ };
1231
+ function depthOfFieldRequestFailure(error) {
1232
+ return Object.freeze({
1233
+ code: error.code,
1234
+ detail: error.detail,
1235
+ expected: error.expected,
1236
+ hint: error.hint
1237
+ });
1238
+ }
1239
+ function resolveDepthOfFieldFrameParams(requested, requestFailure, accepted) {
1240
+ if (requested !== void 0) return requested;
1241
+ if (requestFailure === void 0 || requestFailure.code === "depth-of-field-orthographic-unsupported") {
1242
+ return void 0;
1243
+ }
1244
+ return accepted;
1245
+ }
1246
+ function invalid2(field, value, expected, bound) {
1247
+ return new DepthOfFieldValidationError(
1248
+ "depth-of-field-invalid-params",
1249
+ { field, value, expected, ...bound === void 0 ? {} : { bound } },
1250
+ expected,
1251
+ `set ${field} to ${expected}`
1252
+ );
1253
+ }
1254
+ function focalLength(sensorHeight, fov) {
1255
+ return sensorHeight / (2 * Math.tan(fov / 2));
1256
+ }
1257
+ function opticalCocScale(params) {
1258
+ return params.focalLength / params.sensorHeight / (2 * params.fStop) * (params.focalLength / (params.focusDistance - params.focalLength));
1259
+ }
1260
+ function frameCocCoefficient(params, outputHeight) {
1261
+ return quantizeF32(quantizeF32(outputHeight) * opticalCocScale(params));
1262
+ }
1263
+ function resolveDepthOfFieldFrameValues(params, input) {
1264
+ const focusDistance = quantizeF32(params.focusDistance);
1265
+ const fStop = quantizeF32(params.fStop);
1266
+ const sensorHeight = quantizeF32(params.sensorHeight);
1267
+ const focal = quantizeF32(params.focalLength);
1268
+ const maxRadiusPixels = quantizeF32(params.maxRadiusPixels);
1269
+ const outputHeight = quantizeF32(input.outputHeight);
1270
+ const near = quantizeF32(input.near);
1271
+ const far = quantizeF32(input.far);
1272
+ const finitePositiveFields = [
1273
+ ["focusDistance", focusDistance, params.focusDistance],
1274
+ ["sensorHeight", sensorHeight, params.sensorHeight],
1275
+ ["focalLength", focal, params.focalLength],
1276
+ ["near", near, input.near],
1277
+ ["far", far, input.far]
1278
+ ];
1279
+ for (const [field, value, raw] of finitePositiveFields) {
1280
+ if (!Number.isFinite(value) || value <= 0) {
1281
+ return err(invalid2(field, raw, "a finite positive f32 value"));
1282
+ }
1283
+ }
1284
+ if (!Number.isFinite(fStop) || fStop < MIN_F_STOP || fStop > MAX_F_STOP) {
1285
+ return err(
1286
+ invalid2("fStop", params.fStop, "a finite f32 value in [0.7, 32]", [MIN_F_STOP, MAX_F_STOP])
1287
+ );
1288
+ }
1289
+ if (!Number.isFinite(maxRadiusPixels) || maxRadiusPixels < 0 || maxRadiusPixels > 32) {
1290
+ return err(
1291
+ invalid2("maxRadiusPixels", params.maxRadiusPixels, "a finite f32 value in [0, 32]", [0, 32])
1292
+ );
1293
+ }
1294
+ if (!Number.isFinite(outputHeight) || outputHeight <= 0) {
1295
+ return err(invalid2("outputHeight", input.outputHeight, "a finite positive f32 value"));
1296
+ }
1297
+ if (far <= near) {
1298
+ return err(invalid2("near/far", [input.near, input.far], "finite f32 near > 0 and far > near"));
1299
+ }
1300
+ if (focusDistance <= focal) {
1301
+ return err(invalid2("focusDistance", params.focusDistance, "greater than focalLength in f32"));
1302
+ }
1303
+ const depthRatio = quantizeF32(near / far);
1304
+ if (!Number.isFinite(depthRatio) || depthRatio <= 0) {
1305
+ return err(invalid2("near/far ratio", depthRatio, "a finite positive f32 value"));
1306
+ }
1307
+ for (const raw of [quantizeF32(2 ** -149), 0.5, MAX_LINEAR_DEPTH_RAW]) {
1308
+ const oneMinusRaw = quantizeF32(1 - raw);
1309
+ const weightedRatio = quantizeF32(raw * depthRatio);
1310
+ const denominator = quantizeF32(oneMinusRaw + weightedRatio);
1311
+ const distance = quantizeF32(near / denominator);
1312
+ 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"));
1314
+ }
1315
+ }
1316
+ const cocCoefficient = frameCocCoefficient(
1317
+ {
1318
+ focusDistance,
1319
+ fStop,
1320
+ sensorHeight,
1321
+ focalLength: focal
1322
+ },
1323
+ outputHeight
1324
+ );
1325
+ if (!Number.isFinite(cocCoefficient) || cocCoefficient <= 0) {
1326
+ return err(
1327
+ invalid2("cocCoefficient", cocCoefficient, "a finite positive value representable as f32")
1328
+ );
1329
+ }
1330
+ for (const [field, depth] of [
1331
+ ["near", near],
1332
+ ["far", far]
1333
+ ]) {
1334
+ const focusOverDepth = quantizeF32(focusDistance / depth);
1335
+ const depthFactor = quantizeF32(1 - focusOverDepth);
1336
+ const radius = quantizeF32(cocCoefficient * depthFactor);
1337
+ if (!Number.isFinite(focusOverDepth) || !Number.isFinite(depthFactor) || !Number.isFinite(radius)) {
1338
+ return err(invalid2(`coc.${field}`, radius, "a finite value representable as f32"));
1339
+ }
1340
+ }
1341
+ return ok({
1342
+ focusDistance,
1343
+ fStop,
1344
+ sensorHeight,
1345
+ focalLength: focal,
1346
+ maxRadiusPixels,
1347
+ outputHeight,
1348
+ near,
1349
+ far,
1350
+ cocCoefficient
1351
+ });
1352
+ }
1353
+ function validateDepthOfFieldFrameParams(params, input) {
1354
+ const resolved = resolveDepthOfFieldFrameValues(params, input);
1355
+ return resolved.ok ? ok(void 0) : resolved;
1356
+ }
1357
+ function validateDepthOfFieldParams(input, camera) {
1358
+ if (camera?.projection === "orthographic") {
1359
+ return err(
1360
+ new DepthOfFieldValidationError(
1361
+ "depth-of-field-orthographic-unsupported",
1362
+ { projection: "orthographic" },
1363
+ "DepthOfField requires a perspective Camera",
1364
+ "use a perspective Camera or remove the DepthOfField component"
1365
+ )
1366
+ );
1367
+ }
1368
+ const value = input ?? {};
1369
+ const focusDistance = quantizeF32(
1370
+ value.focusDistance ?? DEFAULT_DEPTH_OF_FIELD_PARAMS.focusDistance
1371
+ );
1372
+ const fStop = quantizeF32(value.fStop ?? DEFAULT_DEPTH_OF_FIELD_PARAMS.fStop);
1373
+ const sensorHeight = quantizeF32(
1374
+ value.sensorHeight ?? DEFAULT_DEPTH_OF_FIELD_PARAMS.sensorHeight
1375
+ );
1376
+ const maxRadiusPixels = quantizeF32(
1377
+ value.maxRadiusPixels ?? DEFAULT_DEPTH_OF_FIELD_PARAMS.maxRadiusPixels
1378
+ );
1379
+ const qualityValue = quantizeF32(value.quality ?? DepthOfFieldQualityValue.medium);
1380
+ const blurSideValue = quantizeF32(value.blurSide ?? DepthOfFieldSideValue.both);
1381
+ const quality = depthOfFieldQualityFromF32(qualityValue);
1382
+ const blurSide = depthOfFieldSideFromF32(blurSideValue);
1383
+ if (!Number.isFinite(focusDistance) || focusDistance <= 0) {
1384
+ return err(
1385
+ invalid2("focusDistance", value.focusDistance ?? focusDistance, "a finite positive f32 value")
1386
+ );
1387
+ }
1388
+ if (!Number.isFinite(fStop) || fStop < MIN_F_STOP || fStop > MAX_F_STOP) {
1389
+ return err(
1390
+ invalid2("fStop", value.fStop ?? fStop, "a finite f32 value in [0.7, 32]", [
1391
+ MIN_F_STOP,
1392
+ MAX_F_STOP
1393
+ ])
1394
+ );
1395
+ }
1396
+ if (!Number.isFinite(sensorHeight) || sensorHeight <= 0) {
1397
+ return err(
1398
+ invalid2("sensorHeight", value.sensorHeight ?? sensorHeight, "a finite positive f32 value")
1399
+ );
1400
+ }
1401
+ if (!Number.isFinite(maxRadiusPixels) || maxRadiusPixels < 0 || maxRadiusPixels > 32) {
1402
+ return err(
1403
+ invalid2(
1404
+ "maxRadiusPixels",
1405
+ value.maxRadiusPixels ?? maxRadiusPixels,
1406
+ "a finite f32 value in [0, 32]",
1407
+ [0, 32]
1408
+ )
1409
+ );
1410
+ }
1411
+ if (quality === void 0) {
1412
+ return err(invalid2("quality", qualityValue, "DepthOfFieldQualityValue.low, medium, or high"));
1413
+ }
1414
+ if (blurSide === void 0) {
1415
+ return err(invalid2("blurSide", blurSideValue, "DepthOfFieldSideValue.both, near, or far"));
1416
+ }
1417
+ let focal = DEFAULT_DEPTH_OF_FIELD_PARAMS.focalLength;
1418
+ if (camera !== void 0) {
1419
+ const fov = quantizeF32(camera.fov);
1420
+ const near = quantizeF32(camera.near);
1421
+ const far = quantizeF32(camera.far);
1422
+ if (!Number.isFinite(fov) || fov <= 0 || fov >= Math.PI) {
1423
+ return err(invalid2("fov", camera.fov, "a finite f32 value in (0, PI)"));
1424
+ }
1425
+ if (!Number.isFinite(near) || !Number.isFinite(far) || near <= 0 || far <= near) {
1426
+ return err(
1427
+ invalid2("near/far", [camera.near, camera.far], "finite f32 near > 0 and far > near")
1428
+ );
1429
+ }
1430
+ focal = quantizeF32(focalLength(sensorHeight, fov));
1431
+ if (!Number.isFinite(focal) || focal <= 0) {
1432
+ return err(invalid2("focalLength", focal, "a finite positive f32 value"));
1433
+ }
1434
+ if (focusDistance < near || focusDistance > far) {
1435
+ return err(
1436
+ invalid2("focusDistance", focusDistance, `a value in [${near}, ${far}]`, [near, far])
1437
+ );
1438
+ }
1439
+ if (focusDistance <= focal) {
1440
+ return err(
1441
+ invalid2("focusDistance", focusDistance, `greater than focalLength in f32 (${focal})`)
1442
+ );
1443
+ }
1444
+ }
1445
+ return ok(
1446
+ Object.freeze({
1447
+ focusDistance,
1448
+ fStop,
1449
+ sensorHeight,
1450
+ maxRadiusPixels,
1451
+ quality,
1452
+ blurSide,
1453
+ focalLength: focal
1454
+ })
1455
+ );
1456
+ }
1457
+ function resolveDepthOfFieldParams(input, camera) {
1458
+ if (input === void 0) return ok(void 0);
1459
+ return validateDepthOfFieldParams(input, camera);
1460
+ }
1461
+ function depthOfFieldTapCount(quality) {
1462
+ switch (quality) {
1463
+ case "low":
1464
+ return 16;
1465
+ case "medium":
1466
+ return 32;
1467
+ case "high":
1468
+ return 64;
1469
+ }
1470
+ }
1471
+ function depthOfFieldSideCode(side) {
1472
+ switch (side) {
1473
+ case "both":
1474
+ return DepthOfFieldSideValue.both;
1475
+ case "near":
1476
+ return DepthOfFieldSideValue.near;
1477
+ case "far":
1478
+ return DepthOfFieldSideValue.far;
1479
+ }
1480
+ }
1481
+ function depthOfFieldQualityCode(quality) {
1482
+ switch (quality) {
1483
+ case "low":
1484
+ return DepthOfFieldQualityValue.low;
1485
+ case "medium":
1486
+ return DepthOfFieldQualityValue.medium;
1487
+ case "high":
1488
+ return DepthOfFieldQualityValue.high;
1489
+ }
1490
+ }
1491
+ function signedDepthOfFieldCoC(params, viewDepth, outputHeight) {
1492
+ if (!Number.isFinite(viewDepth) || viewDepth <= 0 || !Number.isFinite(outputHeight) || outputHeight <= 0 || !Number.isFinite(params.focalLength) || params.focalLength <= 0 || !Number.isFinite(params.sensorHeight) || params.sensorHeight <= 0 || !Number.isFinite(params.fStop) || params.fStop <= 0 || !Number.isFinite(params.focusDistance) || params.focusDistance <= params.focalLength) {
1493
+ return 0;
1494
+ }
1495
+ const focusDistance = quantizeF32(params.focusDistance);
1496
+ const depth = quantizeF32(viewDepth);
1497
+ const focalLength2 = quantizeF32(params.focalLength);
1498
+ const sensorHeight = quantizeF32(params.sensorHeight);
1499
+ const fStop = quantizeF32(params.fStop);
1500
+ const coefficient = frameCocCoefficient(
1501
+ { focusDistance, focalLength: focalLength2, sensorHeight, fStop },
1502
+ outputHeight
1503
+ );
1504
+ const depthFactor = quantizeF32(1 - quantizeF32(focusDistance / depth));
1505
+ const radius = quantizeF32(coefficient * depthFactor);
1506
+ const limit = Number.isFinite(params.maxRadiusPixels) ? quantizeF32(params.maxRadiusPixels) : Number.POSITIVE_INFINITY;
1507
+ return Math.max(-limit, Math.min(limit, Number.isFinite(radius) ? radius : 0));
1508
+ }
1509
+ function packDepthOfFieldParams(params, input) {
1510
+ const frameValues = resolveDepthOfFieldFrameValues(params, input);
1511
+ if (!frameValues.ok) throw frameValues.error;
1512
+ const {
1513
+ focusDistance,
1514
+ fStop,
1515
+ sensorHeight,
1516
+ focalLength: focal,
1517
+ outputHeight,
1518
+ maxRadiusPixels,
1519
+ near,
1520
+ far,
1521
+ cocCoefficient
1522
+ } = frameValues.value;
1523
+ const payload = new Float32Array(DEPTH_OF_FIELD_PARAMS_BYTE_SIZE / 4);
1524
+ payload.set([
1525
+ focusDistance,
1526
+ fStop,
1527
+ sensorHeight,
1528
+ focal,
1529
+ outputHeight,
1530
+ maxRadiusPixels,
1531
+ depthOfFieldSideCode(params.blurSide),
1532
+ depthOfFieldQualityCode(params.quality),
1533
+ near,
1534
+ far,
1535
+ input.useTemporalDepth ? 1 : 0,
1536
+ 0,
1537
+ // row2.w reserved
1538
+ cocCoefficient,
1539
+ // row3.x / WGSL reserved.x
1540
+ 0,
1541
+ 0,
1542
+ 0
1543
+ ]);
1544
+ return new Uint8Array(payload.buffer);
1545
+ }
946
1546
  function hasVolumetricFogCapability(caps, shaders) {
947
1547
  return caps.compute && caps.storageTexture && shaders !== void 0;
948
1548
  }
@@ -1095,6 +1695,7 @@ function projectMeshMaterialBindingObservation(input) {
1095
1695
  });
1096
1696
  return {
1097
1697
  worldId: input.worldId,
1698
+ ...input.worldIdentity === void 0 ? {} : { worldIdentity: input.worldIdentity },
1098
1699
  entityKey: input.entityKey,
1099
1700
  bindings: Object.freeze([...input.bindings]),
1100
1701
  diagnostics: Object.freeze([...input.diagnostics]),
@@ -1301,6 +1902,6 @@ function extractVolumetricFog(inputs) {
1301
1902
  return ok({ status: "available", fog: validated.value });
1302
1903
  }
1303
1904
 
1304
- 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, 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, directionalShadowQualityFromF32, extractVolumetricFog, hasVolumetricFogCapability, orthographic, perspective, pointShapeFromU32, projectMeshMaterialBindingObservation, reflectionProbeUpdateIntentFromF32, reflectionProbeUpdateIntentToF32, resolveIntegratedVolumeConsumer, resolveMeshMaterialBindings, resolveSelectedVolumetricLight, resolveVisibility, resolveVolumetricFogLightPair, summarizeMeshMaterialBindings, tonemapFromF32, tonemapToU32, validateCameraColorGrading, validateCameraExposure, validateDirection, validateDirectionalLightData, validateDynamicResolutionCamera, validateDynamicResolutionParameters, validateLightProbeData, validatePointLightData, validatePointLightShadowData, validateRectAreaLightData, validateSpotLightData, validateVolumetricFog, visibilityStateFromU32 };
1305
- //# sourceMappingURL=chunk-S5UE2T5P.mjs.map
1306
- //# sourceMappingURL=chunk-S5UE2T5P.mjs.map
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