@forgeax/engine-render 0.1.20 → 0.1.23
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 +365 -29
- package/dist/assembly/backend-contract.d.ts +13 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -1
- package/dist/assembly/device-feature-admission.d.ts +18 -0
- package/dist/assembly/device-feature-admission.d.ts.map +1 -0
- package/dist/assembly/directional-shadow-inspection.d.ts +38 -0
- package/dist/assembly/directional-shadow-inspection.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +30 -19
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +19 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/render-target-host.d.ts +46 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -0
- package/dist/assets/render-asset-port.d.ts.map +1 -1
- package/dist/authoring.mjs +4 -1
- package/dist/authoring.mjs.map +1 -1
- package/dist/capture/cube-views.d.ts +21 -0
- package/dist/capture/cube-views.d.ts.map +1 -0
- package/dist/capture/scheduler.d.ts +54 -0
- package/dist/capture/scheduler.d.ts.map +1 -0
- package/dist/{chunk-PCHBPYML.mjs → chunk-4L3P6DT5.mjs} +2 -2
- package/dist/chunk-4L3P6DT5.mjs.map +1 -0
- package/dist/{chunk-VFPLTKCU.mjs → chunk-4NPUASZR.mjs} +15 -4
- package/dist/chunk-4NPUASZR.mjs.map +1 -0
- package/dist/chunk-DIYW3M5D.mjs +5085 -0
- package/dist/chunk-DIYW3M5D.mjs.map +1 -0
- package/dist/chunk-FBC4R44J.mjs +1003 -0
- package/dist/chunk-FBC4R44J.mjs.map +1 -0
- package/dist/{chunk-CDTWTHZR.mjs → chunk-FF7K3FSO.mjs} +474 -168
- package/dist/chunk-FF7K3FSO.mjs.map +1 -0
- package/dist/chunk-HZUPSYW7.mjs +1104 -0
- package/dist/chunk-HZUPSYW7.mjs.map +1 -0
- package/dist/{chunk-TBQJOK2L.mjs → chunk-QODA5UKU.mjs} +321 -269
- package/dist/chunk-QODA5UKU.mjs.map +1 -0
- package/dist/chunk-YALPS44A.mjs +296 -0
- package/dist/chunk-YALPS44A.mjs.map +1 -0
- package/dist/{chunk-4XINDLAY.mjs → chunk-ZUWKAZ2I.mjs} +1963 -2178
- package/dist/chunk-ZUWKAZ2I.mjs.map +1 -0
- package/dist/cluster-binner.d.ts +5 -0
- package/dist/cluster-binner.d.ts.map +1 -1
- package/dist/components/camera.d.ts +1 -0
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/cube-camera.d.ts +20 -0
- package/dist/components/cube-camera.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +11 -2
- package/dist/components/directional-light.d.ts.map +1 -1
- package/dist/components/directional-shadow-filter.d.ts +25 -0
- package/dist/components/directional-shadow-filter.d.ts.map +1 -0
- package/dist/components/index.d.ts +5 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts +4 -0
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/light-probe.d.ts +9 -0
- package/dist/components/light-probe.d.ts.map +1 -0
- package/dist/components/rect-area-light.d.ts +12 -0
- package/dist/components/rect-area-light.d.ts.map +1 -0
- package/dist/components/reflection-probe.d.ts +17 -0
- package/dist/components/reflection-probe.d.ts.map +1 -0
- package/dist/components/scene-instance.d.ts +4 -0
- package/dist/components/scene-instance.d.ts.map +1 -1
- package/dist/components/spot-light.d.ts +3 -0
- package/dist/components/spot-light.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +14836 -9620
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +8 -1
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/device/lifecycle-transaction.d.ts +2 -0
- package/dist/device/lifecycle-transaction.d.ts.map +1 -0
- package/dist/environment/frame.d.ts.map +1 -1
- package/dist/environment/lifecycle.d.ts +5 -0
- package/dist/environment/lifecycle.d.ts.map +1 -1
- package/dist/errors/gpu-driven.d.ts +26 -0
- package/dist/errors/gpu-driven.d.ts.map +1 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/recover.d.ts +9 -1
- package/dist/errors/recover.d.ts.map +1 -1
- package/dist/errors/render.d.ts +166 -93
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/directional-shadow-projection.d.ts +23 -0
- package/dist/extract/directional-shadow-projection.d.ts.map +1 -0
- package/dist/extract/environment.d.ts +14 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/extract/gpu-driven.d.ts +50 -0
- package/dist/extract/gpu-driven.d.ts.map +1 -0
- package/dist/extract/visibility.d.ts.map +1 -1
- package/dist/features/fullscreen.d.ts.map +1 -1
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +10 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +13 -2
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +34 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/prepared-draw.d.ts +63 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +97 -2
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/view-gpu.d.ts +64 -1
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene-schema.d.ts +14 -0
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +8 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/gpu-usage.d.ts +0 -1
- package/dist/gpu-usage.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +21 -19
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +4 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/kernel-cache.d.ts +36 -0
- package/dist/ibl/kernel-cache.d.ts.map +1 -0
- package/dist/index.d.ts +39 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +91 -6
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +214 -1
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +50 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -0
- package/dist/internal.d.ts +9 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +23 -2
- package/dist/internal.mjs.map +1 -1
- package/dist/light-buffer-layout.d.ts +58 -140
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/materials.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +54 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +38 -14
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts +2 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/errors.d.ts +4 -0
- package/dist/pipeline/standard-lighting/errors.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/graph.d.ts +24 -0
- package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts +38 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/layout.d.ts +28 -0
- package/dist/pipeline/standard-lighting/layout.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts +33 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/membership.d.ts +14 -0
- package/dist/pipeline/standard-lighting/membership.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts +16 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/topology.d.ts +45 -0
- package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/transport.d.ts +36 -0
- package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts +4 -13
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +5 -26
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +2 -0
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +40 -7
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/point-shadow-inspection.d.ts +21 -0
- package/dist/point-shadow-inspection.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/ltc-resources.d.ts +31 -0
- package/dist/prepare/extended-lighting/ltc-resources.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/resources.d.ts +72 -0
- package/dist/prepare/extended-lighting/resources.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/spot-modifiers.d.ts +42 -0
- package/dist/prepare/extended-lighting/spot-modifiers.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/state.d.ts +24 -0
- package/dist/prepare/extended-lighting/state.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +33 -36
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +78 -24
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts +5 -0
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +16 -6
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-pass-timing/contract.d.ts +96 -0
- package/dist/record/gpu-pass-timing/contract.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/errors.d.ts +18 -0
- package/dist/record/gpu-pass-timing/errors.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/index.d.ts +8 -0
- package/dist/record/gpu-pass-timing/index.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/parser.d.ts +11 -0
- package/dist/record/gpu-pass-timing/parser.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/session.d.ts +43 -0
- package/dist/record/gpu-pass-timing/session.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +20 -3
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/helpers.d.ts +0 -20
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +6 -1
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +25 -2
- 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 +2 -0
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +98 -6
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +119 -4
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +7 -5
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/reflection/filter.d.ts +22 -0
- package/dist/reflection/filter.d.ts.map +1 -0
- package/dist/reflection/gpu-table.d.ts +25 -0
- package/dist/reflection/gpu-table.d.ts.map +1 -0
- package/dist/reflection/inspection.d.ts +10 -0
- package/dist/reflection/inspection.d.ts.map +1 -0
- package/dist/reflection/projection.d.ts +140 -0
- package/dist/reflection/projection.d.ts.map +1 -0
- package/dist/reflection/record-owner.d.ts +60 -0
- package/dist/reflection/record-owner.d.ts.map +1 -0
- package/dist/render-contract.d.ts +62 -14
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +49 -2
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +160 -31
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +28 -2
- package/dist/render-system.d.ts.map +1 -1
- package/dist/renderer.d.ts +43 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/scene/probe-blend-record.d.ts +22 -0
- package/dist/scene/probe-blend-record.d.ts.map +1 -0
- package/dist/scene/probe-blend.d.ts +142 -0
- package/dist/scene/probe-blend.d.ts.map +1 -0
- package/dist/scene/render-scene-types.d.ts +0 -6
- package/dist/scene/render-scene-types.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +117 -9
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/visibility/bounds.d.ts +20 -0
- package/dist/scene/visibility/bounds.d.ts.map +1 -0
- package/dist/scene/visibility/budget.d.ts +16 -0
- package/dist/scene/visibility/budget.d.ts.map +1 -0
- package/dist/scene/visibility/facet.d.ts +73 -0
- package/dist/scene/visibility/facet.d.ts.map +1 -0
- package/dist/scene/visibility/gpu-frame-timing.d.ts +41 -0
- package/dist/scene/visibility/gpu-frame-timing.d.ts.map +1 -0
- package/dist/scene/visibility/gpu-lod.d.ts +46 -0
- package/dist/scene/visibility/gpu-lod.d.ts.map +1 -0
- package/dist/scene/visibility/inspection.d.ts +132 -0
- package/dist/scene/visibility/inspection.d.ts.map +1 -0
- package/dist/scene/visibility/lod-selector.d.ts +25 -0
- package/dist/scene/visibility/lod-selector.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-confidence.d.ts +81 -0
- package/dist/scene/visibility/occlusion-confidence.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-pass.d.ts +57 -0
- package/dist/scene/visibility/occlusion-pass.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-query-pool.d.ts +57 -0
- package/dist/scene/visibility/occlusion-query-pool.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-runtime.d.ts +96 -0
- package/dist/scene/visibility/occlusion-runtime.d.ts.map +1 -0
- package/dist/scene/visibility/types.d.ts +34 -0
- package/dist/scene/visibility/types.d.ts.map +1 -0
- package/dist/shadow-atlas.d.ts +3 -3
- package/dist/shadow-atlas.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +3 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/ssr/admission.d.ts +122 -0
- package/dist/ssr/admission.d.ts.map +1 -0
- package/dist/ssr/composition.d.ts +32 -0
- package/dist/ssr/composition.d.ts.map +1 -0
- package/dist/ssr/errors.d.ts +39 -0
- package/dist/ssr/errors.d.ts.map +1 -0
- package/dist/ssr/identity.d.ts +13 -0
- package/dist/ssr/identity.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +1 -1
- package/dist/targets/contracts.d.ts +66 -0
- package/dist/targets/contracts.d.ts.map +1 -0
- package/dist/targets/graph-projection.d.ts +29 -0
- package/dist/targets/graph-projection.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +34 -0
- package/dist/targets/material-source.d.ts.map +1 -0
- package/dist/targets/owner.d.ts +32 -0
- package/dist/targets/owner.d.ts.map +1 -0
- package/dist/targets/physical.d.ts +18 -0
- package/dist/targets/physical.d.ts.map +1 -0
- package/dist/targets/readback.d.ts +39 -0
- package/dist/targets/readback.d.ts.map +1 -0
- package/dist/temporal/frame-coordinator.d.ts +13 -0
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +2 -0
- package/dist/temporal/frame.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -5
- package/dist/temporal/view.d.ts +7 -0
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/tilemap-chunk-extract-system.d.ts +1 -1
- package/dist/typed-render-graph-primitives.d.ts +5 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +1 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +9 -5
- package/dist/volume/passes.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/__tests__/bloom-exact-zero.unit.test.ts +48 -19
- package/src/__tests__/bloom-lifecycle.integration.test.ts +41 -13
- package/src/__tests__/camera-target-consumption.unit.test.ts +53 -0
- package/src/__tests__/cluster-binner.unit.test.ts +35 -0
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +12 -2
- package/src/__tests__/cube-camera-scheduler.unit.test.ts +70 -0
- package/src/__tests__/cube-camera-single-submit.perf.test.ts +75 -0
- package/src/__tests__/cube-camera-view-matrices.unit.test.ts +41 -0
- package/src/__tests__/cube-camera-vocabulary.unit.test.ts +47 -0
- package/src/__tests__/cube-camera.integration.test.ts +42 -0
- package/src/__tests__/detached-inspection.integration.test.ts +6 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +85 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +62 -6
- package/src/__tests__/docs-gate-green.unit.test.ts +38 -0
- package/src/__tests__/environment-generation.integration.test.ts +16 -0
- package/src/__tests__/evidence-identity.ts +13 -0
- package/src/__tests__/evidence-identity.unit.test.ts +24 -0
- package/src/__tests__/extended-lighting-recovery.browser.test.ts +14 -0
- package/src/__tests__/extended-lighting-recovery.dawn.test.ts +14 -0
- package/src/__tests__/extended-lighting-recovery.integration.test.ts +81 -0
- package/src/__tests__/extended-lighting-resources.unit.test.ts +51 -0
- package/src/__tests__/extended-lighting-zero-feature.integration.test.ts +52 -0
- package/src/__tests__/factory-contract.integration.test.ts +288 -29
- package/src/__tests__/fog-component.unit.test.ts +67 -0
- package/src/__tests__/fog.integration.test.ts +86 -0
- package/src/__tests__/frame-observation.contract.test.ts +15 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +37 -0
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +10 -8
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +18 -1
- package/src/__tests__/gpu-driven-production.integration.test.ts +579 -17
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +66 -2
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +26 -1
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +101 -6
- package/src/__tests__/gpu-driven-view.browser.test.ts +3 -3
- package/src/__tests__/gpu-driven-view.dawn.test.ts +3 -3
- package/src/__tests__/gpu-driven-view.unit.test.ts +50 -0
- package/src/__tests__/gpu-lod-evidence.ts +188 -0
- package/src/__tests__/gpu-lod-fallback.integration.test.ts +10 -0
- package/src/__tests__/gpu-lod-indirect.integration.test.ts +40 -0
- package/src/__tests__/gpu-lod-parity.dawn.test.ts +29 -0
- package/src/__tests__/gpu-lod-readiness.integration.test.ts +52 -0
- package/src/__tests__/gpu-lod-schema.unit.test.ts +66 -0
- package/src/__tests__/gpu-lod-selector.unit.test.ts +28 -0
- package/src/__tests__/gpu-lod-silhouette.browser.test.ts +13 -0
- package/src/__tests__/gpu-pass-timing-browser-runner.ts +281 -0
- package/src/__tests__/gpu-pass-timing-coexistence.integration.test.ts +80 -0
- package/src/__tests__/gpu-pass-timing-contract.unit.test.ts +243 -0
- package/src/__tests__/gpu-pass-timing-exact-zero.unit.test.ts +131 -0
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +230 -0
- package/src/__tests__/gpu-pass-timing-observation.unit.test.ts +233 -0
- package/src/__tests__/gpu-pass-timing-session.unit.test.ts +438 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +26 -0
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +125 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +66 -1
- package/src/__tests__/gpu-scene.dawn.test.ts +8 -1
- package/src/__tests__/gpu-scene.unit.test.ts +49 -3
- package/src/__tests__/hdrp-group2-visibility.unit.test.ts +24 -0
- package/src/__tests__/instances-culling.integration.test.ts +94 -0
- package/src/__tests__/instances-derived-bounds.unit.test.ts +118 -0
- package/src/__tests__/light-buffer-layout.unit.test.ts +113 -3
- package/src/__tests__/light-inspection.unit.test.ts +55 -0
- package/src/__tests__/light-resource-error.unit.test.ts +43 -0
- package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +109 -0
- package/src/__tests__/lod-bounds.unit.test.ts +42 -0
- package/src/__tests__/lod-cpu-lane.integration.test.ts +55 -0
- package/src/__tests__/lod-cpu-no-change.perf.test.ts +19 -0
- package/src/__tests__/lod-gpu-frame-timing.unit.test.ts +49 -0
- package/src/__tests__/lod-multi-view.integration.test.ts +63 -0
- package/src/__tests__/lod-occlusion-device-loss.integration.test.ts +27 -0
- package/src/__tests__/lod-occlusion-final-decision.integration.test.ts +47 -0
- package/src/__tests__/lod-occlusion-inspection.integration.test.ts +217 -0
- package/src/__tests__/lod-occlusion-inspection.schema.test-d.ts +14 -0
- package/src/__tests__/lod-occlusion-inspection.unit.test.ts +72 -0
- package/src/__tests__/lod-occlusion-visual-evidence.ts +91 -0
- package/src/__tests__/lod-occlusion.browser.test.ts +15 -0
- package/src/__tests__/lod-occlusion.dawn.test.ts +20 -0
- package/src/__tests__/lod-selector.profile.test.ts +35 -0
- package/src/__tests__/lod-selector.unit.test.ts +68 -0
- package/src/__tests__/lod-visibility-identity.unit.test.ts +198 -0
- package/src/__tests__/lod-visibility-lifecycle.integration.test.ts +132 -0
- package/src/__tests__/ltc-resources.unit.test.ts +32 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +17 -0
- package/src/__tests__/material-observation.integration.test.ts +101 -0
- package/src/__tests__/occlusion-confidence.unit.test.ts +168 -0
- package/src/__tests__/occlusion-invalidation.integration.test.ts +37 -0
- package/src/__tests__/occlusion-pass-routing.unit.test.ts +16 -0
- package/src/__tests__/occlusion-pass.dawn.test.ts +20 -0
- package/src/__tests__/occlusion-pass.integration.test.ts +43 -0
- package/src/__tests__/occlusion-pass.rhi-null.test.ts +22 -0
- package/src/__tests__/occlusion-query-pool.rhi-null.test.ts +21 -0
- package/src/__tests__/occlusion-query-pool.unit.test.ts +95 -0
- package/src/__tests__/occlusion-query-ticket.integration.test.ts +47 -0
- package/src/__tests__/occlusion-query.dawn.test.ts +16 -0
- package/src/__tests__/occlusion-query.evidence.ts +178 -0
- package/src/__tests__/occlusion-query.rhi-null.test.ts +31 -0
- package/src/__tests__/occlusion-runtime.unit.test.ts +120 -0
- package/src/__tests__/pbr-view-layout.unit.test.ts +16 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +60 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
- package/src/__tests__/probe-bindings.unit.test.ts +200 -0
- package/src/__tests__/probe-blend-numeric.unit.test.ts +67 -0
- package/src/__tests__/probe-blend-oracle.unit.test.ts +136 -0
- package/src/__tests__/probe-capacity.integration.test.ts +97 -0
- package/src/__tests__/probe-recovery.integration.test.ts +104 -0
- package/src/__tests__/probe-scene-dirty.integration.test.ts +211 -0
- package/src/__tests__/profiler-phase-catalog.test.ts +4 -1
- package/src/__tests__/profiler-phase-token.test.ts +1 -0
- package/src/__tests__/public-surface.test-d.ts +10 -0
- package/src/__tests__/rect-area-boundary.unit.test.ts +24 -0
- package/src/__tests__/reflection-fallback-graph.unit.test.ts +67 -0
- package/src/__tests__/reflection-fallback-inspection.unit.test.ts +77 -0
- package/src/__tests__/reflection-fallback-lifecycle.integration.test.ts +21 -0
- package/src/__tests__/reflection-fallback-projection.unit.test.ts +90 -0
- package/src/__tests__/reflection-fallback-source.unit.test.ts +32 -0
- package/src/__tests__/reflection-probe-authoring.unit.test.ts +71 -0
- package/src/__tests__/reflection-probe-filter.unit.test.ts +54 -0
- package/src/__tests__/reflection-probe-ibl-topology.unit.test.ts +45 -0
- package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
- package/src/__tests__/reflection-probe-pass-encode.integration.test.ts +101 -0
- package/src/__tests__/reflection-probe-performance.perf.test.ts +60 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
- package/src/__tests__/reflection-probe-recovery.integration.test.ts +55 -0
- package/src/__tests__/reflection-probe-selection.unit.test.ts +46 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +19 -3
- package/src/__tests__/render-feature-docs.unit.test.ts +12 -7
- package/src/__tests__/render-graph-fallback.integration.test.ts +24 -0
- package/src/__tests__/render-perf/extended-lighting.bench.test.ts +66 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +447 -18
- package/src/__tests__/render-target-admission.unit.test.ts +80 -0
- package/src/__tests__/render-target-graph-projection.unit.test.ts +102 -0
- package/src/__tests__/render-target-inspection.unit.test.ts +52 -0
- package/src/__tests__/render-target-material-source.test-d.ts +30 -0
- package/src/__tests__/render-target-material-source.unit.test.ts +97 -0
- package/src/__tests__/render-target-owner-placement.unit.test.ts +203 -0
- package/src/__tests__/render-target-owner.unit.test.ts +122 -0
- package/src/__tests__/render-target-probe-soak.perf.test.ts +94 -0
- package/src/__tests__/render-target-public-schema.json +107 -0
- package/src/__tests__/render-target-public-schema.unit.test.ts +91 -0
- package/src/__tests__/render-target-public-surface.test-d.ts +83 -0
- package/src/__tests__/render-target-readback.integration.test.ts +90 -0
- package/src/__tests__/render-target-recovery.integration.test.ts +85 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +124 -0
- package/src/__tests__/renderer-lifecycle.integration.test.ts +14 -0
- package/src/__tests__/shader-stage-surface.unit.test.ts +19 -4
- package/src/__tests__/skin-motion-regression.unit.test.ts +154 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +13 -4
- package/src/__tests__/spot-modifier-projection.unit.test.ts +70 -0
- package/src/__tests__/ssr-admission-matrix.integration.test.ts +206 -0
- package/src/__tests__/ssr-composition.unit.test.ts +46 -0
- package/src/__tests__/ssr-fallback-zero-work.bench.test.ts +94 -0
- package/src/__tests__/ssr-recovery-errors.unit.test.ts +58 -0
- package/src/__tests__/standard-cluster-capability.integration.test.ts +63 -0
- package/src/__tests__/standard-cluster-transport.unit.test.ts +121 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +299 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +15 -5
- package/src/__tests__/standard-lighting-inspection.integration.test.ts +138 -0
- package/src/__tests__/standard-lighting-ssot.unit.test.ts +18 -0
- package/src/__tests__/standard-lighting-write.unit.test.ts +441 -0
- package/src/__tests__/standard-lighting.integration.test.ts +67 -0
- package/src/__tests__/standard-pipeline.dawn.test.ts +206 -5
- package/src/__tests__/standard-pipeline.integration.test.ts +181 -150
- package/src/__tests__/standard-probe-binding.unit.test.ts +25 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +23 -38
- package/src/__tests__/temporal-fallback-generation.integration.test.ts +16 -0
- package/src/__tests__/temporal-view.unit.test.ts +3 -3
- package/src/__tests__/transmission-prewarm.unit.test.ts +69 -0
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +395 -14
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +2 -2
- package/src/__tests__/visibility-budget.integration.test.ts +140 -0
- package/src/__tests__/visibility-budget.unit.test.ts +70 -0
- package/src/__tests__/visibility-extract.integration.test.ts +11 -6
- package/src/__tests__/visibility-resolver.unit.test.ts +15 -0
- package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +6 -3
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +31 -28
- package/src/assembly/backend-contract.ts +13 -0
- package/src/assembly/device-feature-admission.ts +80 -0
- package/src/assembly/directional-shadow-inspection.ts +122 -0
- package/src/assembly/factory.ts +1411 -366
- package/src/assembly/host-contract.ts +35 -0
- package/src/assembly/render-target-host.ts +847 -0
- package/src/assets/asset-decoders.ts +1 -1
- package/src/assets/render-asset-port.ts +7 -1
- package/src/capture/cube-views.ts +69 -0
- package/src/capture/scheduler.ts +265 -0
- package/src/cluster-binner.ts +31 -0
- package/src/components/__tests__/lighting-authoring.unit.test.ts +39 -0
- package/src/components/__tests__/rect-area-light.unit.test.ts +33 -0
- package/src/components/__tests__/schema-contract.unit.test.ts +12 -0
- package/src/components/__tests__/schema-parity.unit.test.ts +9 -0
- package/src/components/camera.ts +4 -0
- package/src/components/cube-camera.ts +52 -0
- package/src/components/directional-light.ts +22 -2
- package/src/components/directional-shadow-filter.ts +57 -0
- package/src/components/index.ts +5 -0
- package/src/components/light-helpers.ts +133 -8
- package/src/components/light-probe.ts +13 -0
- package/src/components/rect-area-light.ts +15 -0
- package/src/components/reflection-probe.ts +49 -0
- package/src/components/scene-instance.ts +6 -0
- package/src/components/spot-light.ts +3 -0
- package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
- package/src/device/gpu-residency.ts +140 -9
- package/src/device/lifecycle-transaction.ts +12 -0
- package/src/environment/frame.ts +6 -24
- package/src/environment/lifecycle.ts +20 -1
- package/src/errors/gpu-driven.ts +92 -0
- package/src/errors/index.ts +1 -0
- package/src/errors/recover.ts +32 -0
- package/src/errors/render.ts +341 -143
- package/src/extract/camera.ts +3 -3
- package/src/extract/directional-shadow-projection.ts +61 -0
- package/src/extract/environment.ts +57 -0
- package/src/extract/gpu-driven.ts +108 -0
- package/src/extract/visibility.ts +2 -1
- package/src/features/fullscreen.ts +3 -0
- package/src/features/targets.ts +4 -1
- package/src/features/types.ts +10 -0
- package/src/fullscreen-post-process-pass.ts +43 -2
- package/src/gpu-driven/batch-topology.ts +207 -28
- package/src/gpu-driven/prepared-draw.ts +208 -0
- package/src/gpu-driven/production-raster.ts +953 -43
- package/src/gpu-driven/view-gpu.ts +411 -29
- package/src/gpu-scene-schema.ts +13 -0
- package/src/gpu-scene.ts +140 -64
- package/src/gpu-usage.ts +0 -1
- package/src/hdrp-buffers.ts +169 -63
- package/src/ibl/IblPipelineCache.ts +11 -0
- package/src/ibl/kernel-cache.ts +88 -0
- package/src/index.ts +222 -0
- package/src/inspection-types.ts +276 -1
- package/src/instances-derived-bounds.ts +171 -0
- package/src/internal.ts +38 -0
- package/src/light-buffer-layout.ts +155 -310
- package/src/materials.ts +16 -2
- package/src/mesh-material-bindings.ts +132 -0
- package/src/pbr-pipeline.ts +255 -60
- package/src/pipeline/standard-forward-lane.ts +93 -16
- package/src/pipeline/standard-lighting/errors.ts +6 -0
- package/src/pipeline/standard-lighting/graph.ts +158 -0
- package/src/pipeline/standard-lighting/inspection.ts +88 -0
- package/src/pipeline/standard-lighting/layout.ts +31 -0
- package/src/pipeline/standard-lighting/light-frame.ts +35 -0
- package/src/pipeline/standard-lighting/membership.ts +43 -0
- package/src/pipeline/standard-lighting/prepare.ts +37 -0
- package/src/pipeline/standard-lighting/topology.ts +120 -0
- package/src/pipeline/standard-lighting/transport.ts +78 -0
- package/src/pipeline/standard-pipeline.ts +124 -193
- package/src/pipeline/standard-post.ts +26 -7
- package/src/pipeline/standard-profile.ts +17 -47
- package/src/pipeline-builder.ts +5 -2
- package/src/pipeline-spec.ts +95 -21
- package/src/plugin.ts +4 -0
- package/src/point-shadow-inspection.ts +55 -0
- package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +56 -0
- package/src/prepare/extended-lighting/ltc-resources.ts +136 -0
- package/src/prepare/extended-lighting/resources.ts +389 -0
- package/src/prepare/extended-lighting/spot-modifiers.ts +194 -0
- package/src/prepare/extended-lighting/state.ts +92 -0
- package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
- package/src/record/__tests__/temporal-payload.unit.test.ts +64 -1
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +73 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +20 -1
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +40 -0
- package/src/record/frame-lighting.ts +591 -452
- package/src/record/frame-snapshot.ts +92 -39
- package/src/record/frame-targets.ts +17 -0
- package/src/record/frame.ts +662 -158
- package/src/record/gpu-pass-timing/contract.ts +180 -0
- package/src/record/gpu-pass-timing/errors.ts +34 -0
- package/src/record/gpu-pass-timing/index.ts +37 -0
- package/src/record/gpu-pass-timing/parser.ts +97 -0
- package/src/record/gpu-pass-timing/session.ts +938 -0
- package/src/record/gpu-timing.ts +112 -39
- package/src/record/helpers.ts +0 -58
- package/src/record/main-pass-geometry.ts +324 -119
- package/src/record/main-pass-material.ts +103 -10
- package/src/record/main-pass-sprite-draws.ts +99 -103
- package/src/record/main-pass.ts +71 -15
- package/src/record/mesh-ssbo.ts +47 -36
- package/src/record/render-context.ts +136 -3
- package/src/record/shadow-pass.ts +83 -68
- package/src/record/skybox-post-pass.ts +20 -4
- package/src/record/typed-frame-graph.ts +1034 -43
- package/src/record/view-ubo.ts +72 -47
- package/src/reflection/filter.ts +81 -0
- package/src/reflection/gpu-table.ts +44 -0
- package/src/reflection/inspection.ts +67 -0
- package/src/reflection/projection.ts +476 -0
- package/src/reflection/record-owner.ts +1283 -0
- package/src/render-contract.ts +93 -10
- package/src/render-graph-primitives.ts +9 -4
- package/src/render-pipeline.ts +122 -2
- package/src/render-system-extract.ts +1041 -225
- package/src/render-system.ts +1310 -85
- package/src/renderer.ts +222 -0
- package/src/scene/__tests__/changed-block-summary.candidate.test.ts +36 -0
- package/src/scene/probe-blend-record.ts +54 -0
- package/src/scene/probe-blend.ts +813 -0
- package/src/scene/render-scene-types.ts +0 -7
- package/src/scene/render-scene.ts +942 -171
- package/src/scene/visibility/bounds.ts +57 -0
- package/src/scene/visibility/budget.ts +40 -0
- package/src/scene/visibility/facet.ts +400 -0
- package/src/scene/visibility/gpu-frame-timing.ts +101 -0
- package/src/scene/visibility/gpu-lod.ts +119 -0
- package/src/scene/visibility/inspection.ts +313 -0
- package/src/scene/visibility/lod-selector.ts +84 -0
- package/src/scene/visibility/occlusion-confidence.ts +478 -0
- package/src/scene/visibility/occlusion-pass.ts +165 -0
- package/src/scene/visibility/occlusion-query-pool.ts +178 -0
- package/src/scene/visibility/occlusion-runtime.ts +672 -0
- package/src/scene/visibility/types.ts +50 -0
- package/src/shadow-atlas.ts +5 -5
- package/src/ssao-buffers.ts +9 -2
- package/src/ssr/admission.ts +451 -0
- package/src/ssr/composition.ts +73 -0
- package/src/ssr/errors.ts +76 -0
- package/src/ssr/identity.ts +12 -0
- package/src/systems/skin-palette-allocator.ts +1 -1
- package/src/targets/contracts.ts +182 -0
- package/src/targets/graph-projection.ts +169 -0
- package/src/targets/material-source.ts +143 -0
- package/src/targets/owner.ts +214 -0
- package/src/targets/physical.ts +18 -0
- package/src/targets/readback.ts +153 -0
- package/src/temporal/frame-coordinator.ts +26 -0
- package/src/temporal/frame.ts +14 -1
- package/src/temporal/view.ts +11 -0
- package/src/tilemap-chunk-extract-system.ts +4 -4
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +59 -20
- package/src/typed-render-graph-primitives.ts +53 -3
- package/src/typed-shadow-passes.ts +46 -40
- package/src/volume/passes.ts +61 -58
- package/dist/.tsbuildinfo +0 -1
- package/dist/chunk-4XINDLAY.mjs.map +0 -1
- package/dist/chunk-CDTWTHZR.mjs.map +0 -1
- package/dist/chunk-M2MP4ZOU.mjs +0 -73
- package/dist/chunk-M2MP4ZOU.mjs.map +0 -1
- package/dist/chunk-PCHBPYML.mjs.map +0 -1
- package/dist/chunk-TBQJOK2L.mjs.map +0 -1
- package/dist/chunk-VFPLTKCU.mjs.map +0 -1
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
DirectionalLight,
|
|
15
15
|
MeshFilter,
|
|
16
16
|
MeshRenderer,
|
|
17
|
+
PointLight,
|
|
17
18
|
TONEMAP_LINEAR,
|
|
18
19
|
} from '../../components';
|
|
19
20
|
import { constructRendererHost, type RhiBackendPack } from '../../construct-renderer';
|
|
@@ -57,8 +58,10 @@ interface TransmissionCase {
|
|
|
57
58
|
readonly thicknessTexture?: number;
|
|
58
59
|
readonly masked?: boolean;
|
|
59
60
|
readonly overlap?: boolean;
|
|
60
|
-
readonly
|
|
61
|
+
readonly renderPath?: 'forward' | 'deferred';
|
|
61
62
|
readonly surfaceQuat?: readonly [number, number, number, number];
|
|
63
|
+
readonly directionalLight?: boolean;
|
|
64
|
+
readonly localLight?: boolean;
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
function textureAsset(value: number): TextureAsset {
|
|
@@ -106,6 +109,7 @@ async function renderCase(testCase: TransmissionCase): Promise<{
|
|
|
106
109
|
readonly pixel: readonly [number, number, number, number];
|
|
107
110
|
readonly passNames: readonly string[];
|
|
108
111
|
readonly observation: boolean;
|
|
112
|
+
readonly errors: readonly string[];
|
|
109
113
|
}> {
|
|
110
114
|
let device: GPUDevice | undefined;
|
|
111
115
|
let configuredDevice: GPUDevice | undefined;
|
|
@@ -157,7 +161,7 @@ async function renderCase(testCase: TransmissionCase): Promise<{
|
|
|
157
161
|
{
|
|
158
162
|
standardProfile: {
|
|
159
163
|
...DEFAULT_STANDARD_PROFILE,
|
|
160
|
-
|
|
164
|
+
renderPath: testCase.renderPath ?? DEFAULT_STANDARD_PROFILE.renderPath,
|
|
161
165
|
},
|
|
162
166
|
},
|
|
163
167
|
{ shaderManifestUrl: ENGINE_MANIFEST_URL },
|
|
@@ -172,6 +176,10 @@ async function renderCase(testCase: TransmissionCase): Promise<{
|
|
|
172
176
|
}
|
|
173
177
|
|
|
174
178
|
const { renderer } = host.value;
|
|
179
|
+
const errors: string[] = [];
|
|
180
|
+
const unsubscribe = renderer.subscribe((event) => {
|
|
181
|
+
if (event.kind === 'error') errors.push(event.error.code);
|
|
182
|
+
});
|
|
175
183
|
const world = new World();
|
|
176
184
|
const lease = renderer.attach(world);
|
|
177
185
|
if (!lease.ok) throw lease.error;
|
|
@@ -277,12 +285,22 @@ async function renderCase(testCase: TransmissionCase): Promise<{
|
|
|
277
285
|
);
|
|
278
286
|
expect(cameraEntity.ok, `${testCase.name}: camera spawn must succeed`).toBe(true);
|
|
279
287
|
if (!cameraEntity.ok) throw cameraEntity.error;
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
288
|
+
if (testCase.directionalLight !== false) {
|
|
289
|
+
const lightEntity = world.spawn({
|
|
290
|
+
component: DirectionalLight,
|
|
291
|
+
data: { direction: [0, 0, -1], color: [1, 1, 1], intensity: 1, castShadow: false },
|
|
292
|
+
});
|
|
293
|
+
expect(lightEntity.ok, `${testCase.name}: light spawn must succeed`).toBe(true);
|
|
294
|
+
if (!lightEntity.ok) throw lightEntity.error;
|
|
295
|
+
}
|
|
296
|
+
if (testCase.localLight === true) {
|
|
297
|
+
const localLightEntity = world.spawn(
|
|
298
|
+
{ component: Transform, data: { pos: [0, 0, 1] } },
|
|
299
|
+
{ component: PointLight, data: { intensity: 8, range: 10 } },
|
|
300
|
+
);
|
|
301
|
+
expect(localLightEntity.ok, `${testCase.name}: local light spawn must succeed`).toBe(true);
|
|
302
|
+
if (!localLightEntity.ok) throw localLightEntity.error;
|
|
303
|
+
}
|
|
286
304
|
world.update().unwrap();
|
|
287
305
|
const drawn = renderer.draw({
|
|
288
306
|
leases: [lease.value],
|
|
@@ -299,10 +317,12 @@ async function renderCase(testCase: TransmissionCase): Promise<{
|
|
|
299
317
|
const renderDevice = configuredDevice ?? device;
|
|
300
318
|
const passNames = renderer.inspect().perFramePassNames;
|
|
301
319
|
expect(renderer.inspect().renderScene.projectionRecords).toBeGreaterThanOrEqual(1);
|
|
320
|
+
unsubscribe();
|
|
302
321
|
return {
|
|
303
322
|
pixel: await readCenter(renderDevice, target),
|
|
304
323
|
passNames,
|
|
305
324
|
observation: observation.ok,
|
|
325
|
+
errors,
|
|
306
326
|
};
|
|
307
327
|
}
|
|
308
328
|
|
|
@@ -403,9 +423,9 @@ describe('Standard transmission Dawn ROI', () => {
|
|
|
403
423
|
);
|
|
404
424
|
}, 120_000);
|
|
405
425
|
|
|
406
|
-
it('exercises
|
|
407
|
-
const
|
|
408
|
-
name: '
|
|
426
|
+
it('exercises both Standard render paths and transmission-before-BLEND overlap order', async () => {
|
|
427
|
+
const forward = await renderCase({
|
|
428
|
+
name: 'forward',
|
|
409
429
|
transmission: 1,
|
|
410
430
|
ior: 1.5,
|
|
411
431
|
thickness: 0.5,
|
|
@@ -413,10 +433,10 @@ describe('Standard transmission Dawn ROI', () => {
|
|
|
413
433
|
attenuationColor: [0.7, 0.8, 0.9],
|
|
414
434
|
attenuationDistance: 2,
|
|
415
435
|
overlap: true,
|
|
416
|
-
|
|
436
|
+
renderPath: 'forward',
|
|
417
437
|
});
|
|
418
|
-
const
|
|
419
|
-
name: '
|
|
438
|
+
const deferred = await renderCase({
|
|
439
|
+
name: 'deferred',
|
|
420
440
|
transmission: 1,
|
|
421
441
|
ior: 1.5,
|
|
422
442
|
thickness: 0.5,
|
|
@@ -424,14 +444,33 @@ describe('Standard transmission Dawn ROI', () => {
|
|
|
424
444
|
attenuationColor: [0.7, 0.8, 0.9],
|
|
425
445
|
attenuationDistance: 2,
|
|
426
446
|
overlap: true,
|
|
427
|
-
|
|
447
|
+
renderPath: 'deferred',
|
|
428
448
|
});
|
|
429
|
-
const transmissionIndex =
|
|
430
|
-
const transparentIndex =
|
|
449
|
+
const transmissionIndex = forward.passNames.indexOf('transmission-forward');
|
|
450
|
+
const transparentIndex = forward.passNames.indexOf('transparent');
|
|
431
451
|
expect(transmissionIndex).toBeGreaterThanOrEqual(0);
|
|
432
452
|
expect(transparentIndex).toBeGreaterThan(transmissionIndex);
|
|
433
|
-
expect(
|
|
434
|
-
expect(
|
|
435
|
-
|
|
453
|
+
expect(deferred.pixel.every(Number.isFinite)).toBe(true);
|
|
454
|
+
expect(forward.pixel.every(Number.isFinite)).toBe(true);
|
|
455
|
+
}, 120_000);
|
|
456
|
+
|
|
457
|
+
it('submits a real clustered local-light frame through the Standard front door', async () => {
|
|
458
|
+
const clustered = await renderCase({
|
|
459
|
+
name: 'clustered-local-light',
|
|
460
|
+
transmission: 0,
|
|
461
|
+
ior: 1.5,
|
|
462
|
+
thickness: 0,
|
|
463
|
+
roughness: 0.4,
|
|
464
|
+
attenuationColor: [1, 1, 1],
|
|
465
|
+
directionalLight: false,
|
|
466
|
+
localLight: true,
|
|
467
|
+
renderPath: 'forward',
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
expect(clustered.passNames).toEqual(
|
|
471
|
+
expect.arrayContaining(['cluster-membership-producer', 'main', 'output-transform']),
|
|
472
|
+
);
|
|
473
|
+
expect(clustered.observation).toBe(true);
|
|
474
|
+
expect(clustered.errors).toEqual([]);
|
|
436
475
|
}, 120_000);
|
|
437
476
|
});
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
} from './render-graph-primitives';
|
|
35
35
|
import type { RenderPipelineFrame, RenderPipelineGpuDrivenProjection } from './render-pipeline';
|
|
36
36
|
import { createRenderPipelineTarget, type RenderPipelineTarget } from './render-pipeline';
|
|
37
|
+
import type { OcclusionFrameProjection } from './scene/visibility/occlusion-runtime';
|
|
37
38
|
import {
|
|
38
39
|
getTemporalBindGroupResources,
|
|
39
40
|
getTemporalGpuState,
|
|
@@ -136,6 +137,7 @@ export interface TypedScenePassOptions {
|
|
|
136
137
|
readonly transmissionBackdrop?: GraphTextureView | undefined;
|
|
137
138
|
readonly extraAccesses?: readonly GraphAccess[] | undefined;
|
|
138
139
|
readonly gpuDriven?: RenderPipelineGpuDrivenProjection | undefined;
|
|
140
|
+
readonly occlusion?: OcclusionFrameProjection | undefined;
|
|
139
141
|
}
|
|
140
142
|
|
|
141
143
|
export function addTypedScenePass(
|
|
@@ -187,6 +189,7 @@ export function addTypedScenePass(
|
|
|
187
189
|
stencilLoadOp: options.depthLoadOp ?? 'clear',
|
|
188
190
|
stencilStoreOp: 'store',
|
|
189
191
|
},
|
|
192
|
+
occlusionQuerySet: options.occlusion?.querySet,
|
|
190
193
|
encode: ({ pass, frame, resources }) => {
|
|
191
194
|
const colorViews = colorTargets.map((target) => resolvedView(resources, target.view));
|
|
192
195
|
const depthView = resolvedView(resources, options.depth.view);
|
|
@@ -222,17 +225,29 @@ export function addTypedScenePass(
|
|
|
222
225
|
projectorSampler:
|
|
223
226
|
internal.spotLightProjector?.sampler ?? internal.volumetricFog?.projectorSampler,
|
|
224
227
|
},
|
|
228
|
+
true,
|
|
229
|
+
internal.standardLighting,
|
|
225
230
|
);
|
|
226
231
|
if (groups.viewBindGroup !== null) {
|
|
227
232
|
options.gpuDriven?.encode(groups.viewBindGroup, pass, resources);
|
|
228
233
|
}
|
|
234
|
+
// The context carries the frame's primary occlusion projection for
|
|
235
|
+
// pipeline construction, but only the pass that owns that projection
|
|
236
|
+
// may begin its query. Forwarding it to deferred/temporal scene passes
|
|
237
|
+
// leaves their descriptors without an occlusionQuerySet and makes Dawn
|
|
238
|
+
// reject beginOcclusionQuery in those passes.
|
|
239
|
+
const activeOcclusion = options.occlusion;
|
|
229
240
|
encodeMainPass(
|
|
230
241
|
{
|
|
231
242
|
...internal,
|
|
243
|
+
...(activeOcclusion === undefined ? {} : { occlusion: activeOcclusion }),
|
|
232
244
|
geometryColorView: colorViews[0] ?? null,
|
|
233
245
|
geometryDepthView: depthView,
|
|
234
246
|
geometryColorResolveView: resolveView,
|
|
235
247
|
transparentColorFormat: colorTargets[0]?.format as GPUTextureFormat,
|
|
248
|
+
...(colorTargets[1]?.format === 'rgba16float'
|
|
249
|
+
? { reflectionFallbackColorFormat: 'rgba16float' as const }
|
|
250
|
+
: {}),
|
|
236
251
|
msaaActive: colorTargets[0]?.sampleCount === 4,
|
|
237
252
|
viewBindGroup: groups.viewBindGroup,
|
|
238
253
|
meshBindGroup: groups.meshBindGroup,
|
|
@@ -254,6 +269,10 @@ export function addTypedScenePass(
|
|
|
254
269
|
: { transmissionBackdropView: transmissionBackdrop }),
|
|
255
270
|
},
|
|
256
271
|
);
|
|
272
|
+
if (activeOcclusion !== undefined) {
|
|
273
|
+
const proxyResult = activeOcclusion.encodeProxyBounds(pass);
|
|
274
|
+
if (!proxyResult.ok) throw proxyResult.error;
|
|
275
|
+
}
|
|
257
276
|
},
|
|
258
277
|
});
|
|
259
278
|
}
|
|
@@ -289,6 +308,37 @@ export function addTypedFrameObservationPass(
|
|
|
289
308
|
});
|
|
290
309
|
}
|
|
291
310
|
|
|
311
|
+
/** Publish the same-frame fallback MRT as a detached, copy-readable source. */
|
|
312
|
+
export function addReflectionFallbackObservationPass(
|
|
313
|
+
graph: RenderGraphBuilder<RenderPipelineFrame>,
|
|
314
|
+
target: RenderPipelineTarget,
|
|
315
|
+
): Result<void, RenderGraphError> {
|
|
316
|
+
return graph.addCopyPass('reflection-fallback-observation', {
|
|
317
|
+
accesses: [{ resource: target.view, usage: 'copy-src' }],
|
|
318
|
+
encode: ({ frame, resources }) => {
|
|
319
|
+
const internal = frame as _InternalRenderPipelineContext;
|
|
320
|
+
const texture = resources.texture(target.texture);
|
|
321
|
+
if (!texture.ok) throw texture.error;
|
|
322
|
+
internal.frameState.reflectionFallbackObservationSource = {
|
|
323
|
+
texture: texture.value,
|
|
324
|
+
descriptor: {
|
|
325
|
+
texture: texture.value,
|
|
326
|
+
format: target.format,
|
|
327
|
+
size: { width: frame.targetW, height: frame.targetH },
|
|
328
|
+
usage:
|
|
329
|
+
GPU_TEXTURE_USAGE_COPY_SRC |
|
|
330
|
+
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |
|
|
331
|
+
GPU_TEXTURE_USAGE_TEXTURE_BINDING,
|
|
332
|
+
sample: target.sampleCount,
|
|
333
|
+
},
|
|
334
|
+
frameId: internal.frameState.frameNumber,
|
|
335
|
+
pipelineId: 'forgeax::standard',
|
|
336
|
+
backendId: internal.runtime.device.caps.backendKind,
|
|
337
|
+
};
|
|
338
|
+
},
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
|
|
292
342
|
export interface TypedBloomTargets {
|
|
293
343
|
readonly scene: RenderPipelineTarget;
|
|
294
344
|
readonly composited: RenderPipelineTarget;
|
|
@@ -696,7 +746,7 @@ export function addTypedOutputTransformPass(
|
|
|
696
746
|
graph: RenderGraphBuilder<RenderPipelineFrame>,
|
|
697
747
|
input: RenderPipelineTarget,
|
|
698
748
|
output: RenderPipelineTarget,
|
|
699
|
-
options: { readonly outputOnly?: boolean; readonly
|
|
749
|
+
options: { readonly outputOnly?: boolean; readonly dither?: boolean } = {},
|
|
700
750
|
): Result<void, RenderGraphError> {
|
|
701
751
|
const outputOnly = options.outputOnly ?? false;
|
|
702
752
|
return addTypedFullscreenPass(graph, {
|
|
@@ -706,7 +756,7 @@ export function addTypedOutputTransformPass(
|
|
|
706
756
|
output,
|
|
707
757
|
outputOnly,
|
|
708
758
|
rawSwapchainOutput: outputOnly,
|
|
709
|
-
...(options.
|
|
759
|
+
...(options.dither !== undefined
|
|
710
760
|
? {
|
|
711
761
|
paramsTransform: (params: Uint8Array | undefined): Uint8Array | undefined => {
|
|
712
762
|
if (params === undefined || params.byteLength !== 16) return params;
|
|
@@ -715,7 +765,7 @@ export function addTypedOutputTransformPass(
|
|
|
715
765
|
transformed.buffer,
|
|
716
766
|
transformed.byteOffset,
|
|
717
767
|
transformed.byteLength,
|
|
718
|
-
).setFloat32(12, 1, true);
|
|
768
|
+
).setFloat32(12, options.dither === true ? 1 : 0, true);
|
|
719
769
|
return transformed;
|
|
720
770
|
},
|
|
721
771
|
}
|
|
@@ -13,7 +13,7 @@ import { createRenderPipelineTarget, type RenderPipelineTarget } from './render-
|
|
|
13
13
|
import { resolveDirectionalShadowAtlasGrid } from './typed-shadow-atlas';
|
|
14
14
|
|
|
15
15
|
export interface TypedShadowTargets {
|
|
16
|
-
readonly directional
|
|
16
|
+
readonly directional?: RenderPipelineTarget | undefined;
|
|
17
17
|
readonly spot: RenderPipelineTarget;
|
|
18
18
|
readonly point?: RenderPipelineTarget | undefined;
|
|
19
19
|
}
|
|
@@ -44,44 +44,50 @@ export function addTypedShadowPasses(
|
|
|
44
44
|
graph: RenderGraphBuilder<RenderPipelineFrame>,
|
|
45
45
|
topology: RenderPipelineTopology,
|
|
46
46
|
): Result<TypedShadowTargets, RenderGraphError> {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
47
|
+
let directional: RenderPipelineTarget | undefined;
|
|
48
|
+
if (topology.shadow.directional !== 'disabled') {
|
|
49
|
+
const { mapSize, cascadeCount } = topology.shadow.directional;
|
|
50
|
+
const atlasGrid = resolveDirectionalShadowAtlasGrid(cascadeCount);
|
|
51
|
+
const target = createRenderPipelineTarget(graph, 'directional-shadow-depth', {
|
|
52
|
+
format: 'depth32float',
|
|
53
|
+
size: {
|
|
54
|
+
width: mapSize * atlasGrid.columns,
|
|
55
|
+
height: mapSize * atlasGrid.rows,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
if (!target.ok) return target;
|
|
59
|
+
const directionalTarget = target.value;
|
|
60
|
+
directional = directionalTarget;
|
|
61
|
+
for (let cascade = 0; cascade < cascadeCount; cascade += 1) {
|
|
62
|
+
const col = cascade % atlasGrid.columns;
|
|
63
|
+
const row = Math.floor(cascade / atlasGrid.columns);
|
|
64
|
+
const added = recordShadowPass(
|
|
65
|
+
graph,
|
|
66
|
+
`shadowCascade${cascade}`,
|
|
67
|
+
directionalTarget,
|
|
68
|
+
cascade === 0 ? 'clear' : 'load',
|
|
69
|
+
({ pass, frame }) =>
|
|
70
|
+
encodeDirectionalShadowPass(frame as never, pass, cascade, {
|
|
71
|
+
x: col * mapSize,
|
|
72
|
+
y: row * mapSize,
|
|
73
|
+
w: mapSize,
|
|
74
|
+
h: mapSize,
|
|
75
|
+
}),
|
|
76
|
+
(frame) => !(frame as _InternalRenderPipelineContext).directionalShadowCacheReuse,
|
|
77
|
+
);
|
|
78
|
+
if (!added.ok) return added;
|
|
79
|
+
}
|
|
80
|
+
const observation = graph.addCopyPass('directional-shadow-observation', {
|
|
81
|
+
accesses: [{ resource: directionalTarget.view, usage: 'copy-src' }],
|
|
82
|
+
encode: ({ frame, resources }) => {
|
|
83
|
+
const internal = frame as _InternalRenderPipelineContext;
|
|
84
|
+
const texture = resources.texture(directionalTarget.texture);
|
|
85
|
+
if (!texture.ok) throw texture.error;
|
|
86
|
+
internal.pipelineState.perPassResources.shadowTexture = texture.value;
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
if (!observation.ok) return observation;
|
|
74
90
|
}
|
|
75
|
-
const observation = graph.addCopyPass('directional-shadow-observation', {
|
|
76
|
-
accesses: [{ resource: directional.value.view, usage: 'copy-src' }],
|
|
77
|
-
encode: ({ frame, resources }) => {
|
|
78
|
-
const internal = frame as _InternalRenderPipelineContext;
|
|
79
|
-
const texture = resources.texture(directional.value.texture);
|
|
80
|
-
if (!texture.ok) throw texture.error;
|
|
81
|
-
internal.pipelineState.perPassResources.shadowTexture = texture.value;
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
if (!observation.ok) return observation;
|
|
85
91
|
|
|
86
92
|
let point: RenderPipelineTarget | undefined;
|
|
87
93
|
if (topology.shadow.pointCount > 0) {
|
|
@@ -148,7 +154,7 @@ export function addTypedShadowPasses(
|
|
|
148
154
|
|
|
149
155
|
const spot = createRenderPipelineTarget(graph, 'spot-shadow-depth', {
|
|
150
156
|
format: 'depth32float',
|
|
151
|
-
size: { width: topology.shadow.
|
|
157
|
+
size: { width: topology.shadow.spotMapSize * 2, height: topology.shadow.spotMapSize * 2 },
|
|
152
158
|
});
|
|
153
159
|
if (!spot.ok) return spot;
|
|
154
160
|
for (let spotIndex = 0; spotIndex < Math.max(1, topology.shadow.spotCount); spotIndex += 1) {
|
|
@@ -162,5 +168,5 @@ export function addTypedShadowPasses(
|
|
|
162
168
|
if (!added.ok) return added;
|
|
163
169
|
}
|
|
164
170
|
|
|
165
|
-
return ok({ directional
|
|
171
|
+
return ok({ directional, spot: spot.value, point });
|
|
166
172
|
}
|
package/src/volume/passes.ts
CHANGED
|
@@ -2,8 +2,8 @@ import type {
|
|
|
2
2
|
GraphBuffer,
|
|
3
3
|
GraphTextureView,
|
|
4
4
|
RenderGraphBuilder,
|
|
5
|
-
RenderGraphError,
|
|
6
5
|
} from '@forgeax/engine-render-graph';
|
|
6
|
+
import { RenderGraphError } from '@forgeax/engine-render-graph';
|
|
7
7
|
import type {
|
|
8
8
|
BindGroup,
|
|
9
9
|
BindGroupLayout,
|
|
@@ -14,18 +14,10 @@ import type {
|
|
|
14
14
|
TextureView,
|
|
15
15
|
} from '@forgeax/engine-rhi';
|
|
16
16
|
import { RhiError } from '@forgeax/engine-rhi';
|
|
17
|
-
import { ok, type Result } from '@forgeax/engine-types';
|
|
17
|
+
import { err, ok, type Result } from '@forgeax/engine-types';
|
|
18
18
|
import { GPU_TEXTURE_USAGE_TEXTURE_BINDING } from '../gpu-texture-usage';
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
GPU_BUFFER_USAGE_STORAGE,
|
|
22
|
-
GPU_BUFFER_USAGE_UNIFORM,
|
|
23
|
-
} from '../gpu-usage';
|
|
24
|
-
import {
|
|
25
|
-
LIGHT_ARRAY_HEADER_BYTES,
|
|
26
|
-
LIGHT_ARRAY_MAX_SLOTS,
|
|
27
|
-
SPOT_LIGHT_STD430_BYTES,
|
|
28
|
-
} from '../light-buffer-layout';
|
|
19
|
+
import { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from '../gpu-usage';
|
|
20
|
+
import type { StandardClusterGraphBuffers } from '../pipeline/standard-lighting/graph';
|
|
29
21
|
import { VIEW_UNIFORM_BYTES } from '../record/view-ubo';
|
|
30
22
|
import type { VolumetricFogFrameContext, VolumetricFogShaderSources } from '../render-contract';
|
|
31
23
|
import type {
|
|
@@ -89,10 +81,12 @@ export interface VolumetricFogPassInputs {
|
|
|
89
81
|
readonly density: GraphTextureView;
|
|
90
82
|
readonly params: GraphBuffer;
|
|
91
83
|
readonly view: GraphBuffer;
|
|
92
|
-
readonly directionalShadow
|
|
84
|
+
readonly directionalShadow?: GraphTextureView;
|
|
93
85
|
readonly spotShadow: GraphTextureView;
|
|
94
|
-
|
|
95
|
-
readonly
|
|
86
|
+
/** The single Standard Cluster light payload consumed by all volume stages. */
|
|
87
|
+
readonly lightData: GraphBuffer;
|
|
88
|
+
/** The Cluster uniform carries the admitted light count for slot guards. */
|
|
89
|
+
readonly clusterUniform: GraphBuffer;
|
|
96
90
|
readonly selectedLightKind: 'directional' | 'point' | 'spot';
|
|
97
91
|
readonly projector?: GraphTextureView;
|
|
98
92
|
}
|
|
@@ -166,13 +160,29 @@ function importVolumeInputs(
|
|
|
166
160
|
topology: RenderPipelineTopology,
|
|
167
161
|
linearHdr: RenderPipelineTarget,
|
|
168
162
|
sceneDepth: GraphTextureView,
|
|
169
|
-
directionalShadow: GraphTextureView,
|
|
163
|
+
directionalShadow: GraphTextureView | undefined,
|
|
170
164
|
spotShadow: GraphTextureView,
|
|
171
165
|
selectedLightKind: 'directional' | 'point' | 'spot' | undefined,
|
|
166
|
+
clusterBuffers: StandardClusterGraphBuffers | null,
|
|
172
167
|
): Result<ImportedVolumeInputs | undefined, RenderGraphError> {
|
|
173
168
|
const volume = topology.volumetricFog;
|
|
174
169
|
if (volume?.enabled !== true || volume.format === undefined || volume.extent === undefined)
|
|
175
170
|
return ok(undefined);
|
|
171
|
+
if (clusterBuffers === null) {
|
|
172
|
+
return err(
|
|
173
|
+
new RenderGraphError({
|
|
174
|
+
code: 'resource-descriptor-invalid',
|
|
175
|
+
expected: 'volumetric fog consumes the Standard Cluster light buffers',
|
|
176
|
+
hint: 'enable the storage-backed Standard Cluster transport before enabling volumetric fog',
|
|
177
|
+
detail: {
|
|
178
|
+
resourceLabel: 'volumetric-fog',
|
|
179
|
+
field: 'clusterBuffers',
|
|
180
|
+
expected: 'StandardClusterGraphBuffers',
|
|
181
|
+
actual: 'missing',
|
|
182
|
+
},
|
|
183
|
+
}),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
176
186
|
const texture = graph.importTexture(
|
|
177
187
|
'volume-density',
|
|
178
188
|
{
|
|
@@ -218,21 +228,6 @@ function importVolumeInputs(
|
|
|
218
228
|
(frame) => frame.pipelineState.viewUniformBuffer,
|
|
219
229
|
);
|
|
220
230
|
if (!view.ok) return view;
|
|
221
|
-
const spotLights = graph.importBuffer(
|
|
222
|
-
'volume-spot-lights',
|
|
223
|
-
{
|
|
224
|
-
size: LIGHT_ARRAY_HEADER_BYTES + LIGHT_ARRAY_MAX_SLOTS * SPOT_LIGHT_STD430_BYTES,
|
|
225
|
-
usage: GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST,
|
|
226
|
-
},
|
|
227
|
-
(frame) => frame.pipelineState.spotLightsBuffer,
|
|
228
|
-
);
|
|
229
|
-
if (!spotLights.ok) return spotLights;
|
|
230
|
-
const pointLights = graph.importBuffer(
|
|
231
|
-
'volume-point-lights',
|
|
232
|
-
{ size: 16 + 4 * 32, usage: GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST },
|
|
233
|
-
(frame) => frame.pipelineState.pointLightsBuffer,
|
|
234
|
-
);
|
|
235
|
-
if (!pointLights.ok) return pointLights;
|
|
236
231
|
let projector: GraphTextureView | undefined;
|
|
237
232
|
if (volume.projector !== undefined) {
|
|
238
233
|
const projectorTexture = graph.importTexture(
|
|
@@ -268,10 +263,10 @@ function importVolumeInputs(
|
|
|
268
263
|
density: density.value,
|
|
269
264
|
params: params.value,
|
|
270
265
|
view: view.value,
|
|
271
|
-
directionalShadow,
|
|
266
|
+
...(directionalShadow === undefined ? {} : { directionalShadow }),
|
|
272
267
|
spotShadow,
|
|
273
|
-
|
|
274
|
-
|
|
268
|
+
lightData: clusterBuffers.lightData,
|
|
269
|
+
clusterUniform: clusterBuffers.clusterUniform,
|
|
275
270
|
selectedLightKind: selectedLightKind ?? 'directional',
|
|
276
271
|
...(projector === undefined ? {} : { projector }),
|
|
277
272
|
});
|
|
@@ -281,8 +276,9 @@ export function addAuthoredVolumetricFogPasses(
|
|
|
281
276
|
topology: RenderPipelineTopology,
|
|
282
277
|
linearHdr: RenderPipelineTarget,
|
|
283
278
|
sceneDepth: GraphTextureView,
|
|
284
|
-
directionalShadow: GraphTextureView,
|
|
279
|
+
directionalShadow: GraphTextureView | undefined,
|
|
285
280
|
spotShadow: GraphTextureView,
|
|
281
|
+
clusterBuffers: StandardClusterGraphBuffers | null,
|
|
286
282
|
): Result<void, RenderGraphError> {
|
|
287
283
|
// A paired Point+Spot volume stores the Spot shadow lane as well. The
|
|
288
284
|
// topology's primary light remains PointLight for radiance selection, but
|
|
@@ -300,6 +296,7 @@ export function addAuthoredVolumetricFogPasses(
|
|
|
300
296
|
directionalShadow,
|
|
301
297
|
spotShadow,
|
|
302
298
|
shadowLightKind,
|
|
299
|
+
clusterBuffers,
|
|
303
300
|
);
|
|
304
301
|
if (!imported.ok) return imported;
|
|
305
302
|
if (imported.value === undefined) return ok(undefined);
|
|
@@ -320,6 +317,15 @@ export function addVolumetricFogPasses(
|
|
|
320
317
|
const packedLayers = Math.ceil(inputs.resources.extent.depth / VOLUME_PACKING_Z);
|
|
321
318
|
const resolvedDispatchX = Math.ceil(inputs.resources.resolvedExtent.width / 8);
|
|
322
319
|
const resolvedDispatchY = Math.ceil(inputs.resources.resolvedExtent.height / 8);
|
|
320
|
+
// Point-light volume injection has no cube-array shadow sampler. It keeps
|
|
321
|
+
// the directional cascade count at zero and therefore needs only a valid
|
|
322
|
+
// 2D depth binding; use the always-present spot target as the inert binding
|
|
323
|
+
// when directional shadows are disabled. Directional selection still uses
|
|
324
|
+
// its own target whenever one exists, and spot selection uses spotShadow.
|
|
325
|
+
const shadowResource =
|
|
326
|
+
inputs.selectedLightKind === 'spot'
|
|
327
|
+
? inputs.spotShadow
|
|
328
|
+
: (inputs.directionalShadow ?? inputs.spotShadow);
|
|
323
329
|
let inject: ComputeState | undefined;
|
|
324
330
|
let integrate: ComputeState | undefined;
|
|
325
331
|
let temporal: ComputeState | undefined;
|
|
@@ -330,12 +336,11 @@ export function addVolumetricFogPasses(
|
|
|
330
336
|
{ resource: inputs.params, usage: 'uniform-read' },
|
|
331
337
|
{ resource: inputs.view, usage: 'uniform-read' },
|
|
332
338
|
{
|
|
333
|
-
resource:
|
|
334
|
-
inputs.selectedLightKind === 'spot' ? inputs.spotShadow : inputs.directionalShadow,
|
|
339
|
+
resource: shadowResource,
|
|
335
340
|
usage: 'sampled-read',
|
|
336
341
|
},
|
|
337
|
-
{ resource: inputs.
|
|
338
|
-
{ resource: inputs.
|
|
342
|
+
{ resource: inputs.lightData, usage: 'storage-read' },
|
|
343
|
+
{ resource: inputs.clusterUniform, usage: 'uniform-read' },
|
|
339
344
|
...(inputs.projector === undefined
|
|
340
345
|
? []
|
|
341
346
|
: [{ resource: inputs.projector, usage: 'sampled-read' as const }]),
|
|
@@ -357,21 +362,19 @@ export function addVolumetricFogPasses(
|
|
|
357
362
|
},
|
|
358
363
|
},
|
|
359
364
|
{ binding: 7, visibility: 4, buffer: { type: 'read-only-storage' } },
|
|
360
|
-
{ binding: 8, visibility: 4, buffer: { type: '
|
|
365
|
+
{ binding: 8, visibility: 4, buffer: { type: 'uniform' } },
|
|
361
366
|
]);
|
|
362
|
-
const shadow = resources.textureView(
|
|
363
|
-
inputs.selectedLightKind === 'spot' ? inputs.spotShadow : inputs.directionalShadow,
|
|
364
|
-
);
|
|
367
|
+
const shadow = resources.textureView(shadowResource);
|
|
365
368
|
const params = resources.buffer(inputs.params);
|
|
366
369
|
const view = resources.buffer(inputs.view);
|
|
367
|
-
const
|
|
368
|
-
const
|
|
370
|
+
const lightData = resources.buffer(inputs.lightData);
|
|
371
|
+
const clusterUniform = resources.buffer(inputs.clusterUniform);
|
|
369
372
|
const froxel = resources.textureView(inputs.resources.froxelView);
|
|
370
373
|
if (!shadow.ok) throw shadow.error;
|
|
371
374
|
if (!params.ok) throw params.error;
|
|
372
375
|
if (!view.ok) throw view.error;
|
|
373
|
-
if (!
|
|
374
|
-
if (!
|
|
376
|
+
if (!lightData.ok) throw lightData.error;
|
|
377
|
+
if (!clusterUniform.ok) throw clusterUniform.error;
|
|
375
378
|
if (!froxel.ok) throw froxel.error;
|
|
376
379
|
const shadowSampler = frame.runtime.device.createSampler({ compare: 'less' });
|
|
377
380
|
if (!shadowSampler.ok) throw shadowSampler.error;
|
|
@@ -381,8 +384,8 @@ export function addVolumetricFogPasses(
|
|
|
381
384
|
{ binding: 4, resource: { kind: 'sampler', value: shadowSampler.value } },
|
|
382
385
|
{ binding: 5, resource: { kind: 'buffer', value: { buffer: params.value } } },
|
|
383
386
|
{ binding: 6, resource: { kind: 'textureView', value: froxel.value as never } },
|
|
384
|
-
{ binding: 7, resource: { kind: 'buffer', value: { buffer:
|
|
385
|
-
{ binding: 8, resource: { kind: 'buffer', value: { buffer:
|
|
387
|
+
{ binding: 7, resource: { kind: 'buffer', value: { buffer: lightData.value } } },
|
|
388
|
+
{ binding: 8, resource: { kind: 'buffer', value: { buffer: clusterUniform.value } } },
|
|
386
389
|
]);
|
|
387
390
|
pass.setPipeline(inject.pipeline);
|
|
388
391
|
pass.setBindGroup(0, bindings);
|
|
@@ -400,8 +403,8 @@ export function addVolumetricFogPasses(
|
|
|
400
403
|
{ resource: inputs.resources.temporalView, usage: 'storage-write' },
|
|
401
404
|
{ resource: inputs.params, usage: 'uniform-read' },
|
|
402
405
|
{ resource: inputs.view, usage: 'uniform-read' },
|
|
403
|
-
{ resource: inputs.
|
|
404
|
-
{ resource: inputs.
|
|
406
|
+
{ resource: inputs.lightData, usage: 'storage-read' },
|
|
407
|
+
{ resource: inputs.clusterUniform, usage: 'uniform-read' },
|
|
405
408
|
...(inputs.projector === undefined
|
|
406
409
|
? []
|
|
407
410
|
: [{ resource: inputs.projector, usage: 'sampled-read' as const }]),
|
|
@@ -443,7 +446,7 @@ export function addVolumetricFogPasses(
|
|
|
443
446
|
},
|
|
444
447
|
},
|
|
445
448
|
{ binding: 10, visibility: 4, buffer: { type: 'read-only-storage' } },
|
|
446
|
-
{ binding: 11, visibility: 4, buffer: { type: '
|
|
449
|
+
{ binding: 11, visibility: 4, buffer: { type: 'uniform' } },
|
|
447
450
|
{ binding: 12, visibility: 4, texture: { sampleType: 'float', viewDimension: '2d' } },
|
|
448
451
|
{ binding: 13, visibility: 4, sampler: { type: 'filtering' } },
|
|
449
452
|
]);
|
|
@@ -455,8 +458,8 @@ export function addVolumetricFogPasses(
|
|
|
455
458
|
const temporalSeed = resources.textureView(inputs.resources.temporalView);
|
|
456
459
|
const params = resources.buffer(inputs.params);
|
|
457
460
|
const view = resources.buffer(inputs.view);
|
|
458
|
-
const
|
|
459
|
-
const
|
|
461
|
+
const lightData = resources.buffer(inputs.lightData);
|
|
462
|
+
const clusterUniform = resources.buffer(inputs.clusterUniform);
|
|
460
463
|
const projector =
|
|
461
464
|
inputs.projector === undefined ? undefined : resources.textureView(inputs.projector);
|
|
462
465
|
if (!froxel.ok) throw froxel.error;
|
|
@@ -467,8 +470,8 @@ export function addVolumetricFogPasses(
|
|
|
467
470
|
if (!temporalSeed.ok) throw temporalSeed.error;
|
|
468
471
|
if (!params.ok) throw params.error;
|
|
469
472
|
if (!view.ok) throw view.error;
|
|
470
|
-
if (!
|
|
471
|
-
if (!
|
|
473
|
+
if (!lightData.ok) throw lightData.error;
|
|
474
|
+
if (!clusterUniform.ok) throw clusterUniform.error;
|
|
472
475
|
if (projector !== undefined && !projector.ok) throw projector.error;
|
|
473
476
|
const sampler = frame.runtime.device.createSampler({
|
|
474
477
|
minFilter: 'linear',
|
|
@@ -494,8 +497,8 @@ export function addVolumetricFogPasses(
|
|
|
494
497
|
{ binding: 7, resource: { kind: 'sampler', value: densitySampler.value } },
|
|
495
498
|
{ binding: 8, resource: { kind: 'textureView', value: historySeed.value as never } },
|
|
496
499
|
{ binding: 9, resource: { kind: 'textureView', value: temporalSeed.value as never } },
|
|
497
|
-
{ binding: 10, resource: { kind: 'buffer', value: { buffer:
|
|
498
|
-
{ binding: 11, resource: { kind: 'buffer', value: { buffer:
|
|
500
|
+
{ binding: 10, resource: { kind: 'buffer', value: { buffer: lightData.value } } },
|
|
501
|
+
{ binding: 11, resource: { kind: 'buffer', value: { buffer: clusterUniform.value } } },
|
|
499
502
|
{
|
|
500
503
|
binding: 12,
|
|
501
504
|
resource: {
|