@forgeax/engine-render 0.1.21 → 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 +150 -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.map +1 -1
- package/dist/assembly/factory.d.ts +14 -6
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +10 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/authoring.mjs +1 -1
- 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-FS2KNUQH.mjs → chunk-FF7K3FSO.mjs} +253 -489
- 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-6OPXDQ2E.mjs → chunk-QODA5UKU.mjs} +33 -294
- 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-5YADUCA7.mjs → chunk-ZUWKAZ2I.mjs} +585 -991
- 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/index.d.ts +3 -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/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 +10437 -10044
- 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/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 +26 -1
- package/dist/errors/render.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/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 +98 -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 +3 -3
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +90 -5
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +163 -1
- package/dist/inspection-types.d.ts.map +1 -1
- 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 -149
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/materials.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +26 -12
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/light-frame.d.ts +3 -3
- package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/topology.d.ts +1 -1
- package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.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 +1 -1
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- 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 +8 -6
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +50 -10
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts +7 -3
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-timing.d.ts +19 -7
- 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 +3 -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/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +57 -6
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +49 -2
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +1 -2
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/reflection/inspection.d.ts +10 -0
- package/dist/reflection/inspection.d.ts.map +1 -0
- package/dist/reflection/projection.d.ts +49 -0
- package/dist/reflection/projection.d.ts.map +1 -1
- 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 +14 -8
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +7 -0
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +104 -16
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +12 -1
- package/dist/render-system.d.ts.map +1 -1
- 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 +103 -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/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/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 +4 -0
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +8 -4
- package/dist/volume/passes.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +5 -0
- package/src/__tests__/detached-inspection.integration.test.ts +6 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +13 -1
- package/src/__tests__/direct-light-snapshot.unit.test.ts +59 -3
- 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 +33 -0
- package/src/__tests__/frame-observation.contract.test.ts +15 -0
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +1 -0
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +1 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +572 -9
- 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 +89 -2
- 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-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__/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__/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__/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__/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-owner-placement.unit.test.ts +39 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
- 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__/renderer-factory-material-contract.unit.test.ts +76 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +22 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +2 -2
- 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-variant-resolution.unit.test.ts +67 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +7 -0
- package/src/__tests__/standard-lighting-inspection.integration.test.ts +1 -1
- package/src/__tests__/standard-lighting-write.unit.test.ts +66 -2
- 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__/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__/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 +16 -9
- package/src/assembly/factory.ts +547 -93
- package/src/assembly/host-contract.ts +10 -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/index.ts +3 -0
- package/src/components/light-helpers.ts +52 -1
- package/src/components/light-probe.ts +13 -0
- package/src/components/rect-area-light.ts +15 -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/lifecycle.ts +8 -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 +55 -1
- package/src/extract/camera.ts +3 -3
- package/src/extract/gpu-driven.ts +108 -0
- package/src/extract/visibility.ts +0 -23
- package/src/gpu-driven/batch-topology.ts +206 -28
- package/src/gpu-driven/prepared-draw.ts +208 -0
- package/src/gpu-driven/production-raster.ts +953 -41
- package/src/gpu-driven/view-gpu.ts +411 -29
- package/src/gpu-scene-schema.ts +13 -0
- package/src/gpu-scene.ts +134 -65
- package/src/gpu-usage.ts +0 -1
- package/src/hdrp-buffers.ts +6 -6
- package/src/index.ts +74 -0
- package/src/inspection-types.ts +220 -1
- package/src/internal.ts +38 -0
- package/src/light-buffer-layout.ts +154 -324
- package/src/materials.ts +16 -2
- package/src/pbr-pipeline.ts +151 -45
- package/src/pipeline/standard-forward-lane.ts +47 -0
- package/src/pipeline/standard-lighting/graph.ts +2 -1
- package/src/pipeline/standard-lighting/light-frame.ts +3 -2
- package/src/pipeline/standard-lighting/topology.ts +1 -1
- package/src/pipeline/standard-lighting/transport.ts +2 -1
- package/src/pipeline/standard-pipeline.ts +2 -0
- package/src/pipeline-builder.ts +5 -2
- package/src/pipeline-spec.ts +12 -1
- package/src/plugin.ts +4 -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 +23 -1
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +20 -1
- package/src/record/frame-lighting.ts +252 -53
- package/src/record/frame-snapshot.ts +57 -12
- package/src/record/frame.ts +410 -93
- package/src/record/gpu-timing.ts +108 -44
- package/src/record/helpers.ts +0 -58
- package/src/record/main-pass-geometry.ts +204 -39
- package/src/record/main-pass-material.ts +8 -1
- package/src/record/main-pass-sprite-draws.ts +52 -85
- package/src/record/mesh-ssbo.ts +47 -36
- package/src/record/render-context.ts +65 -4
- package/src/record/shadow-pass.ts +66 -40
- package/src/record/typed-frame-graph.ts +225 -83
- package/src/record/view-ubo.ts +14 -24
- package/src/reflection/inspection.ts +67 -0
- package/src/reflection/projection.ts +196 -1
- package/src/reflection/record-owner.ts +1283 -0
- package/src/render-contract.ts +17 -5
- package/src/render-pipeline.ts +5 -0
- package/src/render-system-extract.ts +493 -134
- package/src/render-system.ts +811 -615
- 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 +848 -183
- 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/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/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/typed-render-graph-primitives.ts +48 -0
- package/src/volume/passes.ts +46 -49
- package/dist/.tsbuildinfo +0 -1
- package/dist/chunk-5YADUCA7.mjs.map +0 -1
- package/dist/chunk-6OPXDQ2E.mjs.map +0 -1
- package/dist/chunk-BXBQQKFQ.mjs +0 -67
- package/dist/chunk-BXBQQKFQ.mjs.map +0 -1
- package/dist/chunk-FS2KNUQH.mjs.map +0 -1
- package/dist/chunk-PCHBPYML.mjs.map +0 -1
- package/dist/chunk-VFPLTKCU.mjs.map +0 -1
|
@@ -62,6 +62,7 @@ import type {
|
|
|
62
62
|
} from '../render-pipeline';
|
|
63
63
|
import type { ExtractedLights, ExtractedVolumetricFog } from '../render-system-extract';
|
|
64
64
|
import { SHADOW_ATLAS_DEFAULT_FACE_SIZE, SHADOW_ATLAS_DEFAULT_LAYERS } from '../shadow-atlas';
|
|
65
|
+
import type { SsrAdmissionResult } from '../ssr/admission';
|
|
65
66
|
import type { RenderTarget } from '../targets/contracts';
|
|
66
67
|
import type { RenderTargetPhysical } from '../targets/physical';
|
|
67
68
|
import {
|
|
@@ -82,7 +83,7 @@ import { buildPerFrameBindGroups } from './frame-lighting';
|
|
|
82
83
|
import { getTextureIdentity, type RenderFrameState } from './frame-snapshot';
|
|
83
84
|
import type { GpuPassTimingPassIdentity } from './gpu-pass-timing/contract.js';
|
|
84
85
|
import type { GpuPassTimingCapture, GpuPassTimingSession } from './gpu-pass-timing/session.js';
|
|
85
|
-
import type { GpuTimingCapture
|
|
86
|
+
import type { GpuTimingCapture } from './gpu-timing';
|
|
86
87
|
import { encodeMainPass } from './main-pass';
|
|
87
88
|
import type {
|
|
88
89
|
_InternalRenderPipelineContext,
|
|
@@ -104,6 +105,97 @@ export interface TemporalGraphRoster {
|
|
|
104
105
|
readonly uploads: number;
|
|
105
106
|
}
|
|
106
107
|
|
|
108
|
+
export interface ReflectionFallbackGraphRoster {
|
|
109
|
+
readonly enabled: boolean;
|
|
110
|
+
readonly attachments: readonly string[];
|
|
111
|
+
readonly passes: readonly string[];
|
|
112
|
+
readonly bindings: readonly string[];
|
|
113
|
+
readonly historyCount: 0;
|
|
114
|
+
readonly temporalDemand: 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface ReflectionFallbackGraphCandidate {
|
|
118
|
+
readonly generation: number;
|
|
119
|
+
readonly source: 'probe' | 'skylight' | 'neutral';
|
|
120
|
+
readonly roster: ReflectionFallbackGraphRoster;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface SsrAdmissionGraphRoster {
|
|
124
|
+
readonly enabled: boolean;
|
|
125
|
+
readonly attachments: readonly string[];
|
|
126
|
+
readonly passes: readonly string[];
|
|
127
|
+
readonly bindings: readonly string[];
|
|
128
|
+
readonly historyCount: 0;
|
|
129
|
+
readonly temporalDemand: 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Admission is the sole switch for parent SSR graph work. A blocked result
|
|
134
|
+
* projects to an empty roster, so missing receipts cannot allocate or bind
|
|
135
|
+
* any SSR resource.
|
|
136
|
+
*/
|
|
137
|
+
export function createSsrAdmissionGraphRoster(
|
|
138
|
+
admission: Pick<SsrAdmissionResult, 'status'>,
|
|
139
|
+
): SsrAdmissionGraphRoster {
|
|
140
|
+
if (admission.status !== 'admitted') {
|
|
141
|
+
return {
|
|
142
|
+
enabled: false,
|
|
143
|
+
attachments: [],
|
|
144
|
+
passes: [],
|
|
145
|
+
bindings: [],
|
|
146
|
+
historyCount: 0,
|
|
147
|
+
temporalDemand: 0,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
enabled: true,
|
|
152
|
+
attachments: ['ssr-reflection-admission'],
|
|
153
|
+
passes: ['ssr-m0-admission'],
|
|
154
|
+
bindings: ['ssr-reflection-admission'],
|
|
155
|
+
historyCount: 0,
|
|
156
|
+
temporalDemand: 0,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export type ReflectionFallbackGraphFailure = 'compile-failed' | 'encode-failed' | 'submit-failed';
|
|
161
|
+
|
|
162
|
+
export function createReflectionFallbackGraphRoster(input: {
|
|
163
|
+
readonly fallbackDemand: boolean;
|
|
164
|
+
}): ReflectionFallbackGraphRoster {
|
|
165
|
+
if (!input.fallbackDemand) {
|
|
166
|
+
return {
|
|
167
|
+
enabled: false,
|
|
168
|
+
attachments: [],
|
|
169
|
+
passes: [],
|
|
170
|
+
bindings: [],
|
|
171
|
+
historyCount: 0,
|
|
172
|
+
temporalDemand: 0,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
enabled: true,
|
|
177
|
+
attachments: ['reflection-fallback-linear-hdr'],
|
|
178
|
+
passes: ['standard-main'],
|
|
179
|
+
bindings: ['reflection-fallback-output'],
|
|
180
|
+
historyCount: 0,
|
|
181
|
+
temporalDemand: 0,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function commitReflectionFallbackGraph(
|
|
186
|
+
candidate: ReflectionFallbackGraphCandidate,
|
|
187
|
+
result:
|
|
188
|
+
| { readonly ok: true }
|
|
189
|
+
| { readonly ok: false; readonly reason: ReflectionFallbackGraphFailure },
|
|
190
|
+
): {
|
|
191
|
+
readonly visible: boolean;
|
|
192
|
+
readonly generation: number;
|
|
193
|
+
readonly source?: ReflectionFallbackGraphCandidate['source'];
|
|
194
|
+
} {
|
|
195
|
+
if (!result.ok || !candidate.roster.enabled) return { visible: false, generation: 0 };
|
|
196
|
+
return { visible: true, generation: candidate.generation, source: candidate.source };
|
|
197
|
+
}
|
|
198
|
+
|
|
107
199
|
function importTemporalHistoryTarget(
|
|
108
200
|
graph: RenderGraphBuilder<RenderPipelineFrame>,
|
|
109
201
|
label: string,
|
|
@@ -730,16 +822,6 @@ const timingInstrumentationStates = new WeakMap<
|
|
|
730
822
|
TimingInstrumentationState
|
|
731
823
|
>();
|
|
732
824
|
|
|
733
|
-
interface VolumeTimingInstrumentationState {
|
|
734
|
-
readonly instrumentation: RenderGraphPassInstrumentation<RenderPipelineFrame>;
|
|
735
|
-
setCapture(capture: GpuTimingCapture | undefined): void;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
const volumeTimingInstrumentationStates = new WeakMap<
|
|
739
|
-
RenderSystemInternals,
|
|
740
|
-
VolumeTimingInstrumentationState
|
|
741
|
-
>();
|
|
742
|
-
|
|
743
825
|
type CompiledGraphTargetAccess = CompiledRenderGraph<RenderPipelineFrame> & {
|
|
744
826
|
readonly getColorTargetDescriptor: (
|
|
745
827
|
name: string,
|
|
@@ -930,6 +1012,7 @@ function topologyOf(
|
|
|
930
1012
|
standardProfile: internals.standardProfile,
|
|
931
1013
|
config,
|
|
932
1014
|
clearOnly,
|
|
1015
|
+
reflectionFallback: { enabled: frameState.reflectionFallbackDemand === true },
|
|
933
1016
|
surface: {
|
|
934
1017
|
width,
|
|
935
1018
|
height,
|
|
@@ -1262,6 +1345,7 @@ export function ensureCompiledFrameGraph(
|
|
|
1262
1345
|
cubeCaptureState?: CubeCaptureGraphState,
|
|
1263
1346
|
clearOnly = false,
|
|
1264
1347
|
transmissionDemand?: TransmissionDemand,
|
|
1348
|
+
occlusion?: import('../scene/visibility/occlusion-runtime').OcclusionFrameProjection,
|
|
1265
1349
|
volumetricFog?: ExtractedVolumetricFog,
|
|
1266
1350
|
volumeTopologyCandidate = false,
|
|
1267
1351
|
standardLighting?: StandardTopologyInputValue,
|
|
@@ -1354,6 +1438,17 @@ export function ensureCompiledFrameGraph(
|
|
|
1354
1438
|
: topologyResult.value;
|
|
1355
1439
|
const key = JSON.stringify({
|
|
1356
1440
|
topology,
|
|
1441
|
+
// GPU-driven residency can become available after the first record pass
|
|
1442
|
+
// (custom mesh handles are resolved into the per-frame projection). The
|
|
1443
|
+
// topology signature alone is intentionally stable across that lifecycle,
|
|
1444
|
+
// so include the prepared projection's presence to invalidate a cached
|
|
1445
|
+
// CPU-only graph when the GPU owner becomes ready, and vice versa.
|
|
1446
|
+
gpuDrivenProjectionActive: gpuDriven !== undefined,
|
|
1447
|
+
// Query reservations are frame-local transport state. The projection is
|
|
1448
|
+
// renderer-owned and read dynamically by the compiled pass, so a page
|
|
1449
|
+
// rotation must not invalidate the graph or its cached bind groups.
|
|
1450
|
+
occlusionQuery:
|
|
1451
|
+
occlusion === undefined ? undefined : { active: true, sampleCount: occlusion.sampleCount },
|
|
1357
1452
|
cubeCaptureSlots: cubeCaptureState?.work.length ?? 0,
|
|
1358
1453
|
reflectionProbeSlots: cubeCaptureState?.reflectionProbes?.work.map((work) => [
|
|
1359
1454
|
work.probeIndex,
|
|
@@ -1385,6 +1480,7 @@ export function ensureCompiledFrameGraph(
|
|
|
1385
1480
|
graph: builder,
|
|
1386
1481
|
...(standardLighting === undefined ? {} : { standardLighting }),
|
|
1387
1482
|
capabilities: { rgba16floatRenderable: internals.device.caps.rgba16floatRenderable },
|
|
1483
|
+
...(occlusion === undefined ? {} : { occlusion }),
|
|
1388
1484
|
...(taaHistory === undefined ? {} : { taaHistory }),
|
|
1389
1485
|
encodeTransmissionMip: ({ pass, resources, source }) => {
|
|
1390
1486
|
const sourceView = resources.textureView(source);
|
|
@@ -1472,6 +1568,11 @@ export function executeCompiledFrameGraph(
|
|
|
1472
1568
|
frame: RenderPipelineFrame,
|
|
1473
1569
|
encoder: RhiCommandEncoder,
|
|
1474
1570
|
runPass?: import('@forgeax/engine-render-graph').RenderGraphPassRunner,
|
|
1571
|
+
frameHooks?: {
|
|
1572
|
+
readonly afterGraphExecute?: () => Result<void, RhiError>;
|
|
1573
|
+
readonly onSubmitted?: () => void;
|
|
1574
|
+
readonly onAborted?: () => void;
|
|
1575
|
+
},
|
|
1475
1576
|
readbackFaces?: readonly number[],
|
|
1476
1577
|
onSubmitted?: (completed: Promise<unknown>) => void,
|
|
1477
1578
|
timingCapture?: GpuTimingCapture,
|
|
@@ -1494,6 +1595,8 @@ export function executeCompiledFrameGraph(
|
|
|
1494
1595
|
rejectTemporalFrame();
|
|
1495
1596
|
return false;
|
|
1496
1597
|
}
|
|
1598
|
+
const legacyTimingInstrumentation =
|
|
1599
|
+
timingCapture === undefined ? undefined : createTimingInstrumentation(timingCapture);
|
|
1497
1600
|
const timingHost = internals as RenderSystemInternals & {
|
|
1498
1601
|
gpuPassTimingSession?: GpuPassTimingSession | undefined;
|
|
1499
1602
|
gpuPassTimingCapture?: GpuPassTimingCapture | undefined;
|
|
@@ -1525,19 +1628,31 @@ export function executeCompiledFrameGraph(
|
|
|
1525
1628
|
? getTimingInstrumentationState(internals, passTimingCapture)
|
|
1526
1629
|
: timingCapture === undefined
|
|
1527
1630
|
? undefined
|
|
1528
|
-
:
|
|
1631
|
+
: undefined;
|
|
1632
|
+
const graphInstrumentation =
|
|
1633
|
+
passTimingCapture !== undefined
|
|
1634
|
+
? timingInstrumentationState?.instrumentation
|
|
1635
|
+
: legacyTimingInstrumentation;
|
|
1529
1636
|
type PreparedCommand = { readonly command: CommandBuffer };
|
|
1530
1637
|
let preparedCommand: PreparedCommand = { command: undefined as never };
|
|
1531
1638
|
const transaction = executeRendererFrameTransaction<PreparedCommand>({
|
|
1532
1639
|
build: () => ({ ok: true, value: { command: undefined as never } }),
|
|
1533
1640
|
execute: () => {
|
|
1534
|
-
const executed = graph.execute(frame, runPass,
|
|
1641
|
+
const executed = graph.execute(frame, runPass, graphInstrumentation);
|
|
1535
1642
|
timingInstrumentationState?.setCapture(undefined);
|
|
1536
1643
|
if (!executed.ok) {
|
|
1537
1644
|
passTimingCapture?.abort({ code: executed.error.code });
|
|
1538
1645
|
internals.errorRegistry.fire(executed.error);
|
|
1539
1646
|
return { ok: false, stage: 'execute' };
|
|
1540
1647
|
}
|
|
1648
|
+
const afterGraphExecute = frameHooks?.afterGraphExecute;
|
|
1649
|
+
if (afterGraphExecute !== undefined) {
|
|
1650
|
+
const recorded = afterGraphExecute();
|
|
1651
|
+
if (!recorded.ok) {
|
|
1652
|
+
internals.errorRegistry.fire(recorded.error);
|
|
1653
|
+
return { ok: false, stage: 'execute' };
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1541
1656
|
return { ok: true, value: undefined };
|
|
1542
1657
|
},
|
|
1543
1658
|
finish: () => {
|
|
@@ -1664,6 +1779,43 @@ export function executeCompiledFrameGraph(
|
|
|
1664
1779
|
);
|
|
1665
1780
|
}
|
|
1666
1781
|
}
|
|
1782
|
+
const fallbackReadback = frameState.reflectionFallbackReadback;
|
|
1783
|
+
frameState.reflectionFallbackReadback = undefined;
|
|
1784
|
+
if (fallbackReadback !== undefined) {
|
|
1785
|
+
const graphAccess = frameState.perFrameGraph;
|
|
1786
|
+
const graphTexture = graphAccess?.getColorTargetTexture(fallbackReadback.name);
|
|
1787
|
+
const descriptor = graphAccess?.getColorTargetDescriptor(fallbackReadback.name);
|
|
1788
|
+
const matches =
|
|
1789
|
+
graphAccess !== undefined &&
|
|
1790
|
+
graphAccess !== null &&
|
|
1791
|
+
graphTexture !== undefined &&
|
|
1792
|
+
descriptor !== undefined &&
|
|
1793
|
+
descriptor.format === fallbackReadback.expected.format &&
|
|
1794
|
+
descriptor.size.width === fallbackReadback.expected.width &&
|
|
1795
|
+
descriptor.size.height === fallbackReadback.expected.height &&
|
|
1796
|
+
descriptor.sample === 1 &&
|
|
1797
|
+
(descriptor.usage & fallbackReadback.expected.usage) ===
|
|
1798
|
+
fallbackReadback.expected.usage &&
|
|
1799
|
+
graphAccess.graphGeneration === fallbackReadback.expected.graphGeneration &&
|
|
1800
|
+
frameState.frameNumber === fallbackReadback.expected.frameId &&
|
|
1801
|
+
getTextureIdentity(graphTexture) === fallbackReadback.expected.textureIdentity;
|
|
1802
|
+
if (matches && graphTexture !== undefined) {
|
|
1803
|
+
encoder.copyTextureToBuffer(
|
|
1804
|
+
{ texture: graphTexture },
|
|
1805
|
+
{
|
|
1806
|
+
buffer: fallbackReadback.buffer,
|
|
1807
|
+
bytesPerRow: fallbackReadback.bytesPerRow,
|
|
1808
|
+
rowsPerImage: fallbackReadback.height,
|
|
1809
|
+
},
|
|
1810
|
+
{
|
|
1811
|
+
width: fallbackReadback.width,
|
|
1812
|
+
height: fallbackReadback.height,
|
|
1813
|
+
depthOrArrayLayers: 1,
|
|
1814
|
+
},
|
|
1815
|
+
);
|
|
1816
|
+
fallbackReadback.encoded = true;
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1667
1819
|
internals.encodeRenderTargetReadbacks?.(encoder, readbackFaces);
|
|
1668
1820
|
const stagedGpuState = frameState.temporalGpuState;
|
|
1669
1821
|
if (stagedGpuState !== undefined && !hasPendingTemporalGpuSubmit(stagedGpuState)) {
|
|
@@ -1696,6 +1848,13 @@ export function executeCompiledFrameGraph(
|
|
|
1696
1848
|
return { ok: true, value: undefined };
|
|
1697
1849
|
},
|
|
1698
1850
|
submit: () => {
|
|
1851
|
+
const injectedFailure = internals.beforeSubmit?.(internals.device);
|
|
1852
|
+
if (injectedFailure !== undefined) {
|
|
1853
|
+
passTimingCapture?.abort({ code: injectedFailure.code });
|
|
1854
|
+
timingCapture?.discard();
|
|
1855
|
+
internals.errorRegistry.fire(injectedFailure);
|
|
1856
|
+
return { ok: false, stage: 'submit' };
|
|
1857
|
+
}
|
|
1699
1858
|
const submitted = internals.device.queue.submit([preparedCommand.command]);
|
|
1700
1859
|
if (!submitted.ok) {
|
|
1701
1860
|
passTimingCapture?.abort({ code: submitted.error.code });
|
|
@@ -1707,6 +1866,23 @@ export function executeCompiledFrameGraph(
|
|
|
1707
1866
|
return { ok: true, value: undefined };
|
|
1708
1867
|
},
|
|
1709
1868
|
commit: () => {
|
|
1869
|
+
frameHooks?.onSubmitted?.();
|
|
1870
|
+
if (frameState.temporalFrameInput !== undefined) {
|
|
1871
|
+
const temporal = frameState.temporalFrameTransaction.commit({ accepted: true });
|
|
1872
|
+
if (temporal.ok) {
|
|
1873
|
+
frameState.temporalFrame = temporal.value;
|
|
1874
|
+
} else {
|
|
1875
|
+
internals.errorRegistry.fire(
|
|
1876
|
+
new RhiError({
|
|
1877
|
+
code: 'webgpu-runtime-error',
|
|
1878
|
+
expected: 'the staged temporal frame to commit after queue submission',
|
|
1879
|
+
hint: 'discard the temporal candidate and retry the next frame',
|
|
1880
|
+
detail: { error: temporal.error },
|
|
1881
|
+
}),
|
|
1882
|
+
);
|
|
1883
|
+
}
|
|
1884
|
+
frameState.temporalFrameInput = undefined;
|
|
1885
|
+
}
|
|
1710
1886
|
if (passTimingCapture !== undefined) {
|
|
1711
1887
|
const completion = internals.device.queue.onSubmittedWorkDone();
|
|
1712
1888
|
timingHost.gpuPassTimingSubmittedWork = completion;
|
|
@@ -1783,6 +1959,7 @@ export function executeCompiledFrameGraph(
|
|
|
1783
1959
|
onSubmitted?.(internals.device.queue.onSubmittedWorkDone());
|
|
1784
1960
|
},
|
|
1785
1961
|
abort: (failure) => {
|
|
1962
|
+
frameHooks?.onAborted?.();
|
|
1786
1963
|
passTimingCapture?.abort({ code: failure.stage });
|
|
1787
1964
|
timingHost.gpuPassTimingCapture = undefined;
|
|
1788
1965
|
timingHost.gpuPassTimingSubmittedWork = undefined;
|
|
@@ -1814,6 +1991,41 @@ export function executeCompiledFrameGraph(
|
|
|
1814
1991
|
return transaction.ok;
|
|
1815
1992
|
}
|
|
1816
1993
|
|
|
1994
|
+
function createTimingInstrumentation(
|
|
1995
|
+
capture: GpuTimingCapture,
|
|
1996
|
+
): RenderGraphPassInstrumentation<RenderPipelineFrame> {
|
|
1997
|
+
return {
|
|
1998
|
+
begin: (pass): RenderGraphPassInstrumentationScope | undefined => {
|
|
1999
|
+
// WebGPU has no portable timestamp boundary for a copy pass. Do not
|
|
2000
|
+
// pretend a command-encoder marker exists; frame timing remains valid
|
|
2001
|
+
// when at least one raster/compute pass is present.
|
|
2002
|
+
if (pass.kind === 'copy') return undefined;
|
|
2003
|
+
const writes = capture.beginPass(pass.name, pass.kind, pass.executionIndex);
|
|
2004
|
+
if (writes === undefined) return undefined;
|
|
2005
|
+
if (pass.kind === 'raster') {
|
|
2006
|
+
return {
|
|
2007
|
+
renderPassDescriptor: (descriptor) => {
|
|
2008
|
+
if (descriptor.timestampWrites !== undefined) {
|
|
2009
|
+
capture.markOwnerConflict(pass.name);
|
|
2010
|
+
return descriptor;
|
|
2011
|
+
}
|
|
2012
|
+
return { ...descriptor, timestampWrites: writes };
|
|
2013
|
+
},
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
return {
|
|
2017
|
+
computePassDescriptor: (descriptor) => {
|
|
2018
|
+
if (descriptor.timestampWrites !== undefined) {
|
|
2019
|
+
capture.markOwnerConflict(pass.name);
|
|
2020
|
+
return descriptor;
|
|
2021
|
+
}
|
|
2022
|
+
return { ...descriptor, timestampWrites: writes };
|
|
2023
|
+
},
|
|
2024
|
+
};
|
|
2025
|
+
},
|
|
2026
|
+
};
|
|
2027
|
+
}
|
|
2028
|
+
|
|
1817
2029
|
function getTimingInstrumentationState(
|
|
1818
2030
|
internals: RenderSystemInternals,
|
|
1819
2031
|
capture: GpuPassTimingCapture,
|
|
@@ -1912,73 +2124,3 @@ function getTimingInstrumentationState(
|
|
|
1912
2124
|
timingInstrumentationStates.set(internals, state);
|
|
1913
2125
|
return state;
|
|
1914
2126
|
}
|
|
1915
|
-
|
|
1916
|
-
function getVolumeTimingInstrumentationState(
|
|
1917
|
-
internals: RenderSystemInternals,
|
|
1918
|
-
capture: GpuTimingCapture,
|
|
1919
|
-
): VolumeTimingInstrumentationState {
|
|
1920
|
-
const existing = volumeTimingInstrumentationStates.get(internals);
|
|
1921
|
-
if (existing !== undefined) {
|
|
1922
|
-
existing.setCapture(capture);
|
|
1923
|
-
return existing;
|
|
1924
|
-
}
|
|
1925
|
-
let activeCapture: GpuTimingCapture | undefined = capture;
|
|
1926
|
-
let activePassName: string | undefined;
|
|
1927
|
-
let activeWrites: VolumeTimingTimestampWrites | undefined;
|
|
1928
|
-
const rasterScope: RenderGraphPassInstrumentationScope = {
|
|
1929
|
-
renderPassDescriptor: (descriptor) => {
|
|
1930
|
-
const currentCapture = activeCapture;
|
|
1931
|
-
const passName = activePassName;
|
|
1932
|
-
const writes = activeWrites;
|
|
1933
|
-
if (currentCapture === undefined || passName === undefined || writes === undefined) {
|
|
1934
|
-
return descriptor;
|
|
1935
|
-
}
|
|
1936
|
-
if (descriptor.timestampWrites !== undefined) {
|
|
1937
|
-
currentCapture.skipPass(passName);
|
|
1938
|
-
activeWrites = undefined;
|
|
1939
|
-
return descriptor;
|
|
1940
|
-
}
|
|
1941
|
-
return { ...descriptor, timestampWrites: writes };
|
|
1942
|
-
},
|
|
1943
|
-
};
|
|
1944
|
-
const computeScope: RenderGraphPassInstrumentationScope = {
|
|
1945
|
-
computePassDescriptor: (descriptor) => {
|
|
1946
|
-
const currentCapture = activeCapture;
|
|
1947
|
-
const passName = activePassName;
|
|
1948
|
-
const writes = activeWrites;
|
|
1949
|
-
if (currentCapture === undefined || passName === undefined || writes === undefined) {
|
|
1950
|
-
return descriptor;
|
|
1951
|
-
}
|
|
1952
|
-
if (descriptor.timestampWrites !== undefined) {
|
|
1953
|
-
currentCapture.skipPass(passName);
|
|
1954
|
-
activeWrites = undefined;
|
|
1955
|
-
return descriptor;
|
|
1956
|
-
}
|
|
1957
|
-
return { ...descriptor, timestampWrites: writes };
|
|
1958
|
-
},
|
|
1959
|
-
};
|
|
1960
|
-
const instrumentation: RenderGraphPassInstrumentation<RenderPipelineFrame> = {
|
|
1961
|
-
begin: (pass) => {
|
|
1962
|
-
const currentCapture = activeCapture;
|
|
1963
|
-
if (currentCapture === undefined) return undefined;
|
|
1964
|
-
activePassName = pass.name;
|
|
1965
|
-
activeWrites = currentCapture.recordPass(pass.name);
|
|
1966
|
-
if (activeWrites === undefined) return undefined;
|
|
1967
|
-
if (pass.kind === 'raster') return rasterScope;
|
|
1968
|
-
if (pass.kind === 'compute') return computeScope;
|
|
1969
|
-
currentCapture.skipPass(pass.name);
|
|
1970
|
-
activeWrites = undefined;
|
|
1971
|
-
return undefined;
|
|
1972
|
-
},
|
|
1973
|
-
};
|
|
1974
|
-
const state: VolumeTimingInstrumentationState = {
|
|
1975
|
-
instrumentation,
|
|
1976
|
-
setCapture: (nextCapture) => {
|
|
1977
|
-
activeCapture = nextCapture;
|
|
1978
|
-
activePassName = undefined;
|
|
1979
|
-
activeWrites = undefined;
|
|
1980
|
-
},
|
|
1981
|
-
};
|
|
1982
|
-
volumeTimingInstrumentationStates.set(internals, state);
|
|
1983
|
-
return state;
|
|
1984
|
-
}
|
package/src/record/view-ubo.ts
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
import { mat4 } from '@forgeax/engine-math';
|
|
10
10
|
import type { Buffer, RhiQueue } from '@forgeax/engine-rhi';
|
|
11
11
|
import type { DirectionalShadowQuality } from '../components/directional-shadow-filter';
|
|
12
|
-
import type { FogFrame } from '../extract/environment';
|
|
13
12
|
import type { PointsLinesStyle } from '../points-lines/snapshot';
|
|
14
13
|
import type { CameraSnapshot } from '../render-contract';
|
|
15
14
|
import type {
|
|
@@ -140,18 +139,11 @@ export function writeViewUbo(
|
|
|
140
139
|
light: DirectionalLightSnapshot,
|
|
141
140
|
lights: ExtractedLights,
|
|
142
141
|
spotShadowSnapshots: readonly SpotLightSnapshot[],
|
|
143
|
-
|
|
144
|
-
temporal?: TemporalView,
|
|
142
|
+
temporalOrOffset?: TemporalView | LegacyTemporalView | number,
|
|
145
143
|
projectorSpotIndex?: number,
|
|
146
144
|
): void {
|
|
147
|
-
const byteOffset = typeof
|
|
148
|
-
const
|
|
149
|
-
typeof fogOrTemporalOrOffset === 'number' ? undefined : fogOrTemporalOrOffset;
|
|
150
|
-
const isTemporal =
|
|
151
|
-
fogOrTemporal !== undefined &&
|
|
152
|
-
('currentJitterUv' in fogOrTemporal || 'currentUnjitteredViewProjection' in fogOrTemporal);
|
|
153
|
-
const fog = isTemporal ? undefined : fogOrTemporal;
|
|
154
|
-
const resolvedTemporal = temporal ?? (isTemporal ? fogOrTemporal : undefined);
|
|
145
|
+
const byteOffset = typeof temporalOrOffset === 'number' ? temporalOrOffset : 0;
|
|
146
|
+
const resolvedTemporal = typeof temporalOrOffset === 'number' ? undefined : temporalOrOffset;
|
|
155
147
|
// Compose worldViewProj once per frame (view * proj).
|
|
156
148
|
const projMatrix = computeProjectionMatrix(camera);
|
|
157
149
|
const viewMatrix = computeViewMatrix(camera);
|
|
@@ -216,6 +208,16 @@ export function writeViewUbo(
|
|
|
216
208
|
viewPayload[228] = camera.near;
|
|
217
209
|
viewPayload[229] = camera.far;
|
|
218
210
|
viewPayload[230] = camera.projection === 'orthographic' ? 1 : 0;
|
|
211
|
+
const previousCameraPosition =
|
|
212
|
+
resolvedTemporal !== undefined && 'previousCameraPosition' in resolvedTemporal
|
|
213
|
+
? resolvedTemporal.previousCameraPosition
|
|
214
|
+
: undefined;
|
|
215
|
+
if (previousCameraPosition !== undefined) {
|
|
216
|
+
viewPayload[232] = previousCameraPosition[0] ?? 0;
|
|
217
|
+
viewPayload[233] = previousCameraPosition[1] ?? 0;
|
|
218
|
+
viewPayload[234] = previousCameraPosition[2] ?? 0;
|
|
219
|
+
viewPayload[235] = 1;
|
|
220
|
+
}
|
|
219
221
|
// splitPlanes at [108..123] (four vec4 lanes: split/world texel/depth span/reserved).
|
|
220
222
|
if (lights.splitPlanes !== undefined) {
|
|
221
223
|
for (let s = 0; s < 4; s++) {
|
|
@@ -248,7 +250,7 @@ export function writeViewUbo(
|
|
|
248
250
|
// spot index, not by a negative shadow tile: a projector-only spot publishes
|
|
249
251
|
// its matrix in lane 0 so the shader never samples a zero matrix. Shadowed
|
|
250
252
|
// projector spots keep their shadow tile lane and carry the projector bit in
|
|
251
|
-
// the
|
|
253
|
+
// the DirectLightSlot identity word.
|
|
252
254
|
// Folded from the former standalone binding 9 UBO to keep the WebGL2
|
|
253
255
|
// fallback fragment uniform-buffer count <= 11 (GLES 3.0).
|
|
254
256
|
{
|
|
@@ -272,18 +274,6 @@ export function writeViewUbo(
|
|
|
272
274
|
}
|
|
273
275
|
}
|
|
274
276
|
|
|
275
|
-
// Fog is a resource-owner semantic carried by the shared View ABI. Keep the
|
|
276
|
-
// disabled payload zeroed and write only the selected frame facts so both
|
|
277
|
-
// direct and clustered lanes consume the same owner projection.
|
|
278
|
-
if (fog !== undefined) {
|
|
279
|
-
viewPayload[232] = fog.color[0] ?? 0;
|
|
280
|
-
viewPayload[233] = fog.color[1] ?? 0;
|
|
281
|
-
viewPayload[234] = fog.color[2] ?? 0;
|
|
282
|
-
viewPayload[235] = fog.density;
|
|
283
|
-
viewPayload[236] = fog.heightFalloff;
|
|
284
|
-
viewPayload[237] = fog.maxOpacity;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
277
|
const viewUploadResult = queue.writeBuffer(viewUniformBuffer, byteOffset, viewPayload);
|
|
288
278
|
if (!viewUploadResult.ok) throw viewUploadResult.error;
|
|
289
279
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ReflectionFallbackFailureStage,
|
|
3
|
+
ReflectionFallbackInspection,
|
|
4
|
+
ReflectionFallbackReceipt,
|
|
5
|
+
ReflectionFallbackRecoveryAction,
|
|
6
|
+
} from '../inspection-types';
|
|
7
|
+
|
|
8
|
+
export interface ReflectionFallbackFailureInput {
|
|
9
|
+
readonly stage: ReflectionFallbackFailureStage;
|
|
10
|
+
readonly code: string;
|
|
11
|
+
readonly expected: string;
|
|
12
|
+
readonly detail?: Readonly<Record<string, unknown>>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function recoveryFor(
|
|
16
|
+
receipt: ReflectionFallbackReceipt,
|
|
17
|
+
failure?: ReflectionFallbackFailureInput,
|
|
18
|
+
): ReflectionFallbackRecoveryAction {
|
|
19
|
+
if (failure !== undefined) {
|
|
20
|
+
const code = failure.code.toLowerCase();
|
|
21
|
+
if (code.includes('device') || code.includes('format') || code.includes('capability')) {
|
|
22
|
+
return 'rebuild';
|
|
23
|
+
}
|
|
24
|
+
if (failure.stage === 'prepare' || failure.stage === 'filter') return 'recapture';
|
|
25
|
+
if (failure.stage === 'build' || failure.stage === 'encode') return 'rebuild';
|
|
26
|
+
if (failure.stage === 'finish' || failure.stage === 'submit') return 'retry';
|
|
27
|
+
// Completion failures may still retain a source-identical committed row;
|
|
28
|
+
// use it as LKG, otherwise retry the producer completion.
|
|
29
|
+
if (failure.stage === 'completion') {
|
|
30
|
+
if (receipt.source === 'probe' && (receipt.state === 'active' || receipt.state === 'lkg')) {
|
|
31
|
+
return 'use-LKG';
|
|
32
|
+
}
|
|
33
|
+
if (
|
|
34
|
+
receipt.source === 'skylight' &&
|
|
35
|
+
(receipt.state === 'active' || receipt.state === 'lkg')
|
|
36
|
+
) {
|
|
37
|
+
return 'use-Skylight';
|
|
38
|
+
}
|
|
39
|
+
if (receipt.source === 'neutral' && receipt.state === 'neutral') return 'use-neutral';
|
|
40
|
+
return 'retry';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (receipt.source === 'probe' && (receipt.state === 'active' || receipt.state === 'lkg')) {
|
|
44
|
+
return 'use-LKG';
|
|
45
|
+
}
|
|
46
|
+
if (receipt.source === 'skylight' || receipt.state === 'lkg') return 'use-Skylight';
|
|
47
|
+
return 'use-neutral';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Projects producer state and the latest closed failure into detached facts. */
|
|
51
|
+
export function inspectReflectionFallback(
|
|
52
|
+
receipt: ReflectionFallbackReceipt,
|
|
53
|
+
failure?: ReflectionFallbackFailureInput,
|
|
54
|
+
): ReflectionFallbackInspection {
|
|
55
|
+
return {
|
|
56
|
+
receipt,
|
|
57
|
+
recoveryAction: recoveryFor(receipt, failure),
|
|
58
|
+
...(failure === undefined
|
|
59
|
+
? {}
|
|
60
|
+
: {
|
|
61
|
+
failureStage: failure.stage,
|
|
62
|
+
failureCode: failure.code,
|
|
63
|
+
expected: failure.expected,
|
|
64
|
+
...(failure.detail === undefined ? {} : { detail: failure.detail }),
|
|
65
|
+
}),
|
|
66
|
+
};
|
|
67
|
+
}
|