@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,11 +1,12 @@
1
1
  import { GlyphText } from './chunk-ILQ5MEZF.mjs';
2
- import { MeshRenderer, MeshFilter, DirectionalLight, validateDirectionalLightData, PointLight, computeInvRangeSquared, SpotLight, degToCos, RectAreaLight, validateRectAreaLightData, directionalShadowQualityFromF32, PointLightShadow, Skylight, LightProbe, validateLightProbeData, SkyboxBackground, Atmosphere, Instances, Layer, Points, Lines, SortKey, resolveMeshMaterialBindings, pointShapeFromU32, PostProcessParams, buildCubeCameraFaceViews, CubeCamera, cubeCameraUpdateIntentFromF32, ReflectionProbe, reflectionProbeUpdateIntentFromF32, tonemapToU32, resolveVisibility, Fog, VolumetricFog, resolveSelectedVolumetricLight, extractVolumetricFog, MotionBlur, DynamicResolution, ScreenSpaceReflection, Camera, CAMERA_EXPOSURE_MODE_MANUAL, cameraExposureFromColumns, antialiasFromF32, validateDynamicResolutionCamera, bloomEnabledFromF32, tonemapFromF32, cameraProjectionFromF32 } from './chunk-S5UE2T5P.mjs';
2
+ import { MeshRenderer, MeshFilter, DirectionalLight, validateDirectionalLightData, PointLight, computeInvRangeSquared, SpotLight, degToCos, RectAreaLight, validateRectAreaLightData, directionalShadowQualityFromF32, PointLightShadow, Skylight, LightProbe, validateLightProbeData, SkyboxBackground, Atmosphere, selectEnvironment, Instances, Layer, Points, Lines, SortKey, resolveMeshMaterialBindings, pointShapeFromU32, PostProcessParams, buildCubeCameraFaceViews, CubeCamera, cubeCameraUpdateIntentFromF32, ReflectionProbe, reflectionProbeUpdateIntentFromF32, tonemapToU32, resolveVisibility, Fog, VolumetricFog, resolveSelectedVolumetricLight, extractVolumetricFog, MotionBlur, DynamicResolution, ScreenSpaceReflection, DepthOfField, Camera, cameraProjectionFromF32, resolveDepthOfFieldParams, depthOfFieldRequestFailure, CAMERA_EXPOSURE_MODE_MANUAL, cameraExposureFromColumns, antialiasFromF32, validateDynamicResolutionCamera, validateCameraBloom, tonemapFromF32 } from './chunk-PLAXOOX5.mjs';
3
3
  import { SpriteRegionOverride, SpriteInstances, selectActiveCameraIndex, getActiveCamera } from './chunk-PA5DRJNI.mjs';
4
- import { PROBE_BLEND_RECORD_CAPACITY, GPU_BUFFER_USAGE_MAP_READ, GPU_BUFFER_USAGE_VERTEX, GPU_BUFFER_USAGE_COPY_DST, gpuDrivenShadowDrawKey, IES_SLICE_CAPACITY, COOKIE_SLICE_CAPACITY, isStandardPbrSkinMaterialShader, buildGpuDrivenDraws, worldEntityKey, gpuDrivenSourceDrawItemIndex, selectPasses, resolveRenderTargetMaterialSource, isCanonicalStandardPbrMaterialShader, PROBE_BLEND_RECORD_BYTE_SIZE, GPU_BUFFER_USAGE_UNIFORM, GPU_BUFFER_USAGE_QUERY_RESOLVE, GPU_BUFFER_USAGE_COPY_SRC, COOKIE_SLICE_SIZE, isStandardPbrMaterialShader } from './chunk-FUUO4UND.mjs';
5
- import { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID, SHADOW_ATLAS_DEFAULT_LAYERS, SkinMaterialMismatchError, MaterialSkinAttrMissingError, InstanceCollectionError, ShadowInvalidConfigError, EnvironmentSourceConflictError, FogCardinalityError, GPU_TEXTURE_USAGE_COPY_SRC, GPU_TEXTURE_USAGE_COPY_DST, GPU_TEXTURE_USAGE_TEXTURE_BINDING, GPU_TEXTURE_USAGE_STORAGE_BINDING, GPU_TEXTURE_USAGE_RENDER_ATTACHMENT, AtmosphereInvalidParameterError } from './chunk-JRBDO2KB.mjs';
4
+ import { PROBE_BLEND_RECORD_CAPACITY, GPU_BUFFER_USAGE_MAP_READ, GPU_BUFFER_USAGE_VERTEX, GPU_BUFFER_USAGE_COPY_DST, gpuDrivenShadowDrawKey, IES_SLICE_CAPACITY, COOKIE_SLICE_CAPACITY, isStandardPbrSkinMaterialShader, buildGpuDrivenDraws, worldEntityKey, gpuDrivenSourceDrawItemIndex, selectPasses, resolveRenderTargetMaterialSource, isCanonicalStandardPbrMaterialShader, PROBE_BLEND_RECORD_BYTE_SIZE, GPU_BUFFER_USAGE_UNIFORM, GPU_BUFFER_USAGE_QUERY_RESOLVE, GPU_BUFFER_USAGE_COPY_SRC, COOKIE_SLICE_SIZE, isStandardPbrMaterialShader } from './chunk-3RTCJTH4.mjs';
5
+ import { MotionBlurValidationError, STANDARD_OUTPUT_TRANSFORM_FEATURE_ID, SHADOW_ATLAS_DEFAULT_LAYERS, MaterialSkinAttrMissingError, SkinMaterialMismatchError, InstanceCollectionError, ShadowInvalidConfigError, resolveMotionBlurParams, GPU_TEXTURE_USAGE_COPY_SRC, GPU_TEXTURE_USAGE_COPY_DST, GPU_TEXTURE_USAGE_TEXTURE_BINDING, GPU_TEXTURE_USAGE_STORAGE_BINDING, GPU_TEXTURE_USAGE_RENDER_ATTACHMENT } from './chunk-NB2S7ZRX.mjs';
6
6
  import { R_MIN, ok, err, TextError, toShared, handleSlot, AssetError, ASSET_ERROR_HINTS, materialValuesToLinearRuntime, derive, unpackSlot, materialGuidText } from '@forgeax/engine-types';
