@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
|
@@ -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
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
GraphAccess,
|
|
3
|
-
GraphResourceResolver,
|
|
4
|
-
GraphTextureView,
|
|
5
|
-
RenderGraphBuilder,
|
|
1
|
+
import {
|
|
2
|
+
type GraphAccess,
|
|
3
|
+
type GraphResourceResolver,
|
|
4
|
+
type GraphTextureView,
|
|
5
|
+
type RenderGraphBuilder,
|
|
6
6
|
RenderGraphError,
|
|
7
|
-
ResolveContext,
|
|
7
|
+
type ResolveContext,
|
|
8
8
|
} from '@forgeax/engine-render-graph';
|
|
9
9
|
import {
|
|
10
10
|
type Buffer,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
type TextureFormat,
|
|
14
14
|
type TextureView,
|
|
15
15
|
} from '@forgeax/engine-rhi';
|
|
16
|
-
import { ok, type PassKind, type PassSelector, type Result } from '@forgeax/engine-types';
|
|
16
|
+
import { err, ok, type PassKind, type PassSelector, type Result } from '@forgeax/engine-types';
|
|
17
17
|
import {
|
|
18
18
|
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
19
19
|
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,
|
|
@@ -28,10 +28,9 @@ import type {
|
|
|
28
28
|
} from './record/render-context';
|
|
29
29
|
import {
|
|
30
30
|
encodeSkyboxPass,
|
|
31
|
-
recordBloomBlurHPass,
|
|
32
|
-
recordBloomBlurVPass,
|
|
33
|
-
recordBloomBrightPass,
|
|
34
31
|
recordBloomCompositePass,
|
|
32
|
+
recordBloomDownsamplePass,
|
|
33
|
+
recordBloomUpsamplePass,
|
|
35
34
|
} from './record/skybox-post-pass';
|
|
36
35
|
import { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID } from './render-contract';
|
|
37
36
|
import {
|
|
@@ -39,7 +38,12 @@ import {
|
|
|
39
38
|
recordSsaoBlurPass,
|
|
40
39
|
recordSsaoCalcPass,
|
|
41
40
|
} from './render-graph-primitives';
|
|
42
|
-
import type {
|
|
41
|
+
import type {
|
|
42
|
+
RenderPipelineFrame,
|
|
43
|
+
RenderPipelineGpuDrivenFilter,
|
|
44
|
+
RenderPipelineGpuDrivenProjection,
|
|
45
|
+
RenderPipelineSurfaceMediumPair,
|
|
46
|
+
} from './render-pipeline';
|
|
43
47
|
import { createRenderPipelineTarget, type RenderPipelineTarget } from './render-pipeline';
|
|
44
48
|
import type { OcclusionFrameProjection } from './scene/visibility/occlusion-runtime';
|
|
45
49
|
import {
|
|
@@ -266,6 +270,8 @@ export interface TypedScenePassOptions {
|
|
|
266
270
|
readonly sampled?: readonly RenderPipelineTarget[] | undefined;
|
|
267
271
|
readonly directionalShadow?: RenderPipelineTarget | undefined;
|
|
268
272
|
readonly spotShadow?: RenderPipelineTarget | undefined;
|
|
273
|
+
/** Stable world-space cloud shadow map sampled by direct-solar receivers. */
|
|
274
|
+
readonly cloudShadow?: RenderPipelineTarget | undefined;
|
|
269
275
|
readonly ssao?: RenderPipelineTarget | undefined;
|
|
270
276
|
readonly selector: PassSelector;
|
|
271
277
|
readonly passKind?: PassKind | undefined;
|
|
@@ -273,8 +279,24 @@ export interface TypedScenePassOptions {
|
|
|
273
279
|
readonly clearColor?: readonly [number, number, number, number] | undefined;
|
|
274
280
|
readonly colorLoadOp?: GPULoadOp | readonly GPULoadOp[] | undefined;
|
|
275
281
|
readonly depthLoadOp?: GPULoadOp | undefined;
|
|
282
|
+
/** Preserve nearest transparent fragment depth for downstream medium clipping. */
|
|
283
|
+
readonly transparentDepthWrite?: boolean | undefined;
|
|
276
284
|
readonly coverageOnly?: boolean | undefined;
|
|
277
|
-
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;
|
|
278
300
|
/** Exclude material/pass pairs consumed by an earlier graph lane. */
|
|
279
301
|
readonly excludeSelector?: PassSelector | undefined;
|
|
280
302
|
/** Require material membership in another lane without selecting its entries. */
|
|
@@ -300,9 +322,23 @@ export function addTypedScenePass(
|
|
|
300
322
|
resource: target.view,
|
|
301
323
|
usage: 'sampled-read' as const,
|
|
302
324
|
})),
|
|
325
|
+
...(options.cloudShadow === undefined
|
|
326
|
+
? []
|
|
327
|
+
: [{ resource: options.cloudShadow.view, usage: 'sampled-read' as const }]),
|
|
303
328
|
...(options.transmissionBackdrop === undefined
|
|
304
329
|
? []
|
|
305
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
|
+
: []),
|
|
306
342
|
...(options.environment === undefined
|
|
307
343
|
? []
|
|
308
344
|
: [options.environment.irradiance, options.environment.prefilter].map((resource) => ({
|
|
@@ -358,12 +394,28 @@ export function addTypedScenePass(
|
|
|
358
394
|
options.spotShadow === undefined
|
|
359
395
|
? undefined
|
|
360
396
|
: resolvedView(resources, options.spotShadow.view);
|
|
397
|
+
const cloudShadow =
|
|
398
|
+
options.cloudShadow === undefined
|
|
399
|
+
? undefined
|
|
400
|
+
: resolvedView(resources, options.cloudShadow.view);
|
|
361
401
|
const ssao =
|
|
362
402
|
options.ssao === undefined ? undefined : resolvedView(resources, options.ssao.view);
|
|
363
403
|
const transmissionBackdrop =
|
|
364
404
|
options.transmissionBackdrop === undefined
|
|
365
405
|
? null
|
|
366
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);
|
|
367
419
|
internal.frameState.currentDirectionalShadowView = directionalShadow ?? null;
|
|
368
420
|
internal.frameState.currentSpotShadowView = spotShadow ?? null;
|
|
369
421
|
const groups = buildPerFrameBindGroups(
|
|
@@ -375,6 +427,7 @@ export function addTypedScenePass(
|
|
|
375
427
|
{
|
|
376
428
|
directionalShadow,
|
|
377
429
|
spotShadow,
|
|
430
|
+
cloudShadow,
|
|
378
431
|
projector: internal.spotLightProjector?.view ?? internal.volumetricFog?.projectorView,
|
|
379
432
|
projectorSampler:
|
|
380
433
|
internal.spotLightProjector?.sampler ?? internal.volumetricFog?.projectorSampler,
|
|
@@ -428,6 +481,9 @@ export function addTypedScenePass(
|
|
|
428
481
|
passKind: options.passKind ?? 'forward',
|
|
429
482
|
...(options.clearColor === undefined ? {} : { clearColor: options.clearColor }),
|
|
430
483
|
...(options.recordMode === undefined ? {} : { recordMode: options.recordMode }),
|
|
484
|
+
...(options.transparentDepthWrite === undefined
|
|
485
|
+
? {}
|
|
486
|
+
: { transparentDepthWrite: options.transparentDepthWrite }),
|
|
431
487
|
...(options.coverageOnly === undefined ? {} : { coverageOnly: options.coverageOnly }),
|
|
432
488
|
...(options.excludeSelector === undefined
|
|
433
489
|
? {}
|
|
@@ -438,9 +494,20 @@ export function addTypedScenePass(
|
|
|
438
494
|
...(options.transmissionBackdrop === undefined
|
|
439
495
|
? {}
|
|
440
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
|
+
: {}),
|
|
441
505
|
...(options.gpuDriven === undefined
|
|
442
506
|
? {}
|
|
443
507
|
: { gpuDriven: { projection: options.gpuDriven, resources } }),
|
|
508
|
+
...(options.gpuDrivenFilter === undefined
|
|
509
|
+
? {}
|
|
510
|
+
: { gpuDrivenFilter: options.gpuDrivenFilter }),
|
|
444
511
|
});
|
|
445
512
|
// encodeMainPass receives a pass-local context so attachment and
|
|
446
513
|
// bind-group overrides stay isolated. Its material UBO payload cache is
|
|
@@ -502,57 +569,57 @@ export function addReflectionFallbackObservationPass(
|
|
|
502
569
|
export interface TypedBloomTargets {
|
|
503
570
|
readonly scene: RenderPipelineTarget;
|
|
504
571
|
readonly composited: RenderPipelineTarget;
|
|
505
|
-
readonly
|
|
506
|
-
readonly
|
|
507
|
-
readonly
|
|
572
|
+
readonly downsample: readonly RenderPipelineTarget[];
|
|
573
|
+
readonly upsample: readonly RenderPipelineTarget[];
|
|
574
|
+
readonly levelDimensions: readonly { readonly width: number; readonly height: number }[];
|
|
508
575
|
}
|
|
509
576
|
|
|
510
577
|
/** The semantic Bloom pass owner; graph inspection consumes these same identities. */
|
|
511
578
|
export const TYPED_BLOOM_PASS_NAMES = {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
blurV: 'bloom-blur-v',
|
|
579
|
+
downsample: 'bloom-downsample',
|
|
580
|
+
upsample: 'bloom-upsample',
|
|
515
581
|
composite: 'bloom-composite',
|
|
516
582
|
} as const;
|
|
517
583
|
|
|
584
|
+
export function typedBloomLevelPassName(kind: 'downsample' | 'upsample', level: number): string {
|
|
585
|
+
return `${TYPED_BLOOM_PASS_NAMES[kind]}-${level}`;
|
|
586
|
+
}
|
|
587
|
+
|
|
518
588
|
export function addTypedBloomPasses(
|
|
519
589
|
graph: RenderGraphBuilder<RenderPipelineFrame>,
|
|
520
590
|
targets: TypedBloomTargets,
|
|
521
591
|
): Result<void, RenderGraphError> {
|
|
522
|
-
const named = {
|
|
592
|
+
const named: Record<string, RenderPipelineTarget> = {
|
|
523
593
|
hdrColor: targets.scene,
|
|
524
594
|
hdrComposited: targets.composited,
|
|
525
|
-
bloomBright: targets.bright,
|
|
526
|
-
bloomBlurH: targets.blurH,
|
|
527
|
-
bloomBlurV: targets.blurV,
|
|
528
595
|
};
|
|
529
|
-
|
|
530
|
-
{
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
596
|
+
targets.downsample.forEach((target, level) => {
|
|
597
|
+
named[`bloomDownsample${level}`] = target;
|
|
598
|
+
});
|
|
599
|
+
targets.upsample.forEach((target, level) => {
|
|
600
|
+
named[`bloomUpsample${level}`] = target;
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
const add = (
|
|
604
|
+
name: string,
|
|
605
|
+
reads: readonly RenderPipelineTarget[],
|
|
606
|
+
write: RenderPipelineTarget,
|
|
607
|
+
encode: (
|
|
608
|
+
frame: _InternalRenderPipelineContext,
|
|
609
|
+
resolve: ResolveContext,
|
|
610
|
+
pass: import('@forgeax/engine-rhi').RhiRenderPassEncoder,
|
|
611
|
+
level?: number,
|
|
612
|
+
size?: { readonly width: number; readonly height: number },
|
|
613
|
+
) => void,
|
|
614
|
+
level?: number,
|
|
615
|
+
): Result<void, RenderGraphError> => {
|
|
616
|
+
const descriptor = {
|
|
617
|
+
name,
|
|
618
|
+
reads,
|
|
619
|
+
write,
|
|
620
|
+
encode,
|
|
621
|
+
level,
|
|
622
|
+
};
|
|
556
623
|
const added = graph.addRasterPass(descriptor.name, {
|
|
557
624
|
accesses: [
|
|
558
625
|
...descriptor.reads.map((target) => ({
|
|
@@ -574,11 +641,85 @@ export function addTypedBloomPasses(
|
|
|
574
641
|
frame as _InternalRenderPipelineContext,
|
|
575
642
|
legacyResolver(resources, named),
|
|
576
643
|
pass,
|
|
644
|
+
descriptor.level,
|
|
645
|
+
descriptor.level === undefined ? undefined : targets.levelDimensions[descriptor.level],
|
|
577
646
|
),
|
|
578
647
|
});
|
|
648
|
+
return added.ok ? ok(undefined) : added;
|
|
649
|
+
};
|
|
650
|
+
|
|
651
|
+
for (const [level, write] of targets.downsample.entries()) {
|
|
652
|
+
const source = level === 0 ? targets.scene : targets.downsample[level - 1];
|
|
653
|
+
if (source === undefined) {
|
|
654
|
+
return err(
|
|
655
|
+
new RenderGraphError({
|
|
656
|
+
code: 'resource-resolution-failed',
|
|
657
|
+
expected: 'Bloom downsample levels form one adjacent pyramid',
|
|
658
|
+
hint: 'rebuild the Standard Bloom target declaration from one level list',
|
|
659
|
+
detail: { resourceLabel: `bloom-level-${level}` },
|
|
660
|
+
}),
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
const added = add(
|
|
664
|
+
typedBloomLevelPassName('downsample', level),
|
|
665
|
+
[source],
|
|
666
|
+
write,
|
|
667
|
+
(frame, resolve, pass, passLevel) =>
|
|
668
|
+
recordBloomDownsamplePass(
|
|
669
|
+
frame,
|
|
670
|
+
resolve,
|
|
671
|
+
pass,
|
|
672
|
+
passLevel ?? level,
|
|
673
|
+
targets.levelDimensions[passLevel ?? level],
|
|
674
|
+
),
|
|
675
|
+
level,
|
|
676
|
+
);
|
|
579
677
|
if (!added.ok) return added;
|
|
580
678
|
}
|
|
581
|
-
|
|
679
|
+
for (let level = targets.upsample.length - 1; level >= 0; level -= 1) {
|
|
680
|
+
const current = targets.downsample[level];
|
|
681
|
+
const coarse =
|
|
682
|
+
level === targets.downsample.length - 2
|
|
683
|
+
? targets.downsample[level + 1]
|
|
684
|
+
: targets.upsample[level + 1];
|
|
685
|
+
const write = targets.upsample[level];
|
|
686
|
+
if (current === undefined || coarse === undefined || write === undefined) {
|
|
687
|
+
return err(
|
|
688
|
+
new RenderGraphError({
|
|
689
|
+
code: 'resource-resolution-failed',
|
|
690
|
+
expected: 'Bloom downsample and upsample levels form one adjacent pyramid',
|
|
691
|
+
hint: 'rebuild the Standard Bloom target declaration from one level list',
|
|
692
|
+
detail: { resourceLabel: `bloom-level-${level}` },
|
|
693
|
+
}),
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
const added = add(
|
|
697
|
+
typedBloomLevelPassName('upsample', level),
|
|
698
|
+
[current, coarse],
|
|
699
|
+
write,
|
|
700
|
+
(frame, resolve, pass, passLevel) =>
|
|
701
|
+
recordBloomUpsamplePass(frame, resolve, pass, passLevel ?? level),
|
|
702
|
+
level,
|
|
703
|
+
);
|
|
704
|
+
if (!added.ok) return added;
|
|
705
|
+
}
|
|
706
|
+
const finest = targets.upsample[0] ?? targets.downsample[0];
|
|
707
|
+
if (finest === undefined) {
|
|
708
|
+
return err(
|
|
709
|
+
new RenderGraphError({
|
|
710
|
+
code: 'resource-resolution-failed',
|
|
711
|
+
expected: 'Bloom has at least one downsample level',
|
|
712
|
+
hint: 'derive Bloom levels from a positive output extent',
|
|
713
|
+
detail: { resourceLabel: 'bloom-downsample-0' },
|
|
714
|
+
}),
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
return add(
|
|
718
|
+
TYPED_BLOOM_PASS_NAMES.composite,
|
|
719
|
+
[targets.scene, finest],
|
|
720
|
+
targets.composited,
|
|
721
|
+
(frame, resolve, pass) => recordBloomCompositePass(frame, resolve, pass),
|
|
722
|
+
);
|
|
582
723
|
}
|
|
583
724
|
|
|
584
725
|
export interface TypedSsaoTargets {
|