@forgeax/engine-render 0.1.32 → 0.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1374 -142
- package/dist/assembly/analytic-fog-registration.d.ts +3 -0
- package/dist/assembly/analytic-fog-registration.d.ts.map +1 -0
- package/dist/assembly/backend-contract.d.ts +2 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -1
- package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
- package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
- package/dist/assembly/canvas-draw-guard.d.ts +3 -0
- package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
- package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
- package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
- package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
- package/dist/assembly/factory.d.ts +1 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/fxaa-registration.d.ts +4 -0
- package/dist/assembly/fxaa-registration.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +3 -3
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/lod-observation.d.ts +4 -0
- package/dist/assembly/lod-observation.d.ts.map +1 -0
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
- package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
- package/dist/assembly/material-shader-policy.d.ts +16 -2
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
- package/dist/assembly/motion-blur-registration.d.ts +3 -0
- package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
- package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/render-feature-post-processes.d.ts +6 -0
- package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
- package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-inspection.d.ts +11 -0
- package/dist/assembly/renderer-inspection.d.ts.map +1 -1
- package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
- package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
- package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
- package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +2 -2
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
- package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +1 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/authoring.mjs +1 -1
- package/dist/barrel-distortion.d.ts +47 -0
- package/dist/barrel-distortion.d.ts.map +1 -0
- package/dist/bloom-admission.d.ts +13 -0
- package/dist/bloom-admission.d.ts.map +1 -0
- package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
- package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
- package/dist/{chunk-JCIRYQ4V.mjs → chunk-HEB564WF.mjs} +10 -4
- package/dist/chunk-HEB564WF.mjs.map +1 -0
- package/dist/{chunk-JRIPCMYC.mjs → chunk-MKDIT2EM.mjs} +1584 -375
- package/dist/chunk-MKDIT2EM.mjs.map +1 -0
- package/dist/{chunk-S665NJNF.mjs → chunk-OCDLEI6I.mjs} +3 -3
- package/dist/{chunk-S665NJNF.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
- package/dist/chunk-ODZWR6JQ.mjs +4927 -0
- package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
- package/dist/{chunk-DRR7D3KX.mjs → chunk-SHFUFJ5N.mjs} +192 -18
- package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
- package/dist/{chunk-4NNZQCL3.mjs → chunk-UI5SFODX.mjs} +223 -277
- package/dist/chunk-UI5SFODX.mjs.map +1 -0
- package/dist/{chunk-GWCEMDVR.mjs → chunk-UINHLCZA.mjs} +787 -80
- package/dist/chunk-UINHLCZA.mjs.map +1 -0
- package/dist/{chunk-6TFBXLRJ.mjs → chunk-WEX45HKH.mjs} +222 -337
- package/dist/chunk-WEX45HKH.mjs.map +1 -0
- package/dist/cloud/density.d.ts +55 -0
- package/dist/cloud/density.d.ts.map +1 -0
- package/dist/cloud/extract.d.ts +25 -0
- package/dist/cloud/extract.d.ts.map +1 -0
- package/dist/cloud/feature.d.ts +57 -0
- package/dist/cloud/feature.d.ts.map +1 -0
- package/dist/cloud/frame-context.d.ts +8 -0
- package/dist/cloud/frame-context.d.ts.map +1 -0
- package/dist/cloud/inspection.d.ts +59 -0
- package/dist/cloud/inspection.d.ts.map +1 -0
- package/dist/cloud/optics.d.ts +56 -0
- package/dist/cloud/optics.d.ts.map +1 -0
- package/dist/cloud/parameters.d.ts +73 -0
- package/dist/cloud/parameters.d.ts.map +1 -0
- package/dist/cloud/resources.d.ts +60 -0
- package/dist/cloud/resources.d.ts.map +1 -0
- package/dist/cloud/shadow.d.ts +42 -0
- package/dist/cloud/shadow.d.ts.map +1 -0
- package/dist/cloud/temporal.d.ts +74 -0
- package/dist/cloud/temporal.d.ts.map +1 -0
- package/dist/components/atmosphere.d.ts +2 -0
- package/dist/components/atmosphere.d.ts.map +1 -1
- package/dist/components/barrel-distortion.d.ts +13 -0
- package/dist/components/barrel-distortion.d.ts.map +1 -0
- package/dist/components/camera.d.ts +20 -4
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/cloud-layer.d.ts +29 -0
- package/dist/components/cloud-layer.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/instances.d.ts +20 -6
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/components/mesh-filter.d.ts +6 -5
- package/dist/components/mesh-filter.d.ts.map +1 -1
- package/dist/components/motion-blur.d.ts +1 -0
- package/dist/components/motion-blur.d.ts.map +1 -1
- package/dist/construct-renderer.d.ts +1 -1
- package/dist/construct-renderer.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +9751 -3528
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +6 -0
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/dynamic-geometry.d.ts +5 -1
- package/dist/dynamic-geometry.d.ts.map +1 -1
- package/dist/environment/analytic-fog.d.ts +6 -0
- package/dist/environment/analytic-fog.d.ts.map +1 -0
- package/dist/errors/cloud.d.ts +59 -0
- package/dist/errors/cloud.d.ts.map +1 -0
- package/dist/errors/render.d.ts +23 -5
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/examples/single-layer-medium-surface.d.ts +47 -0
- package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +12 -1
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/extract/environment.d.ts +2 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/features/barrel-distortion.d.ts +29 -0
- package/dist/features/barrel-distortion.d.ts.map +1 -0
- package/dist/features/error-reporting.d.ts +17 -0
- package/dist/features/error-reporting.d.ts.map +1 -0
- package/dist/features/host.d.ts +15 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
- package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
- package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
- package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
- package/dist/features/plan.d.ts +15 -4
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +9 -5
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/render-graph-compute.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +5 -0
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +1 -0
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/targets.d.ts +2 -0
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +44 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +15 -7
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-dirty-ranges.d.ts +11 -0
- package/dist/gpu-dirty-ranges.d.ts.map +1 -0
- package/dist/gpu-driven/batch-topology.d.ts +17 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/material-artifacts.d.ts +6 -0
- package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
- package/dist/gpu-driven/prepared-draw.d.ts +7 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster-material.d.ts +178 -0
- package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +50 -4
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/resource-allocation.d.ts +31 -0
- package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
- package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
- package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +35 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +11 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +2 -2
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +10 -1
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +31 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +258 -8
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +178 -3
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instance-buffer-cache.d.ts +4 -4
- package/dist/instance-buffer-cache.d.ts.map +1 -1
- package/dist/instances.d.ts +49 -94
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +7 -7
- package/dist/pbr-pipeline.d.ts +19 -1
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
- package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
- package/dist/pipeline/standard-output/types.d.ts +4 -2
- package/dist/pipeline/standard-output/types.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts +28 -19
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +1 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +2 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/record/barrel-distortion-frame.d.ts +15 -0
- package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
- package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
- package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
- package/dist/record/fold-buckets.d.ts +95 -0
- package/dist/record/fold-buckets.d.ts.map +1 -0
- package/dist/record/fold-instance-buffer.d.ts +6 -0
- package/dist/record/fold-instance-buffer.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +1 -0
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +40 -3
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +14 -62
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-draw-receipts.d.ts +11 -0
- package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +8 -0
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +21 -5
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +7 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +13 -2
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +6 -5
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/motion-blur-receipt.d.ts +11 -0
- package/dist/record/motion-blur-receipt.d.ts.map +1 -0
- package/dist/record/probe-blend-buffer.d.ts +16 -0
- package/dist/record/probe-blend-buffer.d.ts.map +1 -0
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +34 -31
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +2 -0
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +6 -4
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +22 -2
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +11 -3
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/record/volume-params.d.ts +9 -0
- package/dist/record/volume-params.d.ts.map +1 -0
- package/dist/recovery/render-system-candidate.d.ts +10 -0
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +66 -8
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +106 -3
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +3 -2
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +24 -10
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-presentation.d.ts +23 -0
- package/dist/render-system-presentation.d.ts.map +1 -0
- package/dist/render-system-producer-roots.d.ts +10 -0
- package/dist/render-system-producer-roots.d.ts.map +1 -0
- package/dist/render-system-residency.d.ts +12 -0
- package/dist/render-system-residency.d.ts.map +1 -0
- package/dist/render-system.d.ts +26 -15
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/probe-blend.d.ts +27 -0
- package/dist/scene/probe-blend.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +14 -5
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +9 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/surface/dynamic-input.d.ts +133 -0
- package/dist/surface/dynamic-input.d.ts.map +1 -0
- package/dist/surface/gpu-driven.d.ts +41 -0
- package/dist/surface/gpu-driven.d.ts.map +1 -0
- package/dist/surface/submission-observation.d.ts +136 -0
- package/dist/surface/submission-observation.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +7 -0
- package/dist/temporal/frame.d.ts.map +1 -1
- package/dist/temporal/gpu.d.ts +13 -1
- package/dist/temporal/gpu.d.ts.map +1 -1
- package/dist/temporal/index.mjs +5 -5
- package/dist/temporal/inspection.d.ts.map +1 -1
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
- package/dist/temporal/view.d.ts +6 -1
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/transmission/single-layer-medium.d.ts +89 -0
- package/dist/transmission/single-layer-medium.d.ts.map +1 -0
- package/dist/typed-render-graph-primitives.d.ts +24 -9
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/component.d.ts +9 -5
- package/dist/volume/component.d.ts.map +1 -1
- package/dist/volume/extract.d.ts +1 -1
- package/dist/volume/extract.d.ts.map +1 -1
- package/dist/volume/inspection.d.ts +2 -0
- package/dist/volume/inspection.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +4 -1
- package/dist/volume/passes.d.ts.map +1 -1
- package/dist/volume/resources.d.ts.map +1 -1
- package/dist/volume/temporal.d.ts +3 -1
- package/dist/volume/temporal.d.ts.map +1 -1
- package/package.json +22 -21
- package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
- package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
- package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
- package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
- package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
- package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
- package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
- package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
- package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
- package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
- package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
- package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
- package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
- package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
- package/src/__tests__/environment-selection.unit.test.ts +12 -0
- package/src/__tests__/factory-contract.integration.test.ts +626 -113
- package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
- package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
- package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
- package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
- package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
- package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +7 -6
- package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +103 -4
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
- package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
- package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
- package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
- package/src/__tests__/gpu-scene.unit.test.ts +210 -9
- package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
- package/src/__tests__/instances-culling.integration.test.ts +10 -36
- package/src/__tests__/instances-store.unit.test.ts +105 -238
- package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
- package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
- package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
- package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
- package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
- package/src/__tests__/motion-blur-compute.dawn.test.ts +589 -0
- package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
- package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
- package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +21 -0
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
- package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
- package/src/__tests__/probe-bindings.unit.test.ts +582 -1
- package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
- package/src/__tests__/public-surface.test-d.ts +8 -0
- package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +9 -0
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
- package/src/__tests__/render-feature-error-reporting.unit.test.ts +44 -0
- package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
- package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
- package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
- package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
- package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
- package/src/__tests__/render-scene-temporal-retry.unit.test.ts +37 -6
- package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
- package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
- package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
- package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +33 -11
- package/src/__tests__/resource-allocation.unit.test.ts +123 -0
- package/src/__tests__/shader-manifest-fixture.ts +4 -4
- package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
- package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +17 -0
- package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
- package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
- package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
- package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
- package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
- package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
- package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
- package/src/__tests__/standard-pipeline.integration.test.ts +200 -9
- package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
- package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
- package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
- package/src/__tests__/temporal-performance.integration.test.ts +3 -3
- package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
- package/src/__tests__/temporal-view.unit.test.ts +2 -1
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
- package/src/__tests__/visibility-instances.integration.test.ts +7 -19
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
- package/src/__tests__/volume-optics-oracle.unit.test.ts +7 -3
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +189 -15
- package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
- package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
- package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +558 -68
- package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +23 -5
- package/src/assembly/analytic-fog-registration.ts +14 -0
- package/src/assembly/backend-contract.ts +30 -0
- package/src/assembly/barrel-distortion-inspection.ts +22 -0
- package/src/assembly/canvas-draw-guard.ts +11 -0
- package/src/assembly/cloud-shadow-entry.ts +22 -0
- package/src/assembly/dynamic-geometry-host.ts +65 -37
- package/src/assembly/dynamic-geometry-runtime.ts +7 -1
- package/src/assembly/factory.ts +2 -30
- package/src/assembly/fxaa-registration.ts +17 -0
- package/src/assembly/host-contract.ts +3 -3
- package/src/assembly/lod-observation.ts +12 -0
- package/src/assembly/material/assembly.ts +25 -13
- package/src/assembly/material/pipeline-helpers.ts +53 -12
- package/src/assembly/material-shader-policy.ts +55 -0
- package/src/assembly/material-shader-prewarm.ts +21 -10
- package/src/assembly/motion-blur-registration.ts +17 -0
- package/src/assembly/recovery/device-loss-fanout.ts +13 -0
- package/src/assembly/recovery/renderer-recover.ts +41 -18
- package/src/assembly/render-feature-post-processes.ts +54 -0
- package/src/assembly/renderer-facade.ts +6 -1
- package/src/assembly/renderer-feature-inspection.ts +8 -2
- package/src/assembly/renderer-frame-transaction.ts +23 -0
- package/src/assembly/renderer-inspection.ts +28 -0
- package/src/assembly/skin-palette-owner.ts +1 -1
- package/src/assembly/temporal-post-process-prewarm.ts +40 -0
- package/src/assembly/webgpu-pbr-ready.ts +9 -1
- package/src/assembly/webgpu-ready-contract.ts +8 -3
- package/src/assembly/webgpu-ready-per-pass.ts +104 -0
- package/src/assembly/webgpu-ready.ts +296 -306
- package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
- package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
- package/src/assembly/webgpu-renderer.ts +228 -281
- package/src/assembly/webgpu-vertex-layouts.ts +1 -1
- package/src/barrel-distortion.ts +247 -0
- package/src/bloom-admission.ts +21 -0
- package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
- package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
- package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
- package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
- package/src/cloud/density.ts +600 -0
- package/src/cloud/extract.ts +110 -0
- package/src/cloud/feature.ts +1810 -0
- package/src/cloud/frame-context.ts +42 -0
- package/src/cloud/inspection.ts +130 -0
- package/src/cloud/optics.ts +285 -0
- package/src/cloud/parameters.ts +255 -0
- package/src/cloud/resources.ts +122 -0
- package/src/cloud/shadow.ts +167 -0
- package/src/cloud/temporal.ts +226 -0
- package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
- package/src/components/atmosphere.ts +4 -0
- package/src/components/barrel-distortion.ts +46 -0
- package/src/components/camera.ts +66 -10
- package/src/components/cloud-layer.ts +47 -0
- package/src/components/index.ts +2 -0
- package/src/components/instances.ts +18 -45
- package/src/components/mesh-filter.ts +11 -9
- package/src/components/motion-blur.ts +1 -0
- package/src/components/sprite-instances.ts +1 -1
- package/src/construct-renderer.ts +1 -1
- package/src/device/gpu-residency.ts +56 -12
- package/src/dynamic-geometry.ts +12 -1
- package/src/environment/analytic-fog.ts +44 -0
- package/src/environment/background.ts +2 -2
- package/src/errors/cloud.ts +103 -0
- package/src/errors/render.ts +58 -8
- package/src/examples/single-layer-medium-surface.ts +59 -0
- package/src/extract/camera.ts +35 -8
- package/src/extract/contracts.ts +12 -0
- package/src/extract/environment.ts +4 -0
- package/src/features/barrel-distortion.ts +172 -0
- package/src/features/error-reporting.ts +98 -0
- package/src/features/host.ts +138 -24
- package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
- package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
- package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
- package/src/features/motion-blur/motion-blur-params.ts +70 -2
- package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
- package/src/features/plan.ts +33 -8
- package/src/features/prepared-gpu-work.ts +86 -35
- package/src/features/render-graph-compute.ts +13 -5
- package/src/features/render-graph-contribution.ts +11 -0
- package/src/features/render-graph-raster.ts +45 -3
- package/src/features/targets.ts +66 -0
- package/src/features/types.ts +47 -0
- package/src/fullscreen-post-process-pass.ts +41 -9
- package/src/gpu-dirty-ranges.ts +48 -0
- package/src/gpu-driven/batch-topology.ts +53 -0
- package/src/gpu-driven/material-artifacts.ts +35 -32
- package/src/gpu-driven/prepared-draw.ts +27 -14
- package/src/gpu-driven/production-raster-material.ts +1894 -0
- package/src/gpu-driven/production-raster.ts +904 -787
- package/src/gpu-driven/resource-allocation.ts +142 -0
- package/src/gpu-driven/shadow-ownership.ts +71 -0
- package/src/gpu-driven/view-gpu.ts +181 -10
- package/src/gpu-scene.ts +259 -101
- package/src/hdrp-buffers.ts +4 -3
- package/src/ibl/skylight-bind-group.ts +49 -7
- package/src/index.ts +228 -9
- package/src/inspection-types.ts +222 -2
- package/src/instance-buffer-cache.ts +4 -4
- package/src/instances.ts +151 -492
- package/src/pbr-pipeline.ts +219 -13
- package/src/pipeline/single-layer-medium-passes.ts +267 -0
- package/src/pipeline/standard-forward-lane.ts +313 -57
- package/src/pipeline/standard-output/graph.ts +8 -2
- package/src/pipeline/standard-output/types.ts +12 -1
- package/src/pipeline/standard-pipeline.ts +291 -18
- package/src/pipeline/standard-post.ts +397 -102
- package/src/pipeline-builder.ts +1 -1
- package/src/pipeline-spec.ts +5 -5
- package/src/plugin.ts +4 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
- package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
- package/src/prepare/prepared-graphics-resolver.ts +2 -0
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
- package/src/record/__tests__/temporal-payload.unit.test.ts +3 -2
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
- package/src/record/barrel-distortion-frame.ts +110 -0
- package/src/record/dynamic-geometry-consumption.ts +39 -9
- package/src/record/fold-buckets.ts +852 -0
- package/src/record/fold-instance-buffer.ts +51 -0
- package/src/record/frame-lighting.ts +36 -2
- package/src/record/frame-snapshot.ts +44 -4
- package/src/record/frame-targets.ts +10 -6
- package/src/record/frame.ts +373 -1099
- package/src/record/gpu-draw-receipts.ts +38 -0
- package/src/record/gpu-timing.ts +48 -5
- package/src/record/main-pass-geometry.ts +281 -83
- package/src/record/main-pass-material.ts +66 -4
- package/src/record/main-pass-sprite-draws.ts +13 -66
- package/src/record/main-pass.ts +156 -20
- package/src/record/mesh-ssbo.ts +43 -6
- package/src/record/motion-blur-receipt.ts +91 -0
- package/src/record/probe-blend-buffer.ts +180 -0
- package/src/record/recovery-pipeline.ts +35 -3
- package/src/record/render-context.ts +51 -31
- package/src/record/shadow-pass.ts +36 -2
- package/src/record/skybox-post-pass.ts +150 -200
- package/src/record/typed-frame-graph.ts +824 -44
- package/src/record/view-ubo.ts +26 -3
- package/src/record/volume-params.ts +225 -0
- package/src/recovery/render-system-candidate.ts +257 -52
- package/src/reflection/record-owner.ts +7 -3
- package/src/render-contract.ts +71 -8
- package/src/render-graph-primitives.ts +7 -1
- package/src/render-pipeline.ts +136 -1
- package/src/render-system-extract-tail.ts +72 -60
- package/src/render-system-extract.ts +117 -87
- package/src/render-system-presentation.ts +56 -0
- package/src/render-system-producer-roots.ts +96 -0
- package/src/render-system-residency.ts +159 -0
- package/src/render-system.ts +601 -482
- package/src/scene/probe-blend.ts +96 -4
- package/src/scene/render-scene.ts +431 -281
- package/src/ssao-buffers.ts +95 -2
- package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
- package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
- package/src/surface/dynamic-input.ts +658 -0
- package/src/surface/gpu-driven.ts +147 -0
- package/src/surface/submission-observation.ts +517 -0
- package/src/systems/skin-palette-allocator.ts +4 -1
- package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
- package/src/temporal/frame-coordinator.ts +8 -1
- package/src/temporal/frame.ts +20 -0
- package/src/temporal/gpu.ts +101 -17
- package/src/temporal/inspection.ts +7 -1
- package/src/temporal/standard-scene-data.ts +5 -0
- package/src/temporal/target-coverage-attachment.ts +4 -0
- package/src/temporal/view.ts +13 -2
- package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
- package/src/transmission/single-layer-medium.ts +322 -0
- package/src/typed-render-graph-primitives.ts +191 -50
- package/src/volume/component.ts +10 -10
- package/src/volume/extract.ts +11 -5
- package/src/volume/inspection.ts +3 -0
- package/src/volume/passes.ts +95 -8
- package/src/volume/resources.ts +2 -1
- package/src/volume/temporal.ts +11 -0
- package/dist/chunk-4NNZQCL3.mjs.map +0 -1
- package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
- package/dist/chunk-DRR7D3KX.mjs.map +0 -1
- package/dist/chunk-GWCEMDVR.mjs.map +0 -1
- package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
- package/dist/chunk-JRIPCMYC.mjs.map +0 -1
- package/dist/chunk-LULCA3OF.mjs +0 -1713
- package/dist/chunk-LULCA3OF.mjs.map +0 -1
- package/dist/chunk-PA5DRJNI.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/atmosphere.ts","../src/components/camera.ts","../src/components/cube-camera.ts","../src/components/depth-of-field.ts","../src/components/directional-shadow-filter.ts","../src/components/directional-light.ts","../src/components/dynamic-resolution.ts","../src/components/fog.ts","../src/components/instances.ts","../src/components/layer.ts","../src/components/light-helpers.ts","../src/components/light-probe.ts","../src/components/lines.ts","../src/components/mesh-filter.ts","../src/components/mesh-renderer.ts","../src/components/motion-blur.ts","../src/components/point-light.ts","../src/components/point-light-shadow.ts","../src/components/points.ts","../src/components/post-process-params.ts","../src/components/rect-area-light.ts","../src/components/reflection-probe.ts","../src/components/scene-instance.ts","../src/components/screen-space-reflection.ts","../src/components/skybox-background.ts","../src/components/skylight.ts","../src/components/sort-key.ts","../src/components/spot-light.ts","../src/components/visibility.ts","../src/features/depth-of-field/depth-of-field-params.ts","../src/volume/capability.ts","../src/capture/cube-views.ts","../src/mesh-material-bindings.ts","../src/extract/visibility.ts","../src/volume/component.ts","../src/volume/extract.ts"],"names":["defineComponent","err","ok","R_MIN","invalid","focalLength"],"mappings":"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","file":"chunk-GWCEMDVR.mjs","sourcesContent":["import { defineComponent } from '@forgeax/engine-ecs';\n\n/** Analytic atmosphere authoring facts; the directional light supplies the sun. */\nexport const Atmosphere = defineComponent('Atmosphere', {\n turbidity: { type: 'f32', default: 2 },\n rayleigh: { type: 'f32', default: 1 },\n mieCoefficient: { type: 'f32', default: 0.005 },\n mieDirectionalG: { type: 'f32', default: 0.8 },\n sunAngularRadius: { type: 'f32', default: 0.004675 },\n});\n","// @forgeax/engine-render - Camera (projection variant + ortho extension).\n//\n// Schema: 9 f32 columns — perspective quartet (fov + aspect + near + far)\n// + projection discriminator (0 = perspective, 1 = orthographic) + ortho\n// quartet (left + right + bottom + top). The view matrix continues to be\n// derived from the entity's Transform (AC-06 case B fires\n// 'render-system-no-camera' when 0 such entities exist).\n//\n// Projection discriminator:\n// projection === 0 → perspective path; RenderSystem builds\n// mat4.perspective(out, fov, aspect, near, far).\n// WebGPU [0, 1] NDC z; perspective reverse-Z hook is\n// a future spin-off path (plan-strategy §R-7) kept\n// outside M3 scope — the short-name mat4.perspective\n// already writes [0, 1] NDC, matching the ortho branch.\n// projection === 1 → orthographic path; RenderSystem builds\n// mat4.orthographic(out, left, right, top, bottom,\n// near, far) (WebGPU [0, 1] NDC; same z convention).\n//\n// Naming convention: forgeax uses the bare `Camera` name (no `Component`\n// suffix) to follow the unity-style flavor for \"individuating\" component\n// names per plan-strategy 7.2 + D-Q5a user lock.\n//\n// Related: requirements §AC-16 (Camera Ortho + Box3 / Sphere);\n// plan-strategy §M3 range + §R-7 risk (single perspective camera\n// in hello-room does NOT trigger depth-func conflict; multi-camera\n// mixed perspective + ortho deferred to feat-future-camera-depth-func);\n// plan-tasks.json w9 acceptanceCheck.\n\nimport { defineComponent, type SchemaOf, type ShapeOf } from '@forgeax/engine-ecs';\nimport { TONEMAP_SHADER_MODE } from '@forgeax/engine-shader';\n\n/**\n * Projection discriminator literal union (AC-16 narrowing surface).\n * Exposed for consumer code that maps `camera.projection` numeric values back\n * to a switch-able string literal (e.g. RenderSystem dispatch / inspector\n * snapshot rendering).\n */\nexport type CameraProjection = 'perspective' | 'orthographic';\n\n/** Numeric encoding of perspective projection (schema value for `projection`). */\nexport const CAMERA_PROJECTION_PERSPECTIVE = 0;\n/** Numeric encoding of orthographic projection (schema value for `projection`). */\nexport const CAMERA_PROJECTION_ORTHOGRAPHIC = 1;\n\n/** Closed public exposure authoring contract shared by all camera routes. */\nexport type CameraExposure =\n | { readonly kind: 'manual'; readonly multiplier: number }\n | {\n readonly kind: 'auto';\n readonly fallback: number;\n readonly compensationEv: number;\n readonly rangeEv: readonly [min: number, max: number];\n readonly rates: readonly [up: number, down: number];\n };\n\n/** Numeric encoding of manual exposure in the Camera SoA column. */\nexport const CAMERA_EXPOSURE_MODE_MANUAL = 0;\n/** Numeric encoding of GPU-adapted exposure in the Camera SoA column. */\nexport const CAMERA_EXPOSURE_MODE_AUTO = 1;\n\n/** Product-supported white-balance temperature range in Kelvin. */\nexport const CAMERA_TEMPERATURE_MIN = 1000;\nexport const CAMERA_TEMPERATURE_MAX = 40000;\n/** Product-supported normalized tint range. */\nexport const CAMERA_TINT_MIN = -1;\nexport const CAMERA_TINT_MAX = 1;\n\n/** Closed validation failures for the Camera authoring/column boundary. */\nexport type CameraErrorCode =\n | 'camera-exposure-invalid'\n | 'camera-color-grading-invalid'\n | 'camera-exposure-mode-invalid'\n | 'camera-tonemap-invalid'\n | 'camera-antialias-invalid'\n | 'camera-bloom-invalid';\n\nexport interface CameraErrorDetail {\n readonly field: string;\n readonly actual: number | string;\n readonly expected: string;\n}\n\n/** Structured Camera error; callers can branch on the closed `code` union. */\nexport class CameraError<Code extends CameraErrorCode = CameraErrorCode> extends Error {\n readonly code: Code;\n readonly expected: string;\n readonly hint: string;\n readonly detail: CameraErrorDetail;\n\n constructor(code: Code, field: string, actual: number | string, expected: string, hint: string) {\n super(`${code}: ${field}=${String(actual)}; expected ${expected}`);\n this.name = 'CameraError';\n this.code = code;\n this.expected = expected;\n this.hint = hint;\n this.detail = Object.freeze({ field, actual, expected });\n }\n}\n\nfunction actualValue(value: unknown): number | string {\n if (typeof value === 'number' || typeof value === 'string') return value;\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nfunction cameraError<Code extends CameraErrorCode>(\n code: Code,\n field: string,\n actual: unknown,\n expected: string,\n hint: string,\n): CameraError<Code> {\n return new CameraError(code, field, actualValue(actual), expected, hint);\n}\n\nfunction finitePositive(value: number): boolean {\n return Number.isFinite(value) && value > 0;\n}\n\n/** Validate the closed exposure union before it is projected into columns. */\nexport function validateCameraExposure(exposure: CameraExposure): CameraExposure {\n if (typeof exposure !== 'object' || exposure === null) {\n throw cameraError(\n 'camera-exposure-invalid',\n 'value',\n exposure,\n 'an object with kind manual or auto',\n 'choose one member of the CameraExposure union',\n );\n }\n if (exposure.kind === 'manual') {\n if (!finitePositive(exposure.multiplier)) {\n throw cameraError(\n 'camera-exposure-invalid',\n 'multiplier',\n exposure.multiplier,\n 'a finite number greater than zero',\n 'set Camera.exposure to a positive finite manual multiplier',\n );\n }\n return exposure;\n }\n if (exposure.kind === 'auto') {\n const [min, max] = exposure.rangeEv;\n const [up, down] = exposure.rates;\n if (\n !finitePositive(exposure.fallback) ||\n !Number.isFinite(exposure.compensationEv) ||\n !Number.isFinite(min) ||\n !Number.isFinite(max) ||\n min > max ||\n !Number.isFinite(up) ||\n !Number.isFinite(down) ||\n up < 0 ||\n down < 0\n ) {\n throw cameraError(\n 'camera-exposure-invalid',\n 'auto',\n JSON.stringify(exposure),\n 'finite fallback/compensation, an ordered range, and non-negative rates',\n 'inspect fallback, compensationEv, rangeEv, and rates before rebuilding the camera',\n );\n }\n return exposure;\n }\n throw cameraError(\n 'camera-exposure-invalid',\n 'kind',\n (exposure as { readonly kind?: unknown }).kind,\n \"'manual' or 'auto'\",\n 'choose one member of the CameraExposure union',\n );\n}\n\n/** Validate the Camera-owned white-balance and LUT authoring fields. */\nexport function validateCameraColorGrading(\n temperature: number,\n tint: number,\n colorLutStrength: number,\n): void {\n if (\n !Number.isFinite(temperature) ||\n temperature < CAMERA_TEMPERATURE_MIN ||\n temperature > CAMERA_TEMPERATURE_MAX\n ) {\n throw cameraError(\n 'camera-color-grading-invalid',\n 'temperature',\n temperature,\n `a finite value in [${CAMERA_TEMPERATURE_MIN}, ${CAMERA_TEMPERATURE_MAX}]`,\n 'set Camera.temperature to a supported Kelvin value',\n );\n }\n if (!Number.isFinite(tint) || tint < CAMERA_TINT_MIN || tint > CAMERA_TINT_MAX) {\n throw cameraError(\n 'camera-color-grading-invalid',\n 'tint',\n tint,\n `a finite value in [${CAMERA_TINT_MIN}, ${CAMERA_TINT_MAX}]`,\n 'set Camera.tint to a normalized value between -1 and 1',\n );\n }\n if (!Number.isFinite(colorLutStrength) || colorLutStrength < 0 || colorLutStrength > 1) {\n throw cameraError(\n 'camera-color-grading-invalid',\n 'colorLutStrength',\n colorLutStrength,\n 'a finite value in [0, 1]',\n 'set Camera.colorLutStrength to zero to disable the LUT or a blend in [0, 1]',\n );\n }\n}\n\n/**\n * Map a `camera.projection` numeric value to the closed `CameraProjection`\n * string-literal union. Values other than 0 / 1 fall back to `'perspective'`\n * (defensive for defaulted / uninitialised entities; charter proposition 4\n * no silent exception).\n */\nexport function cameraProjectionFromF32(value: number): CameraProjection {\n return value === CAMERA_PROJECTION_ORTHOGRAPHIC ? 'orthographic' : 'perspective';\n}\n\n/**\n * Tone-mapping mode discriminator literal union (AC-01 narrowing surface;\n * feat-20260519-tonemap-reinhard-mvp / M1).\n *\n * Two members for the MVP:\n * `'none'` - default; render-target stays `bgra8unorm-srgb`\n * and the geometry pass writes directly to the\n * swap-chain (zero-overhead opt-out path).\n * `'reinhard-extended'` - Forgeax Reinhard 2002 extended (luminance-domain)\n * opt-in;\n * `'reinhard'` - Three r184 per-channel Reinhard opt-in;\n * geometry pass routes through an `rgba16float`\n * HDR target and a fullscreen tonemap pass\n * (`packages/shader/src/tonemap.wgsl`).\n *\n * The remaining members mirror the Three r184 public names and formulas.\n */\nexport type Tonemap =\n | 'none'\n | 'reinhard-extended'\n | 'reinhard'\n | 'linear'\n | 'cineon'\n | 'aces-filmic'\n | 'agx'\n | 'neutral';\n\n/** Numeric encoding of the no-op tonemap path (schema value for `tonemap`). */\nexport const TONEMAP_NONE = TONEMAP_SHADER_MODE.none;\n/**\n * Numeric encoding of the Reinhard-extended tonemap path\n * (schema value for `tonemap`).\n */\nexport const TONEMAP_REINHARD_EXTENDED = TONEMAP_SHADER_MODE.reinhardExtended;\n/** Numeric encoding of the Three r184 per-channel Reinhard path. */\nexport const TONEMAP_REINHARD = TONEMAP_SHADER_MODE.reinhard;\n/** Numeric encoding of the linear (identity after exposure) tonemap path. */\nexport const TONEMAP_LINEAR = TONEMAP_SHADER_MODE.linear;\n/** Numeric encoding of the Cineon (Kodak log) tonemap path. */\nexport const TONEMAP_CINEON = TONEMAP_SHADER_MODE.cineon;\n/** Numeric encoding of the ACES filmic (Narkowicz 2015) tonemap path. */\nexport const TONEMAP_ACES_FILMIC = TONEMAP_SHADER_MODE.acesFilmic;\n/** Numeric encoding of the AgX (Troy Sobotka / Blender 3.x) tonemap path. */\nexport const TONEMAP_AGX = TONEMAP_SHADER_MODE.agx;\n/** Numeric encoding of the Khronos PBR neutral tonemap path. */\nexport const TONEMAP_NEUTRAL = TONEMAP_SHADER_MODE.neutral;\n\n/**\n * Map a `camera.tonemap` numeric value to the closed `Tonemap` string-literal\n * union. Unknown values fall back to `'none'` for defensive schema decoding.\n */\nexport function tonemapFromF32(value: number): Tonemap {\n switch (value) {\n case TONEMAP_REINHARD_EXTENDED:\n return 'reinhard-extended';\n case TONEMAP_REINHARD:\n return 'reinhard';\n case TONEMAP_LINEAR:\n return 'linear';\n case TONEMAP_CINEON:\n return 'cineon';\n case TONEMAP_ACES_FILMIC:\n return 'aces-filmic';\n case TONEMAP_AGX:\n return 'agx';\n case TONEMAP_NEUTRAL:\n return 'neutral';\n default:\n return 'none';\n }\n}\n\n/**\n * Inverse of {@link tonemapFromF32}: map the closed `Tonemap` string-literal\n * union to the u32 mode the tonemap WGSL `params.mode` switch reads. SSOT for\n * the mode encoding shared by the extract-stage built-in tonemap provider\n * (feat-20260621 M-A3 / w13: `Camera.tonemap` -> `forgeax::tonemap` 16B data)\n * and any other consumer. `'none'` maps to 0 (the tonemap pass never dispatches\n * on the LDR path, so 0 is only ever a placeholder).\n */\nexport function tonemapToU32(mode: Tonemap): number {\n switch (mode) {\n case 'reinhard-extended':\n return TONEMAP_REINHARD_EXTENDED;\n case 'reinhard':\n return TONEMAP_REINHARD;\n case 'linear':\n return TONEMAP_LINEAR;\n case 'cineon':\n return TONEMAP_CINEON;\n case 'aces-filmic':\n return TONEMAP_ACES_FILMIC;\n case 'agx':\n return TONEMAP_AGX;\n case 'neutral':\n return TONEMAP_NEUTRAL;\n case 'none':\n return TONEMAP_NONE;\n }\n throw cameraError(\n 'camera-tonemap-invalid',\n 'tonemap',\n mode,\n 'one of the closed Tonemap values',\n 'select a supported Camera tonemap mode',\n );\n}\n\n/**\n * Anti-alias mode discriminator literal union\n * (feat-20260528-fxaa-post-processing / w2;\n * feat-20260604-learn-render-4-10-anti-aliasing-msaa adds `'msaa'`).\n *\n * Four members:\n * `'none'` - default; no anti-aliasing (zero-overhead opt-out path)\n * `'fxaa'` - FXAA 3.11 fullscreen post-processing pass (screen-space, shading-aliasing)\n * `'msaa'` - 4x hardware multi-sample anti-aliasing (geometry-edge coverage).\n * Active on both HDR and LDR-swap-chain paths, so a default Camera\n * (`tonemap='none'`) with `antialias='msaa'` is NOT a silent no-op.\n * `'taa'` - temporal anti-aliasing; renderer temporal projection owns its\n * jitter and successful-submit history contract.\n *\n * MSAA and FXAA are orthogonal: MSAA resolves geometry-edge aliasing, FXAA\n * resolves shading/high-frequency aliasing. TAA is mutually exclusive with both.\n */\nexport type Antialias = 'none' | 'fxaa' | 'msaa' | 'taa';\n\n/** Numeric encoding of anti-alias disabled (schema value for `antialias`). */\nexport const ANTIALIAS_NONE = 0;\n/** Numeric encoding of FXAA anti-aliasing (schema value for `antialias`). */\nexport const ANTIALIAS_FXAA = 1;\n/** Numeric encoding of MSAA multi-sample anti-aliasing (schema value for `antialias`). */\nexport const ANTIALIAS_MSAA = 2;\n/** Numeric encoding of temporal anti-aliasing (schema value for `antialias`). */\nexport const ANTIALIAS_TAA = 3;\n\n/**\n * Map a `camera.antialias` numeric value to the closed `Antialias`\n * string-literal union. Invalid values fail-fast with structured error (charter P3).\n */\nexport function antialiasFromF32(value: number): Antialias {\n if (value === ANTIALIAS_NONE) return 'none';\n if (value === ANTIALIAS_FXAA) return 'fxaa';\n if (value === ANTIALIAS_MSAA) return 'msaa';\n if (value === ANTIALIAS_TAA) return 'taa';\n throw cameraError(\n 'camera-antialias-invalid',\n 'antialias',\n value,\n `${ANTIALIAS_NONE}, ${ANTIALIAS_FXAA}, ${ANTIALIAS_MSAA}, or ${ANTIALIAS_TAA}`,\n 'select a supported Camera antialias mode',\n );\n}\n\n/**\n * Bloom enabled discriminator literal union\n * (feat-20260531-bloom-first-declarative-render-graph-pass / w2).\n *\n * Two members:\n * `'off'` - default; no bloom post-processing (zero-overhead opt-out path)\n * `'on'` - bloom bright-pass + separable blur + composite pipeline\n *\n * Bloom is a discrete enum (0/1) — illegal values fail-fast with the closed\n * CameraError contract (charter P3), matching antialiasFromF32 precedent.\n */\nexport type BloomEnabled = 'off' | 'on';\n\n/** Numeric encoding of bloom disabled (schema value for `bloom`). */\nexport const BLOOM_DISABLED = 0;\n/** Numeric encoding of bloom enabled (schema value for `bloom`). */\nexport const BLOOM_ENABLED = 1;\n\n/**\n * Map a `camera.bloom` numeric value to the closed `BloomEnabled` string-literal\n * union. Invalid values fail-fast with structured error (charter P3).\n */\nexport function bloomEnabledFromF32(value: number): BloomEnabled {\n if (value === BLOOM_DISABLED) return 'off';\n if (value === BLOOM_ENABLED) return 'on';\n throw cameraError(\n 'camera-bloom-invalid',\n 'bloom',\n value,\n `${BLOOM_DISABLED} or ${BLOOM_ENABLED}`,\n 'select Camera bloom off or on',\n );\n}\n\n/**\n * Camera projection parameters (perspective + orthographic variants) +\n * tonemap trio (mode + exposure + whitePoint).\n *\n * Camera transform comes from the entity's `Transform` (AI users\n * spawn camera entities with both components: see example below).\n *\n * Defaults (do not auto-apply; spawn explicitly for the perspective quartet):\n * fov = pi/4 - 45-degree vertical field of view\n * aspect = 16/9 - widescreen aspect (use canvas.width / canvas.height)\n * near = 0.1\n * far = 100\n * projection = 0 - CAMERA_PROJECTION_PERSPECTIVE (layer-2)\n * left = -1, right = 1, bottom = -1, top = 1 (orthographic; layer-2)\n * tonemap = 0 - TONEMAP_NONE (layer-2; opt-in path stays\n * 0-overhead by default)\n * exposure = 1.0 - layer-2 default for the Reinhard-extended path\n * @applicableWhen tonemap === 'reinhard-extended'\n * whitePoint = 4.0 - layer-2 default for the Reinhard-extended path\n * @applicableWhen tonemap === 'reinhard-extended'\n * @minimum 0 (shader floor `max(Y, 1e-5)` keeps\n * the divisor finite even at 0; D-O3)\n * clearColor = [0, 0, 0, 0]\n * - feat-20260709 M3 / D-3: clear-color is one\n * inline `array<f32,4>` column (collapsed from the\n * feat-20260608 clearR/G/B/A quartet). Defaults to\n * transparent black; an explicit alpha remains\n * visible through this public field.\n *\n * MVP supports a single active camera (the first archetype iteration hit;\n * N>1 fires 'render-system-multi-camera' + uses first). Multi-viewport is\n * OOS (see feat-future-multi-viewport). The orthographic path reuses the\n * same near / far as the perspective path — both variants share the single\n * Camera archetype (17 scalar f32 columns + one historyVersion u32 column +\n * the `clearColor` array<f32,4> column + the `autoAspect` bool column).\n *\n * @example Perspective camera at (0, 0, 3) looking down -Z (zero-config tonemap):\n * world.spawn(\n * { component: Transform, data: {\n * pos: [0, 0, 3],\n * quat: [0, 0, 0, 1],\n * scale: [1, 1, 1],\n * } },\n * { component: Camera, data: {\n * fov: Math.PI / 4, aspect: 16 / 9, near: 0.1, far: 100,\n * } },\n * );\n * // tonemap defaults to 0 (TONEMAP_NONE) - 0-overhead path.\n *\n * @example Opt-in Reinhard-extended tonemap (high-intensity HDR scene):\n * world.spawn(\n * { component: Transform, data: { ... } },\n * { component: Camera, data: {\n * fov: Math.PI / 4, aspect: 16 / 9, near: 0.1, far: 100,\n * tonemap: TONEMAP_REINHARD_EXTENDED,\n * exposure: 1.0,\n * whitePoint: 4.0,\n * } },\n * );\n *\n * @example Orthographic camera spanning [-10, 10]^2 on the near plane:\n * world.spawn(\n * { component: Transform, data: {\n * pos: [0, 0, 5],\n * quat: [0, 0, 0, 1],\n * scale: [1, 1, 1],\n * } },\n * { component: Camera, data: {\n * fov: 0, aspect: 1, near: 0.1, far: 100,\n * projection: CAMERA_PROJECTION_ORTHOGRAPHIC,\n * left: -10, right: 10, bottom: -10, top: 10,\n * } },\n * );\n */\nexport const Camera = defineComponent('Camera', {\n fov: { type: 'f32' },\n aspect: { type: 'f32' },\n near: { type: 'f32' },\n far: { type: 'f32' },\n projection: { type: 'f32', default: 0 },\n left: { type: 'f32', default: -1 },\n right: { type: 'f32', default: 1 },\n bottom: { type: 'f32', default: -1 },\n top: { type: 'f32', default: 1 },\n tonemap: { type: 'f32', default: 0 },\n exposure: { type: 'f32', default: 1.0 },\n exposureMode: { type: 'f32', default: CAMERA_EXPOSURE_MODE_MANUAL },\n compensationEv: { type: 'f32', default: 0 },\n rangeEv: { type: 'array<f32, 2>', default: new Float32Array([-8, 8]) },\n rates: { type: 'array<f32, 2>', default: new Float32Array([3, 1]) },\n whitePoint: { type: 'f32', default: 4.0 },\n temperature: { type: 'f32', default: 6504 },\n tint: { type: 'f32', default: 0 },\n colorLut: { type: 'shared<TextureAsset>', default: 0 as never },\n colorLutStrength: { type: 'f32', default: 0 },\n antialias: { type: 'f32', default: 0 },\n historyVersion: { type: 'u32', default: 0 },\n bloom: { type: 'f32', default: 0 },\n bloomThreshold: { type: 'f32', default: 1.0 },\n bloomIntensity: { type: 'f32', default: 1.0 },\n bloomBlurRadius: { type: 'f32', default: 4.0 },\n // M1 target camera role: zero means this camera is eligible for display;\n // non-zero shared targets are auxiliary producers whose views and receipt\n // promotion remain owned by Renderer.\n target: { type: 'shared<RenderTarget>', simulationTransient: true },\n // feat-20260709 M3 / D-3: clear-color is one inline `array<f32,4>` column.\n // The earlier 4-scalar form (clearR/G/B/A) was chosen when this was believed\n // to be the only SoA-safe shape; the Transform (pos/quat/scale) and light\n // (direction/color) precedents disprove that -- an `array<f32,N>` IS an\n // inline stride-N SoA column, read on the hot path as `col[i*N+a]` with zero\n // allocation, so collapsing four scalars into one column removes three field\n // names a reader must track without changing the storage layout or read\n // pattern. The default `[0, 0, 0, 0]` is transparent black; explicit alpha\n // stays visible through the same public array field.\n clearColor: { type: 'array<f32, 4>', default: new Float32Array([0, 0, 0, 0]) },\n // feat-20260617-host-engine-contract-and-video-cutscene / M3 / D-4: the\n // aspect-sync sidecar on the createApp(canvas) path writes\n // canvas.width / canvas.height into `aspect` every frame when this flag is\n // true. Reuses the existing `bool` column tier (AnimationPlayer.paused /\n // AudioSource.playing precedent) -- zero ECS infrastructure change. Default\n // true so demos that never touch aspect track the canvas automatically\n // (charter P1 default-is-correct); set false for render-to-texture /\n // split-screen cameras that drive aspect themselves. Read it via\n // world.get (readRow narrows bool -> JS boolean); the query-bundle path\n // returns a raw 0/1 number (the `!== 0` always-true trap).\n autoAspect: { type: 'bool', default: true },\n});\n\n// ─── Camera POD type (derived from Camera token — single source, AC-07) ─────\n//\n// ShapeOf<SchemaOf<typeof Camera>> resolves the 20-field POD from the Camera\n// token's schema, which is itself derived from Camera.fields[k].type (D-A7).\n// This replaces the hand-maintained CameraDataPod interface — the field set\n// lives exclusively in the Camera component definition above.\nexport type CameraData = ShapeOf<SchemaOf<typeof Camera>>;\ntype CameraPod = CameraData;\n\n/** Project the Camera SoA columns back into the public closed union. */\nexport function cameraExposureFromColumns(\n input: Pick<CameraData, 'exposureMode' | 'exposure' | 'compensationEv' | 'rangeEv' | 'rates'>,\n): CameraExposure {\n if (input.exposureMode === CAMERA_EXPOSURE_MODE_MANUAL) {\n return validateCameraExposure({ kind: 'manual', multiplier: input.exposure });\n }\n if (input.exposureMode === CAMERA_EXPOSURE_MODE_AUTO) {\n return validateCameraExposure({\n kind: 'auto',\n fallback: input.exposure,\n compensationEv: input.compensationEv,\n rangeEv: [input.rangeEv[0] ?? -8, input.rangeEv[1] ?? 8],\n rates: [input.rates[0] ?? 3, input.rates[1] ?? 1],\n });\n }\n throw cameraError(\n 'camera-exposure-mode-invalid',\n 'exposureMode',\n input.exposureMode,\n `${CAMERA_EXPOSURE_MODE_MANUAL} or ${CAMERA_EXPOSURE_MODE_AUTO}`,\n 'set Camera.exposureMode to the manual or auto encoding',\n );\n}\n\nfunction cameraExposureColumns(\n exposure: CameraExposure,\n): Pick<CameraData, 'exposureMode' | 'exposure' | 'compensationEv' | 'rangeEv' | 'rates'> {\n const checked = validateCameraExposure(exposure);\n if (checked.kind === 'manual') {\n return {\n exposureMode: CAMERA_EXPOSURE_MODE_MANUAL,\n exposure: checked.multiplier,\n compensationEv: 0,\n rangeEv: new Float32Array([-8, 8]),\n rates: new Float32Array([3, 1]),\n };\n }\n return {\n exposureMode: CAMERA_EXPOSURE_MODE_AUTO,\n exposure: checked.fallback,\n compensationEv: checked.compensationEv,\n rangeEv: new Float32Array(checked.rangeEv),\n rates: new Float32Array(checked.rates),\n };\n}\n\ninterface CameraColorGradingOpts {\n exposure?: CameraExposure;\n temperature?: number;\n tint?: number;\n colorLut?: CameraPod['colorLut'];\n colorLutStrength?: number;\n}\n\nfunction cameraColorGradingColumns(\n opts: CameraColorGradingOpts,\n): ReturnType<typeof cameraExposureColumns> &\n Pick<CameraData, 'temperature' | 'tint' | 'colorLut' | 'colorLutStrength'> {\n const exposure = opts.exposure ?? { kind: 'manual', multiplier: 1 };\n const temperature = opts.temperature ?? 6504;\n const tint = opts.tint ?? 0;\n const colorLutStrength = opts.colorLutStrength ?? 0;\n validateCameraColorGrading(temperature, tint, colorLutStrength);\n return {\n ...cameraExposureColumns(exposure),\n temperature,\n tint,\n colorLut: opts.colorLut ?? (0 as CameraPod['colorLut']),\n colorLutStrength,\n };\n}\n\n// ─── Camera factory functions (w13 SSOT refactoring) ─────────────────────\n//\n// Standalone factory functions that return 20-field CameraPod objects\n// matching the Camera component column shape. Not static methods because\n// TypeScript const-namespace merge is not supported, and Object.assign\n// would break the Camera token's reference identity (archetype columns /\n// queries key off the global owner identity associated with the token).\n//\n// Import as:\n// import { Camera, perspective, orthographic } from '@forgeax/engine-render';\n// world.spawn({ component: Camera, data: perspective({ fov: 60, aspect: 4/3 }) });\n//\n// Charter P1 progressive disclosure: Barrel re-exports put perspective\n// / orthographic next to Camera in IDE autocomplete.\n//\n// D-A4 factory retention reason: perspective() / orthographic() carry\n// required/optional parameter semantics that cannot be derived from\n// the schema. perspective requires fov + aspect (no universal default),\n// orthographic requires left/right/bottom/top. The schema/defaults system\n// only records type + optional default value per field — it has no concept\n// of \"this field MUST be supplied by the caller.\" The factories encode\n// that contract at the TypeScript type level, which schema/defaults alone\n// cannot express. Per AC-07, the factories are kept; only the POD type\n// and default literals are derived from the Camera token (SSOT).\n\ninterface CameraPerspectiveOpts {\n fov: number;\n aspect: number;\n near?: number;\n far?: number;\n /**\n * feat-20260617-host-engine-contract-and-video-cutscene / M3: when true\n * (the schema default), the aspect-sync sidecar on the createApp(canvas)\n * path overwrites `aspect` with `canvas.width / canvas.height` every frame.\n * Omit it for the default-correct behaviour; set `false` to opt out (the\n * factory then leaves `aspect` under your control -- render-to-texture,\n * split-screen). Cameras built on the bare `createRenderer` path never\n * receive aspect-sync regardless of this flag.\n */\n autoAspect?: boolean;\n exposure?: CameraExposure;\n temperature?: number;\n tint?: number;\n colorLut?: CameraPod['colorLut'];\n colorLutStrength?: number;\n}\n\ninterface CameraOrthographicOpts {\n left: number;\n right: number;\n bottom: number;\n top: number;\n near?: number;\n far?: number;\n exposure?: CameraExposure;\n temperature?: number;\n tint?: number;\n colorLut?: CameraPod['colorLut'];\n colorLutStrength?: number;\n}\n\n/**\n * Build a CameraPod base from Camera.fields defaults (per-field SSOT).\n * Fields without a default (fov / aspect / near / far — OOS-5) are left\n * unset; caller fills them from opts or sentinel values.\n */\nfunction cameraPodFromDefaults(): CameraPod {\n const base: Record<string, unknown> = {};\n for (const [key, field] of Object.entries(Camera.fields)) {\n if ('default' in field && field.default !== undefined) {\n base[key] = field.default;\n }\n }\n return base as CameraPod;\n}\n\n/**\n * Convenience factory: perspective CameraData POD.\n *\n * `fov` and `aspect` are required (no sensible universal default).\n * `near` defaults to 0.1, `far` defaults to 100.\n * Orthographic quartet defaults to [-1, 1]x[-1, 1]; tonemap defaults to\n * TONEMAP_NONE (0-overhead path).\n *\n * When `autoAspect` is `true` (the default once shipped in M3), the\n * aspect-sync sidecar on the `createApp(canvas)` path automatically writes\n * `canvas.width / canvas.height` into `Camera.aspect` every frame. Set\n * `autoAspect = false` to opt out (render-to-texture, split-screen).\n * Cameras on the `createRenderer` path do not receive aspect-sync.\n *\n * @see {@link https://github.com/Ubpa/forgeax-engine/blob/main/docs/how-to/2026-06-18-host-engine-contract.md | Host-engine contract SSOT}\n *\n * @example\n * ```ts\n * import { Camera, perspective } from '@forgeax/engine-render';\n * world.spawn(\n * { component: Camera, data: perspective({ fov: Math.PI / 3, aspect: 4 / 3 }) }\n * ).unwrap();\n * ```\n *\n * @example With explicit near/far:\n * ```ts\n * const camData = perspective({ fov: Math.PI / 4, aspect: 16 / 9, near: 0.01, far: 1000 });\n * world.spawn({ component: Camera, data: camData }).unwrap();\n * ```\n *\n * @example With non-default clear color (default is `[0, 0, 0, 0]`).\n * `clearColor` is an inline `array<f32,4>` field on `Camera`; spread the\n * factory then override:\n * ```ts\n * world.spawn({\n * component: Camera,\n * data: { ...perspective({ fov: Math.PI / 3, aspect: 4 / 3 }), clearColor: [0, 1, 0, 1] },\n * }).unwrap();\n * ```\n */\nexport function perspective(opts: CameraPerspectiveOpts): CameraPod {\n return {\n // cameraPodFromDefaults() reads autoAspect's schema default (true), so an\n // omitted opts.autoAspect lands the default-correct value; an explicit\n // false overrides it below (D-4: factory one-step opt-out, charter P1).\n ...cameraPodFromDefaults(),\n fov: opts.fov,\n aspect: opts.aspect,\n near: opts.near ?? 0.1,\n far: opts.far ?? 100,\n projection: CAMERA_PROJECTION_PERSPECTIVE,\n ...(opts.autoAspect !== undefined ? { autoAspect: opts.autoAspect } : {}),\n ...cameraColorGradingColumns(opts),\n };\n}\n\n/**\n * Convenience factory: orthographic CameraData POD.\n *\n * All four ortho bounds (`left` / `right` / `bottom` / `top`) are required.\n * `near` defaults to 0.1, `far` defaults to 100.\n * Perspective fields get sentinel defaults (fov=0, aspect=1) for column\n * alignment with the 12-field schema.\n *\n * @example\n * ```ts\n * import { Camera, orthographic } from '@forgeax/engine-render';\n * world.spawn(\n * { component: Camera, data: orthographic({\n * left: -10, right: 10, bottom: -10, top: 10,\n * }) }\n * ).unwrap();\n * ```\n *\n * @example Screen-aligned orthographic for pixel-unit rendering:\n * ```ts\n * const camData = orthographic({ left: 0, right: 800, bottom: 600, top: 0 });\n * world.spawn({ component: Camera, data: camData }).unwrap();\n * ```\n */\nexport function orthographic(opts: CameraOrthographicOpts): CameraPod {\n return {\n ...cameraPodFromDefaults(),\n fov: 0,\n aspect: 1,\n near: opts.near ?? 0.1,\n far: opts.far ?? 100,\n projection: CAMERA_PROJECTION_ORTHOGRAPHIC,\n left: opts.left,\n right: opts.right,\n bottom: opts.bottom,\n top: opts.top,\n ...cameraColorGradingColumns(opts),\n };\n}\n","// @forgeax/engine-render - CubeCamera capture vocabulary.\n//\n// CubeCamera is an ECS capture intent paired with Transform. GPU resources,\n// face views, completed-receipt promotion, and publication remain renderer-owned.\n\nimport { defineComponent, type SchemaOf, type ShapeOf } from '@forgeax/engine-ecs';\nimport { RenderIntentInvalidError } from '../errors/render';\n\nexport const CUBE_CAMERA_UPDATE_ONCE = 0;\nexport const CUBE_CAMERA_UPDATE_ON_DEMAND = 1;\nexport const CUBE_CAMERA_UPDATE_CONTINUOUS = 2;\n\nexport type CubeCameraUpdateIntent = 'once' | 'on-demand' | 'continuous';\n\nexport const CUBE_CAMERA_FACE_ORDER = ['+X', '-X', '+Y', '-Y', '+Z', '-Z'] as const;\nexport type CubeCameraFace = (typeof CUBE_CAMERA_FACE_ORDER)[number];\n\nexport function cubeCameraUpdateIntentFromF32(value: number): CubeCameraUpdateIntent {\n switch (value) {\n case CUBE_CAMERA_UPDATE_ONCE:\n return 'once';\n case CUBE_CAMERA_UPDATE_ON_DEMAND:\n return 'on-demand';\n case CUBE_CAMERA_UPDATE_CONTINUOUS:\n return 'continuous';\n default:\n throw new RenderIntentInvalidError('CubeCamera', value);\n }\n}\n\nexport function cubeCameraUpdateIntentToF32(intent: CubeCameraUpdateIntent): number {\n switch (intent) {\n case 'once':\n return CUBE_CAMERA_UPDATE_ONCE;\n case 'on-demand':\n return CUBE_CAMERA_UPDATE_ON_DEMAND;\n case 'continuous':\n return CUBE_CAMERA_UPDATE_CONTINUOUS;\n }\n}\n\n/** ECS declaration for a bounded, transient six-face capture request. */\nexport const CubeCamera = defineComponent('CubeCamera', {\n target: { type: 'shared<RenderTarget>', simulationTransient: true },\n near: { type: 'f32', default: 0.1 },\n far: { type: 'f32', default: 100 },\n updateIntent: { type: 'f32', default: CUBE_CAMERA_UPDATE_ONCE },\n requestVersion: { type: 'u32', default: 0 },\n faceBudget: { type: 'u32', default: 1 },\n});\n\nexport type CubeCameraData = ShapeOf<SchemaOf<typeof CubeCamera>>;\n","import { defineComponent, type SchemaOf, type ShapeOf } from '@forgeax/engine-ecs';\n\n/** Closed quality budget used by the built-in camera depth-of-field pass. */\nexport type DepthOfFieldQuality = 'low' | 'medium' | 'high';\n\nexport const DepthOfFieldQualityValue = Object.freeze({\n low: 0,\n medium: 1,\n high: 2,\n} as const);\n\n/** Selects which signed circle-of-confusion side contributes to the image. */\nexport type DepthOfFieldSide = 'both' | 'near' | 'far';\n\nexport const DepthOfFieldSideValue = Object.freeze({\n both: 0,\n near: 1,\n far: 2,\n} as const);\n\n/** Active-camera physical depth-of-field authoring data; presence enables it. */\nexport const DepthOfField = defineComponent('DepthOfField', {\n focusDistance: { type: 'f32', default: 8 },\n fStop: { type: 'f32', default: 2.8 },\n sensorHeight: { type: 'f32', default: 0.024 },\n maxRadiusPixels: { type: 'f32', default: 16 },\n quality: { type: 'f32', default: DepthOfFieldQualityValue.medium },\n blurSide: { type: 'f32', default: DepthOfFieldSideValue.both },\n});\n\nexport type DepthOfFieldData = ShapeOf<SchemaOf<typeof DepthOfField>>;\n\nexport function depthOfFieldQualityFromF32(value: number): DepthOfFieldQuality | undefined {\n if (value === DepthOfFieldQualityValue.low) return 'low';\n if (value === DepthOfFieldQualityValue.medium) return 'medium';\n if (value === DepthOfFieldQualityValue.high) return 'high';\n return undefined;\n}\n\nexport function depthOfFieldSideFromF32(value: number): DepthOfFieldSide | undefined {\n if (value === DepthOfFieldSideValue.both) return 'both';\n if (value === DepthOfFieldSideValue.near) return 'near';\n if (value === DepthOfFieldSideValue.far) return 'far';\n return undefined;\n}\n","// @forgeax/engine-render - closed Directional shadow filter vocabulary.\n\n/** Stable serialized labels for Directional shadow filtering. */\nexport const DirectionalShadowFilterValue = Object.freeze({\n pcf1: 1,\n pcf3: 2,\n pcf5: 3,\n pcssMedium: 4,\n pcssHigh: 5,\n} as const);\n\nexport type DirectionalShadowFilterLabel = keyof typeof DirectionalShadowFilterValue;\n\n/**\n * Extract-side semantic projection of the serialized Directional filter.\n * `shadowAngularRadius` is radians and `maxPenumbraTexels` is a finite integer.\n */\nexport type DirectionalShadowQuality =\n | { readonly kind: 'pcf'; readonly kernel: 1 | 3 | 5 }\n | {\n readonly kind: 'pcss';\n readonly preset: 'medium' | 'high';\n readonly angularRadiusRadians: number;\n readonly maxPenumbraTexels: number;\n };\n\n/** Resolve the closed serialized label to the receiver-facing semantic union. */\nexport function directionalShadowQualityFromF32(\n value: number,\n angularRadiusRadians: number,\n maxPenumbraTexels: number,\n): DirectionalShadowQuality | undefined {\n switch (value) {\n case DirectionalShadowFilterValue.pcf1:\n return { kind: 'pcf', kernel: 1 };\n case DirectionalShadowFilterValue.pcf3:\n return { kind: 'pcf', kernel: 3 };\n case DirectionalShadowFilterValue.pcf5:\n return { kind: 'pcf', kernel: 5 };\n case DirectionalShadowFilterValue.pcssMedium:\n return {\n kind: 'pcss',\n preset: 'medium',\n angularRadiusRadians,\n maxPenumbraTexels,\n };\n case DirectionalShadowFilterValue.pcssHigh:\n return {\n kind: 'pcss',\n preset: 'high',\n angularRadiusRadians,\n maxPenumbraTexels,\n };\n default:\n return undefined;\n }\n}\n","// @forgeax/engine-render - DirectionalLight (directional light parameters\n// with merged shadow config).\n//\n// Schema: direction array<f32,3> + color array<f32,3> + intensity f32 + 1 bool\n// castShadow + 8 f32 shadow columns (feat-20260709 M2: direction/color collapsed\n// from 6 per-axis scalar columns to two inline array<f32,3> columns).\n//\n// Direction (xyz, outgoing) + color (rgb, linear space) + intensity in lux.\n// No Transform dependency (directional lights have no position).\n// The public world-unit convention is 1 world unit = 1 meter. Exposure is a\n// camera output concern and is not folded into this light's intensity.\n//\n// 0 DirectionalLight + standard material -> physically correct black render\n// (charter v2 P3/P4); details: AGENTS.md section Breaking changes 2026-05-18.\n//\n// Naming convention: bare entity name aligned with Bevy ECS conventions\n// (feat-20260513-component-naming-bevy-align). Camera / Transform / etc.\n// follow the same single-semantic-entity rule (charter proposition 5).\n//\n// charter mapping: proposition 1 (single import) + proposition 3 (silent\n// failure -> explicit warning; first-frame warn) + proposition 5 (consistent\n// abstraction: lighting parameters mirror GPU-side pbr.wgsl @group(0) view\n// BG light fields).\n//\n// feat-20260621-merge-directionallightshadow-into-directionallight M1:\n// DirectionalLightShadow's 9 shadow fields are merged into DirectionalLight\n// to collapse the dual-component spawn into a single component (D-6 primary\n// decision). castShadow defaults to true so zero-config spawns get shadows\n// by default; set castShadow=false to opt out. D-6 directional stays\n// first-hit-wins -- no ECS cardinality cap. Renderer allocation policy stays\n// with the shadow atlas owner.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\nimport { DirectionalShadowFilterValue } from './directional-shadow-filter';\n\nexport {\n type DirectionalShadowFilterLabel,\n DirectionalShadowFilterValue,\n type DirectionalShadowQuality,\n directionalShadowQualityFromF32,\n} from './directional-shadow-filter';\n\n/**\n * Directional light (sun-like infinite light source) with merged shadow\n * parameters.\n *\n * `direction` @semantics outgoing — points FROM light source TO surface\n * (opposite of Three.js convention; the shader internally negates this\n * vector to obtain the L vector for BRDF evaluation). `color` is\n * linear-space rgb in [0, 1] per channel and `intensity` is lux. Exposure is\n * applied after lighting by the camera output stage; no hidden light\n * multiplier is applied here.\n *\n * castShadow defaults to true — zero-config spawns cast cascaded shadow maps.\n * Set castShadow: false to opt out (shadow fields are still stored but their\n * validation is skipped).\n *\n * Shadow fields (migrated from DirectionalLightShadow, feat-20260621 M1):\n * cascadeCount ∈ {1,2,3,4} — number of cascades (default 4)\n * splitLambda ∈ [0,1] — PSSM split weight (default 0.75)\n * cascadeBlend ∈ [0,0.5] — blend width between cascades (default 0.2)\n * mapSize >= 1 — shadow map resolution (default 2048)\n * depthBias — normalized receiver depth floor (default 0.00001),\n * plus automatic texel/filter/slope coverage\n * normalBias — world-space receiver normal offset (default 0.05)\n * shadowDistance > 0 — how far shadows reach in front of the camera,\n * in world units (default 200). This is the sole\n * coverage knob: the CSM cascades are PSSM-split\n * across [camera near, shadowDistance] and each\n * cascade's orthographic bounds are fit to the\n * camera frustum slice automatically. The near\n * end is derived from the active camera's near\n * plane (no separate near knob — any value other\n * than the camera near either drops near shadows\n * or wastes cascade-0 resolution).\n * shadowFilter ∈ {pcf1, pcf3, pcf5, pcssMedium, pcssHigh} — closed filter profile (default pcf3)\n * shadowAngularRadius ∈ [0.0001, 0.05] radians — PCSS angular light radius (default 0.00465)\n * maxPenumbraTexels ∈ [1, 64], finite integer — PCSS search/filter cap (default 32)\n *\n * @example Spawn a single directional light with default shadows:\n * world.spawn({ component: DirectionalLight, data: {\n * direction: [-0.5, -1, -0.3], // [x, y, z]\n * color: [1, 1, 1], // [r, g, b]\n * intensity: 1,\n * } });\n *\n * @example Opt out of shadows:\n * world.spawn({ component: DirectionalLight, data: {\n * direction: [0, -1, 0], // [x, y, z]\n * castShadow: false,\n * } });\n *\n * @example Explicit shadow config (single-component spawn):\n * world.spawn({ component: DirectionalLight, data: {\n * direction: [0.2, -0.98, 0], // [x, y, z]\n * color: [1, 1, 1], intensity: 1, // color is [r, g, b]\n * cascadeCount: 4, splitLambda: 0.75, cascadeBlend: 0.2,\n * mapSize: 2048, shadowDistance: 200,\n * shadowFilter: DirectionalShadowFilterValue.pcssHigh,\n * shadowAngularRadius: 0.00465, maxPenumbraTexels: 32,\n * } });\n * // shadowFilter uses the numeric DirectionalShadowFilterValue constant,\n * // not the serialized label string 'pcssHigh'.\n *\n * @example 0-light scene must use an unlit shader (standard 0 light = physically correct black):\n * const world = new World();\n * // ... spawn cube + camera, no light ...\n * await renderer.ready;\n * renderer.draw(world); // standard material renders black; switch to an unlit shader (Materials.unlit(...)) for an unlit display\n */\nexport const DirectionalLight = defineComponent('DirectionalLight', {\n // direction is the ONLY field with no default (D-5): omitting it lands the\n // array layer-3 all-zero [0,0,0], which the renderer owner rejects -- there is no\n // universal default direction, so \"default is illegal\" forces an explicit\n // non-zero value. color carries an explicit layer-2 default [1,1,1] (white);\n // the array layer-3 fallback is all-zero, so the default MUST be explicit.\n direction: { type: 'array<f32, 3>' },\n color: { type: 'array<f32, 3>', default: new Float32Array([1, 1, 1]) },\n intensity: { type: 'f32', default: 1 },\n // Shadow opt-out gate: defaults to true so zero-config spawns get shadows.\n castShadow: { type: 'bool', default: true },\n // 9 shadow fields migrated from DirectionalLightShadow (feat-20260621 M1).\n cascadeCount: { type: 'f32', default: 4 },\n splitLambda: { type: 'f32', default: 0.75 },\n cascadeBlend: { type: 'f32', default: 0.2 },\n mapSize: { type: 'f32', default: 2048 },\n depthBias: { type: 'f32', default: 0.00001 },\n normalBias: { type: 'f32', default: 0.05 },\n // Sole shadow coverage knob (feat replaces nearPlane/farPlane). The PSSM\n // near end derives from the active camera near; shadowDistance is the far\n // reach. Default 200 world units (matches UE-style \"dynamic shadow\n // distance\"; the old farPlane default was 50).\n shadowDistance: { type: 'f32', default: 200 },\n shadowFilter: {\n type: 'enum',\n default: DirectionalShadowFilterValue.pcf3,\n labels: DirectionalShadowFilterValue,\n },\n shadowAngularRadius: { type: 'f32', default: 0.00465 },\n maxPenumbraTexels: { type: 'f32', default: 32 },\n});\n","import { defineComponent, type SchemaOf, type ShapeOf } from '@forgeax/engine-ecs';\nimport { err, ok, type Result } from '@forgeax/engine-types';\nimport {\n type DynamicResolutionError,\n DynamicResolutionInvalidParameterError,\n DynamicResolutionRequiresTaaError,\n} from '../errors/render';\n\n/** Optional Camera companion that enables fixed or adaptive internal scaling. */\nexport const DynamicResolution = defineComponent('DynamicResolution', {\n targetGpuMs: { type: 'f32', default: 16.67 },\n minScale: { type: 'f32', default: 0.67 },\n maxScale: { type: 'f32', default: 1.0 },\n});\n\nexport type DynamicResolutionData = ShapeOf<SchemaOf<typeof DynamicResolution>>;\n\nconst DEFAULT_DYNAMIC_RESOLUTION: DynamicResolutionData = Object.freeze({\n targetGpuMs: 16.67,\n minScale: 0.67,\n maxScale: 1,\n});\n\nfunction invalid(\n field: 'targetGpuMs' | 'minScale' | 'maxScale',\n value: number,\n expected: string,\n): DynamicResolutionInvalidParameterError {\n return new DynamicResolutionInvalidParameterError({ field, value, expected });\n}\n\n/** Validate one detached DynamicResolution authoring POD before graph work. */\nexport function validateDynamicResolutionParameters(\n input: Partial<DynamicResolutionData> | undefined,\n): Result<DynamicResolutionData, DynamicResolutionInvalidParameterError> {\n const value = input ?? {};\n const targetGpuMs = value.targetGpuMs ?? DEFAULT_DYNAMIC_RESOLUTION.targetGpuMs;\n const minScale = value.minScale ?? DEFAULT_DYNAMIC_RESOLUTION.minScale;\n const maxScale = value.maxScale ?? DEFAULT_DYNAMIC_RESOLUTION.maxScale;\n if (!Number.isFinite(targetGpuMs) || targetGpuMs <= 0) {\n return err(invalid('targetGpuMs', targetGpuMs, 'finite and greater than 0'));\n }\n if (!Number.isFinite(minScale) || minScale < 0.5 || minScale > 1) {\n return err(invalid('minScale', minScale, 'finite and in [0.5, 1.0]'));\n }\n if (!Number.isFinite(maxScale) || maxScale < 0.5 || maxScale > 1) {\n return err(invalid('maxScale', maxScale, 'finite and in [0.5, 1.0]'));\n }\n if (minScale > maxScale) {\n return err(invalid('minScale', minScale, 'less than or equal to maxScale'));\n }\n return ok(Object.freeze({ targetGpuMs, minScale, maxScale }));\n}\n\n/** Validate the Camera companion relationship at the extraction boundary. */\nexport function validateDynamicResolutionCamera(\n input: Partial<DynamicResolutionData> | undefined,\n antialias: 'none' | 'fxaa' | 'msaa' | 'taa',\n): Result<DynamicResolutionData | undefined, DynamicResolutionError> {\n if (input === undefined) return ok(undefined);\n const parameters = validateDynamicResolutionParameters(input);\n if (!parameters.ok) return parameters;\n if (antialias !== 'taa') {\n return err(new DynamicResolutionRequiresTaaError({ antialias }));\n }\n return parameters;\n}\n","import { defineComponent } from '@forgeax/engine-ecs';\n\n/** Optional height-aware aerial fog, independent from environment source. */\nexport const Fog = defineComponent('Fog', {\n color: { type: 'array<f32, 3>', default: new Float32Array([0.5, 0.5, 0.5]) },\n density: { type: 'f32', default: 0.01 },\n heightFalloff: { type: 'f32', default: 0 },\n maxOpacity: { type: 'f32', default: 1 },\n});\n","// @forgeax/engine-render - renderer-owned large instance association.\n//\n// The ECS component deliberately carries only a stable collection identity.\n// Matrix bytes, revision, capacity, dirty ranges, GPU residency and fallback\n// policy belong to InstanceCollectionStore, exposed from the same Renderer.\n// This keeps large payloads out of the ECS managed BufferPool while retaining\n// ordinary query and entity-lifetime semantics.\n//\n// Authoring example:\n//\n// const transforms = new Float32Array(instanceCount * 16);\n// for (let index = 0; index < instanceCount; index += 1) {\n// const offset = index * 16;\n// transforms[offset] = 1;\n// transforms[offset + 5] = 1;\n// transforms[offset + 10] = 1;\n// transforms[offset + 15] = 1;\n// }\n// const collection = renderer.instances.create({\n// transforms,\n// }).unwrap();\n// world.spawn(\n// { component: MeshFilter, data: { assetHandle: HANDLE_CUBE } },\n// { component: MeshRenderer, data: {} },\n// { component: Instances, data: { collectionId: collection.collectionId } },\n// );\n//\n// Updates stay on the renderer owner and publish one revision:\n//\n// renderer.instances.update(collection.collectionId, {\n// start: 12,\n// transforms: patch,\n// });\n//\n// Render extraction snapshots the validated packed column-major matrices once\n// per frame. Direct, GPU-driven and fallback lanes consume that same detached\n// projection; callers never split one logical collection into ECS chunks.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\nimport type { InstanceCollectionData } from '../instances';\n\n/** Per-entity association with a renderer-owned instance collection. */\nexport const Instances = defineComponent('Instances', {\n collectionId: { type: 'u32', default: 0 },\n});\n\n/** Type-level hint for the `data` object at the Instances spawn site. */\nexport type InstancesData = InstanceCollectionData;\n\nexport type { InstanceCollectionId } from '../instances';\n","// @forgeax/engine-render - Layer (render-order layer index, signed 32-bit).\n//\n// Schema: 1 i32 column (value). Signed two's complement so negatives travel\n// through the spawn payload unchanged — background sprites live at negative\n// values (e.g. -100), the default game layer at 0, foreground at 100, UI at\n// 1000. Layer is consumed at sort time by `transparent-sort.ts` (M-3 w23)\n// as the primary key in the (layer asc, sortValue asc) composite ordering.\n//\n// Naming convention: bare entity name (no Component suffix; single-semantic\n// component idiom aligned with Bevy ECS conventions — Transform / Camera /\n// DirectionalLight follow the same shape, see AGENTS.md §Component naming).\n//\n// Layer is a generic ECS renderer component — NOT a 2D-only special. 3D\n// entities may also carry Layer to bias their bucket placement (charter\n// P4 consistent abstraction: same component drives both pipelines).\n//\n// AC-18 path (1): an entity spawned without an explicit Layer reads back\n// 0 via the existing 4-layer spawn fallback chain\n// (feat-20260517-spawn-default-fallback). This feat does NOT introduce a\n// fifth fallback layer; the silent default flows through layer-3\n// `typeDefault('i32') === 0`.\n//\n// @derives defineComponent factory (packages/ecs/src/component.ts) — i32\n// is a legacy scalar type; its intrinsic properties (byteSize / viewCtor\n// / storage) live in TYPE_METADATA['i32'] (feat-20260602 M1).\n// @reuses spawn 4-layer fallback chain (feat-20260517-spawn-default-fallback)\n// — layer-3 typeDefault('i32') returns 0, no fifth layer.\n//\n// charter mapping: F1 (single-import barrel discovery — Layer joins\n// Transform / MeshFilter / MeshRenderer / Camera / DirectionalLight)\n// + P3 (explicit default — 0 surfaces as a read-back value, not undefined)\n// + P4 (consistent abstraction — Layer is a generic render component, not\n// a 2D-only special).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Render-order layer index.\n *\n * Convention (non-binding; conveys intent, not enforced):\n * - negative (e.g. -100): background layers (sky / parallax tiles).\n * - 0: default game layer.\n * - positive (e.g. 100): foreground layers (overlays, FX).\n * - 1000+: UI / HUD.\n *\n * Signed i32 (two's complement, range \\u00b12\\u00b3\\u00b9). Negatives round-trip\n * through the spawn payload unchanged — no schema-layer mutate. i32 lives in\n * the CPU sort path (transparent-sort.ts M-3 w23); no GPU-side stride\n * compatibility risk.\n *\n * @example Minimal spawn (defaults to game layer 0):\n * world.spawn({ component: Layer, data: {} }); // yields value=0\n *\n * @example Spawn 4 sprites across the conventional layer band:\n * world.spawn({ component: Layer, data: { value: -100 } }); // background\n * world.spawn({ component: Layer, data: { value: 0 } }); // default\n * world.spawn({ component: Layer, data: { value: 100 } }); // foreground\n * world.spawn({ component: Layer, data: { value: 1000 } }); // UI\n *\n * @example Spawn payload omitting Layer — the 4-layer fallback fills 0:\n * const e = world.spawn(\n * { component: Transform, data: { pos: [0, 0, 0],\n * quat: [0, 0, 0, 1], scale: [1, 1, 1] } },\n * );\n * // Layer is not on the entity; query joins must check membership.\n */\nexport const Layer = defineComponent('Layer', {\n value: { type: 'i32', default: 0 },\n});\n","// @forgeax/engine-render - host-side light helpers (M2 / w12).\n//\n// Pure-function single-shot conversion helpers for the SpotLight + PointLight\n// extract path. Host calls each helper once per light entity per frame; the\n// shader then sees only pre-computed `cos*` / `invRangeSquared` values. The\n// runtime range owner is the revision-pinned Three r184 squared window; KHR\n// values remain an import/reference boundary and are not substituted here.\n//\n// AC anchors: requirements AC-03 (deg -> rad -> cos host two-step\n// conversion) + AC-08 (a + b) (KHR quartic + range = 0 NaN protection\n// boundary).\n//\n// Plan-strategy anchors: D-S2 (cone unit deg API + cos shader optimization\n// transparent to AI users) + D-S5 (Layer 1 host-side range = 0 ->\n// invRangeSquared = 1e8 protects the 0 * Infinity = NaN intermediate).\n\nimport { err, ok, R_MIN, type Result } from '@forgeax/engine-types';\nimport { SpawnLightInvalidBoundsError } from '../errors/ecs-validation';\nimport { ShadowInvalidConfigError } from '../errors/render';\nimport { DirectionalShadowFilterValue } from './directional-shadow-filter';\n\nexport type LightValidationError = SpawnLightInvalidBoundsError | ShadowInvalidConfigError;\nexport type LightValidationResult = Result<void, LightValidationError>;\n\nconst RANGE_ZERO_FALLBACK_INV_R2 = 1e8;\nconst DEG_TO_RAD = Math.PI / 180;\nconst PCSS_RADIUS_MIN = 0.0001;\nconst PCSS_RADIUS_MAX = 0.05;\nconst PCSS_PENUMBRA_MIN = 1;\nconst PCSS_PENUMBRA_MAX = 64;\n\n/**\n * Convert SpotLight cone half-angle (degrees) to its cosine.\n *\n * Single-shot deg -> rad -> cos conversion executed once per spot light\n * entity per frame on the host; the GPU shader sees only `cosInner` /\n * `cosOuter` so its falloff path stays branch-free\n * (`smoothstep(cosOuter, cosInner, dot(L, -lightDir))`).\n *\n * @param deg cone half-angle in degrees (component schema field\n * `innerConeDeg` / `outerConeDeg`)\n * @returns `cos(deg * pi / 180)`\n */\nexport function degToCos(deg: number): number {\n return Math.cos(deg * DEG_TO_RAD);\n}\n\n/**\n * Convert PointLight / SpotLight `range` (meters) to `1 / range^2`.\n *\n * Three-branch fold supplies `1 / range^2` for the Three r184 finite-range\n * window `clamp(1 - (d / range)^4, 0, 1)^2`:\n *\n * - `range = +Infinity` -> `0` (no truncation; quartic factor collapses\n * to `1`, falloff reduces to plain `1 / d^2`).\n * - `range = 0` -> `1e8` (host safety boundary; glTF `range: 0` is mapped\n * to the no-cutoff `Infinity` value before this helper is called).\n * - `range > 0` -> `1 / (range * range)` (standard quartic factor).\n *\n * @param range meters (component schema field `range`); `+Infinity` is the\n * KHR no-truncation default\n * @returns `1 / range^2` with three-branch NaN protection\n */\nexport function computeInvRangeSquared(range: number): number {\n if (range === Number.POSITIVE_INFINITY) return 0;\n if (range === 0) return RANGE_ZERO_FALLBACK_INV_R2;\n return 1 / (range * range);\n}\n\n/**\n * feat-20260709 M2 / D-1: shared zero/missing-direction validate for\n * DirectionalLight + SpotLight. `direction` has no layer-2 default, so an\n * omitted direction lands the array layer-3 all-zero -- the same illegal state\n * as an explicit zero vector. SSOT for the rejection so the two lights cannot\n * drift. Returns the structured error to reject, or `null` when the direction\n * is a valid non-zero vector.\n */\nexport function validateDirection(\n componentName: 'DirectionalLight' | 'SpotLight',\n direction: ArrayLike<number> | undefined,\n): SpawnLightInvalidBoundsError | null {\n const dir = direction;\n if (dir === undefined || ((dir[0] ?? 0) === 0 && (dir[1] ?? 0) === 0 && (dir[2] ?? 0) === 0)) {\n return new SpawnLightInvalidBoundsError(\n componentName,\n 'direction',\n dir === undefined ? [0, 0, 0] : [dir[0] ?? 0, dir[1] ?? 0, dir[2] ?? 0],\n );\n }\n return null;\n}\n\n/** Validate directional-light payloads at the render owner boundary. */\nexport function validateDirectionalLightData(\n data: Readonly<Record<string, unknown>>,\n): LightValidationResult {\n const directionError = validateDirection(\n 'DirectionalLight',\n data.direction as ArrayLike<number> | undefined,\n );\n if (directionError !== null) return err(directionError);\n if (data.castShadow === false) return ok(undefined);\n\n const mapSize = (data.mapSize as number | undefined) ?? 2048;\n if (mapSize < 1) {\n return err(new ShadowInvalidConfigError('mapSize', mapSize, 1));\n }\n const cascadeCount = (data.cascadeCount as number | undefined) ?? 4;\n if (cascadeCount < 1 || cascadeCount > 4 || !Number.isInteger(cascadeCount)) {\n return err(new ShadowInvalidConfigError('cascadeCount', cascadeCount, 1, 4));\n }\n const splitLambda = (data.splitLambda as number | undefined) ?? 0.75;\n if (splitLambda < 0 || splitLambda > 1) {\n return err(new ShadowInvalidConfigError('splitLambda', splitLambda, 0, 1));\n }\n const cascadeBlend = (data.cascadeBlend as number | undefined) ?? 0.2;\n if (cascadeBlend < 0 || cascadeBlend > 0.5) {\n return err(new ShadowInvalidConfigError('cascadeBlend', cascadeBlend, 0, 0.5));\n }\n const shadowDistance = (data.shadowDistance as number | undefined) ?? 200;\n if (shadowDistance <= 0) {\n return err(new ShadowInvalidConfigError('shadowDistance', shadowDistance, 0, '>'));\n }\n const shadowFilter =\n (data.shadowFilter as number | undefined) ?? DirectionalShadowFilterValue.pcf3;\n const allowedFilters = Object.values(DirectionalShadowFilterValue);\n if (!Number.isFinite(shadowFilter) || !allowedFilters.includes(shadowFilter as never)) {\n return err(\n new ShadowInvalidConfigError(\n 'shadowFilter',\n shadowFilter,\n { kind: 'allowed-values', values: allowedFilters },\n undefined,\n 'one of [pcf1, pcf3, pcf5, pcssMedium, pcssHigh]',\n ),\n );\n }\n if (\n shadowFilter === DirectionalShadowFilterValue.pcssMedium ||\n shadowFilter === DirectionalShadowFilterValue.pcssHigh\n ) {\n const shadowAngularRadius = (data.shadowAngularRadius as number | undefined) ?? 0.00465;\n if (!Number.isFinite(shadowAngularRadius)) {\n return err(\n new ShadowInvalidConfigError('shadowAngularRadius', shadowAngularRadius, {\n kind: 'range',\n min: PCSS_RADIUS_MIN,\n max: PCSS_RADIUS_MAX,\n }),\n );\n }\n // ECS stores this field as f32; both authored endpoints round outward.\n // Accept their stored representations, but not the adjacent out-of-range f32.\n if (\n shadowAngularRadius < Math.fround(PCSS_RADIUS_MIN) ||\n shadowAngularRadius > Math.fround(PCSS_RADIUS_MAX)\n ) {\n return err(\n new ShadowInvalidConfigError('shadowAngularRadius', shadowAngularRadius, {\n kind: 'range',\n min: PCSS_RADIUS_MIN,\n max: PCSS_RADIUS_MAX,\n }),\n );\n }\n const maxPenumbraTexels = (data.maxPenumbraTexels as number | undefined) ?? 32;\n if (\n !Number.isFinite(maxPenumbraTexels) ||\n !Number.isInteger(maxPenumbraTexels) ||\n maxPenumbraTexels < PCSS_PENUMBRA_MIN ||\n maxPenumbraTexels > PCSS_PENUMBRA_MAX\n ) {\n return err(\n new ShadowInvalidConfigError(\n 'maxPenumbraTexels',\n maxPenumbraTexels,\n { kind: 'range', min: PCSS_PENUMBRA_MIN, max: PCSS_PENUMBRA_MAX },\n undefined,\n 'a finite integer in [1, 64]',\n ),\n );\n }\n }\n return ok(undefined);\n}\n\n/** Validate spot-light payloads at the render owner boundary. */\nexport function validateSpotLightData(\n data: Readonly<Record<string, unknown>>,\n): LightValidationResult {\n const directionError = validateDirection(\n 'SpotLight',\n data.direction as ArrayLike<number> | undefined,\n );\n if (directionError !== null) return err(directionError);\n if (data.castShadow === false) return ok(undefined);\n\n const range = (data.range as number | undefined) ?? 10;\n if (typeof range !== 'number' || Number.isNaN(range) || range < 0) {\n return err(new SpawnLightInvalidBoundsError('SpotLight', 'range', range));\n }\n const innerConeDeg = (data.innerConeDeg as number | undefined) ?? 0;\n const outerConeDeg = (data.outerConeDeg as number | undefined) ?? 45;\n if (outerConeDeg > 90) {\n return err(new SpawnLightInvalidBoundsError('SpotLight', 'outerNinety', outerConeDeg));\n }\n if (outerConeDeg <= innerConeDeg) {\n return err(new SpawnLightInvalidBoundsError('SpotLight', 'innerOuter', outerConeDeg));\n }\n const mapSize = (data.mapSize as number | undefined) ?? 2048;\n if (mapSize < 1) return err(new ShadowInvalidConfigError('mapSize', mapSize, 1));\n const nearPlane = data.nearPlane as number | undefined;\n const farPlane = data.farPlane as number | undefined;\n if (nearPlane !== undefined && farPlane !== undefined && farPlane <= nearPlane) {\n return err(new ShadowInvalidConfigError('farPlane', farPlane, nearPlane));\n }\n const pcfKernelSize = (data.pcfKernelSize as number | undefined) ?? 3;\n if (pcfKernelSize < 1 || pcfKernelSize % 2 === 0) {\n return err(\n new ShadowInvalidConfigError(\n 'pcfKernelSize',\n pcfKernelSize,\n { kind: 'lower-bound', operator: '>=', value: 1 },\n undefined,\n 'an odd integer >= 1',\n ),\n );\n }\n const shadowIntensity = (data.shadowIntensity as number | undefined) ?? 1;\n if (!Number.isFinite(shadowIntensity) || shadowIntensity < 0 || shadowIntensity > 1) {\n return err(new ShadowInvalidConfigError('shadowIntensity', shadowIntensity, 0, 1));\n }\n return ok(undefined);\n}\n\n/** Validate point-light payloads at the render owner boundary. */\nexport function validatePointLightData(\n data: Readonly<Record<string, unknown>>,\n): LightValidationResult {\n const range = (data.range as number | undefined) ?? 10;\n if (typeof range !== 'number' || Number.isNaN(range) || range < 0) {\n return err(new SpawnLightInvalidBoundsError('PointLight', 'range', range));\n }\n return ok(undefined);\n}\n\n/** Validate point-light shadow payloads at the render owner boundary. */\nexport function validatePointLightShadowData(\n data: Readonly<Record<string, unknown>>,\n): LightValidationResult {\n const mapSize = (data.mapSize as number | undefined) ?? 512;\n if (mapSize < 1) return err(new ShadowInvalidConfigError('mapSize', mapSize, 1));\n const nearPlane = (data.nearPlane as number | undefined) ?? 0.1;\n const farPlane = (data.farPlane as number | undefined) ?? 25;\n if (farPlane <= nearPlane) {\n return err(new ShadowInvalidConfigError('farPlane', farPlane, nearPlane));\n }\n const pcfKernelSize = (data.pcfKernelSize as number | undefined) ?? 3;\n if (pcfKernelSize < 1 || pcfKernelSize % 2 === 0) {\n return err(\n new ShadowInvalidConfigError(\n 'pcfKernelSize',\n pcfKernelSize,\n { kind: 'lower-bound', operator: '>=', value: 1 },\n undefined,\n 'an odd integer >= 1',\n ),\n );\n }\n return ok(undefined);\n}\n\n/** Validate rectangular area-light authoring facts before renderer admission. */\nexport function validateRectAreaLightData(\n data: Readonly<Record<string, unknown>>,\n): LightValidationResult {\n const intensity = (data.intensity as number | undefined) ?? 1;\n if (typeof intensity !== 'number' || !Number.isFinite(intensity) || intensity < 0) {\n return err(new SpawnLightInvalidBoundsError('RectAreaLight', 'intensity', intensity));\n }\n const color = (data.color as ArrayLike<number> | undefined) ?? [1, 1, 1];\n if (\n color.length !== 3 ||\n Array.from(color).some(\n (value) => typeof value !== 'number' || !Number.isFinite(value) || value < 0,\n )\n ) {\n return err(new SpawnLightInvalidBoundsError('RectAreaLight', 'color', Array.from(color)));\n }\n for (const field of ['width', 'height', 'range'] as const) {\n const value = (data[field] as number | undefined) ?? (field === 'range' ? 10 : 1);\n if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {\n return err(new SpawnLightInvalidBoundsError('RectAreaLight', field, value));\n }\n }\n return ok(undefined);\n}\n\n/** Validate the fixed 27-value SH payload and minimum finite radius. */\nexport function validateLightProbeData(\n data: Readonly<Record<string, unknown>>,\n): LightValidationResult {\n const irradiance = data.irradiance as ArrayLike<number> | undefined;\n if (\n irradiance === undefined ||\n irradiance.length !== 27 ||\n Array.from(irradiance).some((value) => typeof value !== 'number' || !Number.isFinite(value))\n ) {\n return err(\n new SpawnLightInvalidBoundsError(\n 'LightProbe',\n 'irradiance',\n irradiance === undefined ? [] : Array.from(irradiance),\n ),\n );\n }\n const radius = (data.radius as number | undefined) ?? R_MIN;\n if (typeof radius !== 'number' || !Number.isFinite(radius) || radius < R_MIN) {\n return err(new SpawnLightInvalidBoundsError('LightProbe', 'radius', radius));\n }\n return ok(undefined);\n}\n","// @forgeax/engine-render - local diffuse LightProbe authoring facts.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\nimport { R_MIN } from '@forgeax/engine-types';\n\n/**\n * Local diffuse irradiance probe. Transform supplies position; the 27 SH\n * values are nine RGB groups in the fixed real-SH order.\n */\nexport const LightProbe = defineComponent('LightProbe', {\n irradiance: { type: 'array<f32, 27>' },\n radius: { type: 'f32', default: R_MIN },\n});\n","import { defineComponent } from '@forgeax/engine-ecs';\n\n/** Screen-space independent line segment style. */\nexport const Lines = defineComponent(\n 'Lines',\n {\n widthPx: { type: 'f32', default: 1 },\n },\n {\n meta: {\n quickStart: 'Attach Lines to render line-list MeshAsset pairs in screen pixels.',\n diagnostics: 'Inspect widthPx at the points-lines admission boundary.',\n recovery: 'Use points-lines-invalid-style for non-finite or non-positive widthPx values.',\n boundaries:\n 'Lines owns raster width only; MeshFilter and MeshRenderer own geometry and material.',\n },\n },\n);\n","// @forgeax/engine-render - MeshFilter (mesh asset reference).\n//\n// Schema: `{ assetHandle: 'shared<MeshAsset>' }`. The schema-vocab\n// `'shared<T>'` keyword stores a u32 column and type-derives to\n// `Handle<'MeshAsset', 'shared'>` (engine-ecs Handle<T,M> twoParam\n// phantom; `'shared'` mode = ref-counted retain on set / release on\n// clear, lifecycle owned by `SharedRefStore` per feat-20260614).\n// The brand prevents cross-asset assignment at compile time (e.g.\n// `Handle<'TextureAsset','shared'>` is not assignable to `assetHandle`).\n//\n// AI users spawn with the assets-runtime constants `HANDLE_CUBE` /\n// `HANDLE_TRIANGLE` (now branded `Handle<'MeshAsset','shared'>` to\n// match the schema-derived shape); custom mesh registration is owned by\n// feat-future-asset-system (this MVP only exposes builtin handles).\n//\n// Naming flavor: unity-style \"MeshFilter / MeshRenderer\" pair, but the forgeax\n// pair does NOT mirror Unity's filter-toggle semantics - MeshFilter only\n// carries the geometry ref, MeshRenderer only carries the material handle;\n// the pair is independently composable. D-Q7 default-material policy\n// (feat-20260517-merge-mesh-renderer-material-renderer plan-strategy §2.2):\n// case A (entity carries MeshFilter without MeshRenderer) -> archetype\n// query never matches -> entity is silently absent from the\n// RenderableSnapshot[] (NO default-material fallback, NO onError fire);\n// case B (MeshRenderer.material omitted at spawn) -> mid-grey\n// defaultMaterialSnapshot fallback (no onError); case C (material handle\n// unresolved) -> RhiError 'asset-not-registered' (mirrors the\n// MeshFilter.assetHandle dangling-ref path).\n//\n// charter mapping: proposition 1 (single import) + proposition 4 (explicit\n// failure: missing or unregistered handle fires onError 'asset-not-registered'\n// with .detail = { assetHandle } + cross-asset brand mismatch is a TS\n// compile-time error) + proposition 5 (consistent abstraction: the schema\n// vocab `'shared<T>'` is the SSOT for AssetRegistry-owned handles across\n// the engine).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Mesh filter (geometry asset reference).\n *\n * `assetHandle` carries a `Handle<'MeshAsset', 'shared'>` (u32-stored)\n * pointing into `engine.assets: AssetRegistry`. Use the predefined\n * constants `HANDLE_CUBE` / `HANDLE_TRIANGLE` exported from\n * `@forgeax/engine-render`; custom-mesh registration is OOS in MVP (see\n * feat-future-asset-system).\n *\n * Error path: if the handle is not registered at draw time, RenderSystem\n * fires `Renderer.onError` with\n * `RhiError({ code: 'asset-not-registered', detail: { assetHandle } })`\n * and skips this entity (other entities continue rendering; charter\n * proposition 9 graceful degradation).\n *\n * @example Spawn an entity referencing the builtin cube mesh:\n * import { MeshFilter } from '@forgeax/engine-render';\n * import { HANDLE_CUBE } from '@forgeax/engine-assets-runtime';\n * world.spawn({ component: MeshFilter, data: { assetHandle: HANDLE_CUBE } });\n */\nexport const MeshFilter = defineComponent('MeshFilter', {\n assetHandle: { type: 'shared<MeshAsset>' },\n});\n","// @forgeax/engine-render - MeshRenderer (multi-material array slot).\n//\n// feat-20260608-mesh-multi-section-primitive-multi-material-slot M2 / w7:\n// the single `material` field is replaced with `materials` — an\n// `array<shared<MaterialAsset>>` indexed by MeshAsset.materialSlots. Entries\n// are sparse positional overrides: a missing/zero entry inherits the Mesh\n// slot default, while a defaultless slot inherits the neutral engine material.\n//\n// The schema-vocab keyword `'array<shared<MaterialAsset>>'` (feat-20260614\n// M5 -- migrated from `'array<handle<MaterialAsset>>'`) stores as a u32\n// column slot array; the brand prevents cross-asset assignment at compile\n// time. The `'shared<T>'` arm routes element retain/release through\n// SharedRefStore (M4 / w13) on overwrite / archetype migration.\n//\n// charter mapping: proposition 1 (single import — `MeshRenderer` is the\n// only material-binding component AI users see); proposition 3\n// (machine-readable schema > prose); proposition 4 (explicit failure: the\n// TS brand on `Handle<'MaterialAsset','shared'>` rejects cross-variant\n// assignment at compile time); proposition 5 (consistent abstraction:\n// shading model classification (`'unlit'` / `'standard'`) lives ONLY on\n// the asset discriminant, NOT on the component name).\n//\n// RenderSystem consumption: `render-system-extract.ts` runs ONE archetype\n// query (`world.query(MeshRenderer)`) and routes per entity by\n// `mat.materialShaderId` (shader identity) to the unlit.wgsl or pbr.wgsl\n// pipeline tag.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Mesh renderer (ECS component, multi-material array).\n *\n * Stores `materials: readonly Handle<'MaterialAsset','shared'>[]`\n * (u32-stored array, indexed by MeshAsset.materialSlots). Submeshes point to\n * those stable slots through `Submesh.materialSlot`. The asset's `passes[].shader`\n * identity is the SSOT for which pipeline RenderSystem routes the entity\n * to (record stage dispatches on `materialShaderId`).\n *\n * Defaults map carries `materials: []`: every slot inherits its Mesh-owned\n * default, or the neutral engine material when that slot is intentionally\n * defaultless.\n *\n * @example Spawn while inheriting every Mesh slot default:\n * world.spawn({ component: MeshRenderer, data: {} });\n *\n * @example Spawn an unlit-targeted entity:\n * import { MeshRenderer, Materials } from '@forgeax/engine-render';\n * const matPayload = engine.assets.catalog(matGuid, Materials.unlit([1, 0, 0, 1])).value;\n * const matHandle = world.allocSharedRef('MaterialAsset', matPayload);\n * world.spawn({ component: MeshRenderer, data: { materials: [matHandle] } });\n *\n * @example Spawn a standard (PBR) entity:\n * const matPayload = engine.assets.catalog(matGuid, Materials.standard({\n * baseColor: [0.5, 0.5, 0.5, 1], metallic: 0, roughness: 0.4,\n * })).value;\n * const matHandle = world.allocSharedRef('MaterialAsset', matPayload);\n * world.spawn({ component: MeshRenderer, data: { materials: [matHandle] } });\n */\nexport const MeshRenderer = defineComponent('MeshRenderer', {\n materials: { type: 'array<shared<MaterialAsset>>', default: [] },\n});\n","import { defineComponent } from '@forgeax/engine-ecs';\n\n/** Active-camera motion blur authoring data; presence enables the feature. */\nexport const MotionBlur = defineComponent('MotionBlur', {\n shutterAngle: { type: 'f32', default: 180 },\n maxRadiusPixels: { type: 'f32', default: 32 },\n sampleCount: { type: 'f32', default: 8 },\n});\n","// @forgeax/engine-render - PointLight (omnidirectional point-light parameters).\n//\n// Schema: color array<f32,3> + intensity f32 + range f32 (feat-20260709 M2:\n// color collapsed from 3 per-axis scalar columns to one inline array<f32,3>).\n// `position` comes from the Transform component; PointLight requires a\n// companion Transform on the same entity (ECS query: `[Transform, PointLight]`).\n// `range` units are meters; defaults to `10.0`. Runtime finite-range\n// attenuation is the Three r184 squared window; the KHR unsquared curve is an\n// import/reference boundary only. See `light-helpers.ts` for the host-side\n// range projection.\n//\n// 0 light + standard material -> physically correct black render\n// (feat-20260518-pbr-direct-lighting-mvp). The runtime once-warn channel\n// (M5 / w25) collapses to \"directionalCount + pointCount + spotCount === 0\";\n// see packages/runtime/README.md section Common pitfalls for the AI-user\n// guidance after the M5 docs land.\n//\n// Naming convention: bare entity name aligned with Bevy ECS conventions\n// (feat-20260513-component-naming-bevy-align). DirectionalLight / SpotLight\n// follow the same single-semantic-entity rule (charter proposition 5).\n//\n// charter mapping: proposition 1 (single import + IDE autocomplete on\n// payload.range) + proposition 3 (silent failure -> explicit failure;\n// spawn-time fail-fast on range<0 / NaN with structured EcsError) +\n// proposition 5 (consistent abstraction: shared payload shape with\n// SpotLight; `range` semantics aligned with KHR_lights_punctual).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Omnidirectional point light (KHR_lights_punctual `point` type).\n *\n * `position` source: the companion `Transform` component on the same entity.\n * Spawn via `world.spawn({ component: Transform, data: ... }, { component: PointLight, data: ... })`\n * so the render system extract path can join the two via the\n * `[Transform, PointLight]` ECS query.\n *\n * `color` is linear-space rgb in `[0, 1]` per channel; `intensity` is candela;\n * `range` is in meters and defaults to `10.0`\n * (KHR convention; `+Infinity` is the KHR no-truncation value, retained\n * for KHR_lights_punctual `range: 0` bridging via `light-helpers.ts`).\n * The runtime window is `clamp(1 - (d / range)^4, 0, 1)^2`; its no-cutoff\n * boundary uses inverse-square decay with the shader safety floor. Exposure is\n * applied after lighting and never multiplied into intensity.\n *\n * @example Spawn a single point light at (5, 3, 5):\n * world.spawn(\n * { component: Transform, data: { pos: [5, 3, 5] } },\n * { component: PointLight, data: { intensity: 8, range: 25 } },\n * );\n *\n * @example Minimal spawn -- defaults give neutral white at full strength, range 10m:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 1, 0] } },\n * { component: PointLight, data: {} },\n * );\n * // resolves to color=[1, 1, 1], intensity=1, range=10.0.\n */\nexport const PointLight = defineComponent('PointLight', {\n // color carries an explicit layer-2 default [1,1,1] (white); the array\n // layer-3 fallback is all-zero, so the default MUST be explicit (D-5).\n color: { type: 'array<f32, 3>', default: new Float32Array([1, 1, 1]) },\n intensity: { type: 'f32', default: 1 },\n range: { type: 'f32', default: 10.0 },\n});\n","// @forgeax/engine-runtime — PointLightShadow (omnidirectional point-light\n// shadow mapping parameters; cube-array atlas variant).\n//\n// Schema: 6 f32 columns — mapSize (u32, stored as f32), depthBias, normalBias,\n// nearPlane, farPlane, pcfKernelSize (u32, stored as f32). No fixed-extent\n// field — cube map uses fov=90 perspective, not ortho.\n//\n// Atlas capacity is a renderer policy; ECS does not enforce a component\n// cardinality bound.\n// Co-located with DirectionalLight in components/ (research L1.2).\n//\n// Naming convention: bare entity name (AGENTS.md §Component naming), no\n// Component suffix. Same defineComponent pattern and ShadowInvalidConfigError\n// surface as the shadow fields merged into DirectionalLight (feat-20260621 M1).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Omnidirectional point-light shadow mapping parameters.\n *\n * The renderer may batch this component into a bounded atlas, but the ECS\n * component remains a plain storage schema and carries no cardinality policy.\n *\n * @example Spawn a point light with default shadow config:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 4, 0] } },\n * { component: PointLight, data: { range: 25 } },\n * { component: PointLightShadow, data: {} }, // 6 fields filled from defaults\n * );\n *\n * @example Spawn with explicit map size and bias:\n * world.spawn(\n * { component: PointLightShadow, data: { mapSize: 1024, depthBias: 0.01 } },\n * );\n */\nexport const PointLightShadow = defineComponent('PointLightShadow', {\n mapSize: { type: 'f32', default: 512 },\n depthBias: { type: 'f32', default: 0.005 },\n normalBias: { type: 'f32', default: 0.05 },\n nearPlane: { type: 'f32', default: 0.1 },\n farPlane: { type: 'f32', default: 25 },\n pcfKernelSize: { type: 'f32', default: 3 },\n});\n","import { defineComponent } from '@forgeax/engine-ecs';\n\n/** Public point raster shapes backed by the ECS enum column. */\nexport type PointShape = keyof typeof PointShapeValue;\n\n/** Numeric labels stored by the public Points shape enum field. */\nexport const PointShapeValue = Object.freeze({\n square: 0,\n circle: 1,\n} as const);\n\n/** Decode the Points shape column without treating an unknown value as valid. */\nexport function pointShapeFromU32(value: number): PointShape | undefined {\n switch (value) {\n case PointShapeValue.square:\n return 'square';\n case PointShapeValue.circle:\n return 'circle';\n default:\n return undefined;\n }\n}\n\n/** Screen-space point style. Geometry and material remain on their own owners. */\nexport const Points = defineComponent(\n 'Points',\n {\n sizePx: { type: 'f32', default: 4 },\n shape: { type: 'enum', default: PointShapeValue.square, labels: PointShapeValue },\n },\n {\n meta: {\n quickStart: 'Attach Points to render point-list MeshAsset vertices in screen pixels.',\n diagnostics: 'Inspect sizePx and decode shape with pointShapeFromU32.',\n recovery: 'Use points-lines-invalid-style for non-finite or non-positive sizePx values.',\n boundaries:\n 'Points owns raster size and shape only; MeshFilter and MeshRenderer own geometry and material.',\n },\n },\n);\n","// @forgeax/engine-render - PostProcessParams component.\n//\n// Schema: { shader: 'string', data: 'buffer' }.\n//\n// `shader` identifies the fullscreen post-process shader (the same id as passed to\n// the feature host registers for `id`). `data` carries the per-frame params\n// bytes as a variable-byte ECS managed buffer slot. The write side (world.spawn /\n// world.set) accepts every AllowSharedBufferSource (Float32Array / ArrayBuffer /\n// Uint8Array / typed array) and the ECS normalizes it to Uint8Array bytes\n// (feat-20260621 V2 / AC-A4); the read side (world.get) returns Uint8Array, which\n// satisfies AllowSharedBufferSource for GPU queue.writeBuffer ingestion.\n//\n// Single-semantic component — drops the `Component` suffix\n// (AGENTS.md §Component naming rule #1). The `data` field uses the ECS 'buffer'\n// vocab keyword (plan-strategy D-7) for variable-byte storage.\n//\n// Data flow (plan-strategy D-1):\n// extract -> iterate PostProcessParams-bearing entities ->\n// collect into Map<shaderId, AllowSharedBufferSource> snapshot ->\n// dispatchFullscreenPass picks up per-shader data -> writeBuffer to eager UBO.\n//\n// Decision anchors:\n// - requirements AC-A2 (data-driven, no imperative renderer.setParams mutator)\n// - requirements AC-A4 (AllowSharedBufferSource type on the data field)\n// - plan-strategy D-1 (new single-semantic ECS component for params)\n// - plan-strategy D-7 (ECS 'buffer' vocab keyword for variable-byte storage)\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\nconst schema = {\n shader: 'string',\n data: 'buffer',\n} as const;\n\nexport const PostProcessParams = defineComponent('PostProcessParams', schema);\n","// @forgeax/engine-render - single-sided rectangular area-light authoring facts.\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Single-sided rectangular area light. Transform supplies the center and\n * world orientation; width and height remain authored emitter dimensions.\n */\nexport const RectAreaLight = defineComponent('RectAreaLight', {\n color: { type: 'array<f32, 3>', default: new Float32Array([1, 1, 1]) },\n intensity: { type: 'f32', default: 1 },\n width: { type: 'f32', default: 1 },\n height: { type: 'f32', default: 1 },\n range: { type: 'f32', default: 10 },\n});\n","// @forgeax/engine-render - local reflection probe vocabulary.\n//\n// A ReflectionProbe is an ECS authoring fact. The renderer owns its six-face\n// capture, PMREM output, box selection, and Skylight fallback; this component\n// never carries a GPU handle or an authored material reference.\n\nimport { defineComponent, type SchemaOf, type ShapeOf } from '@forgeax/engine-ecs';\nimport { RenderIntentInvalidError } from '../errors/render';\n\nexport const REFLECTION_PROBE_UPDATE_ONCE = 0;\nexport const REFLECTION_PROBE_UPDATE_ON_CHANGE = 1;\nexport const REFLECTION_PROBE_UPDATE_CONTINUOUS = 2;\n\nexport type ReflectionProbeUpdateIntent = 'once' | 'on-change' | 'continuous';\n\nexport function reflectionProbeUpdateIntentFromF32(value: number): ReflectionProbeUpdateIntent {\n switch (value) {\n case REFLECTION_PROBE_UPDATE_ONCE:\n return 'once';\n case REFLECTION_PROBE_UPDATE_ON_CHANGE:\n return 'on-change';\n case REFLECTION_PROBE_UPDATE_CONTINUOUS:\n return 'continuous';\n default:\n throw new RenderIntentInvalidError('ReflectionProbe', value);\n }\n}\n\nexport function reflectionProbeUpdateIntentToF32(intent: ReflectionProbeUpdateIntent): number {\n switch (intent) {\n case 'once':\n return REFLECTION_PROBE_UPDATE_ONCE;\n case 'on-change':\n return REFLECTION_PROBE_UPDATE_ON_CHANGE;\n case 'continuous':\n return REFLECTION_PROBE_UPDATE_CONTINUOUS;\n }\n}\n\nexport const ReflectionProbe = defineComponent('ReflectionProbe', {\n halfExtents: { type: 'array<f32, 3>', default: new Float32Array([1, 1, 1]) },\n priority: { type: 'f32', default: 0 },\n boxProjection: { type: 'bool', default: false },\n intensity: { type: 'f32', default: 1 },\n resolution: { type: 'u32', default: 256 },\n updateIntent: { type: 'f32', default: REFLECTION_PROBE_UPDATE_ONCE },\n invalidationVersion: { type: 'u32', default: 0 },\n});\n\nexport type ReflectionProbeData = ShapeOf<SchemaOf<typeof ReflectionProbe>>;\n","// @forgeax/engine-runtime - SceneInstance component (feat-20260608-\n// scene-nesting-ecs-fication M2 / w16).\n//\n// Single ECS fat component carrying everything that used to live on the\n// old `SceneInstance` + `SceneInstanceContainer` pair (deleted\n// in M3). Schema fits the ECS schema vocab (3 single-identifier fields):\n//\n// { source: 'shared<SceneAsset>',\n// mapping: 'array<entity>',\n// state: 'unique<SceneInstanceState>' }\n//\n// `source` carries the SceneAsset handle the synthetic root entity was\n// instantiated from (Tier-A AssetUnion handle, AGENTS.md §Assets submodule).\n// `mapping` is the LocalEntityId -> Entity table indexed positionally\n// (mapping[localId] = spawned Entity); the ECS variable-array column gives\n// us a SoA-friendly read path for query<SceneInstance> scans without\n// touching the dynamic Map/Set state.\n// `state` is a `ref<SceneInstanceState>` slot — World holds the live\n// SceneInstanceState payload in its UniqueRefStore and World despawn\n// auto-releases the ref u32 (the same path used by audio / physics\n// payloads, plan-strategy §D-2). Each instantiateScene call calls\n// `world.allocUniqueRef('SceneInstanceState', state)` once and stores the\n// returned u32 in this column.\n//\n// Decision anchors:\n// - plan-strategy §D-2 (single ref wraps SceneInstanceState dynamic\n// structure; ECS schema vocab `\\w+` rejects `ref<Map<...>>`)\n// - plan-strategy §3.2 sequence (sequence diagram step 'set ... state:\n// {entityToLocalId, detached, overrides, rootEntities}')\n// - AGENTS.md §Component naming rule #1 (single-semantic component drops\n// `Component` suffix)\n// - charter F1 (single-import barrel: SceneInstance lives in\n// `@forgeax/engine-render` next to Transform / Camera / DirectionalLight)\n// - charter P3 (machine-readable schema: 3 closed fields)\n// - charter P4 (consistent abstraction: instance == entity carrying\n// SceneInstance — same `world.query({ read: [SceneInstance] })` /\n// `world.get(root, SceneInstance)` path as another component)\n\nimport { defineComponent, type EntityHandle } from '@forgeax/engine-ecs';\nimport type { MountOverride } from '@forgeax/engine-scene';\nimport type { LocalEntityId } from '@forgeax/engine-types';\n\n/**\n * Per-component, per-field override record carried in `SceneInstanceState`.\n *\n * Composite key `<componentName>:<fieldName>` keeps the override map flat\n * (single Map nesting level) so AI users walking `state.overrides` see one\n * iteration depth — D-2 prefers a single SSOT over multi-Map nesting that\n * would make iteration order ambiguous (charter F1: single mental model).\n *\n * The value is `unknown` because the per-component schema vocab lives in the\n * ECS layer; runtime fail-fast via `EcsErrorCode = 'scene-override-type-\n * mismatch'` (plan-strategy §D-9) catches type drift on the apply path.\n *\n * @internal Surface from `state.overrides` only; AI users never construct a\n * record directly. Use `world.setSceneOverride(root, member, comp,\n * field, value)` to write and `world.removeSceneOverride(root, member,\n * comp, field)` to roll back to the source SceneAsset value.\n */\nexport interface SceneInstanceOverrideRecord {\n readonly comp: string;\n /**\n * Component-granular add-or-patch discriminant (feat-20260713 M1 / w4):\n * present -> this record patches a single field; absent -> it adds/upserts\n * the whole `comp` (M2 apply semantics). Mirrors `MountOverride.field`.\n */\n readonly field?: string;\n readonly value: unknown;\n}\n\n/**\n * Dynamic state payload for one SceneInstance — held in the World's\n * UniqueRefStore behind a `ref<SceneInstanceState>` slot on the synthetic\n * root entity. Mirrors the old class-based layout (plan-strategy §D-2 +\n * design doc §11.2 internal-state-table) but flattened into plain JS Maps/Sets so\n * AI users can iterate without indirection.\n *\n * Lifecycle:\n * - allocated by `world.instantiateScene(handle, parent?)` — the W in\n * `world.allocUniqueRef('SceneInstanceState', state)` returns the u32\n * slot id stored in the SceneInstance.state column;\n * - released by `world.despawn(root)` (the standard `ref<T>` release loop)\n * or explicitly via `world.despawnScene(root)` / `world.despawnDescendants(root)`.\n *\n * AI users typically reach this struct only through the read path\n * `world.get(root, SceneInstance).state.overrides.get(<comp>:<field>)` for\n * inspection; mutation happens through the 8 World methods.\n */\nexport interface SceneInstanceState {\n /**\n * SceneAsset handle the instance was instantiated from. Mirrors the\n * SceneInstance.source column for AI users who already have a\n * SceneInstanceState in hand and want the source handle without a second\n * `world.get` round-trip.\n */\n readonly source: import('@forgeax/engine-types').Handle<'SceneAsset', 'shared'>;\n\n /** Author scene identity used by instance-relative SceneEntityRef resolution. */\n readonly sceneSourceKey?: string;\n\n /** Stable author bindingKey to live Entity mapping for this concrete instance. */\n readonly bindings: Map<string, EntityHandle>;\n\n /**\n * Reverse mapping (live `Entity` -> source `LocalEntityId`). Used by\n * `world.setSceneOverride` to validate the member entity belongs to this\n * instance + by `world.detachSceneMember` / `world.reattachSceneMember`\n * to translate caller-side Entity values back to their authored localId.\n */\n readonly entityToLocalId: Map<EntityHandle, LocalEntityId>;\n\n /**\n * LocalEntityIds of members the AI user marked detached via\n * `world.detachSceneMember(root, member)`. The member entities stay\n * alive in the World; only the bookkeeping marker moves so\n * `world.despawnDescendants(root, { keepDetached: true })` can skip them.\n * Detach is idempotent (set semantics).\n */\n readonly detachedLocalIds: Set<LocalEntityId>;\n\n /**\n * Per-member runtime overrides keyed by `<localId>` -> `<comp>:<field>`\n * -> override record. mount-time overrides (authored on the SceneAsset's\n * `mounts[].overrides`) populate this map at instantiate-time so AI\n * users see them via the same read path as runtime\n * `setSceneOverride` writes (single SSOT).\n */\n readonly overrides: Map<LocalEntityId, Map<string, SceneInstanceOverrideRecord>>;\n\n /**\n * Top-level root entities of the materialised tree (members without a\n * ChildOf parent at instantiate time). The synthetic root entity that\n * carries the SceneInstance component itself is NOT in this list — it is\n * the parent of every member entity (plan-strategy §3.2 sequence step 7).\n */\n readonly rootEntities: EntityHandle[];\n\n /** Synthetic roots of recursively mounted SceneAssets owned by this instance. */\n readonly mountRoots: EntityHandle[];\n\n /**\n * Total slot count `entities.length + sum(mounts[].memberCount)` —\n * captured at instantiate-time so cycle / count consistency checks\n * (e.g. `world.getSceneAssetForInstance(root)` symmetry) can compare\n * against the live SceneInstance.mapping column without re-reading the\n * SceneAsset.\n */\n readonly totalSlots: number;\n\n /**\n * Mount-time override authored on the parent SceneAsset's `mounts[]`\n * record. Captured at instantiate-time so `world.removeSceneOverride`\n * can fall back to the mount-time value before going to the source\n * SceneAsset value (plan-strategy §D-2).\n */\n readonly mountTimeOverrides: readonly MountOverride[];\n}\n\n/**\n * SceneInstance ECS component — synthetic root entity payload for one\n * materialised SceneAsset (instance == entity carrying SceneInstance,\n * charter P4).\n *\n * AI users discover the component via IDE autocomplete on\n * `@forgeax/engine-render` (single-import barrel; AGENTS.md §Components):\n *\n * ```ts\n * import { SceneInstance } from '@forgeax/engine-render';\n * for (const row of world.query({ read: [SceneInstance] }).unwrap()) {\n * console.log(`root=${row.entity} source=${row.get(SceneInstance).source}`);\n * }\n *\n * const inst = world.get(root, SceneInstance).value;\n * const memberEntity = inst.mapping[localId]; // Uint32Array snapshot\n * for (const detached of inst.state.detachedLocalIds) { /* ... *\\/ }\n * ```\n *\n * The component does not register a relationship — synthetic root +\n * members are wired through the standard `ChildOf` (member -> root) so\n * the existing `world.iterDescendants(root)` / Children mirror code paths\n * apply unchanged (plan-strategy §D-5).\n *\n * @example Materialise + inspect a SceneAsset:\n * const { root, diagnostics } = world.instantiateScene(handle).value;\n * const inst = world.get(root, SceneInstance).value;\n * // inst.source === handle, inst.mapping is Uint32Array(totalSlots)\n * // inst.state holds entityToLocalId / detachedLocalIds / overrides /\n * // rootEntities / mountRoots / totalSlots / mountTimeOverrides.\n */\nexport const SceneInstance = defineComponent(\n 'SceneInstance',\n {\n source: { type: 'shared<SceneAsset>' },\n mapping: { type: 'array<entity>' },\n // The unique slot is the ECS storage seam for the instance's structured\n // runtime payload; keep the nested semantic visible to schema consumers.\n state: { type: 'unique<SceneInstanceState>', shape: 'nested' },\n },\n { transient: true },\n);\n","// @forgeax/engine-render - ScreenSpaceReflection authoring component.\n//\n// The component is an opt-in camera effect. It carries only the three\n// bounded authoring values; all graph, resource, history, and backend state\n// remains renderer-owned.\n\nimport { defineComponent, type SchemaOf, type ShapeOf } from '@forgeax/engine-ecs';\n\n/**\n * Schema-derived ScreenSpaceReflection authoring data.\n *\n * The defaults are conservative and are validated against the active camera\n * view range before a spatial candidate is admitted.\n */\nexport const ScreenSpaceReflection = defineComponent('ScreenSpaceReflection', {\n maxDistance: { type: 'f32', default: 40 },\n thickness: { type: 'f32', default: 0.2 },\n maxRoughness: { type: 'f32', default: 0.6 },\n});\n\nexport type ScreenSpaceReflectionData = ShapeOf<SchemaOf<typeof ScreenSpaceReflection>>;\n","// @forgeax/engine-runtime - SkyboxBackground (environment cubemap render background).\n//\n// Schema: 3 fields -- equirect (Handle<EquirectAsset>, u32-stored handle)\n// + mode (f32 enum column, discriminator) + rotation (quaternion xyzw,\n// default identity). Naming convention follows the\n// single-semantic component rule: no Component suffix (AGENTS.md rule #1).\n//\n// feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M3 / w16:\n// the field is `equirect: shared<EquirectAsset>` (the retired\n// `cubemap: shared<CubeTextureAsset>` is gone). The skybox reuses the same\n// equirect handle as the Skylight; the cubemap projection is internal and\n// driven by the render-system record arm (no user upload call).\n//\n// Plan-strategy D-5: mode is a f32 enum column (ECS columns are POD, no\n// string unions in archetype storage). Consumer-facing type safety is\n// provided by the `SkyboxMode` literal union + `skyboxModeFromF32` mapper\n// (same pattern as cameraProjectionFromF32 in camera.ts:51,105,145,221-237).\n//\n// OOS-1: `mode: 'atmosphere'` implementation is deferred -- the union\n// shape leaves room for additive growth without breaking the f32 enum\n// encoding.\n//\n// AI user minimum spawn (charter P4):\n// world.spawn({ component: SkyboxBackground, data: { equirect, mode: 0 } });\n//\n// Single component activates the skybox render pass transparently when a\n// Skylight + tonemap active camera is present (skybox reuses the same\n// equirect handle as Skylight).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Skybox mode literal union (AC-02 narrowing surface).\n * Currently only 'cubemap' -- future 'atmosphere' deferred per OOS-1.\n */\nexport type SkyboxMode = 'cubemap';\n\n/** Numeric encoding of cubemap skybox mode (schema value for `mode`). */\nexport const SKYBOX_MODE_CUBEMAP = 0;\n\n/**\n * Map a `SkyboxBackground.mode` numeric value to the closed `SkyboxMode`\n * string-literal union. Only member currently is 'cubemap'; the exhaustive\n * switch is ready for future mode additions (e.g. 'atmosphere', OOS-1).\n */\nexport function skyboxModeFromF32(value: number): SkyboxMode {\n switch (value) {\n case SKYBOX_MODE_CUBEMAP:\n return 'cubemap';\n // Future: case SKYBOX_MODE_ATMOSPHERE: return 'atmosphere';\n }\n // Unrecognised value: fall back to 'cubemap' (charter P3 -- no silent\n // exception; the fallback preserves rendering on stale numerics while\n // the exhaustive switch shape ensures AI users catch new members at\n // compile time when a mode is added).\n return 'cubemap';\n}\n\n/**\n * SkyboxBackground: full-screen environment cubemap background.\n *\n * Renders a fullscreen triangle that reconstructs world-space view\n * direction from the camera's inverseViewProj matrix (View UBO),\n * samples a cubemap with the view direction, and writes an HDR color\n * to the hdrColor render target (before the main geometry pass).\n *\n * The skybox pass is automatically activated when a SkyboxBackground\n * entity exists, a Skylight entity provides the equirect source, and the\n * active Camera has tonemap active. The skybox reuses the same equirect\n * handle as the Skylight entity -- two independent components sharing the\n * same GPU resource (the internally-projected cubemap).\n *\n * `equirect` is a `Handle<EquirectAsset>` resolved from a vite pack-index\n * GUID via `engine.assets.loadByGuid<EquirectAsset>(guid)`. The cubemap\n * projection is internal and driven by the render-system record arm; there\n * is no user upload call.\n *\n * `mode` is a numeric discriminator column (`'f32'`). Use\n * `SKYBOX_MODE_CUBEMAP` for the cubemap render path.\n *\n * `rotation` is an environment-space quaternion in `[x, y, z, w]` order.\n * It rotates the sampled cubemap without changing the camera or rebaking the\n * source equirectangular asset.\n *\n * @example Minimum spawn (defaults mode=0):\n * // equirectHandle resolved from loadByGuid<EquirectAsset> (same handle as\n * // the Skylight).\n * world.spawn({ component: SkyboxBackground, data: { equirect: equirectHandle } });\n *\n * @example Single handle shared between Skylight (IBL) and SkyboxBackground:\n * const hdrRes = await engine.assets.loadByGuid<EquirectAsset>(guid);\n * if (!hdrRes.ok) throw hdrRes.error;\n * world.spawn({ component: Skylight, data: { equirect: hdrRes.value } });\n * world.spawn({ component: SkyboxBackground, data: { equirect: hdrRes.value } });\n */\nexport const SkyboxBackground = defineComponent('SkyboxBackground', {\n // The GPU skybox projection is render-owned presentation state; restore\n // keeps the portable mode/rotation controls and lets the owner re-resolve\n // the environment asset on the target world.\n equirect: { type: 'shared<EquirectAsset>', simulationTransient: true },\n mode: { type: 'f32', default: SKYBOX_MODE_CUBEMAP },\n rotation: { type: 'array<f32, 4>', default: new Float32Array([0, 0, 0, 1]) },\n});\n","// @forgeax/engine-runtime - Skylight (ambient environment light).\n//\n// Schema: 4 fields -- equirect (Handle<EquirectAsset>, u32-stored handle,\n// OPTIONAL) + color (array<f32,3>, default [1,1,1] = white) + intensity (f32,\n// default 1.0) + rotation (quaternion xyzw, default identity). feat-20260709 M2 collapsed colorR/G/B into one inline\n// array<f32,3> column. Naming convention follows the DirectionalLight / PointLight /\n// SpotLight family: no Component suffix (AGENTS.md rule #1).\n//\n// Plan-strategy D-6: Skylight component schema is registered but no\n// independent ECS system is created. All Skylight processing happens inside\n// RenderSystem's extract/record phases.\n//\n// AI user minimum spawn (AC-13, charter P4):\n// world.spawn({ component: Skylight, data: {} }); // instant white ambient\n//\n// A single Skylight activates ambient lighting transparently. The `equirect`\n// field is OPTIONAL: omit it for a constant solid-color ambient that needs NO\n// async GPU precompute -- the engine binds a 1x1 white irradiance cube, so\n// ambient = color * intensity * albedo is live on the very first frame (this\n// is the fix for the downstream \"scene is black until the async IBL cubemap\n// finishes uploading\" gap). Supply an equirect to upgrade to full image-based\n// lighting (diffuse irradiance + specular prefilter); `color` * `intensity`\n// still scales the IBL result, so both are live dynamic dials either way.\n//\n// feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M3 / w16:\n// the field is `equirect: shared<EquirectAsset>` (the retired\n// `cubemap: shared<CubeTextureAsset>` is gone). AI users declare the equirect\n// source directly; the render-system record arm projects the cubemap + IBL\n// chain internally and lazily (no user upload call) -- there is no\n// uploadCubemapFromEquirect on the public surface.\n//\n// Edge cases handled by w18 / w19:\n// - Multi-Skylight: first archetype hit wins, console.warn in dev+prod\n// - intensity=0: ambient term = 0, mathematically valid, no warn\n// - No equirect: solid-color ambient via the white fallback cube (no async)\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Skylight ambient environment light.\n *\n * A single Skylight entity provides ambient lighting for all StandardMaterial\n * surfaces. When Atmosphere is selected and equirect is omitted, the same sky\n * cube supplies diffuse and roughness-filtered specular IBL. Color/intensity\n * still scale the result; without Atmosphere the solid-color behavior applies.\n * Two authored inputs share one component:\n *\n * - **Solid-color ambient (no equirect).** Omit `equirect` for a constant\n * ambient = `color` * `intensity` applied immediately, with no async GPU\n * precompute. The engine samples a built-in 1x1 white irradiance cube, so a\n * freshly-loaded scene is lit on its first frame instead of being black\n * until an IBL upload finishes.\n * - **Image-based lighting (with equirect).** Supply `equirect` to upgrade to\n * diffuse irradiance + specular prefilter IBL. The engine runs the full\n * precompute (equirect->cubemap, irradiance convolution, prefilter mip\n * chain, BRDF LUT) transparently inside the render-system record arm;\n * `color` * `intensity` then scale the IBL ambient.\n *\n * `equirect` is an OPTIONAL `Handle<EquirectAsset>` resolved from a vite\n * pack-index GUID via `engine.assets.loadByGuid<EquirectAsset>(guid)`. The\n * cubemap projection is internal and idempotent: the same equirect source\n * always resolves to the same GPU cubemap (no user upload call).\n *\n * `color` is the linear-space ambient tint (default white [1, 1, 1]).\n * `intensity` is a linear multiplier (default 1.0; 0 disables ambient). Both\n * are read every frame, so they are live dynamic dials.\n *\n * `rotation` is an environment-space quaternion in `[x, y, z, w]` order.\n * The default identity quaternion leaves the source orientation unchanged;\n * changing it rotates the IBL at sample time without rebaking the source.\n *\n * @example Instant white ambient (no asset, no async):\n * world.spawn({ component: Skylight, data: {} });\n *\n * @example Dim warm ambient:\n * world.spawn({ component: Skylight, data: { color: [1, 0.9, 0.8], intensity: 0.3 } }); // color is [r, g, b]\n *\n * @example Full IBL from an HDR equirect (declarative -- no upload call):\n * // 1. resolve GUID from vite pack-index (see forgeax-engine-vite-plugin-pack)\n * import { AssetGuid } from '@forgeax/engine-pack/guid';\n * const guidRes = AssetGuid.parse('019e4a26-3c29-7420-af5d-20f2724a16b0');\n * if (!guidRes.ok) throw guidRes.error;\n * // 2. load the HDR equirect via the GUID-addressed pack route\n * const hdrRes = await engine.assets.loadByGuid<EquirectAsset>(guidRes.value);\n * if (!hdrRes.ok) throw hdrRes.error;\n * // 3. spawn the Skylight — the equirect handle activates the full IBL path;\n * // the cubemap + IBL precompute happen lazily inside the record arm.\n * world.spawn({ component: Skylight, data: { equirect: hdrRes.value } });\n */\nexport const Skylight = defineComponent('Skylight', {\n // The GPU equirect-to-cubemap projection is render-owned presentation\n // state. Record/restore preserves the portable lighting controls while the\n // render owner resolves this asset again on the target world.\n equirect: { type: 'shared<EquirectAsset>', simulationTransient: true },\n // color carries an explicit layer-2 default [1,1,1] (white); the array\n // layer-3 fallback is all-zero, so the default MUST be explicit (D-5).\n color: { type: 'array<f32, 3>', default: new Float32Array([1, 1, 1]) },\n intensity: { type: 'f32', default: 1.0 },\n rotation: { type: 'array<f32, 4>', default: new Float32Array([0, 0, 0, 1]) },\n});\n","// @forgeax/engine-render - SortKey (per-entity transparent sort override, f32).\n//\n// Schema: 1 f32 column (value). Entity-level sort override consumed by\n// `transparent-sort.ts` (M-3 w23): when present, SortKey.value REPLACES\n// the mode-formula result for this entity in the (layer, sortValue)\n// composite ordering. Override priority is higher than every\n// TransparentSortConfig mode computation (horizontal-z / Y-sort /\n// Y-Z-blend) so AI users can pin a single entity above / below the\n// procedural ordering without reshaping the entire scene.\n//\n// Like Layer, SortKey is a generic ECS renderer component — NOT a\n// 2D-only special. 3D entities may also carry SortKey to bias their\n// position inside the transparent bucket (charter P4 consistent\n// abstraction: same component drives both pipelines).\n//\n// AC-19 derivation audit row (4) names this file as the\n// `defineComponent` factory derivation. JSDoc surfaces the override\n// priority via @derives (ECS factory) annotation; the consumer side\n// of the override behaviour is implemented + verified in M-3 w16 +\n// w23, not here.\n//\n// @derives defineComponent factory (packages/ecs/src/component.ts) —\n// f32 is a legacy scalar type; its intrinsic properties (byteSize / viewCtor\n// / storage) live in TYPE_METADATA['f32'] (feat-20260602 M1).\n//\n// charter mapping: F1 (single-import barrel - joins Layer / Transform\n// / MeshFilter / MeshRenderer / Camera / DirectionalLight) +\n// P3 (explicit default 0.0 surfaces via the 4-layer fallback chain) +\n// P4 (consistent abstraction — generic render component, not 2D-only).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\n/**\n * Per-entity transparent-sort override.\n *\n * When attached to an entity inside the transparent bucket (M-3 w22),\n * `SortKey.value` REPLACES the result of `TransparentSortConfig.mode`\n * formula evaluation for this entity. Sort key range is the host's\n * choice — typical use is small (e.g. -10 ... +10) to keep the\n * composite (layer asc, sortValue asc) ordering predictable; large\n * magnitudes work but cross-layer biasing should usually go through\n * `Layer` instead.\n *\n * Override priority (M-3 w23 transparent-sort algorithm):\n *\n * if (world.has(entity, SortKey)) {\n * sortValue = world.get(entity, SortKey).value;\n * } else {\n * sortValue = modeFormula(mode, transform, sprite);\n * }\n *\n * SortKey lives alongside Layer in the (layer, sortValue) composite\n * key — Layer remains the primary key, SortKey replaces the secondary\n * key. This means a `Layer { value: 100 }` foreground entity with\n * `SortKey { value: -99 }` still draws AFTER a `Layer { value: 0 }`\n * background entity; SortKey biases WITHIN a layer, not ACROSS layers.\n *\n * @example Minimal spawn (no override, use mode formula):\n * world.spawn({ component: SortKey, data: {} }); // yields value=0\n *\n * @example Bias one sprite above the JRPG Y-sort formula:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 1, 0],\n * quat: [0, 0, 0, 1], scale: [1, 1, 1] } },\n * { component: Layer, data: { value: 0 } },\n * { component: SortKey, data: { value: -100 } },\n * );\n *\n * @example Spawn payload omitting SortKey — the 4-layer fallback fills 0:\n * // entity reads back SortKey only if explicitly attached;\n * // otherwise the mode-formula path is taken by transparent-sort.ts.\n */\nexport const SortKey = defineComponent('SortKey', {\n value: { type: 'f32', default: 0 },\n});\n","// @forgeax/engine-render - SpotLight (cone-restricted spot-light parameters).\n//\n// Schema: direction array<f32,3> + color array<f32,3> + intensity + range +\n// innerConeDeg + outerConeDeg (feat-20260709 M2: direction/color collapsed from\n// 6 per-axis scalar columns to two inline array<f32,3> columns). `position`\n// comes from the\n// Transform component; SpotLight requires a companion Transform on the same\n// entity (ECS query: `[Transform, SpotLight]`). Cone units are degrees on\n// the Component API surface (charter F1 prior-knowledge alignment with\n// Three.js); the host-side extract step pre-converts to `cosInner` /\n// `cosOuter` before GPU upload (plan-strategy section 8.2 naming convention\n// + D-3 host-side cone conversion).\n//\n// `range` units are meters; defaults to `10.0`. Runtime finite-range\n// attenuation is the Three r184 squared window; the KHR unsquared curve is an\n// import/reference boundary only. The cone falloff is layered on top with\n// `smoothstep(cosOuter, cosInner, dot(L, -direction))` (plan-strategy D-S4).\n//\n// 0 light + standard material -> physically correct black render. The\n// once-warn channel collapses to \"directionalCount + pointCount +\n// spotCount === 0\" (M5 / w25).\n//\n// feat-20260625-spot-light-shadow-mapping M1 w4: embedded castShadow (default true)\n// + 7 shadow fields (mapSize / depthBias / normalBias / nearPlane / farPlane /\n// pcfKernelSize / shadowIntensity) aligned with DirectionalLight vocabulary (plan-strategy D-6;\n// charter P4 consistent abstraction). Zero-config spawns cast spot shadows;\n// set castShadow:false to opt out (validate short-circuits on false, AC-03).\n// Shadow atlas cap of 4 is enforced at extract stage, not component layer (OOS-5).\n//\n// charter mapping: proposition 1 (single import + IDE autocomplete on\n// payload.outerConeDeg with no `as` cast) + proposition 3 (silent failure\n// -> explicit failure; spawn-time fail-fast on three bound violations) +\n// proposition 5 (consistent abstraction: outgoing direction semantics\n// shared with DirectionalLight; cone deg API + cos shader uniform\n// pre-conversion mirrors directional path's host-side `lightDir x intensity`\n// pre-multiplication).\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\nexport interface SpotLightProjector {\n readonly guid: string;\n readonly generation: number;\n readonly revision: number;\n}\n\nexport interface SpotLightAuthoring {\n /** Optional GUID-backed TextureAsset projector; absent keeps the normal spot path. */\n readonly projector?: SpotLightProjector;\n}\n\n/**\n * Cone-restricted spot light (KHR_lights_punctual `spot` type). Casts shadows\n * by default (castShadow defaults to true) — zero-config spawns project hard\n * PCF shadows through an independent spot depth atlas.\n *\n * `direction` @semantics outgoing -- points FROM light source TO the\n * scene (consistent with `DirectionalLight`; the shader internally negates\n * this vector to obtain the L vector for BRDF evaluation:\n * `let l = normalize(-light.direction)`). Extract owns the single\n * normalization step for the snapshot; URP and HDRP consume that normalized\n * value without re-normalizing. `position` source: the companion\n * `Transform` component on the same entity.\n *\n * `innerConeDeg` is the half-angle of the saturated bright region (cone\n * fully bright at the axis); `outerConeDeg` is the half-angle of the\n * falloff edge (cone fully dark beyond). Unit is **degrees**;\n * `outerConeDeg in (innerConeDeg, 90]` (KHR upper bound; spawn-time\n * validation rejects `outer > 90` and `outer <= inner`). The host-side\n * extract step converts both to `cos*` before GPU upload so the shader\n * only sees pre-computed cosines (plan-strategy D-S2 byte freeze; charter\n * P4 host pre-multiplication parity).\n *\n * `color` is linear-space rgb in `[0, 1]` per channel; `intensity` is candela;\n * `range` is in meters and defaults to `10.0`. Exposure is a camera output\n * operation and does not change the stored intensity.\n *\n * Shadow fields (embedded, aligned with DirectionalLight):\n * castShadow ∈ {true, false} — shadow opt-out gate (default true)\n * mapSize >= 1 — shadow map resolution per tile (default 2048)\n * depthBias — shadow acne bias (default 0.005)\n * normalBias — shadow acne normal offset (default 0.05)\n * nearPlane — shadow-camera near (default 0.1)\n * farPlane — shadow-camera far (default 50)\n * pcfKernelSize odd >= 1 — PCF kernel width (default 3)\n * shadowIntensity in [0,1] — residual light in shadow (default 1)\n *\n * Atlas capacity is capped at 4 castShadow spot lights by the extract stage;\n * the 5th light onward keeps direct illumination but shadowAtlasTile = -1\n * (AC-05: clip is programmatically detectable, light stays visible).\n *\n * @example Spawn a single spot light casting shadows (zero-config):\n * world.spawn(\n * { component: Transform, data: { pos: [0, 5, 0] } },\n * { component: SpotLight, data: { direction: [0, -1, 0] } }, // [x, y, z]\n * );\n *\n * @example Opt out of shadows:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 5, 0] } },\n * { component: SpotLight, data: { direction: [0, -1, 0], castShadow: false } },\n * );\n *\n * @example Explicit shadow config:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 5, 0] } },\n * { component: SpotLight, data: { direction: [0, -1, 0], depthBias: 0.01, normalBias: 0.08, mapSize: 1024 } },\n * );\n *\n * @example Minimal spawn -- defaults give neutral white at full strength, range 10m, KHR pi/4 cone:\n * world.spawn(\n * { component: Transform, data: { pos: [0, 5, 0] } },\n * { component: SpotLight, data: { direction: [0, -1, 0] } }, // [x, y, z]\n * );\n * // resolves to color=[1,1,1], intensity=1, range=10.0,\n * // innerConeDeg=0, outerConeDeg=45 (KHR pi/4 equivalent).\n */\nexport const SpotLight = defineComponent('SpotLight', {\n // direction has no default (D-5): omitting it lands the array layer-3\n // all-zero, which validate() rejects. color carries an explicit layer-2\n // default [1,1,1] (white); the array layer-3 fallback is all-zero.\n direction: { type: 'array<f32, 3>' },\n color: { type: 'array<f32, 3>', default: new Float32Array([1, 1, 1]) },\n intensity: { type: 'f32', default: 1 },\n range: { type: 'f32', default: 10.0 },\n innerConeDeg: { type: 'f32', default: 0 },\n outerConeDeg: { type: 'f32', default: 45 },\n iesProfile: { type: 'shared<IesProfileAsset>' },\n cookie: { type: 'shared<TextureAsset>' },\n rollDeg: { type: 'f32', default: 0 },\n // Shadow opt-out gate: defaults to true so zero-config spawns cast shadows.\n castShadow: { type: 'bool', default: true },\n // 7 shadow fields aligned with the shared light shadow vocabulary.\n mapSize: { type: 'f32', default: 2048 },\n depthBias: { type: 'f32', default: 0.005 },\n normalBias: { type: 'f32', default: 0.05 },\n nearPlane: { type: 'f32', default: 0.1 },\n farPlane: { type: 'f32', default: 50 },\n pcfKernelSize: { type: 'f32', default: 3 },\n // Three's SpotLight.shadow.intensity is the fraction of visibility applied\n // to a shadowed contribution. Keep it in the author-facing [0,1] domain;\n // extract/record transport this one fact to surface and volume consumers.\n shadowIntensity: { type: 'f32', default: 1 },\n // Shared TextureAsset identity; publication and residency remain owned by\n // the existing asset and GPU resource owners.\n projector: { type: 'shared<TextureAsset>', simulationTransient: true },\n});\n","import { defineComponent } from '@forgeax/engine-ecs';\n\n/** Numeric labels stored by the public Visibility enum field. */\nexport const VisibilityStateValue = Object.freeze({\n inherited: 0,\n hidden: 1,\n visible: 2,\n} as const);\n\n/** Author visibility intent accepted by the Visibility component. */\nexport type VisibilityState = keyof typeof VisibilityStateValue;\n\n/**\n * Decode the stored u32 without treating an unknown value as a valid state.\n * Invalid values are rejected at ECS write boundaries; undefined remains an\n * explicit signal for readers that inspect externally corrupted columns.\n */\nexport function visibilityStateFromU32(value: number): VisibilityState | undefined {\n switch (value) {\n case VisibilityStateValue.inherited:\n return 'inherited';\n case VisibilityStateValue.hidden:\n return 'hidden';\n case VisibilityStateValue.visible:\n return 'visible';\n default:\n return undefined;\n }\n}\n\n/**\n * Author intent for render participation. Omitted state is inherited and is\n * therefore visible when no valid parent intent is available.\n */\nexport const Visibility = defineComponent(\n 'Visibility',\n {\n state: {\n type: 'enum',\n default: VisibilityStateValue.inherited,\n labels: VisibilityStateValue,\n },\n },\n {\n meta: {\n quickStart: 'Attach Visibility to author render participation intent.',\n diagnostics: 'Compare the ECS state with resolveVisibility and renderer.visibilityStats.',\n recovery: 'Use structured ECS write errors and repair the owning scene relation.',\n boundaries:\n 'Visibility does not own camera, picking, lifecycle, assets, or VFX shadow policy.',\n },\n },\n);\n","import { err, ok, type Result } from '@forgeax/engine-types';\nimport {\n type DepthOfFieldData,\n type DepthOfFieldQuality,\n DepthOfFieldQualityValue,\n type DepthOfFieldSide,\n DepthOfFieldSideValue,\n depthOfFieldQualityFromF32,\n depthOfFieldSideFromF32,\n} from '../../components/depth-of-field';\n\nexport const DEPTH_OF_FIELD_PARAMS_BYTE_SIZE = 64;\n\n// Camera component values cross the UBO boundary as f32. Keep bounds in that\n// same representation so the authored decimal boundary 0.7 remains valid\n// after quantization.\nconst MIN_F_STOP = Math.fround(0.7);\nconst MAX_F_STOP = Math.fround(32);\nconst MAX_LINEAR_DEPTH_RAW = Math.fround(1 - 2 ** -24);\n\nexport interface DepthOfFieldParams {\n readonly focusDistance: number;\n readonly fStop: number;\n readonly sensorHeight: number;\n readonly maxRadiusPixels: number;\n readonly quality: DepthOfFieldQuality;\n readonly blurSide: DepthOfFieldSide;\n readonly focalLength: number;\n}\n\nexport const DEFAULT_DEPTH_OF_FIELD_PARAMS: DepthOfFieldParams = Object.freeze({\n focusDistance: 8,\n fStop: 2.8,\n sensorHeight: 0.024,\n maxRadiusPixels: 16,\n quality: 'medium',\n blurSide: 'both',\n focalLength: 0,\n});\n\nfunction quantizeF32(value: number): number {\n return Math.fround(value);\n}\n\nexport type DepthOfFieldErrorCode =\n | 'depth-of-field-invalid-params'\n | 'depth-of-field-orthographic-unsupported';\n\nexport interface DepthOfFieldInvalidParamsDetail {\n readonly field: string;\n readonly value: unknown;\n readonly expected: string;\n readonly bound?: readonly [number, number] | undefined;\n}\n\nexport interface DepthOfFieldOrthographicDetail {\n readonly projection: 'orthographic';\n}\n\nexport type DepthOfFieldErrorDetail =\n | DepthOfFieldInvalidParamsDetail\n | DepthOfFieldOrthographicDetail;\n\n/** Detached validation facts carried from extract to renderer inspection. */\nexport interface DepthOfFieldRequestFailure {\n readonly code: DepthOfFieldErrorCode;\n readonly detail: DepthOfFieldErrorDetail;\n readonly expected: string;\n readonly hint: string;\n}\n\nexport class DepthOfFieldValidationError extends Error {\n readonly code: DepthOfFieldErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail: DepthOfFieldErrorDetail;\n\n constructor(\n code: DepthOfFieldErrorCode,\n detail: DepthOfFieldErrorDetail,\n expected: string,\n hint: string,\n ) {\n super(`${code}: ${expected}`);\n this.name = 'DepthOfFieldValidationError';\n this.code = code;\n this.expected = expected;\n this.hint = hint;\n this.detail = detail;\n }\n}\n\nexport function depthOfFieldRequestFailure(\n error: DepthOfFieldValidationError,\n): DepthOfFieldRequestFailure {\n return Object.freeze({\n code: error.code,\n detail: error.detail,\n expected: error.expected,\n hint: error.hint,\n });\n}\n\n/**\n * Resolve the params used by a frame when authoring validation failed.\n * Invalid/unsupported requests stay visible as errors, but an already\n * accepted DoF graph must keep receiving its last-known-good UBO until the\n * author submits a valid replacement or explicitly removes the component.\n */\nexport function resolveDepthOfFieldFrameParams(\n requested: DepthOfFieldParams | undefined,\n requestFailure: DepthOfFieldRequestFailure | undefined,\n accepted: DepthOfFieldParams | undefined,\n): DepthOfFieldParams | undefined {\n if (requested !== undefined) return requested;\n if (\n requestFailure === undefined ||\n requestFailure.code === 'depth-of-field-orthographic-unsupported'\n ) {\n return undefined;\n }\n return accepted;\n}\n\nexport interface DepthOfFieldCameraInput {\n readonly projection: 'perspective' | 'orthographic';\n readonly fov: number;\n readonly near: number;\n readonly far: number;\n}\n\nfunction invalid(\n field: string,\n value: unknown,\n expected: string,\n bound?: readonly [number, number],\n): DepthOfFieldValidationError {\n return new DepthOfFieldValidationError(\n 'depth-of-field-invalid-params',\n { field, value, expected, ...(bound === undefined ? {} : { bound }) },\n expected,\n `set ${field} to ${expected}`,\n );\n}\n\nfunction focalLength(sensorHeight: number, fov: number): number {\n return sensorHeight / (2 * Math.tan(fov / 2));\n}\n\nfunction opticalCocScale(\n params: Pick<DepthOfFieldParams, 'focalLength' | 'sensorHeight' | 'fStop' | 'focusDistance'>,\n): number {\n // This is evaluated on the CPU once per frame. Keep the ratios separate so\n // the final f32 coefficient does not inherit an avoidable focalLength^2\n // overflow.\n return (\n (params.focalLength / params.sensorHeight / (2 * params.fStop)) *\n (params.focalLength / (params.focusDistance - params.focalLength))\n );\n}\n\nfunction frameCocCoefficient(\n params: Pick<DepthOfFieldParams, 'focalLength' | 'sensorHeight' | 'fStop' | 'focusDistance'>,\n outputHeight: number,\n): number {\n return quantizeF32(quantizeF32(outputHeight) * opticalCocScale(params));\n}\n\ninterface DepthOfFieldFrameValues {\n readonly focusDistance: number;\n readonly fStop: number;\n readonly sensorHeight: number;\n readonly focalLength: number;\n readonly maxRadiusPixels: number;\n readonly outputHeight: number;\n readonly near: number;\n readonly far: number;\n readonly cocCoefficient: number;\n}\n\nfunction resolveDepthOfFieldFrameValues(\n params: DepthOfFieldParams,\n input: {\n readonly outputHeight: number;\n readonly near: number;\n readonly far: number;\n readonly useTemporalDepth: boolean;\n },\n): Result<DepthOfFieldFrameValues, DepthOfFieldValidationError> {\n const focusDistance = quantizeF32(params.focusDistance);\n const fStop = quantizeF32(params.fStop);\n const sensorHeight = quantizeF32(params.sensorHeight);\n const focal = quantizeF32(params.focalLength);\n const maxRadiusPixels = quantizeF32(params.maxRadiusPixels);\n const outputHeight = quantizeF32(input.outputHeight);\n const near = quantizeF32(input.near);\n const far = quantizeF32(input.far);\n const finitePositiveFields: readonly [string, number, number][] = [\n ['focusDistance', focusDistance, params.focusDistance],\n ['sensorHeight', sensorHeight, params.sensorHeight],\n ['focalLength', focal, params.focalLength],\n ['near', near, input.near],\n ['far', far, input.far],\n ];\n for (const [field, value, raw] of finitePositiveFields) {\n if (!Number.isFinite(value) || value <= 0) {\n return err(invalid(field, raw, 'a finite positive f32 value'));\n }\n }\n if (!Number.isFinite(fStop) || fStop < MIN_F_STOP || fStop > MAX_F_STOP) {\n return err(\n invalid('fStop', params.fStop, 'a finite f32 value in [0.7, 32]', [MIN_F_STOP, MAX_F_STOP]),\n );\n }\n if (!Number.isFinite(maxRadiusPixels) || maxRadiusPixels < 0 || maxRadiusPixels > 32) {\n return err(\n invalid('maxRadiusPixels', params.maxRadiusPixels, 'a finite f32 value in [0, 32]', [0, 32]),\n );\n }\n if (!Number.isFinite(outputHeight) || outputHeight <= 0) {\n return err(invalid('outputHeight', input.outputHeight, 'a finite positive f32 value'));\n }\n if (far <= near) {\n return err(invalid('near/far', [input.near, input.far], 'finite f32 near > 0 and far > near'));\n }\n if (focusDistance <= focal) {\n return err(invalid('focusDistance', params.focusDistance, 'greater than focalLength in f32'));\n }\n\n // linearDepth() uses this ratio and denominator order in both WGSL\n // variants. Reject a ratio that disappears at f32 precision, then check the\n // near, mid and largest-valid raw-depth samples for finite denominators and\n // reconstructed distances. The denominator is strictly positive for valid\n // raw depth, so no world-unit epsilon belongs in the shader.\n const depthRatio = quantizeF32(near / far);\n if (!Number.isFinite(depthRatio) || depthRatio <= 0) {\n return err(invalid('near/far ratio', depthRatio, 'a finite positive f32 value'));\n }\n for (const raw of [quantizeF32(2 ** -149), 0.5, MAX_LINEAR_DEPTH_RAW]) {\n const oneMinusRaw = quantizeF32(1 - raw);\n const weightedRatio = quantizeF32(raw * depthRatio);\n const denominator = quantizeF32(oneMinusRaw + weightedRatio);\n const distance = quantizeF32(near / denominator);\n if (\n !Number.isFinite(oneMinusRaw) ||\n oneMinusRaw <= 0 ||\n !Number.isFinite(weightedRatio) ||\n !Number.isFinite(denominator) ||\n denominator <= 0 ||\n !Number.isFinite(distance) ||\n distance <= 0\n ) {\n return err(invalid('linearDepth', distance, 'finite positive f32 reconstruction'));\n }\n }\n\n const cocCoefficient = frameCocCoefficient(\n {\n focusDistance,\n fStop,\n sensorHeight,\n focalLength: focal,\n },\n outputHeight,\n );\n if (!Number.isFinite(cocCoefficient) || cocCoefficient <= 0) {\n return err(\n invalid('cocCoefficient', cocCoefficient, 'a finite positive value representable as f32'),\n );\n }\n // The shader evaluates C * (1 - focus / depth). Check each f32 operation at\n // the projection endpoints before the UBO is written.\n for (const [field, depth] of [\n ['near', near],\n ['far', far],\n ] as const) {\n const focusOverDepth = quantizeF32(focusDistance / depth);\n const depthFactor = quantizeF32(1 - focusOverDepth);\n const radius = quantizeF32(cocCoefficient * depthFactor);\n if (\n !Number.isFinite(focusOverDepth) ||\n !Number.isFinite(depthFactor) ||\n !Number.isFinite(radius)\n ) {\n return err(invalid(`coc.${field}`, radius, 'a finite value representable as f32'));\n }\n }\n\n return ok({\n focusDistance,\n fStop,\n sensorHeight,\n focalLength: focal,\n maxRadiusPixels,\n outputHeight,\n near,\n far,\n cocCoefficient,\n });\n}\n\n/**\n * Validate the values that cross the f32 camera UBO boundary for one frame.\n * Camera and DoF schemas already use f32 columns, but direct callers and\n * synthetic frame tests can still supply wider JS numbers. Quantize first so\n * admission and the WGSL consumer make the same decision.\n */\nexport function validateDepthOfFieldFrameParams(\n params: DepthOfFieldParams,\n input: {\n readonly outputHeight: number;\n readonly near: number;\n readonly far: number;\n readonly useTemporalDepth: boolean;\n },\n): Result<void, DepthOfFieldValidationError> {\n const resolved = resolveDepthOfFieldFrameValues(params, input);\n return resolved.ok ? ok(undefined) : resolved;\n}\n\n/**\n * Validate and derive one camera DoF declaration at the frame admission seam.\n * The returned focal length is a derived fact; callers never author it.\n */\nexport function validateDepthOfFieldParams(\n input: Partial<DepthOfFieldData> | undefined,\n camera?: DepthOfFieldCameraInput,\n): Result<DepthOfFieldParams, DepthOfFieldValidationError> {\n if (camera?.projection === 'orthographic') {\n return err(\n new DepthOfFieldValidationError(\n 'depth-of-field-orthographic-unsupported',\n { projection: 'orthographic' },\n 'DepthOfField requires a perspective Camera',\n 'use a perspective Camera or remove the DepthOfField component',\n ),\n );\n }\n const value = input ?? {};\n const focusDistance = quantizeF32(\n value.focusDistance ?? DEFAULT_DEPTH_OF_FIELD_PARAMS.focusDistance,\n );\n const fStop = quantizeF32(value.fStop ?? DEFAULT_DEPTH_OF_FIELD_PARAMS.fStop);\n const sensorHeight = quantizeF32(\n value.sensorHeight ?? DEFAULT_DEPTH_OF_FIELD_PARAMS.sensorHeight,\n );\n const maxRadiusPixels = quantizeF32(\n value.maxRadiusPixels ?? DEFAULT_DEPTH_OF_FIELD_PARAMS.maxRadiusPixels,\n );\n const qualityValue = quantizeF32(value.quality ?? DepthOfFieldQualityValue.medium);\n const blurSideValue = quantizeF32(value.blurSide ?? DepthOfFieldSideValue.both);\n const quality = depthOfFieldQualityFromF32(qualityValue);\n const blurSide = depthOfFieldSideFromF32(blurSideValue);\n if (!Number.isFinite(focusDistance) || focusDistance <= 0) {\n return err(\n invalid('focusDistance', value.focusDistance ?? focusDistance, 'a finite positive f32 value'),\n );\n }\n if (!Number.isFinite(fStop) || fStop < MIN_F_STOP || fStop > MAX_F_STOP) {\n return err(\n invalid('fStop', value.fStop ?? fStop, 'a finite f32 value in [0.7, 32]', [\n MIN_F_STOP,\n MAX_F_STOP,\n ]),\n );\n }\n if (!Number.isFinite(sensorHeight) || sensorHeight <= 0) {\n return err(\n invalid('sensorHeight', value.sensorHeight ?? sensorHeight, 'a finite positive f32 value'),\n );\n }\n if (!Number.isFinite(maxRadiusPixels) || maxRadiusPixels < 0 || maxRadiusPixels > 32) {\n return err(\n invalid(\n 'maxRadiusPixels',\n value.maxRadiusPixels ?? maxRadiusPixels,\n 'a finite f32 value in [0, 32]',\n [0, 32],\n ),\n );\n }\n if (quality === undefined) {\n return err(invalid('quality', qualityValue, 'DepthOfFieldQualityValue.low, medium, or high'));\n }\n if (blurSide === undefined) {\n return err(invalid('blurSide', blurSideValue, 'DepthOfFieldSideValue.both, near, or far'));\n }\n\n let focal = DEFAULT_DEPTH_OF_FIELD_PARAMS.focalLength;\n if (camera !== undefined) {\n const fov = quantizeF32(camera.fov);\n const near = quantizeF32(camera.near);\n const far = quantizeF32(camera.far);\n if (!Number.isFinite(fov) || fov <= 0 || fov >= Math.PI) {\n return err(invalid('fov', camera.fov, 'a finite f32 value in (0, PI)'));\n }\n if (!Number.isFinite(near) || !Number.isFinite(far) || near <= 0 || far <= near) {\n return err(\n invalid('near/far', [camera.near, camera.far], 'finite f32 near > 0 and far > near'),\n );\n }\n focal = quantizeF32(focalLength(sensorHeight, fov));\n if (!Number.isFinite(focal) || focal <= 0) {\n return err(invalid('focalLength', focal, 'a finite positive f32 value'));\n }\n if (focusDistance < near || focusDistance > far) {\n return err(\n invalid('focusDistance', focusDistance, `a value in [${near}, ${far}]`, [near, far]),\n );\n }\n if (focusDistance <= focal) {\n return err(\n invalid('focusDistance', focusDistance, `greater than focalLength in f32 (${focal})`),\n );\n }\n }\n return ok(\n Object.freeze({\n focusDistance,\n fStop,\n sensorHeight,\n maxRadiusPixels,\n quality,\n blurSide,\n focalLength: focal,\n }),\n );\n}\n\nexport function resolveDepthOfFieldParams(\n input: Partial<DepthOfFieldData> | undefined,\n camera?: DepthOfFieldCameraInput,\n): Result<DepthOfFieldParams | undefined, DepthOfFieldValidationError> {\n if (input === undefined) return ok(undefined);\n return validateDepthOfFieldParams(input, camera);\n}\n\nexport function depthOfFieldTapCount(quality: DepthOfFieldQuality): 16 | 32 | 64 {\n switch (quality) {\n case 'low':\n return 16;\n case 'medium':\n return 32;\n case 'high':\n return 64;\n }\n}\n\nexport function depthOfFieldSideCode(side: DepthOfFieldSide): 0 | 1 | 2 {\n switch (side) {\n case 'both':\n return DepthOfFieldSideValue.both;\n case 'near':\n return DepthOfFieldSideValue.near;\n case 'far':\n return DepthOfFieldSideValue.far;\n }\n}\n\nexport function depthOfFieldQualityCode(quality: DepthOfFieldQuality): 0 | 1 | 2 {\n switch (quality) {\n case 'low':\n return DepthOfFieldQualityValue.low;\n case 'medium':\n return DepthOfFieldQualityValue.medium;\n case 'high':\n return DepthOfFieldQualityValue.high;\n }\n}\n\n/** Signed thin-lens circle-of-confusion radius in final output pixels. */\nexport function signedDepthOfFieldCoC(\n params: Pick<DepthOfFieldParams, 'focalLength' | 'sensorHeight' | 'fStop' | 'focusDistance'> &\n Partial<Pick<DepthOfFieldParams, 'maxRadiusPixels'>>,\n viewDepth: number,\n outputHeight: number,\n): number {\n if (\n !Number.isFinite(viewDepth) ||\n viewDepth <= 0 ||\n !Number.isFinite(outputHeight) ||\n outputHeight <= 0 ||\n !Number.isFinite(params.focalLength) ||\n params.focalLength <= 0 ||\n !Number.isFinite(params.sensorHeight) ||\n params.sensorHeight <= 0 ||\n !Number.isFinite(params.fStop) ||\n params.fStop <= 0 ||\n !Number.isFinite(params.focusDistance) ||\n params.focusDistance <= params.focalLength\n ) {\n return 0;\n }\n const focusDistance = quantizeF32(params.focusDistance);\n const depth = quantizeF32(viewDepth);\n const focalLength = quantizeF32(params.focalLength);\n const sensorHeight = quantizeF32(params.sensorHeight);\n const fStop = quantizeF32(params.fStop);\n const coefficient = frameCocCoefficient(\n { focusDistance, focalLength, sensorHeight, fStop },\n outputHeight,\n );\n const depthFactor = quantizeF32(1 - quantizeF32(focusDistance / depth));\n const radius = quantizeF32(coefficient * depthFactor);\n const limit = Number.isFinite(params.maxRadiusPixels)\n ? quantizeF32(params.maxRadiusPixels as number)\n : Number.POSITIVE_INFINITY;\n return Math.max(-limit, Math.min(limit, Number.isFinite(radius) ? radius : 0));\n}\n\n/** Pack the one renderer-owned per-frame DoF UBO (4 x vec4, 64 bytes). */\nexport function packDepthOfFieldParams(\n params: DepthOfFieldParams,\n input: {\n readonly outputHeight: number;\n readonly near: number;\n readonly far: number;\n readonly useTemporalDepth: boolean;\n },\n): Uint8Array {\n const frameValues = resolveDepthOfFieldFrameValues(params, input);\n if (!frameValues.ok) throw frameValues.error;\n const {\n focusDistance,\n fStop,\n sensorHeight,\n focalLength: focal,\n outputHeight,\n maxRadiusPixels,\n near,\n far,\n cocCoefficient,\n } = frameValues.value;\n const payload = new Float32Array(DEPTH_OF_FIELD_PARAMS_BYTE_SIZE / 4);\n // row3.x is the frame CoC coefficient; the remaining reserved lanes stay\n // zero so the existing 64-byte binding contract remains unchanged.\n payload.set([\n focusDistance,\n fStop,\n sensorHeight,\n focal,\n outputHeight,\n maxRadiusPixels,\n depthOfFieldSideCode(params.blurSide),\n depthOfFieldQualityCode(params.quality),\n near,\n far,\n input.useTemporalDepth ? 1 : 0,\n 0, // row2.w reserved\n cocCoefficient, // row3.x / WGSL reserved.x\n 0,\n 0,\n 0,\n ]);\n return new Uint8Array(payload.buffer);\n}\n","import { Entity, type EntityHandle, type World } from '@forgeax/engine-ecs';\nimport type { RhiCaps } from '@forgeax/engine-rhi';\nimport { Transform } from '@forgeax/engine-scene';\nimport { DirectionalLight } from '../components/directional-light';\nimport { PointLight } from '../components/point-light';\nimport { SpotLight } from '../components/spot-light';\n\n/**\n * The single capability predicate for the authored volumetric-fog producer.\n * Shader sources are part of the device-bound bundle: compute/storage alone\n * is not enough to claim that the three fused graph passes can execute.\n */\nexport function hasVolumetricFogCapability(\n caps: Pick<RhiCaps, 'compute' | 'storageTexture'>,\n shaders: unknown,\n): boolean {\n return caps.compute && caps.storageTexture && shaders !== undefined;\n}\n\nexport type VolumetricFogLightKind = 'directional' | 'point' | 'spot';\n// The exact parity authoring mode is the closed `point-spot` pair.\n\nexport type VolumetricFogLightResolution =\n | {\n readonly status: 'available';\n readonly entity: EntityHandle;\n readonly kind: VolumetricFogLightKind;\n }\n | {\n readonly status: 'unresolved';\n readonly reason: 'missing-entity' | 'wrong-component' | 'ambiguous';\n readonly entity: EntityHandle;\n readonly expected: 'DirectionalLight | PointLight | SpotLight';\n readonly actual: string;\n readonly hint: string;\n };\n\nexport type VolumetricFogLightPairResolution =\n | {\n readonly status: 'available';\n readonly mode: 'point-spot';\n readonly point: EntityHandle;\n readonly spot: EntityHandle;\n }\n | {\n readonly status: 'unresolved';\n readonly reason: 'missing-entity' | 'same-entity' | 'wrong-component';\n readonly point: EntityHandle;\n readonly spot: EntityHandle;\n readonly expected: 'PointLight + SpotLight in the same World';\n readonly actual: string;\n readonly hint: string;\n };\n\n/** Resolve the narrow official Point+Spot pair without creating a light owner. */\nexport function resolveVolumetricFogLightPair(\n world: World,\n point: EntityHandle,\n spot: EntityHandle,\n): VolumetricFogLightPairResolution {\n const expected = 'PointLight + SpotLight in the same World' as const;\n if (!world.get(point, Entity).ok || !world.get(spot, Entity).ok) {\n return {\n status: 'unresolved',\n reason: 'missing-entity',\n point,\n spot,\n expected,\n actual: 'point or spot entity is absent from this World',\n hint: 'assign two live entities from the same World and retry',\n };\n }\n if (point === spot) {\n return {\n status: 'unresolved',\n reason: 'same-entity',\n point,\n spot,\n expected,\n actual: 'PointLight and SpotLight share one EntityHandle',\n hint: 'spawn PointLight and SpotLight on two different entities',\n };\n }\n const pointValid = world.hasComponent(point, PointLight) && world.hasComponent(point, Transform);\n const spotValid = world.hasComponent(spot, SpotLight) && world.hasComponent(spot, Transform);\n if (!pointValid || !spotValid) {\n return {\n status: 'unresolved',\n reason: 'wrong-component',\n point,\n spot,\n expected,\n actual: `pointValid=${pointValid}; spotValid=${spotValid}`,\n hint: 'attach PointLight and SpotLight with Transform to separate same-World entities',\n };\n }\n return { status: 'available', mode: 'point-spot', point, spot };\n}\n\n/**\n * Resolve the required VolumetricFog.light reference in its owning World.\n * PointLight is a valid primary selection for the exact Point+Spot pair.\n * EntityHandle has no portable world tag, so a handle absent from this World\n * (the same World contract) is reported as missing-entity;\n * is reported as missing-entity; callers must not manufacture a light.\n */\nexport function resolveSelectedVolumetricLight(\n world: World,\n entity: EntityHandle,\n): VolumetricFogLightResolution {\n const expected = 'DirectionalLight | PointLight | SpotLight' as const;\n if (!world.get(entity, Entity).ok) {\n return {\n status: 'unresolved',\n reason: 'missing-entity',\n entity,\n expected,\n actual: 'missing or foreign World entity',\n hint: 'assign VolumetricFog.light to a live DirectionalLight or SpotLight in this World',\n };\n }\n const hasDirectional = world.hasComponent(entity, DirectionalLight);\n const hasSpot = world.hasComponent(entity, SpotLight);\n if (hasDirectional && hasSpot) {\n return {\n status: 'unresolved',\n reason: 'ambiguous',\n entity,\n expected,\n actual: 'DirectionalLight + SpotLight',\n hint: 'remove one mutually exclusive light component from the selected entity',\n };\n }\n if (hasDirectional) return { status: 'available', entity, kind: 'directional' };\n if (world.hasComponent(entity, PointLight) && world.hasComponent(entity, Transform)) {\n return { status: 'available', entity, kind: 'point' };\n }\n if (hasSpot && world.hasComponent(entity, Transform)) {\n return { status: 'available', entity, kind: 'spot' };\n }\n const actual = hasSpot\n ? 'SpotLight without Transform'\n : world.hasComponent(entity, PointLight)\n ? 'PointLight'\n : 'other component';\n return {\n status: 'unresolved',\n reason: 'wrong-component',\n entity,\n expected,\n actual,\n hint: 'add exactly one supported light component and a Transform for PointLight or SpotLight in the same World',\n };\n}\n\nexport interface IntegratedVolumeResource {\n /** Logical resolved-volume identity; this is not a physical graph resource. */\n readonly identity: 'volume-integrated';\n readonly format: 'rgba16float';\n readonly stage: 'resolved';\n}\n\nexport type VolumeConsumer = 'opaque' | 'transparent' | 'sprite' | 'vfx' | 'custom';\n\nexport function resolveIntegratedVolumeConsumer(\n resource: IntegratedVolumeResource,\n consumer: VolumeConsumer,\n): { readonly consumer: VolumeConsumer; readonly resource: IntegratedVolumeResource } {\n // The volume owner supplies this prepared logical resource. Consumers only\n // receive its identity and format; they never allocate a view or own the\n // history lifetime here.\n return { consumer, resource };\n}\n","import { type Mat4, mat4, type Vec3Like } from '@forgeax/engine-math';\nimport { CUBE_CAMERA_FACE_ORDER, type CubeCameraFace } from '../components/cube-camera';\n\nexport interface CubeCameraFaceView {\n readonly position: Vec3Like;\n readonly face: CubeCameraFace;\n readonly direction: readonly [number, number, number];\n readonly up: readonly [number, number, number];\n readonly near: number;\n readonly far: number;\n readonly view: Mat4;\n readonly projection: Mat4;\n readonly viewProjection: Mat4;\n}\n\nexport interface CubeCameraFaceViewInput {\n readonly position: Vec3Like;\n readonly near: number;\n readonly far: number;\n}\n\nconst FACE_ORIENTATION: ReadonlyArray<{\n readonly direction: readonly [number, number, number];\n readonly up: readonly [number, number, number];\n}> = [\n { direction: [1, 0, 0], up: [0, 1, 0] },\n { direction: [-1, 0, 0], up: [0, 1, 0] },\n { direction: [0, 1, 0], up: [0, 0, -1] },\n { direction: [0, -1, 0], up: [0, 0, 1] },\n { direction: [0, 0, 1], up: [0, 1, 0] },\n { direction: [0, 0, -1], up: [0, 1, 0] },\n];\n\nfunction assertRange(near: number, far: number): void {\n if (!Number.isFinite(near) || near <= 0 || !Number.isFinite(far) || far <= near) {\n throw new RangeError('CubeCamera requires finite near > 0 and far > near.');\n }\n}\n\n/** Build the only supported +X,-X,+Y,-Y,+Z,-Z cube orientation. */\nexport function buildCubeCameraFaceViews(input: CubeCameraFaceViewInput): CubeCameraFaceView[] {\n assertRange(input.near, input.far);\n const views: CubeCameraFaceView[] = [];\n for (const [index, face] of CUBE_CAMERA_FACE_ORDER.entries()) {\n const orientation = FACE_ORIENTATION[index];\n if (orientation === undefined)\n throw new Error(`CubeCamera face orientation missing at ${index}`);\n const target: Vec3Like = [\n (input.position[0] ?? 0) + orientation.direction[0],\n (input.position[1] ?? 0) + orientation.direction[1],\n (input.position[2] ?? 0) + orientation.direction[2],\n ];\n const view = mat4.lookAt(mat4.create(), input.position, target, orientation.up);\n const projection = mat4.perspective(mat4.create(), Math.PI / 2, 1, input.near, input.far);\n const viewProjection = mat4.multiply(mat4.create(), projection, view);\n views.push({\n position: input.position,\n face,\n direction: orientation.direction,\n up: orientation.up,\n near: input.near,\n far: input.far,\n view,\n projection,\n viewProjection,\n });\n }\n return views;\n}\n","import type { AssetErrorDetail, AssetGuid, MeshAsset } from '@forgeax/engine-types';\n\nexport type MeshMaterialBindingSource = 'renderer-override' | 'mesh-default' | 'engine-default';\n\nexport interface MeshMaterialBindingDiagnostic {\n readonly code:\n | 'mesh-renderer-material-override-invalid'\n | 'mesh-renderer-material-override-overflow';\n readonly slotIndex: number;\n readonly handle?: number;\n /** Structured detail mirrors the renderer error for the active frame. */\n readonly detail?: Readonly<AssetErrorDetail>;\n}\n\n/** Detached final-frame receipt for the Standard material IBL binding chain. */\nexport interface IblBindingResourceInspection {\n readonly viewIdentity: number;\n readonly samplerIdentity: number;\n readonly deviceGeneration: number;\n}\n\nexport interface IblBindingEntryInspection {\n readonly binding: number;\n readonly kind: 'textureView' | 'sampler' | 'buffer';\n readonly resourceIdentity: number;\n}\n\nexport interface IblBindingInspection {\n readonly status: 'binding-chain-consistent' | 'binding-chain-mismatch';\n readonly frameId: number;\n readonly deviceGeneration: number;\n readonly active: 'active' | 'fallback';\n readonly cache: {\n readonly identity: number;\n readonly generation: number;\n readonly prefilterMipCount: number;\n readonly prefilterViewMipCount: number;\n };\n readonly sampler: {\n readonly expected: {\n readonly magFilter: 'linear';\n readonly minFilter: 'linear';\n readonly mipmapFilter: 'linear';\n readonly addressModeU: 'clamp-to-edge';\n readonly addressModeV: 'clamp-to-edge';\n readonly addressModeW: 'clamp-to-edge';\n };\n readonly identities: readonly number[];\n };\n readonly resources: {\n readonly irradiance: IblBindingResourceInspection;\n readonly prefilter: IblBindingResourceInspection;\n readonly brdfLut: IblBindingResourceInspection;\n readonly intensityBufferIdentity: number;\n };\n readonly material?: {\n readonly bindGroupIdentity: number;\n readonly materialBglIdentity: number;\n readonly cache: 'hit' | 'miss';\n readonly skylightBindingStart: number;\n readonly entries: readonly IblBindingEntryInspection[];\n readonly reflectionBindings: readonly number[];\n };\n readonly pipeline?: {\n readonly pipelineIdentity: number;\n readonly effectiveMaterialLayoutIdentity: string | undefined;\n readonly materialBglIdentity: number;\n readonly bindGroupIdentity: number;\n readonly drawFrameId: number;\n };\n readonly errors: readonly string[];\n}\n\nexport interface ResolvedMeshMaterialBinding {\n readonly handle: number;\n readonly source: MeshMaterialBindingSource;\n}\n\n/** Lifecycle values projected from an already prepared resident binding. */\nexport type MeshMaterialBindingReadiness = 'ready' | 'pending' | 'failed' | 'last-known-good';\n\n/** Structured producer failure retained by the renderer's bounded projection. */\nexport interface MeshMaterialBindingPreparationFailure {\n readonly code: string;\n readonly expected: string;\n readonly hint: string;\n readonly detail?: Readonly<Record<string, unknown>>;\n}\n\nexport interface MeshMaterialBindingSamplerObservation {\n readonly handle: number;\n readonly resident: boolean;\n}\n\nexport interface MeshMaterialBindingTextureObservation {\n readonly handle: number;\n readonly mipLevelCount: number;\n}\n\n/**\n * One material-slot's bounded resident projection. The renderer reports only\n * resources it actually resolved for the slot; Pack/AssetRegistry lifecycle\n * records stay owned by the producer and are never copied here.\n */\nexport interface MeshMaterialBindingResidency {\n readonly readiness: MeshMaterialBindingReadiness;\n readonly samplers: readonly MeshMaterialBindingSamplerObservation[];\n readonly textures: readonly MeshMaterialBindingTextureObservation[];\n readonly preparationFailure?: MeshMaterialBindingPreparationFailure;\n}\n\n/** Public read-only observation of the bindings used by the last frame. */\nexport interface MeshMaterialBindingObservation {\n readonly worldId: number;\n /** Stable World identity for cross-world inspection; worldId is only a frame slot. */\n readonly worldIdentity?: string;\n readonly entityKey: number;\n readonly bindings: readonly ResolvedMeshMaterialBinding[];\n readonly diagnostics: readonly MeshMaterialBindingDiagnostic[];\n /** One resident projection per resolved material slot. */\n readonly residency: readonly MeshMaterialBindingResidency[];\n}\n\nexport interface MeshMaterialBindingSummary {\n readonly total: number;\n readonly ready: number;\n readonly pending: number;\n readonly failed: number;\n readonly lastKnownGood: number;\n readonly textureCount: number;\n readonly samplerCount: number;\n}\n\nconst EMPTY_RESIDENCY: MeshMaterialBindingResidency = Object.freeze({\n readiness: 'pending',\n samplers: Object.freeze([]),\n textures: Object.freeze([]),\n});\n\n/**\n * Build the sole renderer observation projection from the resident seam.\n * Missing facts remain `pending`; they are never guessed from a URL, asset\n * name, or authoring field. Slot cardinality is normalized so aggregation is\n * deterministic even while a preparation candidate is incomplete.\n */\nexport function projectMeshMaterialBindingObservation(input: {\n readonly worldId: number;\n readonly worldIdentity?: string;\n readonly entityKey: number;\n readonly bindings: readonly ResolvedMeshMaterialBinding[];\n readonly diagnostics: readonly MeshMaterialBindingDiagnostic[];\n readonly residency?: readonly MeshMaterialBindingResidency[];\n}): MeshMaterialBindingObservation {\n const residency = input.bindings.map((_, index) => {\n const value = input.residency?.[index] ?? EMPTY_RESIDENCY;\n return Object.freeze({\n ...value,\n samplers: Object.freeze(value.samplers.map((sampler) => Object.freeze({ ...sampler }))),\n textures: Object.freeze(value.textures.map((texture) => Object.freeze({ ...texture }))),\n ...(value.preparationFailure === undefined\n ? {}\n : {\n preparationFailure: Object.freeze({\n ...value.preparationFailure,\n ...(value.preparationFailure.detail === undefined\n ? {}\n : { detail: Object.freeze({ ...value.preparationFailure.detail }) }),\n }),\n }),\n });\n });\n return {\n worldId: input.worldId,\n ...(input.worldIdentity === undefined ? {} : { worldIdentity: input.worldIdentity }),\n entityKey: input.entityKey,\n bindings: Object.freeze([...input.bindings]),\n diagnostics: Object.freeze([...input.diagnostics]),\n residency: Object.freeze(residency),\n };\n}\n\n/** Recompute bounded readiness/resource counts from retained observations. */\nexport function summarizeMeshMaterialBindings(\n observations: readonly MeshMaterialBindingObservation[],\n): MeshMaterialBindingSummary {\n let ready = 0;\n let pending = 0;\n let failed = 0;\n let lastKnownGood = 0;\n let textureCount = 0;\n let samplerCount = 0;\n for (const observation of observations) {\n for (const residency of observation.residency) {\n switch (residency.readiness) {\n case 'ready':\n ready += 1;\n break;\n case 'pending':\n pending += 1;\n break;\n case 'failed':\n failed += 1;\n break;\n case 'last-known-good':\n lastKnownGood += 1;\n break;\n }\n textureCount += residency.textures.length;\n samplerCount += residency.samplers.length;\n }\n }\n return {\n total: ready + pending + failed + lastKnownGood,\n ready,\n pending,\n failed,\n lastKnownGood,\n textureCount,\n samplerCount,\n };\n}\n\nexport type ResolveMeshMaterialBindingsResult =\n | {\n readonly ok: true;\n readonly bindings: readonly ResolvedMeshMaterialBinding[];\n readonly diagnostics: readonly MeshMaterialBindingDiagnostic[];\n }\n | {\n readonly ok: false;\n readonly code: 'mesh-material-slots-missing';\n }\n | {\n readonly ok: false;\n readonly code: 'mesh-default-material-not-ready';\n readonly slotIndex: number;\n readonly defaultMaterial: AssetGuid;\n };\n\n/**\n * Single owner of the instance override -> mesh default -> engine default\n * inheritance rule. It resolves once per logical slot; submeshes only project\n * their materialSlot index onto the returned table.\n */\nexport function resolveMeshMaterialBindings(\n mesh: MeshAsset,\n rendererOverrides: ArrayLike<number>,\n deps: {\n readonly isValidOverride: (handle: number) => boolean;\n readonly resolveMeshDefault: (guid: AssetGuid) => number | undefined;\n },\n): ResolveMeshMaterialBindingsResult {\n const bindings: ResolvedMeshMaterialBinding[] = [];\n const diagnostics: MeshMaterialBindingDiagnostic[] = [];\n\n if (!Array.isArray(mesh.materialSlots)) {\n return { ok: false, code: 'mesh-material-slots-missing' };\n }\n\n if (rendererOverrides.length > mesh.materialSlots.length) {\n diagnostics.push({\n code: 'mesh-renderer-material-override-overflow',\n slotIndex: mesh.materialSlots.length,\n });\n }\n\n for (let slotIndex = 0; slotIndex < mesh.materialSlots.length; slotIndex++) {\n const override = rendererOverrides[slotIndex] ?? 0;\n if (override !== 0 && deps.isValidOverride(override)) {\n bindings.push({ handle: override, source: 'renderer-override' });\n continue;\n }\n if (override !== 0) {\n diagnostics.push({\n code: 'mesh-renderer-material-override-invalid',\n slotIndex,\n handle: override,\n });\n }\n const declaredDefault = mesh.materialSlots[slotIndex]?.defaultMaterial;\n if (declaredDefault !== undefined) {\n const handle = deps.resolveMeshDefault(declaredDefault);\n if (handle === undefined) {\n return {\n ok: false,\n code: 'mesh-default-material-not-ready',\n slotIndex,\n defaultMaterial: declaredDefault,\n };\n }\n bindings.push({ handle, source: 'mesh-default' });\n continue;\n }\n bindings.push({ handle: 0, source: 'engine-default' });\n }\n\n return { ok: true, bindings, diagnostics };\n}\n","import type { EntityHandle, World } from '@forgeax/engine-ecs';\nimport {\n projectHierarchy,\n type SceneHierarchyDiagnostic,\n type SceneHierarchySnapshot,\n} from '@forgeax/engine-scene';\nimport {\n Visibility,\n type VisibilityState,\n VisibilityStateValue,\n visibilityStateFromU32,\n} from '../components/visibility';\n\nexport type VisibilitySource = 'default' | 'self' | 'parent';\n\nexport interface VisibilityResolution {\n /** The component value authored on this entity before inheritance. */\n readonly intent: VisibilityState;\n /** The state consumed by render candidates after parent resolution. */\n readonly effective: 'hidden' | 'visible';\n /** Explains whether the effective state came from self, parent, or default. */\n readonly source: VisibilitySource;\n}\n\nexport interface VisibilitySnapshot {\n readonly diagnostics: readonly SceneHierarchyDiagnostic[];\n readonly hasAnyIntent: boolean;\n readonly hasAnyHiddenIntent: boolean;\n get(entity: EntityHandle): VisibilityResolution | undefined;\n /** Resolve effective visibility for a render candidate, including inherited defaults. */\n effective(entity: EntityHandle): 'hidden' | 'visible';\n}\n\ninterface ResolutionState {\n readonly intent: VisibilityState;\n readonly effective: 'hidden' | 'visible';\n readonly source: VisibilitySource;\n}\n\n/**\n * Resolve author intent against the scene-owned valid parent projection.\n * Diagnostics are preserved for callers to repair hierarchy input before retry.\n */\nexport function resolveVisibility(\n world: World,\n hierarchy: SceneHierarchySnapshot = projectHierarchy(world),\n): VisibilitySnapshot {\n // Visibility is an opt-in component. Query only the owning archetypes\n // instead of walking every Entity row with an optional column; the latter\n // made a World with no visibility intents pay a full-scene scan on each\n // extraction. QueryRow.entity is sourced from the essential Entity column,\n // so the required Visibility read retains the same handle and intent\n // semantics while keeping the hot path sparse.\n const query = world.query({ read: [Visibility] });\n const visitVisibilityRows = (visit: (entity: EntityHandle, rawState: number) => void): void => {\n if (!query.ok) return;\n // Dense component spans keep the per-frame summary on typed-array reads\n // instead of allocating a QueryRow facade for every visibility-bearing\n // entity. Keep the row path as a defensive fallback if a future storage\n // mode cannot expose spans.\n const spans = query.value.spans();\n if (spans.ok) {\n for (const span of spans.value) {\n const states = span.get(Visibility).state;\n for (let index = 0; index < span.length; index += 1) {\n visit(span.entities[index] as EntityHandle, states[index] ?? 0);\n }\n }\n return;\n }\n for (const row of query.value) {\n visit(row.entity, row.get(Visibility).state);\n }\n };\n let intentCount = 0;\n let hasAnyHiddenIntent = false;\n visitVisibilityRows((_entity, rawState) => {\n intentCount += 1;\n if (rawState === VisibilityStateValue.hidden) {\n hasAnyHiddenIntent = true;\n }\n });\n\n let resolveEntity: ((entity: EntityHandle) => ResolutionState | undefined) | undefined;\n let hasIntent: ((entity: EntityHandle) => boolean) | undefined;\n const ensureResolver = (): void => {\n if (resolveEntity !== undefined) return;\n const intentByEntity = new Map<EntityHandle, VisibilityState>();\n visitVisibilityRows((entity, rawState) => {\n const intent = visibilityStateFromU32(rawState);\n if (intent !== undefined) {\n intentByEntity.set(entity, intent);\n }\n });\n hasIntent = (entity: EntityHandle): boolean => intentByEntity.has(entity);\n const resolved = new Map<EntityHandle, ResolutionState>();\n const resolving = new Set<EntityHandle>();\n resolveEntity = (entity: EntityHandle): ResolutionState | undefined => {\n const existing = resolved.get(entity);\n if (existing !== undefined) return existing;\n if (resolving.has(entity)) return undefined;\n\n const intent = intentByEntity.get(entity) ?? 'inherited';\n resolving.add(entity);\n\n let result: ResolutionState;\n if (intent === 'hidden') {\n result = { intent, effective: 'hidden', source: 'self' };\n } else if (intent === 'visible') {\n result = { intent, effective: 'visible', source: 'self' };\n } else {\n const parent = hierarchy.getParent(entity);\n const parentResult = parent === undefined ? undefined : resolveEntity?.(parent);\n result =\n parentResult === undefined\n ? { intent, effective: 'visible', source: 'default' }\n : { intent, effective: parentResult.effective, source: 'parent' };\n }\n\n resolving.delete(entity);\n resolved.set(entity, result);\n return result;\n };\n };\n\n const snapshot: VisibilitySnapshot = {\n diagnostics: hierarchy.diagnostics,\n hasAnyIntent: intentCount > 0,\n hasAnyHiddenIntent,\n get(entity: EntityHandle): VisibilityResolution | undefined {\n ensureResolver();\n return hasIntent?.(entity) ? resolveEntity?.(entity) : undefined;\n },\n effective(entity: EntityHandle): 'hidden' | 'visible' {\n ensureResolver();\n return resolveEntity?.(entity)?.effective ?? 'visible';\n },\n };\n return snapshot;\n}\n","import { defineComponent, type EntityHandle } from '@forgeax/engine-ecs';\nimport { err, ok, type Result } from '@forgeax/engine-types';\nimport {\n VolumeDensityShapeMismatchError,\n type VolumeError,\n VolumeInvalidBoundsError,\n VolumeInvalidParametersError,\n VolumeOwnerConflictError,\n} from '../errors/render';\n\nexport interface VolumeDensityBinding {\n readonly guid: string;\n readonly generation: number;\n readonly shape: {\n readonly viewDimension: '2d' | '2d-array' | '3d';\n readonly extent: {\n readonly width: number;\n readonly height: number;\n readonly depth?: number;\n readonly layers?: number;\n };\n };\n readonly format: string;\n readonly colorSpace?: 'linear' | 'srgb';\n}\n\nexport interface VolumeBounds {\n readonly min: readonly [number, number, number];\n readonly max: readonly [number, number, number];\n}\n\nexport interface VolumetricFogAuthoring {\n /** Invalid authoring reports closed code, expected, hint, and detail fields. */\n /** The selected DirectionalLight or PointLight in this World. */\n readonly light: EntityHandle;\n /** The optional same-World SpotLight paired with a PointLight. */\n readonly spotLight?: EntityHandle;\n /** Linear scalar density over bounds; the renderer adds no noise or animation. */\n readonly density: VolumeDensityBinding;\n readonly bounds: VolumeBounds;\n readonly extinction: readonly [number, number, number];\n readonly albedo: readonly [number, number, number];\n readonly emission: readonly [number, number, number];\n readonly anisotropy: number;\n readonly maxDistance: number;\n readonly ownerCount?: number;\n}\n\nexport type VolumetricFogLightSelection =\n | { readonly light: EntityHandle; readonly spotLight?: undefined }\n | { readonly light: EntityHandle; readonly spotLight: EntityHandle };\n\nexport interface ValidatedVolumetricFog extends VolumetricFogAuthoring {\n readonly ownerCount: 1;\n}\n\nexport const VolumetricFog = defineComponent('VolumetricFog', {\n light: { type: 'entity' },\n spotLight: { type: 'entity' },\n density: { type: 'shared<TextureAsset>', simulationTransient: true },\n boundsMin: { type: 'array<f32, 3>' },\n boundsMax: { type: 'array<f32, 3>' },\n extinction: { type: 'array<f32, 3>' },\n albedo: { type: 'array<f32, 3>' },\n emission: { type: 'array<f32, 3>' },\n anisotropy: { type: 'f32', default: 0 },\n maxDistance: { type: 'f32', default: 100 },\n});\n\nfunction finiteVector(value: readonly [number, number, number]): boolean {\n return value.every(Number.isFinite);\n}\n\nfunction validBounds(bounds: VolumeBounds): boolean {\n if (!finiteVector(bounds.min) || !finiteVector(bounds.max)) return false;\n return bounds.max.every((value, index) => value > (bounds.min[index] ?? value));\n}\n\nfunction validRange(\n value: readonly [number, number, number],\n min: number,\n max = Infinity,\n): boolean {\n return value.every((entry) => Number.isFinite(entry) && entry >= min && entry <= max);\n}\n\nexport function validateVolumetricFog(\n input: VolumetricFogAuthoring,\n): Result<ValidatedVolumetricFog, VolumeError> {\n const ownerCount = input.ownerCount ?? 1;\n if (ownerCount !== 1) return err(new VolumeOwnerConflictError(ownerCount));\n if (input.density.shape.viewDimension !== '3d' || input.density.colorSpace === 'srgb') {\n return err(\n new VolumeDensityShapeMismatchError(input.density.guid, input.density.shape.viewDimension),\n );\n }\n if (!validBounds(input.bounds)) return err(new VolumeInvalidBoundsError(input.bounds));\n if (\n !validRange(input.extinction, 0) ||\n !validRange(input.albedo, 0, 1) ||\n !validRange(input.emission, 0) ||\n !Number.isFinite(input.anisotropy) ||\n input.anisotropy <= -1 ||\n input.anisotropy >= 1 ||\n !Number.isFinite(input.maxDistance) ||\n input.maxDistance <= 0\n ) {\n return err(new VolumeInvalidParametersError(input));\n }\n return ok({ ...input, ownerCount: 1 });\n}\n","import { err, ok, type Result } from '@forgeax/engine-types';\nimport { type VolumeError, VolumeOwnerConflictError } from '../errors/render';\nimport {\n type ValidatedVolumetricFog,\n type VolumetricFogAuthoring,\n validateVolumetricFog,\n} from './component';\n\nexport type VolumetricFogExtract =\n | { readonly status: 'off' }\n | { readonly status: 'available'; readonly fog: ValidatedVolumetricFog };\n\nexport function extractVolumetricFog(\n inputs: readonly VolumetricFogAuthoring[],\n): Result<VolumetricFogExtract, VolumeError> {\n if (inputs.length === 0) return ok({ status: 'off' });\n if (inputs.length !== 1) return err(new VolumeOwnerConflictError(inputs.length));\n const validated = validateVolumetricFog(inputs[0] as VolumetricFogAuthoring);\n if (!validated.ok) return validated;\n return ok({ status: 'available', fog: validated.value });\n}\n"]}
|