7
7
  import { err as err$1, ok as ok$1, RhiError } from '@forgeax/engine-rhi';
8
8
  import { resolveAssetHandle, walkMaterialPassesOverSharedRefs, selectMaterialPassProgram, materialParametersToParamSchema as materialParametersToParamSchema$1 } from '@forgeax/engine-assets-runtime';
9
+ import { Time } from '@forgeax/engine-ecs';
9
10
  import { SpawnLightInvalidBoundsError, routeWorldError, SpriteInstancesMutuallyExclusiveWithInstancesError, SpriteInstancesRequiresSpriteShaderError, SpriteInstancesCountMismatchError, readRenderArrayView } from '@forgeax/engine-ecs/projection';
10
11
  import { vec3, mat4, frustum, box3 } from '@forgeax/engine-math';
11
12
  import { AssetGuid } from '@forgeax/engine-pack/guid';
@@ -183,6 +184,24 @@ function projectLightInspection(input) {
183
184
  function lightInspectionIdentity(topology, generation) {
184
185
  return `${topology}:generation-${generation}`;
185
186
  }
187
+ var emptyBloomInspection = () => ({
188
+ graphStatus: "empty",
189
+ enabled: false,
190
+ levelCount: 0,
191
+ levelDimensions: [],
192
+ downsamplePassCount: 0,
193
+ upsamplePassCount: 0,
194
+ targetCount: 0,
195
+ targetBytes: 0,
196
+ resourceCount: 0,
197
+ passCount: 0,
198
+ encodeCount: 0,
199
+ bindGroupCount: 0,
200
+ uploadCount: 0,
201
+ residentChildBytes: 0,
202
+ generation: 0,
203
+ state: "off"
204
+ });
186
205
 
187
206
  // src/prepare/extended-lighting/state.ts
188
207
  function createExtendedLightingState(generation) {
@@ -938,8 +957,8 @@ var OcclusionRenderRuntime = class {
938
957
  if (this.queryLatencySamplesUs.length === 0) {
939
958
  return { median: 0, p95: 0, last: this.lastQueryLatencyUs };
940
959
  }
941
- const sorted2 = [...this.queryLatencySamplesUs].sort((left, right) => left - right);
942
- const rank = (percentile) => sorted2[Math.max(0, Math.ceil(sorted2.length * percentile) - 1)] ?? 0;
960
+ const sorted = [...this.queryLatencySamplesUs].sort((left, right) => left - right);
961
+ const rank = (percentile) => sorted[Math.max(0, Math.ceil(sorted.length * percentile) - 1)] ?? 0;
943
962
  return {
944
963
  median: rank(0.5),
945
964
  p95: rank(0.95),
@@ -1224,181 +1243,6 @@ function runtimeError(hint) {
1224
1243
  });
1225
1244
  }
1226
1245
 
1227
- // src/environment/signature.ts
1228
- function sorted(items) {
1229
- return [...items].sort((left, right) => left.entityKey - right.entityKey);
1230
- }
1231
- function environmentSignature(input) {
1232
- return JSON.stringify({
1233
- environments: sorted(input.environments),
1234
- fogs: sorted(input.fogs),
1235
- suns: sorted(input.suns)
1236
- });
1237
- }
1238
- function environmentOnlySignature(input) {
1239
- return JSON.stringify({
1240
- environments: sorted(input.environments),
1241
- suns: sorted(input.suns)
1242
- });
1243
- }
1244
- function fogOnlySignature(input) {
1245
- return JSON.stringify({ fogs: sorted(input.fogs) });
1246
- }
1247
- function environmentFactSignatures(input) {
1248
- return {
1249
- environmentSignature: environmentOnlySignature(input),
1250
- fogSignature: fogOnlySignature(input),
1251
- signature: environmentSignature(input)
1252
- };
1253
- }
1254
-
1255
- // src/extract/environment.ts
1256
- var ATMOSPHERE_PARAMETER_RANGES = Object.freeze({
1257
- turbidity: Object.freeze({ min: 1, max: 20 }),
1258
- rayleigh: Object.freeze({ min: 0, max: Number.POSITIVE_INFINITY }),
1259
- mieCoefficient: Object.freeze({ min: 0, max: Number.POSITIVE_INFINITY }),
1260
- mieDirectionalG: Object.freeze({ min: 0, max: 0.999 }),
1261
- sunAngularRadius: Object.freeze({ min: 0, max: Number.POSITIVE_INFINITY })
1262
- });
1263
- function validateFogParameters(candidate) {
1264
- if (candidate.color.length !== 3) {
1265
- return {
1266
- field: "color",
1267
- value: candidate.color.length,
1268
- expected: "exactly three finite channels in [0, 1]"
1269
- };
1270
- }
1271
- for (let index = 0; index < candidate.color.length; index += 1) {
1272
- const value = candidate.color[index];
1273
- if (value === void 0 || !Number.isFinite(value) || value < 0 || value > 1) {
1274
- return {
1275
- field: `color[${index}]`,
1276
- value: value ?? Number.NaN,
1277
- expected: "a finite number in [0, 1]"
1278
- };
1279
- }
1280
- }
1281
- if (!Number.isFinite(candidate.density) || candidate.density < 0) {
1282
- return { field: "density", value: candidate.density, expected: "a finite number >= 0" };
1283
- }
1284
- if (!Number.isFinite(candidate.heightFalloff) || candidate.heightFalloff < 0) {
1285
- return {
1286
- field: "heightFalloff",
1287
- value: candidate.heightFalloff,
1288
- expected: "a finite number >= 0"
1289
- };
1290
- }
1291
- if (!Number.isFinite(candidate.maxOpacity) || candidate.maxOpacity < 0 || candidate.maxOpacity > 1) {
1292
- return {
1293
- field: "maxOpacity",
1294
- value: candidate.maxOpacity,
1295
- expected: "a finite number in [0, 1]"
1296
- };
1297
- }
1298
- return void 0;
1299
- }
1300
- function validateAtmosphereParameters(parameters) {
1301
- for (const field of Object.keys(ATMOSPHERE_PARAMETER_RANGES)) {
1302
- const value = parameters[field];
1303
- const range = ATMOSPHERE_PARAMETER_RANGES[field];
1304
- if (!Number.isFinite(value) || value < range.min || value > range.max) {
1305
- return new AtmosphereInvalidParameterError(field, value, range);
1306
- }
1307
- }
1308
- return void 0;
1309
- }
1310
-
1311
- // src/environment/frame.ts
1312
- var SKYLIGHT_RECOVERY_FALLBACK = Object.freeze({
1313
- kind: "skylight",
1314
- active: false
1315
- });
1316
- var EnvironmentSelectionParameterError = class extends Error {
1317
- code = "environment-selection-invalid";
1318
- expected;
1319
- hint;
1320
- detail;
1321
- constructor(field, value, expected) {
1322
- super(`environment selection field ${field} is invalid`);
1323
- this.name = "EnvironmentSelectionParameterError";
1324
- this.expected = expected;
1325
- this.hint = `set ${field} to a finite value satisfying ${expected}`;
1326
- this.detail = { field, value };
1327
- }
1328
- };
1329
- var SunCardinalityError = class extends Error {
1330
- code = "sun-cardinality";
1331
- expected = "atmosphere has exactly one sun owner";
1332
- hint = "add exactly one DirectionalLight sun for the atmosphere owner";
1333
- detail;
1334
- constructor(value) {
1335
- super(`atmosphere sun cardinality is ${value}`);
1336
- this.name = "SunCardinalityError";
1337
- this.detail = { field: "sun", value };
1338
- }
1339
- };
1340
- function freezeCandidate(candidate) {
1341
- return Object.freeze(candidate);
1342
- }
1343
- function freezeFog(candidate) {
1344
- return Object.freeze({
1345
- ...candidate,
1346
- color: Object.freeze([...candidate.color])
1347
- });
1348
- }
1349
- function selectEnvironment(input) {
1350
- if (input.environments.length > 1) {
1351
- return err(
1352
- new EnvironmentSourceConflictError(
1353
- [...input.environments].sort((left, right) => left.entityKey - right.entityKey).map(({ kind, entityKey, sourceKey }) => ({ kind, entityKey, sourceKey }))
1354
- )
1355
- );
1356
- }
1357
- if (input.fogs.length > 1) return err(new FogCardinalityError(input.fogs.length));
1358
- const selectedFog = input.fogs[0];
1359
- if (selectedFog !== void 0) {
1360
- const issue = validateFogParameters(selectedFog);
1361
- if (issue !== void 0) {
1362
- return err(new EnvironmentSelectionParameterError(issue.field, issue.value, issue.expected));
1363
- }
1364
- }
1365
- const selected = input.environments[0];
1366
- if (selected?.kind === "atmosphere") {
1367
- const invalid = validateAtmosphereParameters(selected.atmosphere);
1368
- if (invalid !== void 0) return err(invalid);
1369
- }
1370
- if (selected?.kind === "atmosphere" && input.suns.length !== 1) {
1371
- return err(new SunCardinalityError(input.suns.length));
1372
- }
1373
- const source = selected === void 0 ? { kind: "none" } : selected.kind === "atmosphere" ? {
1374
- kind: "atmosphere",
1375
- entityKey: selected.entityKey,
1376
- sourceKey: selected.sourceKey,
1377
- atmosphere: Object.freeze({ ...selected.atmosphere })
1378
- } : {
1379
- kind: "image",
1380
- entityKey: selected.entityKey,
1381
- sourceKey: selected.sourceKey
1382
- };
1383
- const sun = input.suns[0] === void 0 ? void 0 : freezeCandidate({ ...input.suns[0] });
1384
- const fog = selectedFog === void 0 ? void 0 : freezeFog(selectedFog);
1385
- const signatureInput = {
1386
- environments: selected === void 0 ? [] : [selected],
1387
- fogs: selectedFog === void 0 ? [] : [selectedFog],
1388
- suns: input.suns
1389
- };
1390
- const signatures = environmentFactSignatures(signatureInput);
1391
- const result = {
1392
- source: Object.freeze(source),
1393
- fog,
1394
- ...signatures,
1395
- revision: 0,
1396
- sun
1397
- };
1398
- Object.defineProperty(result, "lane", { value: input.lane, enumerable: false });
1399
- return ok(Object.freeze(result));
1400
- }
1401
-
1402
1246
  // src/extract/directional-shadow-projection.ts
1403
1247
  function projectDirectionalShadow(fits, mapSize, shadowFilter, shadowAngularRadius, maxPenumbraTexels) {
1404
1248
  if (!Number.isFinite(mapSize) || mapSize < 1) return void 0;
@@ -1984,6 +1828,14 @@ function buildShadowFrusta(lights) {
1984
1828
  function skinPaletteIdentity(world, entity) {
1985
1829
  return `skin:${world.identity}:${entity}`;
1986
1830
  }
1831
+ function materialProgramSelectionRequiresSkin(selection) {
1832
+ if (selection.abi?.skinPaletteAddress !== void 0) return true;
1833
+ const semantics = new Set((selection.abi?.vertexInputs ?? []).map((input) => input.semantic));
1834
+ return semantics.has("skinIndex") && semantics.has("skinWeight");
1835
+ }
1836
+ function isMissingMaterialProgram(error) {
1837
+ return error !== null && typeof error === "object" && error.code === "material-specialization-not-cooked";
1838
+ }
1987
1839
  function extractFrames(worlds, owner, assets, pipelineState, materialSnapshotCachesByWorld, options = {}) {
1988
1840
  const cameraOwner = typeof owner === "number" ? owner : owner.cameraOwner;
1989
1841
  const resourceOwner = typeof owner === "number" ? owner : owner.resourceOwner;
@@ -2046,9 +1898,10 @@ function extractFrames(worlds, owner, assets, pipelineState, materialSnapshotCac
2046
1898
  });
2047
1899
  const frame = extractFrame(world, prepared);
2048
1900
  framesByWorld.set(wi, frame);
2049
- } catch (err8) {
1901
+ } catch (err6) {
1902
+ if (err6 instanceof MotionBlurValidationError) throw err6;
2050
1903
  try {
2051
- createWorldInternalView(world)._routeError(err8, {
1904
+ createWorldInternalView(world)._routeError(err6, {
2052
1905
  severity: Severity.Error,
2053
1906
  systemName: `RenderSystem.extractFrames(world[${wi}])`
2054
1907
  });
@@ -2919,7 +2772,9 @@ function extractFrame(world, context) {
2919
2772
  rayleigh: value.rayleigh,
2920
2773
  mieCoefficient: value.mieCoefficient,
2921
2774
  mieDirectionalG: value.mieDirectionalG,
2922
- sunAngularRadius: value.sunAngularRadius
2775
+ sunAngularRadius: value.sunAngularRadius,
2776
+ circumsolarStrength: value.circumsolarStrength,
2777
+ circumsolarWidth: value.circumsolarWidth
2923
2778
  };
2924
2779
  environmentCandidates.push({
2925
2780
  kind: "atmosphere",
@@ -3077,6 +2932,9 @@ function extractFrame(world, context) {
3077
2932
  if (!authorVisible && !retainHidden) {
3078
2933
  continue;
3079
2934
  }
2935
+ if (isRenderable && fAssetHandle === 0) {
2936
+ continue;
2937
+ }
3080
2938
  const layerVal = fLayerValue ?? 0;
3081
2939
  const pendingDispatch = [];
3082
2940
  const materialsView = worldInternal._getArrayView(entity, MeshRenderer, "materials");
@@ -3198,6 +3056,7 @@ function extractFrame(world, context) {
3198
3056
  const handleRaw = materialHandles[0] ?? 0;
3199
3057
  const cachedMaterial = handleRaw !== 0 && !hasSpriteRegionOverride && !hasSkin ? materialSnapshotCache.get(handleRaw) : void 0;
3200
3058
  let materialSnap;
3059
+ let materialProgramSelections;
3201
3060
  if (cachedMaterial !== void 0) {
3202
3061
  materialSnap = cachedMaterial.snapshot;
3203
3062
  if (isRenderable) {
@@ -3261,28 +3120,28 @@ function extractFrame(world, context) {
3261
3120
  } else {
3262
3121
  const resolvedResult = walkMaterialPassesOverSharedRefs(world, tagged, assets);
3263
3122
  if (!resolvedResult.ok) {
3264
- const err8 = resolvedResult.error;
3265
- switch (err8.code) {
3123
+ const err6 = resolvedResult.error;
3124
+ switch (err6.code) {
3266
3125
  case "material-parent-not-found":
3267
3126
  case "material-no-effective-pass":
3268
3127
  case "material-value-unknown":
3269
3128
  case "material-value-type-mismatch":
3270
3129
  case "material-contract-program-mismatch":
3271
- worldInternal._routeError(err8, {
3130
+ worldInternal._routeError(err6, {
3272
3131
  severity: Severity.Error,
3273
- systemName: `RenderSystem.extract (${err8.code})`
3132
+ systemName: `RenderSystem.extract (${err6.code})`
3274
3133
  });
3275
3134
  break;
3276
3135
  case "material-circular-inheritance":
3277
- worldInternal._routeError(err8, {
3136
+ worldInternal._routeError(err6, {
3278
3137
  severity: Severity.Error,
3279
3138
  systemName: "RenderSystem.extract (material-circular-inheritance)"
3280
3139
  });
3281
3140
  break;
3282
3141
  default:
3283
- worldInternal._routeError(err8, {
3142
+ worldInternal._routeError(err6, {
3284
3143
  severity: Severity.Error,
3285
- systemName: `RenderSystem.extract (_materialWalk: ${err8.code})`
3144
+ systemName: `RenderSystem.extract (_materialWalk: ${err6.code})`
3286
3145
  });
3287
3146
  }
3288
3147
  continue;
@@ -3293,10 +3152,41 @@ function extractFrame(world, context) {
3293
3152
  ...context.materialContext,
3294
3153
  geometry: hasSkin ? "skinned" : context.materialContext.geometry
3295
3154
  };
3296
- const materialProgramKeys = materialProgramKeysForMaterial(
3297
- asset,
3298
- assets,
3299
- materialContext
3155
+ try {
3156
+ materialProgramSelections = materialProgramSelectionsForMaterial(
3157
+ asset,
3158
+ assets,
3159
+ materialContext
3160
+ );
3161
+ } catch (error) {
3162
+ if (isMissingMaterialProgram(error) && materialContext?.geometry === "mesh") {
3163
+ try {
3164
+ const skinnedSelections = materialProgramSelectionsForMaterial(asset, assets, {
3165
+ ...materialContext,
3166
+ geometry: "skinned"
3167
+ });
3168
+ if (skinnedSelections?.some(materialProgramSelectionRequiresSkin) === true && gpuDrivenMesh !== void 0) {
3169
+ const hasSkinIndex = gpuDrivenMesh.attributes.skinIndex !== void 0;
3170
+ const hasSkinWeight = gpuDrivenMesh.attributes.skinWeight !== void 0;
3171
+ if (!hasSkinIndex || !hasSkinWeight) {
3172
+ const missing = !hasSkinIndex && !hasSkinWeight ? "both" : !hasSkinIndex ? "skinIndex" : "skinWeight";
3173
+ worldInternal._routeError(new MaterialSkinAttrMissingError(entity, missing), {
3174
+ severity: Severity.Error,
3175
+ systemName: "RenderSystem.extract (material-skin-attr-missing)"
3176
+ });
3177
+ continue;
3178
+ }
3179
+ }
3180
+ } catch {
3181
+ }
3182
+ }
3183
+ throw error;
3184
+ }
3185
+ const materialProgramKeys = materialProgramSelections === void 0 ? void 0 : Object.fromEntries(
3186
+ materialProgramSelections.map(({ pass, specializationKey }) => [
3187
+ pass,
3188
+ specializationKey
3189
+ ])
3300
3190
  );
3301
3191
  const materialSceneIndexProgramKeys = materialSceneIndexProgramKeysForMaterial(
3302
3192
  asset,
@@ -3341,7 +3231,7 @@ function extractFrame(world, context) {
3341
3231
  );
3342
3232
  {
3343
3233
  const hasSkinSkel = hasSkin && skinSkeletonView !== void 0 && skinSkeletonView !== void 0 && skinSkeletonView !== 0;
3344
- const isPbrSkinMaterial = isStandardPbrSkinMaterialShader(firstPassShader);
3234
+ const isPbrSkinMaterial = materialProgramSelections?.some(materialProgramSelectionRequiresSkin) === true || isStandardPbrSkinMaterialShader(firstPassShader);
3345
3235
  if (hasSkinSkel && !isPbrSkinMaterial) {
3346
3236
  worldInternal._routeError(new SkinMaterialMismatchError(entity, firstPassShader), {
3347
3237
  severity: Severity.Error,
@@ -3707,7 +3597,7 @@ function extractFrame(world, context) {
3707
3597
  }
3708
3598
  if (skinSlice === void 0 && hasSkin) {
3709
3599
  releaseSkinIdentity();
3710
- if (materialSnap.materialShaderId === "forgeax::pbr-skin") {
3600
+ if (materialSnap.materialShaderId === "forgeax::pbr-skin" || materialProgramSelections?.some(materialProgramSelectionRequiresSkin) === true) {
3711
3601
  pendingDispatch.length = 0;
3712
3602
  continue;
3713
3603
  }
@@ -3887,6 +3777,7 @@ function extractFrame(world, context) {
3887
3777
  }
3888
3778
  instancesSnap = {
3889
3779
  transforms: collectionResult.value.transforms,
3780
+ generations: collectionResult.value.generations,
3890
3781
  instanceCount: collectionResult.value.count,
3891
3782
  collectionId: collectionResult.value.collectionId,
3892
3783
  revision: collectionResult.value.revision,
@@ -4310,6 +4201,30 @@ function runtimeMaterialShaderId(module, passName) {
4310
4201
  function materialProgramKeysForMaterial(material, assets, context) {
4311
4202
  return materialProgramKeysForAddress(material, assets, context, "direct");
4312
4203
  }
4204
+ function materialProgramSelectionsForMaterial(material, assets, context, address = "direct") {
4205
+ const projection = assets.getMaterialProjectionForPayload(material);
4206
+ if (projection === void 0) return void 0;
4207
+ if (context === void 0)
4208
+ throw new Error("Published material selection requires renderer-owned compiler context");
4209
+ return projection.passes.map((pass) => {
4210
+ const mode = String(
4211
+ pass.renderState?.tags?.LightMode ?? pass.name
4212
+ );
4213
+ const passKind = /shadow/i.test(mode) ? "shadow" : /depth/i.test(mode) ? "depth" : "forward";
4214
+ const selectedContext = {
4215
+ ...context,
4216
+ pass: passKind,
4217
+ pipeline: /deferred|gbuffer/i.test(mode) ? "deferred" : context.pipeline
4218
+ };
4219
+ const selected = selectMaterialPassProgram(projection, pass.name, selectedContext, address);
4220
+ return {
4221
+ pass: pass.name,
4222
+ context: selectedContext,
4223
+ specializationKey: selected.specializationKey,
4224
+ ...selected.abi === void 0 ? {} : { abi: selected.abi }
4225
+ };
4226
+ });
4227
+ }
4313
4228
  function materialSceneIndexProgramKeysForMaterial(material, assets, context) {
4314
4229
  const projection = assets.getMaterialProjectionForPayload(material);
4315
4230
  if (projection === void 0) return void 0;
@@ -4335,35 +4250,19 @@ function materialSceneIndexProgramKeysForMaterial(material, assets, context) {
4335
4250
  );
4336
4251
  entries[pass.name] = { specializationKey: selected.specializationKey, pass: passKind };
4337
4252
  } catch (error) {
4338
- if (!isMissingMaterialProgram(error)) throw error;
4253
+ if (!isMissingMaterialProgram2(error)) throw error;
4339
4254
  }
4340
4255
  }
4341
4256
  return Object.keys(entries).length === 0 ? void 0 : entries;
4342
4257
  }
4343
- function isMissingMaterialProgram(error) {
4258
+ function isMissingMaterialProgram2(error) {
4344
4259
  return error !== null && typeof error === "object" && error.code === "material-specialization-not-cooked";
4345
4260
  }
4346
4261
  function materialProgramKeysForAddress(material, assets, context, address) {
4347
- const projection = assets.getMaterialProjectionForPayload(material);
4348
- if (projection === void 0) return void 0;
4349
- if (context === void 0)
4350
- throw new Error("Published material selection requires renderer-owned compiler context");
4351
- const entries = [];
4352
- for (const pass of projection.passes) {
4353
- const mode = String(
4354
- pass.renderState?.tags?.LightMode ?? pass.name
4355
- );
4356
- const selectedContext = {
4357
- ...context,
4358
- pass: /shadow/i.test(mode) ? "shadow" : /depth/i.test(mode) ? "depth" : "forward",
4359
- pipeline: /deferred|gbuffer/i.test(mode) ? "deferred" : context.pipeline
4360
- };
4361
- entries.push([
4362
- pass.name,
4363
- selectMaterialPassProgram(projection, pass.name, selectedContext, address).specializationKey
4364
- ]);
4365
- }
4366
- return entries.length === 0 ? void 0 : Object.fromEntries(entries);
4262
+ const selections = materialProgramSelectionsForMaterial(material, assets, context, address);
4263
+ return selections === void 0 ? void 0 : Object.fromEntries(
4264
+ selections.map(({ pass, specializationKey }) => [pass, specializationKey])
4265
+ );
4367
4266
  }
4368
4267
  function runtimeMaterialShaderIdForMaterial(passes, programs) {
4369
4268
  const pass = passes.find(
@@ -4965,6 +4864,22 @@ function computeDirectionalCsm(direction, config, cameraData) {
4965
4864
  if ((ls[2] ?? 0) < minZ) minZ = ls[2] ?? 0;
4966
4865
  if ((ls[2] ?? 0) > maxZ) maxZ = ls[2] ?? 0;
4967
4866
  }
4867
+ const texelX = (maxX - minX) / config.mapSize;
4868
+ const texelY = (maxY - minY) / config.mapSize;
4869
+ if (Number.isFinite(texelX) && texelX > 0) {
4870
+ const centerX = (minX + maxX) * 0.5;
4871
+ const snappedCenterX = Math.round(centerX / texelX) * texelX;
4872
+ const halfWidth = (maxX - minX) * 0.5 + texelX * 0.5;
4873
+ minX = snappedCenterX - halfWidth;
4874
+ maxX = snappedCenterX + halfWidth;
4875
+ }
4876
+ if (Number.isFinite(texelY) && texelY > 0) {
4877
+ const centerY = (minY + maxY) * 0.5;
4878
+ const snappedCenterY = Math.round(centerY / texelY) * texelY;
4879
+ const halfHeight = (maxY - minY) * 0.5 + texelY * 0.5;
4880
+ minY = snappedCenterY - halfHeight;
4881
+ maxY = snappedCenterY + halfHeight;
4882
+ }
4968
4883
  const nearZ = Math.max(maxZ, lightSpaceMaxZFull);
4969
4884
  const orthoProj = mat4.create();
4970
4885
  mat4.orthographic(orthoProj, minX, maxX, maxY, minY, -nearZ, -minZ);
@@ -5008,14 +4923,26 @@ function collectCameraSnapshots(world) {
5008
4923
  const cameras = [];
5009
4924
  const cameraQuery = world.query({
5010
4925
  read: [Camera],
5011
- optional: [MotionBlur, DynamicResolution, ScreenSpaceReflection],
4926
+ optional: [MotionBlur, DynamicResolution, ScreenSpaceReflection, DepthOfField],
5012
4927
  with: [Transform, GlobalTransform]
5013
4928
  }).unwrap();
5014
4929
  for (const row of cameraQuery) {
5015
4930
  const cam = row.get(Camera);
5016
4931
  const motionBlur = row.get(MotionBlur);
4932
+ const motionBlurResult = resolveMotionBlurParams(motionBlur);
4933
+ if (!motionBlurResult.ok) throw motionBlurResult.error;
4934
+ const motionBlurParams = motionBlurResult.value;
4935
+ const depthOfField = row.get(DepthOfField);
5017
4936
  const dynamicResolution = row.get(DynamicResolution);
5018
4937
  const screenSpaceReflection = row.get(ScreenSpaceReflection);
4938
+ const projection = cameraProjectionFromF32(cam.projection);
4939
+ const depthOfFieldResult = resolveDepthOfFieldParams(depthOfField, {
4940
+ projection,
4941
+ fov: cam.fov,
4942
+ near: cam.near,
4943
+ far: cam.far
4944
+ });
4945
+ const depthOfFieldError = depthOfFieldResult.ok ? void 0 : depthOfFieldRequestFailure(depthOfFieldResult.error);
5019
4946
  const entity = row.entity;
5020
4947
  const view = worldInternal._getArrayView(entity, GlobalTransform, "world");
5021
4948
  if (view === void 0) continue;
@@ -5042,7 +4969,7 @@ function collectCameraSnapshots(world) {
5042
4969
  aspect: cam.aspect,
5043
4970
  near: cam.near,
5044
4971
  far: cam.far,
5045
- projection: cameraProjectionFromF32(cam.projection),
4972
+ projection,
5046
4973
  orthoLeft: cam.left,
5047
4974
  orthoRight: cam.right,
5048
4975
  orthoBottom: cam.bottom,
@@ -5053,21 +4980,31 @@ function collectCameraSnapshots(world) {
5053
4980
  ...output === void 0 ? {} : { output },
5054
4981
  antialias,
5055
4982
  ...dynamicResolutionResult.value === void 0 ? {} : { dynamicResolution: dynamicResolutionResult.value },
5056
- bloom: bloomEnabledFromF32(cam.bloom),
4983
+ bloom: validateCameraBloom(
4984
+ cam.bloom,
4985
+ cam.bloomThreshold,
4986
+ cam.bloomIntensity,
4987
+ cam.bloomSoftKnee,
4988
+ cam.bloomScatter
4989
+ ),
5057
4990
  bloomThreshold: cam.bloomThreshold,
5058
4991
  bloomIntensity: cam.bloomIntensity,
5059
- bloomBlurRadius: cam.bloomBlurRadius,
4992
+ bloomSoftKnee: cam.bloomSoftKnee,
4993
+ bloomScatter: cam.bloomScatter,
5060
4994
  clearColor: [
5061
4995
  cam.clearColor[0] ?? 0,
5062
4996
  cam.clearColor[1] ?? 0,
5063
4997
  cam.clearColor[2] ?? 0,
5064
4998
  cam.clearColor[3] ?? 1
5065
4999
  ],
5066
- ...motionBlur === void 0 ? {} : {
5000
+ ...depthOfFieldResult.ok && depthOfFieldResult.value !== void 0 ? { depthOfField: depthOfFieldResult.value } : {},
5001
+ ...depthOfFieldError === void 0 ? {} : { depthOfFieldError },
5002
+ ...motionBlurParams === void 0 ? {} : {
5067
5003
  motionBlur: {
5068
- shutterAngle: motionBlur.shutterAngle,
5069
- maxRadiusPixels: motionBlur.maxRadiusPixels,
5070
- sampleCount: motionBlur.sampleCount
5004
+ shutterAngle: motionBlurParams.shutterAngle,
5005
+ maxRadiusPixels: motionBlurParams.maxRadiusPixels,
5006
+ sampleCount: motionBlurParams.sampleCount,
5007
+ targetFps: motionBlurParams.targetFps
5071
5008
  }
5072
5009
  },
5073
5010
  ...screenSpaceReflection === void 0 ? {} : {
@@ -5245,6 +5182,8 @@ function textureDigest(texture2) {
5245
5182
  return `fnv1a:${hash.toString(16).padStart(8, "0")}`;
5246
5183
  }
5247
5184
  function extractVolumeSnapshot(world, assets, worldInternal) {
5185
+ const elapsed = world.getResource(Time).elapsed;
5186
+ const worldTimeSeconds = Number.isFinite(elapsed) ? Math.max(0, elapsed) : 0;
5248
5187
  const query = world.query({ read: [VolumetricFog] }).unwrap();
5249
5188
  const authorings = [];
5250
5189
  let selectedLight;
@@ -5274,7 +5213,7 @@ function extractVolumeSnapshot(world, assets, worldInternal) {
5274
5213
  }) : resolved.error,
5275
5214
  { severity: Severity.Error, systemName: "RenderSystem.extract (volumetric-density)" }
5276
5215
  );
5277
- return { status: "degraded" };
5216
+ return { status: "degraded", worldTimeSeconds };
5278
5217
  }
5279
5218
  const densityAsset = resolved.value;
5280
5219
  const guid = assets?.guidOf(densityAsset) ?? `handle:${Number(densityHandle)}`;
@@ -5331,6 +5270,7 @@ function extractVolumeSnapshot(world, assets, worldInternal) {
5331
5270
  });
5332
5271
  return {
5333
5272
  status: "degraded",
5273
+ worldTimeSeconds,
5334
5274
  ...first === void 0 ? {} : {
5335
5275
  densityHandle: first.densityHandle,
5336
5276
  densityAsset: first.densityAsset,
@@ -5355,6 +5295,7 @@ function extractVolumeSnapshot(world, assets, worldInternal) {
5355
5295
  };
5356
5296
  return {
5357
5297
  status: "available",
5298
+ worldTimeSeconds,
5358
5299
  fog: extracted.value.fog,
5359
5300
  densityHandle: first.densityHandle,
5360
5301
  densityAsset: first.densityAsset,
@@ -5903,6 +5844,6 @@ var ProbeBlendSceneProjection = class {
5903
5844
  }
5904
5845
  };
5905
5846
 
5906
- export { InstanceBoundsCache, OcclusionRenderRuntime, PROBE_MAX_CONTRIBUTORS, ProbeBlendSceneProjection, SKYLIGHT_RECOVERY_FALLBACK, SSR_HISTORY_FORMAT, SsrHistoryOwner, admitProbeContributors, blendLightProbes, buildRectAreaWorldFrame, buildShadowFrusta, createCookieProjectionMatrixData, createExtendedLightingState, createSsrHistoryOwner, createSsrSpatialResources, estimateSsrSpatialMemory, extractFrames, fingerprintNumericArray, glyphTextLayoutSystem, primitiveKey, primitiveKeyId, projectExtendedLightingInspection, promoteExtendedLightingCandidate, recordExtendedLightingFailure, rectAreaFacesPoint, scaledProbeWeight, setOcclusionRuntimeTestHooks, viewKey, viewKeyId };
5907
- //# sourceMappingURL=chunk-C3DDSXYK.mjs.map
5908
- //# sourceMappingURL=chunk-C3DDSXYK.mjs.map
5847
+ export { InstanceBoundsCache, OcclusionRenderRuntime, PROBE_MAX_CONTRIBUTORS, ProbeBlendSceneProjection, SSR_HISTORY_FORMAT, SsrHistoryOwner, admitProbeContributors, blendLightProbes, buildRectAreaWorldFrame, buildShadowFrusta, createCookieProjectionMatrixData, createExtendedLightingState, createSsrHistoryOwner, createSsrSpatialResources, emptyBloomInspection, estimateSsrSpatialMemory, extractFrames, fingerprintNumericArray, glyphTextLayoutSystem, primitiveKey, primitiveKeyId, projectExtendedLightingInspection, promoteExtendedLightingCandidate, recordExtendedLightingFailure, rectAreaFacesPoint, scaledProbeWeight, setOcclusionRuntimeTestHooks, viewKey, viewKeyId };
5848
+ //# sourceMappingURL=chunk-OO3DRYK7.mjs.map
5849
+ //# sourceMappingURL=chunk-OO3DRYK7.mjs.map