@forgeax/engine-render 0.1.33 → 0.1.35
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 +1062 -127
- 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/device-feature-admission.d.ts +2 -2
- 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/host-contract.d.ts +6 -5
- package/dist/assembly/host-contract.d.ts.map +1 -1
- 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/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/render-target-host.d.ts +5 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -1
- 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/webgpu-pbr-ready.d.ts +1 -0
- package/dist/assembly/webgpu-pbr-ready.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 +1 -1
- 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 +2 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/authoring.mjs +2 -4
- package/dist/authoring.mjs.map +1 -1
- package/dist/barrel-distortion.d.ts +47 -0
- package/dist/barrel-distortion.d.ts.map +1 -0
- package/dist/chunk-3XUBWRY2.mjs +1842 -0
- package/dist/chunk-3XUBWRY2.mjs.map +1 -0
- package/dist/{chunk-OO3DRYK7.mjs → chunk-G6HDNGY7.mjs} +2400 -1767
- package/dist/chunk-G6HDNGY7.mjs.map +1 -0
- package/dist/{chunk-ZDQWGQW7.mjs → chunk-LM5IE7GF.mjs} +4 -4
- package/dist/{chunk-ZDQWGQW7.mjs.map → chunk-LM5IE7GF.mjs.map} +1 -1
- package/dist/{chunk-VOZWDM3L.mjs → chunk-LNIUIKQ7.mjs} +1514 -498
- package/dist/chunk-LNIUIKQ7.mjs.map +1 -0
- package/dist/chunk-MXTWKZO4.mjs +3268 -0
- package/dist/chunk-MXTWKZO4.mjs.map +1 -0
- package/dist/chunk-MZ4C7EHF.mjs +6942 -0
- package/dist/chunk-MZ4C7EHF.mjs.map +1 -0
- package/dist/chunk-RIPAEGI6.mjs +48 -0
- package/dist/chunk-RIPAEGI6.mjs.map +1 -0
- package/dist/{chunk-LEAXOMYJ.mjs → chunk-SGPUJW3F.mjs} +117 -5
- package/dist/chunk-SGPUJW3F.mjs.map +1 -0
- package/dist/{chunk-PA5DRJNI.mjs → chunk-X2KA6WHM.mjs} +29 -4
- package/dist/chunk-X2KA6WHM.mjs.map +1 -0
- package/dist/{chunk-BLXGONR2.mjs → chunk-XSFB7XXQ.mjs} +51 -4
- package/dist/chunk-XSFB7XXQ.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/barrel-distortion.d.ts +13 -0
- package/dist/components/barrel-distortion.d.ts.map +1 -0
- 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/construct-renderer.d.ts +1 -1
- package/dist/construct-renderer.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +8406 -5785
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +19 -19
- 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/errors/cloud.d.ts +59 -0
- package/dist/errors/cloud.d.ts.map +1 -0
- package/dist/errors/render.d.ts +20 -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 +5 -1
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/extract/material-context.d.ts +7 -0
- package/dist/extract/material-context.d.ts.map +1 -0
- 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 +6 -2
- package/dist/features/error-reporting.d.ts.map +1 -1
- package/dist/features/host.d.ts +15 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/plan.d.ts +10 -0
- package/dist/features/plan.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 +48 -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/glyph-text-layout-system.d.ts +1 -1
- package/dist/glyph-text-layout-system.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.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 +47 -3
- 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 +26 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +5 -0
- 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/frame-resources.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +14 -5
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +30 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +780 -9
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +135 -1
- 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 +47 -100
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +7 -8
- package/dist/internal.mjs.map +1 -1
- package/dist/pbr-pipeline.d.ts +22 -4
- 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/lut-gpu.d.ts +2 -2
- package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -1
- package/dist/pipeline/standard-output/resources.d.ts +2 -2
- package/dist/pipeline/standard-output/resources.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.map +1 -1
- package/dist/pipeline-builder.d.ts +1 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- 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/publication/contract.d.ts +77 -0
- package/dist/publication/contract.d.ts.map +1 -0
- package/dist/publication/dependencies.d.ts +7 -0
- package/dist/publication/dependencies.d.ts.map +1 -0
- package/dist/publication/prepare-geometry.d.ts +9 -0
- package/dist/publication/prepare-geometry.d.ts.map +1 -0
- package/dist/publication/programs.d.ts +5 -0
- package/dist/publication/programs.d.ts.map +1 -0
- package/dist/publication/publisher.d.ts +33 -0
- package/dist/publication/publisher.d.ts.map +1 -0
- package/dist/publication/receiver.d.ts +29 -0
- package/dist/publication/receiver.d.ts.map +1 -0
- package/dist/publication/resource-scope.d.ts +18 -0
- package/dist/publication/resource-scope.d.ts.map +1 -0
- package/dist/publication/targets.d.ts +33 -0
- package/dist/publication/targets.d.ts.map +1 -0
- package/dist/publication/video.d.ts +5 -0
- package/dist/publication/video.d.ts.map +1 -0
- 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 +43 -9
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts +15 -65
- 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/helpers.d.ts +2 -2
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +22 -6
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +14 -10
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +3 -16
- 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/motion-blur-receipt.d.ts +11 -0
- package/dist/record/motion-blur-receipt.d.ts.map +1 -0
- package/dist/record/prepared-material-bindings.d.ts +3 -3
- package/dist/record/prepared-material-bindings.d.ts.map +1 -1
- 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 +24 -5
- 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 +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/sprite-instance-buffer.d.ts +31 -0
- package/dist/record/sprite-instance-buffer.d.ts.map +1 -0
- package/dist/record/target-capture-graph.d.ts +19 -0
- package/dist/record/target-capture-graph.d.ts.map +1 -0
- package/dist/record/typed-frame-graph.d.ts +24 -15
- 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 +14 -4
- 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 +46 -5
- 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 +103 -2
- 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 +18 -9
- 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-projections.d.ts +3 -2
- package/dist/render-system-projections.d.ts.map +1 -1
- 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 +22 -21
- 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 +18 -7
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/render-source.d.ts +42 -0
- package/dist/scene/render-source.d.ts.map +1 -0
- package/dist/scene/source-systems.d.ts +6 -0
- package/dist/scene/source-systems.d.ts.map +1 -0
- 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/systems/skin-palette-types.d.ts +10 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -1
- package/dist/systems/transparent-dispatch.d.ts +2 -2
- package/dist/systems/transparent-dispatch.d.ts.map +1 -1
- package/dist/systems/transparent-sort-config.d.ts +2 -1
- package/dist/systems/transparent-sort-config.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 +6 -7
- 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/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 +14 -2
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/component.d.ts +9 -4
- 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/package.json +22 -21
- package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
- package/src/__tests__/auto-exposure-transaction.integration.test.ts +4 -9
- 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__/construct-renderer-identity.unit.test.ts +49 -0
- package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +3 -2
- 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__/factory-contract.integration.test.ts +295 -45
- package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
- 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-material-artifacts.unit.test.ts +143 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +5 -6
- package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +6 -5
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +94 -6
- 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-scene.unit.test.ts +119 -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 +97 -305
- package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +4 -1
- package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +145 -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__/materials-standard-contract.unit.test.ts +0 -1
- 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 +13 -7
- 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 +66 -8
- package/src/__tests__/physical-material-budget.unit.test.ts +40 -0
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
- package/src/__tests__/probe-bindings.unit.test.ts +582 -1
- package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
- 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 +8 -0
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
- package/src/__tests__/render-feature-error-reporting.unit.test.ts +21 -1
- 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-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 +20 -20
- 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 +42 -8
- package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +26 -10
- package/src/__tests__/resource-allocation.unit.test.ts +123 -0
- 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 +15 -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-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.integration.test.ts +182 -1
- 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__/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 +4 -2
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +30 -20
- 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 +113 -9
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +5 -3
- 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/device-feature-admission.ts +2 -2
- 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/host-contract.ts +8 -5
- 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/recovery/device-loss-fanout.ts +13 -0
- package/src/assembly/recovery/renderer-recover.ts +50 -18
- package/src/assembly/render-feature-post-processes.ts +54 -0
- package/src/assembly/render-target-host.ts +57 -47
- package/src/assembly/renderer-facade.ts +7 -2
- 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 +3 -3
- package/src/assembly/webgpu-pbr-ready.ts +9 -1
- package/src/assembly/webgpu-ready-per-pass.ts +104 -0
- package/src/assembly/webgpu-ready.ts +116 -62
- 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 +303 -313
- package/src/assembly/webgpu-vertex-layouts.ts +1 -1
- package/src/barrel-distortion.ts +247 -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/barrel-distortion.ts +46 -0
- 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/sprite-instances.ts +1 -1
- package/src/construct-renderer.ts +1 -1
- package/src/device/gpu-residency.ts +26 -25
- package/src/dynamic-geometry.ts +12 -1
- package/src/errors/cloud.ts +103 -0
- package/src/errors/render.ts +47 -8
- package/src/examples/single-layer-medium-surface.ts +59 -0
- package/src/extract/camera.ts +15 -1
- package/src/extract/contracts.ts +5 -0
- package/src/extract/material-context.ts +21 -0
- package/src/features/barrel-distortion.ts +172 -0
- package/src/features/error-reporting.ts +26 -6
- package/src/features/host.ts +128 -19
- package/src/features/plan.ts +10 -0
- package/src/features/render-graph-contribution.ts +9 -0
- package/src/features/render-graph-raster.ts +45 -3
- package/src/features/targets.ts +66 -0
- package/src/features/types.ts +51 -0
- package/src/fullscreen-post-process-pass.ts +41 -9
- package/src/glyph-text-layout-system.ts +2 -2
- package/src/gpu-dirty-ranges.ts +48 -0
- package/src/gpu-driven/batch-topology.ts +53 -0
- package/src/gpu-driven/material-artifacts.ts +33 -25
- package/src/gpu-driven/prepared-draw.ts +12 -4
- package/src/gpu-driven/production-raster-material.ts +1894 -0
- package/src/gpu-driven/production-raster.ts +825 -784
- 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 +164 -10
- package/src/gpu-scene.ts +75 -84
- package/src/hdrp-buffers.ts +4 -3
- package/src/ibl/frame-resources.ts +0 -1
- package/src/ibl/skylight-bind-group.ts +62 -32
- package/src/index.ts +205 -9
- package/src/inspection-types.ts +162 -0
- package/src/instance-buffer-cache.ts +4 -4
- package/src/instances.ts +152 -569
- package/src/pbr-pipeline.ts +230 -30
- 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/lut-gpu.ts +3 -3
- package/src/pipeline/standard-output/resources.ts +2 -2
- package/src/pipeline/standard-output/types.ts +12 -1
- package/src/pipeline/standard-pipeline.ts +291 -18
- package/src/pipeline/standard-post.ts +90 -24
- package/src/pipeline-builder.ts +1 -1
- package/src/plugin.ts +4 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
- package/src/prepare/prepared-graphics-resolver.ts +2 -0
- package/src/publication/__tests__/derived-geometry.integration.test.ts +177 -0
- package/src/publication/__tests__/features.integration.test.ts +122 -0
- package/src/publication/__tests__/programs.unit.test.ts +25 -0
- package/src/publication/__tests__/publication.integration.test.ts +370 -0
- package/src/publication/__tests__/targets.integration.test.ts +120 -0
- package/src/publication/__tests__/video.browser.test.ts +50 -0
- package/src/publication/contract.ts +104 -0
- package/src/publication/dependencies.ts +54 -0
- package/src/publication/prepare-geometry.ts +94 -0
- package/src/publication/programs.ts +45 -0
- package/src/publication/publisher.ts +618 -0
- package/src/publication/receiver.ts +297 -0
- package/src/publication/resource-scope.ts +31 -0
- package/src/publication/targets.ts +182 -0
- package/src/publication/video.ts +33 -0
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +15 -1
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +9 -11
- package/src/record/__tests__/temporal-payload.unit.test.ts +1 -1
- 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__/video-texture-view.unit.test.ts +9 -9
- 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 +855 -0
- package/src/record/fold-instance-buffer.ts +51 -0
- package/src/record/frame-lighting.ts +36 -2
- package/src/record/frame-snapshot.ts +45 -9
- package/src/record/frame.ts +258 -1105
- package/src/record/gpu-draw-receipts.ts +38 -0
- package/src/record/gpu-timing.ts +48 -5
- package/src/record/helpers.ts +2 -2
- package/src/record/main-pass-geometry.ts +272 -84
- package/src/record/main-pass-material.ts +102 -36
- package/src/record/main-pass-sprite-draws.ts +13 -217
- package/src/record/main-pass.ts +164 -27
- package/src/record/motion-blur-receipt.ts +91 -0
- package/src/record/prepared-material-bindings.ts +11 -6
- package/src/record/probe-blend-buffer.ts +180 -0
- package/src/record/recovery-pipeline.ts +35 -3
- package/src/record/render-context.ts +41 -5
- package/src/record/shadow-pass.ts +30 -4
- package/src/record/skybox-post-pass.ts +28 -4
- package/src/record/sprite-instance-buffer.ts +155 -0
- package/src/record/target-capture-graph.ts +258 -0
- package/src/record/typed-frame-graph.ts +776 -340
- package/src/record/view-ubo.ts +27 -4
- package/src/record/volume-params.ts +225 -0
- package/src/recovery/render-system-candidate.ts +243 -50
- package/src/reflection/record-owner.ts +7 -3
- package/src/render-contract.ts +54 -5
- package/src/render-graph-primitives.ts +7 -1
- package/src/render-pipeline.ts +130 -0
- package/src/render-system-extract-tail.ts +90 -78
- package/src/render-system-extract.ts +76 -76
- package/src/render-system-presentation.ts +56 -0
- package/src/render-system-producer-roots.ts +96 -0
- package/src/render-system-projections.ts +3 -2
- package/src/render-system-residency.ts +159 -0
- package/src/render-system.ts +421 -408
- package/src/scene/probe-blend.ts +96 -4
- package/src/scene/render-scene.ts +416 -337
- package/src/scene/render-source.ts +90 -0
- package/src/scene/source-systems.ts +33 -0
- 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 +5 -1
- package/src/systems/skin-palette-types.ts +11 -0
- package/src/systems/transparent-dispatch.ts +2 -2
- package/src/systems/transparent-sort-config.ts +3 -1
- 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/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 +70 -2
- package/src/volume/component.ts +10 -9
- package/src/volume/extract.ts +11 -5
- package/src/volume/inspection.ts +3 -0
- package/src/volume/passes.ts +87 -4
- package/src/volume/resources.ts +2 -1
- package/dist/chunk-3RTCJTH4.mjs +0 -1610
- package/dist/chunk-3RTCJTH4.mjs.map +0 -1
- package/dist/chunk-BLXGONR2.mjs.map +0 -1
- package/dist/chunk-ILQ5MEZF.mjs +0 -32
- package/dist/chunk-ILQ5MEZF.mjs.map +0 -1
- package/dist/chunk-LEAXOMYJ.mjs.map +0 -1
- package/dist/chunk-NB2S7ZRX.mjs +0 -1783
- package/dist/chunk-NB2S7ZRX.mjs.map +0 -1
- package/dist/chunk-NNQL7CB3.mjs +0 -1713
- package/dist/chunk-NNQL7CB3.mjs.map +0 -1
- package/dist/chunk-OO3DRYK7.mjs.map +0 -1
- package/dist/chunk-PA5DRJNI.mjs.map +0 -1
- package/dist/chunk-PLAXOOX5.mjs +0 -1907
- package/dist/chunk-PLAXOOX5.mjs.map +0 -1
- package/dist/chunk-RXZ3RGOU.mjs +0 -53
- package/dist/chunk-RXZ3RGOU.mjs.map +0 -1
- package/dist/chunk-VOZWDM3L.mjs.map +0 -1
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import { type Color3, fresnelReflectance, type Uv2 } from './oracle.js';
|
|
2
|
+
|
|
3
|
+
export type MediumVector3 = readonly [number, number, number];
|
|
4
|
+
|
|
5
|
+
export interface SingleLayerMediumCoefficients {
|
|
6
|
+
/** Linear, inverse-metre absorption coefficients. */
|
|
7
|
+
readonly absorption: MediumVector3;
|
|
8
|
+
/** Linear, inverse-metre scattering coefficients. */
|
|
9
|
+
readonly scattering: MediumVector3;
|
|
10
|
+
readonly ior: number;
|
|
11
|
+
/** Henyey-Greenstein phase anisotropy in [-1, 1]. */
|
|
12
|
+
readonly phaseG?: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SingleLayerMediumOptics {
|
|
16
|
+
readonly sigmaT: MediumVector3;
|
|
17
|
+
readonly transmittance: MediumVector3;
|
|
18
|
+
/** Uniform-medium single-scatter integral sigmaS * (1 - T) / sigmaT. */
|
|
19
|
+
readonly singleScatter: MediumVector3;
|
|
20
|
+
readonly reflectance: number;
|
|
21
|
+
readonly transmissionWeight: number;
|
|
22
|
+
readonly phase: number;
|
|
23
|
+
readonly distanceMeters: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type SingleLayerMediumBackgroundReason = 'front' | 'shore' | 'edge' | 'sky-miss';
|
|
27
|
+
|
|
28
|
+
export interface SingleLayerMediumBackgroundCandidate {
|
|
29
|
+
readonly color: Color3;
|
|
30
|
+
readonly depthMeters: number;
|
|
31
|
+
readonly uv: Uv2;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface SingleLayerMediumBackgroundInput {
|
|
35
|
+
/** No-water color and raw depth must come from the same view identity. */
|
|
36
|
+
readonly original: SingleLayerMediumBackgroundCandidate;
|
|
37
|
+
/** Refracted candidate carries color and depth as one pair. */
|
|
38
|
+
readonly refracted?: SingleLayerMediumBackgroundCandidate;
|
|
39
|
+
readonly environment?: Color3;
|
|
40
|
+
readonly surfaceDepthMeters: number;
|
|
41
|
+
readonly maxDistanceMeters: number;
|
|
42
|
+
readonly depthToleranceMeters?: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface SingleLayerMediumBackgroundResolution {
|
|
46
|
+
readonly source: 'refracted' | 'unrefracted' | 'environment';
|
|
47
|
+
readonly reason?: SingleLayerMediumBackgroundReason;
|
|
48
|
+
readonly candidate: SingleLayerMediumBackgroundCandidate | undefined;
|
|
49
|
+
readonly color: Color3;
|
|
50
|
+
readonly distanceMeters: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const DEFAULT_MAX_DISTANCE_METERS = 1000;
|
|
54
|
+
const DEFAULT_DEPTH_TOLERANCE_METERS = 0.001;
|
|
55
|
+
const DEFAULT_IOR = 1.333;
|
|
56
|
+
|
|
57
|
+
const finiteOr = (value: number, fallback: number): number =>
|
|
58
|
+
Number.isFinite(value) ? value : fallback;
|
|
59
|
+
|
|
60
|
+
function oneMinusExpNeg(value: number): number {
|
|
61
|
+
const x = Math.max(finiteOr(value, 0), 0);
|
|
62
|
+
if (x < 1e-3) {
|
|
63
|
+
const x2 = x * x;
|
|
64
|
+
return x * (1 - x * 0.5 + x2 / 6 - (x * x2) / 24);
|
|
65
|
+
}
|
|
66
|
+
return -Math.expm1(-x);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function singleScatterIntegral(sigmaS: number, sigmaT: number, distance: number): number {
|
|
70
|
+
const scattering = Math.max(finiteOr(sigmaS, 0), 0);
|
|
71
|
+
const extinction = Math.max(finiteOr(sigmaT, 0), 0);
|
|
72
|
+
const path = Math.max(finiteOr(distance, 0), 0);
|
|
73
|
+
if (extinction === 0) return scattering * path;
|
|
74
|
+
return (scattering * oneMinusExpNeg(extinction * path)) / extinction;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const nonNegative = (value: number): number => Math.max(finiteOr(value, 0), 0);
|
|
78
|
+
|
|
79
|
+
const clamp01 = (value: number): number => Math.min(Math.max(finiteOr(value, 0), 0), 1);
|
|
80
|
+
|
|
81
|
+
/** Test an endpoint against the undisturbed geometric water plane. */
|
|
82
|
+
export function isBelowSingleLayerMediumPlane(input: {
|
|
83
|
+
readonly surfacePosition: MediumVector3;
|
|
84
|
+
readonly geometricNormal: MediumVector3;
|
|
85
|
+
readonly endpoint: MediumVector3;
|
|
86
|
+
readonly epsilonMeters?: number;
|
|
87
|
+
}): boolean {
|
|
88
|
+
const [nx, ny, nz] = input.geometricNormal;
|
|
89
|
+
const length = Math.hypot(nx, ny, nz);
|
|
90
|
+
if (!Number.isFinite(length) || length <= 1e-8) return false;
|
|
91
|
+
const signedDistance =
|
|
92
|
+
((input.endpoint[0] - input.surfacePosition[0]) * nx +
|
|
93
|
+
(input.endpoint[1] - input.surfacePosition[1]) * ny +
|
|
94
|
+
(input.endpoint[2] - input.surfacePosition[2]) * nz) /
|
|
95
|
+
length;
|
|
96
|
+
return Number.isFinite(signedDistance) && signedDistance <= (input.epsilonMeters ?? 0.001);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function vector3(input: MediumVector3 | undefined): MediumVector3 {
|
|
100
|
+
return [nonNegative(input?.[0] ?? 0), nonNegative(input?.[1] ?? 0), nonNegative(input?.[2] ?? 0)];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function finiteColor(input: Color3 | undefined): input is Color3 {
|
|
104
|
+
return input !== undefined && input.length === 3 && input.every(Number.isFinite);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function finiteUv(input: Uv2): boolean {
|
|
108
|
+
return input.length === 2 && input.every(Number.isFinite);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function safeDistance(value: number, maxDistance: number): number {
|
|
112
|
+
return Math.min(Math.max(finiteOr(value, 0), 0), maxDistance);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Evaluate the stable analytic portion of the Engine's single-layer model.
|
|
117
|
+
* Zero extinction uses the continuous limit and every returned component is
|
|
118
|
+
* finite, even when an authored value is NaN or infinite.
|
|
119
|
+
*/
|
|
120
|
+
export function integrateSingleLayerMedium(input: {
|
|
121
|
+
readonly coefficients: SingleLayerMediumCoefficients;
|
|
122
|
+
readonly distanceMeters: number;
|
|
123
|
+
readonly cosTheta: number;
|
|
124
|
+
readonly phaseCosTheta?: number;
|
|
125
|
+
/** Finite authored propagation bound; defaults to the conservative 1000 m bound. */
|
|
126
|
+
readonly maxDistanceMeters?: number;
|
|
127
|
+
}): SingleLayerMediumOptics {
|
|
128
|
+
const absorption = vector3(input.coefficients.absorption);
|
|
129
|
+
const scattering = vector3(input.coefficients.scattering);
|
|
130
|
+
const sigmaT: MediumVector3 = [
|
|
131
|
+
absorption[0] + scattering[0],
|
|
132
|
+
absorption[1] + scattering[1],
|
|
133
|
+
absorption[2] + scattering[2],
|
|
134
|
+
];
|
|
135
|
+
const maxDistanceMeters = Math.min(
|
|
136
|
+
Math.max(
|
|
137
|
+
finiteOr(input.maxDistanceMeters ?? DEFAULT_MAX_DISTANCE_METERS, DEFAULT_MAX_DISTANCE_METERS),
|
|
138
|
+
0,
|
|
139
|
+
),
|
|
140
|
+
100000,
|
|
141
|
+
);
|
|
142
|
+
const distanceMeters = safeDistance(input.distanceMeters, maxDistanceMeters);
|
|
143
|
+
const transmittance: MediumVector3 = [
|
|
144
|
+
Number.isFinite(sigmaT[0]) && sigmaT[0] > 0 ? Math.exp(-sigmaT[0] * distanceMeters) : 1,
|
|
145
|
+
Number.isFinite(sigmaT[1]) && sigmaT[1] > 0 ? Math.exp(-sigmaT[1] * distanceMeters) : 1,
|
|
146
|
+
Number.isFinite(sigmaT[2]) && sigmaT[2] > 0 ? Math.exp(-sigmaT[2] * distanceMeters) : 1,
|
|
147
|
+
];
|
|
148
|
+
const singleScatter: MediumVector3 = [
|
|
149
|
+
singleScatterIntegral(scattering[0], sigmaT[0], distanceMeters),
|
|
150
|
+
singleScatterIntegral(scattering[1], sigmaT[1], distanceMeters),
|
|
151
|
+
singleScatterIntegral(scattering[2], sigmaT[2], distanceMeters),
|
|
152
|
+
];
|
|
153
|
+
const iorCandidate = finiteOr(input.coefficients.ior, DEFAULT_IOR);
|
|
154
|
+
const ior = iorCandidate >= 1 ? iorCandidate : DEFAULT_IOR;
|
|
155
|
+
const reflectance = fresnelReflectance(input.cosTheta, 1 / ior);
|
|
156
|
+
const transmissionWeight = 1 - reflectance;
|
|
157
|
+
const phaseG = Math.min(Math.max(finiteOr(input.coefficients.phaseG ?? 0, 0), -1), 1);
|
|
158
|
+
const phaseCosTheta = clamp01(input.phaseCosTheta ?? input.cosTheta);
|
|
159
|
+
const phaseDenominator = Math.max(1 + phaseG * phaseG - 2 * phaseG * phaseCosTheta, 1e-6);
|
|
160
|
+
const phase = (1 - phaseG * phaseG) / (4 * Math.PI * phaseDenominator ** 1.5);
|
|
161
|
+
return {
|
|
162
|
+
sigmaT,
|
|
163
|
+
transmittance,
|
|
164
|
+
singleScatter,
|
|
165
|
+
reflectance,
|
|
166
|
+
transmissionWeight,
|
|
167
|
+
phase: finiteOr(phase, 1 / (4 * Math.PI)),
|
|
168
|
+
distanceMeters,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Compose linear HDR terms after exactly one Fresnel allocation. */
|
|
173
|
+
export function composeSingleLayerMediumColor(input: {
|
|
174
|
+
readonly optics: SingleLayerMediumOptics;
|
|
175
|
+
readonly background: Color3;
|
|
176
|
+
readonly reflection: Color3;
|
|
177
|
+
readonly foamColor?: Color3;
|
|
178
|
+
readonly coverage?: number;
|
|
179
|
+
readonly foam?: number;
|
|
180
|
+
}): Color3 {
|
|
181
|
+
const coverage = clamp01(input.coverage ?? 1);
|
|
182
|
+
const foam = clamp01(input.foam ?? 0) * coverage;
|
|
183
|
+
const foamColor = finiteColor(input.foamColor) ? input.foamColor : [1, 1, 1];
|
|
184
|
+
const background = finiteColor(input.background) ? input.background : [0, 0, 0];
|
|
185
|
+
const reflection = finiteColor(input.reflection) ? input.reflection : [0, 0, 0];
|
|
186
|
+
const medium: MediumVector3 = [
|
|
187
|
+
background[0] * input.optics.transmittance[0] + input.optics.singleScatter[0],
|
|
188
|
+
background[1] * input.optics.transmittance[1] + input.optics.singleScatter[1],
|
|
189
|
+
background[2] * input.optics.transmittance[2] + input.optics.singleScatter[2],
|
|
190
|
+
];
|
|
191
|
+
const waterWeight = input.optics.transmissionWeight * coverage * (1 - foam);
|
|
192
|
+
const reflectionWeight = input.optics.reflectance * coverage;
|
|
193
|
+
const foamWeight = foam;
|
|
194
|
+
return [
|
|
195
|
+
finiteOr(
|
|
196
|
+
reflection[0] * reflectionWeight + medium[0] * waterWeight + foamColor[0] * foamWeight,
|
|
197
|
+
0,
|
|
198
|
+
),
|
|
199
|
+
finiteOr(
|
|
200
|
+
reflection[1] * reflectionWeight + medium[1] * waterWeight + foamColor[1] * foamWeight,
|
|
201
|
+
0,
|
|
202
|
+
),
|
|
203
|
+
finiteOr(
|
|
204
|
+
reflection[2] * reflectionWeight + medium[2] * waterWeight + foamColor[2] * foamWeight,
|
|
205
|
+
0,
|
|
206
|
+
),
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function validCandidate(
|
|
211
|
+
candidate: SingleLayerMediumBackgroundCandidate | undefined,
|
|
212
|
+
maxDistance: number,
|
|
213
|
+
): candidate is SingleLayerMediumBackgroundCandidate {
|
|
214
|
+
return (
|
|
215
|
+
candidate !== undefined &&
|
|
216
|
+
finiteColor(candidate.color) &&
|
|
217
|
+
finiteUv(candidate.uv) &&
|
|
218
|
+
Number.isFinite(candidate.depthMeters) &&
|
|
219
|
+
candidate.depthMeters >= 0 &&
|
|
220
|
+
candidate.depthMeters <= maxDistance
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Resolve paired color/depth input with front, shore, edge, and sky-miss
|
|
226
|
+
* reasons. Environment is a reflection/background fallback only; it is never
|
|
227
|
+
* used as a riverbed transmission sample when a valid original pair exists.
|
|
228
|
+
*/
|
|
229
|
+
export function resolveSingleLayerMediumBackground(
|
|
230
|
+
input: SingleLayerMediumBackgroundInput,
|
|
231
|
+
): SingleLayerMediumBackgroundResolution {
|
|
232
|
+
const maxDistance = Math.max(finiteOr(input.maxDistanceMeters, DEFAULT_MAX_DISTANCE_METERS), 0);
|
|
233
|
+
const tolerance = Math.max(
|
|
234
|
+
finiteOr(
|
|
235
|
+
input.depthToleranceMeters ?? DEFAULT_DEPTH_TOLERANCE_METERS,
|
|
236
|
+
DEFAULT_DEPTH_TOLERANCE_METERS,
|
|
237
|
+
),
|
|
238
|
+
0,
|
|
239
|
+
);
|
|
240
|
+
const surfaceDepth = finiteOr(input.surfaceDepthMeters, 0);
|
|
241
|
+
if (
|
|
242
|
+
validCandidate(input.refracted, maxDistance) &&
|
|
243
|
+
input.refracted.uv.every((coordinate) => coordinate >= 0 && coordinate <= 1)
|
|
244
|
+
) {
|
|
245
|
+
if (input.refracted.depthMeters + tolerance < surfaceDepth) {
|
|
246
|
+
return {
|
|
247
|
+
source: 'unrefracted',
|
|
248
|
+
reason: 'front',
|
|
249
|
+
candidate: validCandidate(input.original, maxDistance) ? input.original : undefined,
|
|
250
|
+
color: validCandidate(input.original, maxDistance) ? input.original.color : [0, 0, 0],
|
|
251
|
+
distanceMeters: validCandidate(input.original, maxDistance)
|
|
252
|
+
? Math.max(input.original.depthMeters - surfaceDepth, 0)
|
|
253
|
+
: 0,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
source: 'refracted',
|
|
258
|
+
candidate: input.refracted,
|
|
259
|
+
color: input.refracted.color,
|
|
260
|
+
distanceMeters: Math.max(input.refracted.depthMeters - surfaceDepth, 0),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
if (validCandidate(input.original, maxDistance)) {
|
|
264
|
+
const reason: SingleLayerMediumBackgroundReason =
|
|
265
|
+
input.refracted === undefined
|
|
266
|
+
? 'shore'
|
|
267
|
+
: finiteUv(input.refracted.uv) &&
|
|
268
|
+
input.refracted.uv.some((coordinate) => coordinate < 0 || coordinate > 1)
|
|
269
|
+
? 'edge'
|
|
270
|
+
: 'shore';
|
|
271
|
+
return {
|
|
272
|
+
source: 'unrefracted',
|
|
273
|
+
reason,
|
|
274
|
+
candidate: input.original,
|
|
275
|
+
color: input.original.color,
|
|
276
|
+
distanceMeters: Math.max(input.original.depthMeters - surfaceDepth, 0),
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
if (finiteColor(input.environment)) {
|
|
280
|
+
return {
|
|
281
|
+
source: 'environment',
|
|
282
|
+
reason: 'sky-miss',
|
|
283
|
+
candidate: undefined,
|
|
284
|
+
color: input.environment,
|
|
285
|
+
distanceMeters: maxDistance,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
source: 'environment',
|
|
290
|
+
reason: 'sky-miss',
|
|
291
|
+
candidate: undefined,
|
|
292
|
+
color: [0, 0, 0],
|
|
293
|
+
distanceMeters: maxDistance,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** Screen-space approximation of the Euclidean endpoint path, clamped to the declared maximum. */
|
|
298
|
+
export function estimateSingleLayerPathLength(input: {
|
|
299
|
+
readonly surfacePosition: readonly [number, number, number];
|
|
300
|
+
readonly backgroundPosition: readonly [number, number, number] | undefined;
|
|
301
|
+
readonly maxDistanceMeters: number;
|
|
302
|
+
}): { readonly distanceMeters: number; readonly valid: boolean } {
|
|
303
|
+
const maxDistance = Math.max(finiteOr(input.maxDistanceMeters, DEFAULT_MAX_DISTANCE_METERS), 0);
|
|
304
|
+
if (
|
|
305
|
+
input.surfacePosition.length !== 3 ||
|
|
306
|
+
input.backgroundPosition === undefined ||
|
|
307
|
+
input.backgroundPosition.length !== 3 ||
|
|
308
|
+
!input.surfacePosition.every(Number.isFinite) ||
|
|
309
|
+
!input.backgroundPosition.every(Number.isFinite)
|
|
310
|
+
) {
|
|
311
|
+
return { distanceMeters: maxDistance, valid: false };
|
|
312
|
+
}
|
|
313
|
+
const distance = Math.hypot(
|
|
314
|
+
(input.backgroundPosition[0] ?? 0) - (input.surfacePosition[0] ?? 0),
|
|
315
|
+
(input.backgroundPosition[1] ?? 0) - (input.surfacePosition[1] ?? 0),
|
|
316
|
+
(input.backgroundPosition[2] ?? 0) - (input.surfacePosition[2] ?? 0),
|
|
317
|
+
);
|
|
318
|
+
return {
|
|
319
|
+
distanceMeters: Math.min(Math.max(finiteOr(distance, maxDistance), 0), maxDistance),
|
|
320
|
+
valid: Number.isFinite(distance),
|
|
321
|
+
};
|
|
322
|
+
}
|
|
@@ -38,7 +38,12 @@ import {
|
|
|
38
38
|
recordSsaoBlurPass,
|
|
39
39
|
recordSsaoCalcPass,
|
|
40
40
|
} from './render-graph-primitives';
|
|
41
|
-
import type {
|
|
41
|
+
import type {
|
|
42
|
+
RenderPipelineFrame,
|
|
43
|
+
RenderPipelineGpuDrivenFilter,
|
|
44
|
+
RenderPipelineGpuDrivenProjection,
|
|
45
|
+
RenderPipelineSurfaceMediumPair,
|
|
46
|
+
} from './render-pipeline';
|
|
42
47
|
import { createRenderPipelineTarget, type RenderPipelineTarget } from './render-pipeline';
|
|
43
48
|
import type { OcclusionFrameProjection } from './scene/visibility/occlusion-runtime';
|
|
44
49
|
import {
|
|
@@ -265,6 +270,8 @@ export interface TypedScenePassOptions {
|
|
|
265
270
|
readonly sampled?: readonly RenderPipelineTarget[] | undefined;
|
|
266
271
|
readonly directionalShadow?: RenderPipelineTarget | undefined;
|
|
267
272
|
readonly spotShadow?: RenderPipelineTarget | undefined;
|
|
273
|
+
/** Stable world-space cloud shadow map sampled by direct-solar receivers. */
|
|
274
|
+
readonly cloudShadow?: RenderPipelineTarget | undefined;
|
|
268
275
|
readonly ssao?: RenderPipelineTarget | undefined;
|
|
269
276
|
readonly selector: PassSelector;
|
|
270
277
|
readonly passKind?: PassKind | undefined;
|
|
@@ -272,8 +279,24 @@ export interface TypedScenePassOptions {
|
|
|
272
279
|
readonly clearColor?: readonly [number, number, number, number] | undefined;
|
|
273
280
|
readonly colorLoadOp?: GPULoadOp | readonly GPULoadOp[] | undefined;
|
|
274
281
|
readonly depthLoadOp?: GPULoadOp | undefined;
|
|
282
|
+
/** Preserve nearest transparent fragment depth for downstream medium clipping. */
|
|
283
|
+
readonly transparentDepthWrite?: boolean | undefined;
|
|
275
284
|
readonly coverageOnly?: boolean | undefined;
|
|
276
|
-
readonly recordMode?:
|
|
285
|
+
readonly recordMode?:
|
|
286
|
+
| 'opaque'
|
|
287
|
+
| 'transmission'
|
|
288
|
+
| 'transparent'
|
|
289
|
+
| 'single-layer-medium-nearest-layer'
|
|
290
|
+
| 'single-layer-medium-color'
|
|
291
|
+
| undefined;
|
|
292
|
+
/** Graph-paired Surface inputs. The raw depth status is intentionally typed. */
|
|
293
|
+
readonly surfacePair?: RenderPipelineSurfaceMediumPair | undefined;
|
|
294
|
+
/** Nearest-layer color produced by the preceding medium pass. */
|
|
295
|
+
readonly surfaceNearestLayer?: GraphTextureView | undefined;
|
|
296
|
+
/** Nearest-layer depth produced by the preceding medium pass. */
|
|
297
|
+
readonly surfaceNearestDepth?: GraphTextureView | undefined;
|
|
298
|
+
/** Restrict GPU-driven projection to the material family owned by this pass. */
|
|
299
|
+
readonly gpuDrivenFilter?: RenderPipelineGpuDrivenFilter | undefined;
|
|
277
300
|
/** Exclude material/pass pairs consumed by an earlier graph lane. */
|
|
278
301
|
readonly excludeSelector?: PassSelector | undefined;
|
|
279
302
|
/** Require material membership in another lane without selecting its entries. */
|
|
@@ -299,9 +322,23 @@ export function addTypedScenePass(
|
|
|
299
322
|
resource: target.view,
|
|
300
323
|
usage: 'sampled-read' as const,
|
|
301
324
|
})),
|
|
325
|
+
...(options.cloudShadow === undefined
|
|
326
|
+
? []
|
|
327
|
+
: [{ resource: options.cloudShadow.view, usage: 'sampled-read' as const }]),
|
|
302
328
|
...(options.transmissionBackdrop === undefined
|
|
303
329
|
? []
|
|
304
330
|
: [{ resource: options.transmissionBackdrop, usage: 'sampled-read' as const }]),
|
|
331
|
+
...(options.surfacePair?.rawDepth.status === 'available'
|
|
332
|
+
? [{ resource: options.surfacePair.rawDepth.view, usage: 'sampled-read' as const }]
|
|
333
|
+
: []),
|
|
334
|
+
...(options.recordMode === 'single-layer-medium-color' &&
|
|
335
|
+
options.surfaceNearestLayer !== undefined
|
|
336
|
+
? [{ resource: options.surfaceNearestLayer, usage: 'sampled-read' as const }]
|
|
337
|
+
: []),
|
|
338
|
+
...(options.recordMode === 'single-layer-medium-color' &&
|
|
339
|
+
options.surfaceNearestDepth !== undefined
|
|
340
|
+
? [{ resource: options.surfaceNearestDepth, usage: 'sampled-read' as const }]
|
|
341
|
+
: []),
|
|
305
342
|
...(options.environment === undefined
|
|
306
343
|
? []
|
|
307
344
|
: [options.environment.irradiance, options.environment.prefilter].map((resource) => ({
|
|
@@ -357,12 +394,28 @@ export function addTypedScenePass(
|
|
|
357
394
|
options.spotShadow === undefined
|
|
358
395
|
? undefined
|
|
359
396
|
: resolvedView(resources, options.spotShadow.view);
|
|
397
|
+
const cloudShadow =
|
|
398
|
+
options.cloudShadow === undefined
|
|
399
|
+
? undefined
|
|
400
|
+
: resolvedView(resources, options.cloudShadow.view);
|
|
360
401
|
const ssao =
|
|
361
402
|
options.ssao === undefined ? undefined : resolvedView(resources, options.ssao.view);
|
|
362
403
|
const transmissionBackdrop =
|
|
363
404
|
options.transmissionBackdrop === undefined
|
|
364
405
|
? null
|
|
365
406
|
: resolvedView(resources, options.transmissionBackdrop);
|
|
407
|
+
const surfaceRawDepth =
|
|
408
|
+
options.surfacePair?.rawDepth.status === 'available'
|
|
409
|
+
? resolvedView(resources, options.surfacePair.rawDepth.view)
|
|
410
|
+
: null;
|
|
411
|
+
const surfaceNearestLayer =
|
|
412
|
+
options.surfaceNearestLayer === undefined
|
|
413
|
+
? null
|
|
414
|
+
: resolvedView(resources, options.surfaceNearestLayer);
|
|
415
|
+
const surfaceNearestDepth =
|
|
416
|
+
options.surfaceNearestDepth === undefined
|
|
417
|
+
? null
|
|
418
|
+
: resolvedView(resources, options.surfaceNearestDepth);
|
|
366
419
|
internal.frameState.currentDirectionalShadowView = directionalShadow ?? null;
|
|
367
420
|
internal.frameState.currentSpotShadowView = spotShadow ?? null;
|
|
368
421
|
const groups = buildPerFrameBindGroups(
|
|
@@ -374,6 +427,7 @@ export function addTypedScenePass(
|
|
|
374
427
|
{
|
|
375
428
|
directionalShadow,
|
|
376
429
|
spotShadow,
|
|
430
|
+
cloudShadow,
|
|
377
431
|
projector: internal.spotLightProjector?.view ?? internal.volumetricFog?.projectorView,
|
|
378
432
|
projectorSampler:
|
|
379
433
|
internal.spotLightProjector?.sampler ?? internal.volumetricFog?.projectorSampler,
|
|
@@ -427,6 +481,9 @@ export function addTypedScenePass(
|
|
|
427
481
|
passKind: options.passKind ?? 'forward',
|
|
428
482
|
...(options.clearColor === undefined ? {} : { clearColor: options.clearColor }),
|
|
429
483
|
...(options.recordMode === undefined ? {} : { recordMode: options.recordMode }),
|
|
484
|
+
...(options.transparentDepthWrite === undefined
|
|
485
|
+
? {}
|
|
486
|
+
: { transparentDepthWrite: options.transparentDepthWrite }),
|
|
430
487
|
...(options.coverageOnly === undefined ? {} : { coverageOnly: options.coverageOnly }),
|
|
431
488
|
...(options.excludeSelector === undefined
|
|
432
489
|
? {}
|
|
@@ -437,9 +494,20 @@ export function addTypedScenePass(
|
|
|
437
494
|
...(options.transmissionBackdrop === undefined
|
|
438
495
|
? {}
|
|
439
496
|
: { transmissionBackdropView: transmissionBackdrop }),
|
|
497
|
+
...(surfaceRawDepth === null ? {} : { surfaceRawDepthView: surfaceRawDepth }),
|
|
498
|
+
...(surfaceNearestLayer === null ? {} : { surfaceNearestLayerView: surfaceNearestLayer }),
|
|
499
|
+
...(surfaceNearestDepth === null ? {} : { surfaceNearestDepthView: surfaceNearestDepth }),
|
|
500
|
+
...(options.recordMode === 'single-layer-medium-nearest-layer'
|
|
501
|
+
? { fragmentEntryPoint: 'fs_nearest_layer' }
|
|
502
|
+
: options.recordMode === 'single-layer-medium-color'
|
|
503
|
+
? { fragmentEntryPoint: 'fs_color' }
|
|
504
|
+
: {}),
|
|
440
505
|
...(options.gpuDriven === undefined
|
|
441
506
|
? {}
|
|
442
507
|
: { gpuDriven: { projection: options.gpuDriven, resources } }),
|
|
508
|
+
...(options.gpuDrivenFilter === undefined
|
|
509
|
+
? {}
|
|
510
|
+
: { gpuDrivenFilter: options.gpuDrivenFilter }),
|
|
443
511
|
});
|
|
444
512
|
// encodeMainPass receives a pass-local context so attachment and
|
|
445
513
|
// bind-group overrides stay isolated. Its material UBO payload cache is
|
package/src/volume/component.ts
CHANGED
|
@@ -5,9 +5,11 @@ import {
|
|
|
5
5
|
type VolumeError,
|
|
6
6
|
VolumeInvalidBoundsError,
|
|
7
7
|
VolumeInvalidParametersError,
|
|
8
|
-
VolumeOwnerConflictError,
|
|
9
8
|
} from '../errors/render';
|
|
10
9
|
|
|
10
|
+
export const MAX_VOLUMETRIC_FOG_OWNERS = 8;
|
|
11
|
+
export const VolumetricFogSamplingValue = { noise: 0, density: 1 } as const;
|
|
12
|
+
|
|
11
13
|
export interface VolumeDensityBinding {
|
|
12
14
|
readonly guid: string;
|
|
13
15
|
readonly generation: number;
|
|
@@ -42,16 +44,15 @@ export interface VolumetricFogAuthoring {
|
|
|
42
44
|
readonly emission: readonly [number, number, number];
|
|
43
45
|
readonly anisotropy: number;
|
|
44
46
|
readonly maxDistance: number;
|
|
45
|
-
|
|
47
|
+
/** Noise grain is the atmospheric default; density samples local bounds directly. */
|
|
48
|
+
readonly sampling?: 'noise' | 'density';
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
export type VolumetricFogLightSelection =
|
|
49
52
|
| { readonly light: EntityHandle; readonly spotLight?: undefined }
|
|
50
53
|
| { readonly light: EntityHandle; readonly spotLight: EntityHandle };
|
|
51
54
|
|
|
52
|
-
export
|
|
53
|
-
readonly ownerCount: 1;
|
|
54
|
-
}
|
|
55
|
+
export type ValidatedVolumetricFog = VolumetricFogAuthoring;
|
|
55
56
|
|
|
56
57
|
export const VolumetricFog = defineComponent('VolumetricFog', {
|
|
57
58
|
light: { type: 'entity' },
|
|
@@ -64,6 +65,7 @@ export const VolumetricFog = defineComponent('VolumetricFog', {
|
|
|
64
65
|
emission: { type: 'array<f32, 3>' },
|
|
65
66
|
anisotropy: { type: 'f32', default: 0 },
|
|
66
67
|
maxDistance: { type: 'f32', default: 100 },
|
|
68
|
+
sampling: { type: 'enum', labels: VolumetricFogSamplingValue, default: 0 },
|
|
67
69
|
});
|
|
68
70
|
|
|
69
71
|
function finiteVector(value: readonly [number, number, number]): boolean {
|
|
@@ -86,8 +88,6 @@ function validRange(
|
|
|
86
88
|
export function validateVolumetricFog(
|
|
87
89
|
input: VolumetricFogAuthoring,
|
|
88
90
|
): Result<ValidatedVolumetricFog, VolumeError> {
|
|
89
|
-
const ownerCount = input.ownerCount ?? 1;
|
|
90
|
-
if (ownerCount !== 1) return err(new VolumeOwnerConflictError(ownerCount));
|
|
91
91
|
if (input.density.shape.viewDimension !== '3d' || input.density.colorSpace === 'srgb') {
|
|
92
92
|
return err(
|
|
93
93
|
new VolumeDensityShapeMismatchError(input.density.guid, input.density.shape.viewDimension),
|
|
@@ -102,9 +102,10 @@ export function validateVolumetricFog(
|
|
|
102
102
|
input.anisotropy <= -1 ||
|
|
103
103
|
input.anisotropy >= 1 ||
|
|
104
104
|
!Number.isFinite(input.maxDistance) ||
|
|
105
|
-
input.maxDistance <= 0
|
|
105
|
+
input.maxDistance <= 0 ||
|
|
106
|
+
(input.sampling !== undefined && input.sampling !== 'noise' && input.sampling !== 'density')
|
|
106
107
|
) {
|
|
107
108
|
return err(new VolumeInvalidParametersError(input));
|
|
108
109
|
}
|
|
109
|
-
return ok(
|
|
110
|
+
return ok(input);
|
|
110
111
|
}
|
package/src/volume/extract.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { err, ok, type Result } from '@forgeax/engine-types';
|
|
2
2
|
import { type VolumeError, VolumeOwnerConflictError } from '../errors/render';
|
|
3
3
|
import {
|
|
4
|
+
MAX_VOLUMETRIC_FOG_OWNERS,
|
|
4
5
|
type ValidatedVolumetricFog,
|
|
5
6
|
type VolumetricFogAuthoring,
|
|
6
7
|
validateVolumetricFog,
|
|
@@ -8,14 +9,19 @@ import {
|
|
|
8
9
|
|
|
9
10
|
export type VolumetricFogExtract =
|
|
10
11
|
| { readonly status: 'off' }
|
|
11
|
-
| { readonly status: 'available'; readonly
|
|
12
|
+
| { readonly status: 'available'; readonly fogs: readonly ValidatedVolumetricFog[] };
|
|
12
13
|
|
|
13
14
|
export function extractVolumetricFog(
|
|
14
15
|
inputs: readonly VolumetricFogAuthoring[],
|
|
15
16
|
): Result<VolumetricFogExtract, VolumeError> {
|
|
16
17
|
if (inputs.length === 0) return ok({ status: 'off' });
|
|
17
|
-
if (inputs.length
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
if (inputs.length > MAX_VOLUMETRIC_FOG_OWNERS)
|
|
19
|
+
return err(new VolumeOwnerConflictError(inputs.length));
|
|
20
|
+
const fogs: ValidatedVolumetricFog[] = [];
|
|
21
|
+
for (const input of inputs) {
|
|
22
|
+
const validated = validateVolumetricFog(input);
|
|
23
|
+
if (!validated.ok) return validated;
|
|
24
|
+
fogs.push(validated.value);
|
|
25
|
+
}
|
|
26
|
+
return ok({ status: 'available', fogs });
|
|
21
27
|
}
|
package/src/volume/inspection.ts
CHANGED
|
@@ -7,6 +7,8 @@ export type VolumetricFogInspectionStatus = 'off' | 'available' | 'unavailable'
|
|
|
7
7
|
export type VolumetricFogResourceStage = 'none' | 'candidate' | 'accepted' | 'lkg' | 'recovering';
|
|
8
8
|
|
|
9
9
|
export interface VolumetricFogInspection {
|
|
10
|
+
/** Owners in the last successfully submitted volume collection. */
|
|
11
|
+
readonly ownerCount: number;
|
|
10
12
|
readonly status: VolumetricFogInspectionStatus;
|
|
11
13
|
readonly resourceStage: VolumetricFogResourceStage;
|
|
12
14
|
readonly guid: string | undefined;
|
|
@@ -57,6 +59,7 @@ export function inspectVolumetricFog(input: VolumetricFogInspectionInput): Volum
|
|
|
57
59
|
? 'degraded'
|
|
58
60
|
: 'available';
|
|
59
61
|
return Object.freeze({
|
|
62
|
+
ownerCount: 0,
|
|
60
63
|
status,
|
|
61
64
|
resourceStage: resourceStage(input),
|
|
62
65
|
guid: recovery?.guid,
|