@forgeax/engine-render 0.1.2
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/LICENSE +202 -0
- package/README.md +1019 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/__tests__/analytic-sky-contract.test.d.ts +2 -0
- package/dist/__tests__/analytic-sky-contract.test.d.ts.map +1 -0
- package/dist/__tests__/analytic-sky-falsify.test.d.ts +2 -0
- package/dist/__tests__/analytic-sky-falsify.test.d.ts.map +1 -0
- package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts +2 -0
- package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts.map +1 -0
- package/dist/__tests__/authoring-path.unit.test.d.ts +2 -0
- package/dist/__tests__/authoring-path.unit.test.d.ts.map +1 -0
- package/dist/__tests__/backend-selection-rhi-capture.test-d.d.ts +2 -0
- package/dist/__tests__/backend-selection-rhi-capture.test-d.d.ts.map +1 -0
- package/dist/__tests__/backend-selection.integration.test.d.ts +2 -0
- package/dist/__tests__/backend-selection.integration.test.d.ts.map +1 -0
- package/dist/__tests__/callback-inference.test-d.d.ts +2 -0
- package/dist/__tests__/callback-inference.test-d.d.ts.map +1 -0
- package/dist/__tests__/camera-temporal.test-d.d.ts +2 -0
- package/dist/__tests__/camera-temporal.test-d.d.ts.map +1 -0
- package/dist/__tests__/camera-temporal.test.d.ts +2 -0
- package/dist/__tests__/camera-temporal.test.d.ts.map +1 -0
- package/dist/__tests__/cluster-binner.test.d.ts +2 -0
- package/dist/__tests__/cluster-binner.test.d.ts.map +1 -0
- package/dist/__tests__/cluster-grid-default-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/cluster-grid-default-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/construct-renderer-identity.unit.test.d.ts +2 -0
- package/dist/__tests__/construct-renderer-identity.unit.test.d.ts.map +1 -0
- package/dist/__tests__/direct-extract-consumer-contract.test-d.d.ts +2 -0
- package/dist/__tests__/direct-extract-consumer-contract.test-d.d.ts.map +1 -0
- package/dist/__tests__/direct-light-snapshot.unit.test.d.ts +2 -0
- package/dist/__tests__/direct-light-snapshot.unit.test.d.ts.map +1 -0
- package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts +2 -0
- package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts.map +1 -0
- package/dist/__tests__/environment-inspection.test.d.ts +2 -0
- package/dist/__tests__/environment-inspection.test.d.ts.map +1 -0
- package/dist/__tests__/factory-contract.integration.test.d.ts +2 -0
- package/dist/__tests__/factory-contract.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fallback-row-stride-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/fallback-row-stride-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/fog-ai-user.fixture.d.ts +2 -0
- package/dist/__tests__/fog-ai-user.fixture.d.ts.map +1 -0
- package/dist/__tests__/fog-custom-render-feature.fixture.d.ts +16 -0
- package/dist/__tests__/fog-custom-render-feature.fixture.d.ts.map +1 -0
- package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts +2 -0
- package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fog-inspection.integration.test.d.ts +2 -0
- package/dist/__tests__/fog-inspection.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fog-owner-state.integration.test.d.ts +2 -0
- package/dist/__tests__/fog-owner-state.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts +2 -0
- package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fog-public-surface.integration.test.d.ts +2 -0
- package/dist/__tests__/fog-public-surface.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fog-ray-contract.integration.test.d.ts +2 -0
- package/dist/__tests__/fog-ray-contract.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fog-source-absence.integration.test.d.ts +2 -0
- package/dist/__tests__/fog-source-absence.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fog-temporal.integration.test.d.ts +2 -0
- package/dist/__tests__/fog-temporal.integration.test.d.ts.map +1 -0
- package/dist/__tests__/frame-chain.unit.test.d.ts +2 -0
- package/dist/__tests__/frame-chain.unit.test.d.ts.map +1 -0
- package/dist/__tests__/frame-observation.contract.test.d.ts +2 -0
- package/dist/__tests__/frame-observation.contract.test.d.ts.map +1 -0
- package/dist/__tests__/glyph-text-layout-recovery.unit.test.d.ts +2 -0
- package/dist/__tests__/glyph-text-layout-recovery.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts +6 -0
- package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster.browser.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-indirect-raster.browser.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-indirect-raster.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-production.integration.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-production.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-scaling.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-scaling.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts +12 -0
- package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view-graph.integration.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view-graph.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view.browser.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view.browser.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-resource-store-stride.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-resource-store-stride.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts +2 -0
- package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts +7 -0
- package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph.browser.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene-render-graph.browser.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene-render-graph.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-schema.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene-schema.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene.unit.test.d.ts.map +1 -0
- package/dist/__tests__/hdrp-pipeline.unit.test.d.ts +2 -0
- package/dist/__tests__/hdrp-pipeline.unit.test.d.ts.map +1 -0
- package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts +2 -0
- package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts.map +1 -0
- package/dist/__tests__/infinite-grid-no-vertex-probe.unit.test.d.ts +2 -0
- package/dist/__tests__/infinite-grid-no-vertex-probe.unit.test.d.ts.map +1 -0
- package/dist/__tests__/injection-kind-owner.test-d.d.ts +2 -0
- package/dist/__tests__/injection-kind-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/ktx2-basis-gpu-consumer.dawn.test.d.ts +2 -0
- package/dist/__tests__/ktx2-basis-gpu-consumer.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/light-buffer-layout.unit.test.d.ts +2 -0
- package/dist/__tests__/light-buffer-layout.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-contract-inventory.unit.test.d.ts +2 -0
- package/dist/__tests__/material-contract-inventory.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-cooked-projection.unit.test.d.ts +2 -0
- package/dist/__tests__/material-cooked-projection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts +2 -0
- package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts.map +1 -0
- package/dist/__tests__/material-derived-payload.integration.test.d.ts +2 -0
- package/dist/__tests__/material-derived-payload.integration.test.d.ts.map +1 -0
- package/dist/__tests__/material-snapshot-mutation.integration.test.d.ts +2 -0
- package/dist/__tests__/material-snapshot-mutation.integration.test.d.ts.map +1 -0
- package/dist/__tests__/material-static-dynamic-route.unit.test.d.ts +2 -0
- package/dist/__tests__/material-static-dynamic-route.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-stride-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/material-stride-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/materials.unit.test.d.ts +2 -0
- package/dist/__tests__/materials.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-buffer-usage-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-buffer-usage-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-material-bindings.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-material-bindings.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-stride-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-stride-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/morph-culling-reentry.dawn.test.d.ts +2 -0
- package/dist/__tests__/morph-culling-reentry.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/morph-feature-gpu-work.integration.test.d.ts +2 -0
- package/dist/__tests__/morph-feature-gpu-work.integration.test.d.ts.map +1 -0
- package/dist/__tests__/morph-visual-evidence.integration.test.d.ts +2 -0
- package/dist/__tests__/morph-visual-evidence.integration.test.d.ts.map +1 -0
- package/dist/__tests__/nineslice-handle-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/nineslice-handle-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/param-schema-projection-census.unit.test.d.ts +2 -0
- package/dist/__tests__/param-schema-projection-census.unit.test.d.ts.map +1 -0
- package/dist/__tests__/persistent-render-scene.unit.test.d.ts +2 -0
- package/dist/__tests__/persistent-render-scene.unit.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts +2 -0
- package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline-pass-trace.test.d.ts +2 -0
- package/dist/__tests__/pipeline-pass-trace.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline-stage-owner.test-d.d.ts +2 -0
- package/dist/__tests__/pipeline-stage-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/plugin.test.d.ts +2 -0
- package/dist/__tests__/plugin.test.d.ts.map +1 -0
- package/dist/__tests__/post-process-error-policy-owner.unit.test.d.ts +2 -0
- package/dist/__tests__/post-process-error-policy-owner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-buffer-kind-owner.test-d.d.ts +2 -0
- package/dist/__tests__/prepared-buffer-kind-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-capability.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-capability.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-generation.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-generation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-lifecycle.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-lifecycle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-pipeline-warmup.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-pipeline-warmup.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-resolver.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-resolver.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-snapshot.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-snapshot.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-store.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-store.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-validation.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-validation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-default-off.test.d.ts +2 -0
- package/dist/__tests__/profiler-default-off.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-phase-catalog.test.d.ts +2 -0
- package/dist/__tests__/profiler-phase-catalog.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-phase-integration.test.d.ts +2 -0
- package/dist/__tests__/profiler-phase-integration.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-phase-token.test.d.ts +2 -0
- package/dist/__tests__/profiler-phase-token.test.d.ts.map +1 -0
- package/dist/__tests__/public-pipeline-id.test-d.d.ts +2 -0
- package/dist/__tests__/public-pipeline-id.test-d.d.ts.map +1 -0
- package/dist/__tests__/public-surface.test-d.d.ts +2 -0
- package/dist/__tests__/public-surface.test-d.d.ts.map +1 -0
- package/dist/__tests__/recover-error-policy-owner.unit.test.d.ts +2 -0
- package/dist/__tests__/recover-error-policy-owner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-dispatch-membership.unit.test.d.ts +2 -0
- package/dist/__tests__/render-dispatch-membership.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-error-code-owner.test-d.d.ts +2 -0
- package/dist/__tests__/render-error-code-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-error-detail-ssot.test-d.d.ts +2 -0
- package/dist/__tests__/render-error-detail-ssot.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts +2 -0
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-assembly.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-assembly.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-construction.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-construction.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-context.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-context.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-contract.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-contract.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-diagnostics.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-diagnostics.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-docs.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-docs.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-errors.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-errors.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-gpu-work.integration.test.d.ts +2 -0
- package/dist/__tests__/render-feature-gpu-work.integration.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-graph.integration.test.d.ts +2 -0
- package/dist/__tests__/render-feature-graph.integration.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-order.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-order.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-diagnostics.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-diagnostics.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-errors.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-errors.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics-docs.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics-docs.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics-isolation.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics-isolation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics-negative.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics-negative.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-public-surface.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-public-surface.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-retry.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-retry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-scheduling.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-scheduling.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-stage-failed-policy-owner.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-stage-failed-policy-owner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-stage-fault-recovery.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-stage-fault-recovery.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-staging.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-staging.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-visibility-context.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-visibility-context.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-visibility-context.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-visibility-context.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-zero-work.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-zero-work.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-compute-raster-gpu.d.ts +7 -0
- package/dist/__tests__/render-graph-compute-raster-gpu.d.ts.map +1 -0
- package/dist/__tests__/render-graph-compute-raster.browser.test.d.ts +2 -0
- package/dist/__tests__/render-graph-compute-raster.browser.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-compute-raster.dawn.test.d.ts +2 -0
- package/dist/__tests__/render-graph-compute-raster.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-hzb-gpu.d.ts +7 -0
- package/dist/__tests__/render-graph-hzb-gpu.d.ts.map +1 -0
- package/dist/__tests__/render-graph-hzb.browser.test.d.ts +2 -0
- package/dist/__tests__/render-graph-hzb.browser.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-hzb.dawn.test.d.ts +2 -0
- package/dist/__tests__/render-graph-hzb.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-primitives.unit.test.d.ts +2 -0
- package/dist/__tests__/render-graph-primitives.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-storage-indirect-gpu.d.ts +12 -0
- package/dist/__tests__/render-graph-storage-indirect-gpu.d.ts.map +1 -0
- package/dist/__tests__/render-graph-storage-indirect.browser.test.d.ts +2 -0
- package/dist/__tests__/render-graph-storage-indirect.browser.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-storage-indirect.dawn.test.d.ts +2 -0
- package/dist/__tests__/render-graph-storage-indirect.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/render-scene-projection.unit.test.d.ts +2 -0
- package/dist/__tests__/render-scene-projection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/renderer-factory-material-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/renderer-factory-material-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/renderer-lifecycle.integration.test.d.ts +2 -0
- package/dist/__tests__/renderer-lifecycle.integration.test.d.ts.map +1 -0
- package/dist/__tests__/renderer-render-scene-public.test-d.d.ts +2 -0
- package/dist/__tests__/renderer-render-scene-public.test-d.d.ts.map +1 -0
- package/dist/__tests__/rhi-backend-package-boundary.unit.test.d.ts +2 -0
- package/dist/__tests__/rhi-backend-package-boundary.unit.test.d.ts.map +1 -0
- package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts +2 -0
- package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts.map +1 -0
- package/dist/__tests__/scriptable-pack-consumer.test-d.d.ts +2 -0
- package/dist/__tests__/scriptable-pack-consumer.test-d.d.ts.map +1 -0
- package/dist/__tests__/shader-stage-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/shader-stage-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/ssao-kernel-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/ssao-kernel-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/sun-snapshot-consumers.test.d.ts +2 -0
- package/dist/__tests__/sun-snapshot-consumers.test.d.ts.map +1 -0
- package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts +2 -0
- package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/surface-configuration.unit.test.d.ts +2 -0
- package/dist/__tests__/surface-configuration.unit.test.d.ts.map +1 -0
- package/dist/__tests__/taa-history-store.unit.test.d.ts +2 -0
- package/dist/__tests__/taa-history-store.unit.test.d.ts.map +1 -0
- package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts +2 -0
- package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts.map +1 -0
- package/dist/__tests__/temporal-inspection.unit.test.d.ts +2 -0
- package/dist/__tests__/temporal-inspection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/texture-usage-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/texture-usage-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/typed-pipeline-topology.unit.test.d.ts +2 -0
- package/dist/__tests__/typed-pipeline-topology.unit.test.d.ts.map +1 -0
- package/dist/__tests__/urp-pipeline-targets.unit.test.d.ts +2 -0
- package/dist/__tests__/urp-pipeline-targets.unit.test.d.ts.map +1 -0
- package/dist/__tests__/urp-pipeline.unit.test.d.ts +2 -0
- package/dist/__tests__/urp-pipeline.unit.test.d.ts.map +1 -0
- package/dist/__tests__/vertex-color-pipeline.unit.test.d.ts +2 -0
- package/dist/__tests__/vertex-color-pipeline.unit.test.d.ts.map +1 -0
- package/dist/__tests__/vertex-layout-consumer.unit.test.d.ts +2 -0
- package/dist/__tests__/vertex-layout-consumer.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-diagnostics.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-diagnostics.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-extract.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-extract.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-extract.perf.test.d.ts +2 -0
- package/dist/__tests__/visibility-extract.perf.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-feature-dedup.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-feature-dedup.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-hidden-report.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-hidden-report.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-instances.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-instances.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-multi-world.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-multi-world.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-producer-matrix.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-producer-matrix.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-producer-matrix.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-producer-matrix.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-public-surface.test-d.d.ts +2 -0
- package/dist/__tests__/visibility-public-surface.test-d.d.ts.map +1 -0
- package/dist/__tests__/visibility-resolver.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-resolver.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-snapshot-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-snapshot-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/vocabulary.unit.test.d.ts +2 -0
- package/dist/__tests__/vocabulary.unit.test.d.ts.map +1 -0
- package/dist/assets/__tests__/asset-decoders.unit.test.d.ts +2 -0
- package/dist/assets/__tests__/asset-decoders.unit.test.d.ts.map +1 -0
- package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts +2 -0
- package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts.map +1 -0
- package/dist/assets/__tests__/render-asset-port.unit.test.d.ts +2 -0
- package/dist/assets/__tests__/render-asset-port.unit.test.d.ts.map +1 -0
- package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts +2 -0
- package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts.map +1 -0
- package/dist/assets/asset-decoders.d.ts +5 -0
- package/dist/assets/asset-decoders.d.ts.map +1 -0
- package/dist/assets/render-asset-port.d.ts +17 -0
- package/dist/assets/render-asset-port.d.ts.map +1 -0
- package/dist/assets/resolve-render-asset.d.ts +6 -0
- package/dist/assets/resolve-render-asset.d.ts.map +1 -0
- package/dist/authoring.d.ts +12 -0
- package/dist/authoring.d.ts.map +1 -0
- package/dist/authoring.mjs +5 -0
- package/dist/authoring.mjs.map +1 -0
- package/dist/chunk-33UF5SAO.mjs +7397 -0
- package/dist/chunk-33UF5SAO.mjs.map +1 -0
- package/dist/chunk-A5QCJSNL.mjs +29913 -0
- package/dist/chunk-A5QCJSNL.mjs.map +1 -0
- package/dist/chunk-JMSB7AR4.mjs +3 -0
- package/dist/chunk-JMSB7AR4.mjs.map +1 -0
- package/dist/chunk-LXNGO6AO.mjs +569 -0
- package/dist/chunk-LXNGO6AO.mjs.map +1 -0
- package/dist/chunk-QRXPSX4X.mjs +659 -0
- package/dist/chunk-QRXPSX4X.mjs.map +1 -0
- package/dist/chunk-YAKEQPWO.mjs +1439 -0
- package/dist/chunk-YAKEQPWO.mjs.map +1 -0
- package/dist/cluster-binner.d.ts +152 -0
- package/dist/cluster-binner.d.ts.map +1 -0
- package/dist/components/__tests__/atmosphere-red.test.d.ts +2 -0
- package/dist/components/__tests__/atmosphere-red.test.d.ts.map +1 -0
- package/dist/components/__tests__/atmosphere.test.d.ts +2 -0
- package/dist/components/__tests__/atmosphere.test.d.ts.map +1 -0
- package/dist/components/__tests__/fog.test-d.d.ts +2 -0
- package/dist/components/__tests__/fog.test-d.d.ts.map +1 -0
- package/dist/components/__tests__/fog.test.d.ts +2 -0
- package/dist/components/__tests__/fog.test.d.ts.map +1 -0
- package/dist/components/__tests__/schema-parity.unit.test.d.ts +2 -0
- package/dist/components/__tests__/schema-parity.unit.test.d.ts.map +1 -0
- package/dist/components/__tests__/visibility-schema.unit.test.d.ts +2 -0
- package/dist/components/__tests__/visibility-schema.unit.test.d.ts.map +1 -0
- package/dist/components/atmosphere.d.ts +18 -0
- package/dist/components/atmosphere.d.ts.map +1 -0
- package/dist/components/camera.d.ts +311 -0
- package/dist/components/camera.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +76 -0
- package/dist/components/directional-light.d.ts.map +1 -0
- package/dist/components/environment.d.ts +116 -0
- package/dist/components/environment.d.ts.map +1 -0
- package/dist/components/glyph-text.d.ts +26 -0
- package/dist/components/glyph-text.d.ts.map +1 -0
- package/dist/components/index.d.ts +22 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/instances.d.ts +41 -0
- package/dist/components/instances.d.ts.map +1 -0
- package/dist/components/layer.d.ts +34 -0
- package/dist/components/layer.d.ts.map +1 -0
- package/dist/components/light-helpers.d.ts +53 -0
- package/dist/components/light-helpers.d.ts.map +1 -0
- package/dist/components/mesh-filter.d.ts +24 -0
- package/dist/components/mesh-filter.d.ts.map +1 -0
- package/dist/components/mesh-renderer.d.ts +33 -0
- package/dist/components/mesh-renderer.d.ts.map +1 -0
- package/dist/components/point-light-shadow.d.ts +27 -0
- package/dist/components/point-light-shadow.d.ts.map +1 -0
- package/dist/components/point-light.d.ts +35 -0
- package/dist/components/point-light.d.ts.map +1 -0
- package/dist/components/post-process-params.d.ts +5 -0
- package/dist/components/post-process-params.d.ts.map +1 -0
- package/dist/components/scene-instance.d.ts +140 -0
- package/dist/components/scene-instance.d.ts.map +1 -0
- package/dist/components/sort-key.d.ts +44 -0
- package/dist/components/sort-key.d.ts.map +1 -0
- package/dist/components/spot-light.d.ts +81 -0
- package/dist/components/spot-light.d.ts.map +1 -0
- package/dist/components/sprite-animation.d.ts +75 -0
- package/dist/components/sprite-animation.d.ts.map +1 -0
- package/dist/components/sprite-instances.d.ts +51 -0
- package/dist/components/sprite-instances.d.ts.map +1 -0
- package/dist/components/sprite-playback-mode.d.ts +37 -0
- package/dist/components/sprite-playback-mode.d.ts.map +1 -0
- package/dist/components/sprite-region-override.d.ts +47 -0
- package/dist/components/sprite-region-override.d.ts.map +1 -0
- package/dist/components/tile-layer.d.ts +101 -0
- package/dist/components/tile-layer.d.ts.map +1 -0
- package/dist/components/tilemap.d.ts +25 -0
- package/dist/components/tilemap.d.ts.map +1 -0
- package/dist/components/visibility.d.ts +22 -0
- package/dist/components/visibility.d.ts.map +1 -0
- package/dist/construct-renderer.d.ts +2 -0
- package/dist/construct-renderer.d.ts.map +1 -0
- package/dist/construct-renderer.mjs +6 -0
- package/dist/construct-renderer.mjs.map +1 -0
- package/dist/debug-draw-glue.d.ts +56 -0
- package/dist/debug-draw-glue.d.ts.map +1 -0
- package/dist/deferred-lighting.d.ts +13 -0
- package/dist/deferred-lighting.d.ts.map +1 -0
- package/dist/dynamic-texture-store.d.ts +42 -0
- package/dist/dynamic-texture-store.d.ts.map +1 -0
- package/dist/engine-metrics.d.ts +23 -0
- package/dist/engine-metrics.d.ts.map +1 -0
- package/dist/environment/__tests__/failure-injection.test.d.ts +2 -0
- package/dist/environment/__tests__/failure-injection.test.d.ts.map +1 -0
- package/dist/environment/__tests__/generation-red.test.d.ts +2 -0
- package/dist/environment/__tests__/generation-red.test.d.ts.map +1 -0
- package/dist/environment/__tests__/generation.test.d.ts +2 -0
- package/dist/environment/__tests__/generation.test.d.ts.map +1 -0
- package/dist/environment/__tests__/graph-transaction.test.d.ts +2 -0
- package/dist/environment/__tests__/graph-transaction.test.d.ts.map +1 -0
- package/dist/environment/__tests__/inspection-red.test.d.ts +2 -0
- package/dist/environment/__tests__/inspection-red.test.d.ts.map +1 -0
- package/dist/environment/__tests__/lifecycle-evidence.test.d.ts +2 -0
- package/dist/environment/__tests__/lifecycle-evidence.test.d.ts.map +1 -0
- package/dist/environment/__tests__/pipeline-topology.test.d.ts +2 -0
- package/dist/environment/__tests__/pipeline-topology.test.d.ts.map +1 -0
- package/dist/environment/__tests__/readiness.test.d.ts +2 -0
- package/dist/environment/__tests__/readiness.test.d.ts.map +1 -0
- package/dist/environment/__tests__/recovery.test.d.ts +2 -0
- package/dist/environment/__tests__/recovery.test.d.ts.map +1 -0
- package/dist/environment/__tests__/resize-dispose.test.d.ts +2 -0
- package/dist/environment/__tests__/resize-dispose.test.d.ts.map +1 -0
- package/dist/environment/__tests__/signature-red.test.d.ts +2 -0
- package/dist/environment/__tests__/signature-red.test.d.ts.map +1 -0
- package/dist/environment/__tests__/signature.test.d.ts +2 -0
- package/dist/environment/__tests__/signature.test.d.ts.map +1 -0
- package/dist/environment/descriptors.d.ts +2 -0
- package/dist/environment/descriptors.d.ts.map +1 -0
- package/dist/environment/extracted-environment.d.ts +53 -0
- package/dist/environment/extracted-environment.d.ts.map +1 -0
- package/dist/environment/generation.d.ts +62 -0
- package/dist/environment/generation.d.ts.map +1 -0
- package/dist/environment/gpu-bundle.d.ts +23 -0
- package/dist/environment/gpu-bundle.d.ts.map +1 -0
- package/dist/environment/graph.d.ts +108 -0
- package/dist/environment/graph.d.ts.map +1 -0
- package/dist/environment/inspection.d.ts +48 -0
- package/dist/environment/inspection.d.ts.map +1 -0
- package/dist/environment/lifecycle.d.ts +22 -0
- package/dist/environment/lifecycle.d.ts.map +1 -0
- package/dist/environment/readiness.d.ts +29 -0
- package/dist/environment/readiness.d.ts.map +1 -0
- package/dist/environment/signature.d.ts +70 -0
- package/dist/environment/signature.d.ts.map +1 -0
- package/dist/errors/ecs-validation.d.ts +3 -0
- package/dist/errors/ecs-validation.d.ts.map +1 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/recover.d.ts +78 -0
- package/dist/errors/recover.d.ts.map +1 -0
- package/dist/errors/render.d.ts +633 -0
- package/dist/errors/render.d.ts.map +1 -0
- package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts +2 -0
- package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts.map +1 -0
- package/dist/extract/__tests__/environment-source.test.d.ts +2 -0
- package/dist/extract/__tests__/environment-source.test.d.ts.map +1 -0
- package/dist/extract/__tests__/schema-readers.unit.test.d.ts +2 -0
- package/dist/extract/__tests__/schema-readers.unit.test.d.ts.map +1 -0
- package/dist/extract/directional-csm.d.ts +129 -0
- package/dist/extract/directional-csm.d.ts.map +1 -0
- package/dist/extract/index.d.ts +5 -0
- package/dist/extract/index.d.ts.map +1 -0
- package/dist/extract/material-interface.d.ts +56 -0
- package/dist/extract/material-interface.d.ts.map +1 -0
- package/dist/extract/schema-readers.d.ts +20 -0
- package/dist/extract/schema-readers.d.ts.map +1 -0
- package/dist/extract/visibility.d.ts +26 -0
- package/dist/extract/visibility.d.ts.map +1 -0
- package/dist/features/graph-contribution.d.ts +64 -0
- package/dist/features/graph-contribution.d.ts.map +1 -0
- package/dist/features/host.d.ts +100 -0
- package/dist/features/host.d.ts.map +1 -0
- package/dist/features/index.d.ts +21 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/morph/index.d.ts +3 -0
- package/dist/features/morph/index.d.ts.map +1 -0
- package/dist/features/morph/morph-bounds.d.ts +42 -0
- package/dist/features/morph/morph-bounds.d.ts.map +1 -0
- package/dist/features/morph/morph-feature.d.ts +45 -0
- package/dist/features/morph/morph-feature.d.ts.map +1 -0
- package/dist/features/prepared-gpu-work.d.ts +113 -0
- package/dist/features/prepared-gpu-work.d.ts.map +1 -0
- package/dist/features/prepared-graphics-store.d.ts +65 -0
- package/dist/features/prepared-graphics-store.d.ts.map +1 -0
- package/dist/features/prepared-graphics.d.ts +225 -0
- package/dist/features/prepared-graphics.d.ts.map +1 -0
- package/dist/features/render-graph-compute.d.ts +13 -0
- package/dist/features/render-graph-compute.d.ts.map +1 -0
- package/dist/features/render-graph-contribution.d.ts +15 -0
- package/dist/features/render-graph-contribution.d.ts.map +1 -0
- package/dist/features/render-graph-raster.d.ts +34 -0
- package/dist/features/render-graph-raster.d.ts.map +1 -0
- package/dist/features/render-graph-resources.d.ts +11 -0
- package/dist/features/render-graph-resources.d.ts.map +1 -0
- package/dist/features/scene-temporal.d.ts +45 -0
- package/dist/features/scene-temporal.d.ts.map +1 -0
- package/dist/features/taa-resolve.d.ts +21 -0
- package/dist/features/taa-resolve.d.ts.map +1 -0
- package/dist/features/targets.d.ts +32 -0
- package/dist/features/targets.d.ts.map +1 -0
- package/dist/features/types.d.ts +247 -0
- package/dist/features/types.d.ts.map +1 -0
- package/dist/frame-chain.d.ts +14 -0
- package/dist/frame-chain.d.ts.map +1 -0
- package/dist/fullscreen-post-process-pass.d.ts +178 -0
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -0
- package/dist/glyph-text-layout-system.d.ts +18 -0
- package/dist/glyph-text-layout-system.d.ts.map +1 -0
- package/dist/gpu-driven/batch-topology.d.ts +124 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +150 -0
- package/dist/gpu-driven/production-raster.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +141 -0
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -0
- package/dist/gpu-driven/view-reference.d.ts +15 -0
- package/dist/gpu-driven/view-reference.d.ts.map +1 -0
- package/dist/gpu-resource-store.d.ts +294 -0
- package/dist/gpu-resource-store.d.ts.map +1 -0
- package/dist/gpu-resource.d.ts +73 -0
- package/dist/gpu-resource.d.ts.map +1 -0
- package/dist/gpu-scene-schema.d.ts +171 -0
- package/dist/gpu-scene-schema.d.ts.map +1 -0
- package/dist/gpu-scene.d.ts +81 -0
- package/dist/gpu-scene.d.ts.map +1 -0
- package/dist/gpu-stage.d.ts +4 -0
- package/dist/gpu-stage.d.ts.map +1 -0
- package/dist/gpu-texture-usage.d.ts +6 -0
- package/dist/gpu-texture-usage.d.ts.map +1 -0
- package/dist/gpu-usage.d.ts +9 -0
- package/dist/gpu-usage.d.ts.map +1 -0
- package/dist/hdrp-buffers.d.ts +213 -0
- package/dist/hdrp-buffers.d.ts.map +1 -0
- package/dist/hdrp-cluster-membership.d.ts +2 -0
- package/dist/hdrp-cluster-membership.d.ts.map +1 -0
- package/dist/hdrp-pipeline.d.ts +36 -0
- package/dist/hdrp-pipeline.d.ts.map +1 -0
- package/dist/ibl/IblPipelineCache.d.ts +274 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -0
- package/dist/ibl/cubemap-projection.d.ts +23 -0
- package/dist/ibl/cubemap-projection.d.ts.map +1 -0
- package/dist/ibl/face-uniforms.d.ts +65 -0
- package/dist/ibl/face-uniforms.d.ts.map +1 -0
- package/dist/ibl/skylight-bind-group.d.ts +130 -0
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +5 -0
- package/dist/index.mjs.map +1 -0
- package/dist/instance-buffer-cache.d.ts +59 -0
- package/dist/instance-buffer-cache.d.ts.map +1 -0
- package/dist/internal.d.ts +74 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.mjs +45 -0
- package/dist/internal.mjs.map +1 -0
- package/dist/lifecycle.d.ts +28 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/light-buffer-layout.d.ts +164 -0
- package/dist/light-buffer-layout.d.ts.map +1 -0
- package/dist/materials.d.ts +50 -0
- package/dist/materials.d.ts.map +1 -0
- package/dist/mesh-material-bindings.d.ts +44 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -0
- package/dist/mesh-update-errors.d.ts +71 -0
- package/dist/mesh-update-errors.d.ts.map +1 -0
- package/dist/mipmap-generator.d.ts +39 -0
- package/dist/mipmap-generator.d.ts.map +1 -0
- package/dist/param-schema-projection-census.d.ts +18 -0
- package/dist/param-schema-projection-census.d.ts.map +1 -0
- package/dist/pbr-pipeline.d.ts +253 -0
- package/dist/pbr-pipeline.d.ts.map +1 -0
- package/dist/persistent-render-scene.d.ts +158 -0
- package/dist/persistent-render-scene.d.ts.map +1 -0
- package/dist/pipeline/index.d.ts +11 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline-builder.d.ts +122 -0
- package/dist/pipeline-builder.d.ts.map +1 -0
- package/dist/pipeline-errors.d.ts +110 -0
- package/dist/pipeline-errors.d.ts.map +1 -0
- package/dist/pipeline-spec.d.ts +506 -0
- package/dist/pipeline-spec.d.ts.map +1 -0
- package/dist/plugin.d.ts +17 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/post-process-errors.d.ts +182 -0
- package/dist/post-process-errors.d.ts.map +1 -0
- package/dist/prepare/__tests__/schema-readers.unit.test.d.ts +2 -0
- package/dist/prepare/__tests__/schema-readers.unit.test.d.ts.map +1 -0
- package/dist/prepare/index.d.ts +4 -0
- package/dist/prepare/index.d.ts.map +1 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts +62 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -0
- package/dist/prepare/schema-readers.d.ts +11 -0
- package/dist/prepare/schema-readers.d.ts.map +1 -0
- package/dist/record/__tests__/environment-record.test.d.ts +2 -0
- package/dist/record/__tests__/environment-record.test.d.ts.map +1 -0
- package/dist/record/__tests__/frame-targets.unit.test.d.ts +2 -0
- package/dist/record/__tests__/frame-targets.unit.test.d.ts.map +1 -0
- package/dist/record/__tests__/material-bg-cache.unit.test.d.ts +2 -0
- package/dist/record/__tests__/material-bg-cache.unit.test.d.ts.map +1 -0
- package/dist/record/__tests__/material-slot-plan.unit.test.d.ts +2 -0
- package/dist/record/__tests__/material-slot-plan.unit.test.d.ts.map +1 -0
- package/dist/record/__tests__/membership-timing.unit.test.d.ts +2 -0
- package/dist/record/__tests__/membership-timing.unit.test.d.ts.map +1 -0
- package/dist/record/__tests__/render-submission.integration.test.d.ts +2 -0
- package/dist/record/__tests__/render-submission.integration.test.d.ts.map +1 -0
- package/dist/record/__tests__/render-submission.perf.test.d.ts +2 -0
- package/dist/record/__tests__/render-submission.perf.test.d.ts.map +1 -0
- package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts +2 -0
- package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts.map +1 -0
- package/dist/record/__tests__/video-texture-view.unit.test.d.ts +2 -0
- package/dist/record/__tests__/video-texture-view.unit.test.d.ts.map +1 -0
- package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts +2 -0
- package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +187 -0
- package/dist/record/frame-lighting.d.ts.map +1 -0
- package/dist/record/frame-observation.d.ts +38 -0
- package/dist/record/frame-observation.d.ts.map +1 -0
- package/dist/record/frame-snapshot.d.ts +429 -0
- package/dist/record/frame-snapshot.d.ts.map +1 -0
- package/dist/record/frame-targets.d.ts +53 -0
- package/dist/record/frame-targets.d.ts.map +1 -0
- package/dist/record/frame.d.ts +59 -0
- package/dist/record/frame.d.ts.map +1 -0
- package/dist/record/helpers.d.ts +101 -0
- package/dist/record/helpers.d.ts.map +1 -0
- package/dist/record/index.d.ts +15 -0
- package/dist/record/index.d.ts.map +1 -0
- package/dist/record/main-pass-geometry.d.ts +20 -0
- package/dist/record/main-pass-geometry.d.ts.map +1 -0
- package/dist/record/main-pass-material.d.ts +173 -0
- package/dist/record/main-pass-material.d.ts.map +1 -0
- package/dist/record/main-pass-skin.d.ts +46 -0
- package/dist/record/main-pass-skin.d.ts.map +1 -0
- package/dist/record/main-pass-sprite-draws.d.ts +18 -0
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -0
- package/dist/record/main-pass-sprite.d.ts +69 -0
- package/dist/record/main-pass-sprite.d.ts.map +1 -0
- package/dist/record/main-pass.d.ts +20 -0
- package/dist/record/main-pass.d.ts.map +1 -0
- package/dist/record/material-payload.d.ts +43 -0
- package/dist/record/material-payload.d.ts.map +1 -0
- package/dist/record/material-slot-plan.d.ts +26 -0
- package/dist/record/material-slot-plan.d.ts.map +1 -0
- package/dist/record/membership-timing.d.ts +232 -0
- package/dist/record/membership-timing.d.ts.map +1 -0
- package/dist/record/mesh-ssbo.d.ts +173 -0
- package/dist/record/mesh-ssbo.d.ts.map +1 -0
- package/dist/record/shadow-caster-uniform.d.ts +8 -0
- package/dist/record/shadow-caster-uniform.d.ts.map +1 -0
- package/dist/record/shadow-pass.d.ts +125 -0
- package/dist/record/shadow-pass.d.ts.map +1 -0
- package/dist/record/shadow-submit-mode.d.ts +66 -0
- package/dist/record/shadow-submit-mode.d.ts.map +1 -0
- package/dist/record/skybox-post-pass.d.ts +33 -0
- package/dist/record/skybox-post-pass.d.ts.map +1 -0
- package/dist/record/typed-frame-graph.d.ts +13 -0
- package/dist/record/typed-frame-graph.d.ts.map +1 -0
- package/dist/record/view-ubo.d.ts +39 -0
- package/dist/record/view-ubo.d.ts.map +1 -0
- package/dist/render-data.d.ts +143 -0
- package/dist/render-data.d.ts.map +1 -0
- package/dist/render-dispatch-membership.d.ts +47 -0
- package/dist/render-dispatch-membership.d.ts.map +1 -0
- package/dist/render-graph-primitives.d.ts +424 -0
- package/dist/render-graph-primitives.d.ts.map +1 -0
- package/dist/render-pipeline-context.d.ts +289 -0
- package/dist/render-pipeline-context.d.ts.map +1 -0
- package/dist/render-pipeline-target.d.ts +16 -0
- package/dist/render-pipeline-target.d.ts.map +1 -0
- package/dist/render-pipeline.d.ts +149 -0
- package/dist/render-pipeline.d.ts.map +1 -0
- package/dist/render-scene-projection.d.ts +174 -0
- package/dist/render-scene-projection.d.ts.map +1 -0
- package/dist/render-system-extract.d.ts +1096 -0
- package/dist/render-system-extract.d.ts.map +1 -0
- package/dist/render-system-fold.d.ts +266 -0
- package/dist/render-system-fold.d.ts.map +1 -0
- package/dist/render-system.d.ts +814 -0
- package/dist/render-system.d.ts.map +1 -0
- package/dist/renderer/asset-service.d.ts +10 -0
- package/dist/renderer/asset-service.d.ts.map +1 -0
- package/dist/renderer/backend-selection.d.ts +26 -0
- package/dist/renderer/backend-selection.d.ts.map +1 -0
- package/dist/renderer/environment-classify.d.ts +6 -0
- package/dist/renderer/environment-classify.d.ts.map +1 -0
- package/dist/renderer/environment-error.d.ts +13 -0
- package/dist/renderer/environment-error.d.ts.map +1 -0
- package/dist/renderer/material/assembly.d.ts +22 -0
- package/dist/renderer/material/assembly.d.ts.map +1 -0
- package/dist/renderer/material/pipeline-projection.d.ts +91 -0
- package/dist/renderer/material/pipeline-projection.d.ts.map +1 -0
- package/dist/renderer/renderer-factory.d.ts +283 -0
- package/dist/renderer/renderer-factory.d.ts.map +1 -0
- package/dist/renderer.d.ts +771 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/scene-instances/post-spawn-resolve-joints.d.ts +33 -0
- package/dist/scene-instances/post-spawn-resolve-joints.d.ts.map +1 -0
- package/dist/scene-utils/collect-subtree.d.ts +11 -0
- package/dist/scene-utils/collect-subtree.d.ts.map +1 -0
- package/dist/shadow-atlas.d.ts +117 -0
- package/dist/shadow-atlas.d.ts.map +1 -0
- package/dist/ssao-buffers.d.ts +31 -0
- package/dist/ssao-buffers.d.ts.map +1 -0
- package/dist/ssao-config.d.ts +28 -0
- package/dist/ssao-config.d.ts.map +1 -0
- package/dist/ssao-data.d.ts +34 -0
- package/dist/ssao-data.d.ts.map +1 -0
- package/dist/surface-format.d.ts +10 -0
- package/dist/surface-format.d.ts.map +1 -0
- package/dist/systems/active-camera.d.ts +53 -0
- package/dist/systems/active-camera.d.ts.map +1 -0
- package/dist/systems/pass-selector.d.ts +24 -0
- package/dist/systems/pass-selector.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +51 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -0
- package/dist/systems/transparent-sort-config.d.ts +91 -0
- package/dist/systems/transparent-sort-config.d.ts.map +1 -0
- package/dist/taa-history-store.d.ts +88 -0
- package/dist/taa-history-store.d.ts.map +1 -0
- package/dist/temporal-coverage.d.ts +35 -0
- package/dist/temporal-coverage.d.ts.map +1 -0
- package/dist/temporal-frame-transaction.d.ts +92 -0
- package/dist/temporal-frame-transaction.d.ts.map +1 -0
- package/dist/temporal-inspection.d.ts +57 -0
- package/dist/temporal-inspection.d.ts.map +1 -0
- package/dist/temporal-view.d.ts +43 -0
- package/dist/temporal-view.d.ts.map +1 -0
- package/dist/tilemap/resolve-tileset-runtime.d.ts +23 -0
- package/dist/tilemap/resolve-tileset-runtime.d.ts.map +1 -0
- package/dist/tilemap-chunk-extract-system.d.ts +142 -0
- package/dist/tilemap-chunk-extract-system.d.ts.map +1 -0
- package/dist/typed-render-graph-primitives.d.ts +59 -0
- package/dist/typed-render-graph-primitives.d.ts.map +1 -0
- package/dist/typed-shadow-passes.d.ts +11 -0
- package/dist/typed-shadow-passes.d.ts.map +1 -0
- package/dist/urp-pipeline.d.ts +4 -0
- package/dist/urp-pipeline.d.ts.map +1 -0
- package/package.json +94 -0
- package/src/__tests__/analytic-sky-contract.test.ts +27 -0
- package/src/__tests__/analytic-sky-falsify-carriers.mjs +43 -0
- package/src/__tests__/analytic-sky-falsify.test.ts +94 -0
- package/src/__tests__/assets-runtime-handoff.integration.test.ts +36 -0
- package/src/__tests__/authoring-path.unit.test.ts +14 -0
- package/src/__tests__/backend-selection-rhi-capture.test-d.ts +21 -0
- package/src/__tests__/backend-selection.integration.test.ts +11 -0
- package/src/__tests__/callback-inference.test-d.ts +5 -0
- package/src/__tests__/camera-temporal.test-d.ts +8 -0
- package/src/__tests__/camera-temporal.test.ts +188 -0
- package/src/__tests__/cluster-binner.test.ts +272 -0
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +17 -0
- package/src/__tests__/construct-renderer-identity.unit.test.ts +10 -0
- package/src/__tests__/direct-extract-consumer-contract.test-d.ts +34 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +71 -0
- package/src/__tests__/directional-shadow-probe-atlas-layout.unit.test.ts +18 -0
- package/src/__tests__/environment-inspection.test.ts +45 -0
- package/src/__tests__/factory-contract.integration.test.ts +331 -0
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +18 -0
- package/src/__tests__/fog-ai-user.fixture.ts +350 -0
- package/src/__tests__/fog-custom-render-feature.fixture.ts +33 -0
- package/src/__tests__/fog-custom-render-feature.integration.test.ts +76 -0
- package/src/__tests__/fog-inspection.integration.test.ts +127 -0
- package/src/__tests__/fog-owner-state.integration.test.ts +112 -0
- package/src/__tests__/fog-pipeline-topology.integration.test.ts +93 -0
- package/src/__tests__/fog-public-surface.integration.test.ts +60 -0
- package/src/__tests__/fog-ray-contract.integration.test.ts +73 -0
- package/src/__tests__/fog-source-absence.integration.test.ts +51 -0
- package/src/__tests__/fog-temporal.integration.test.ts +115 -0
- package/src/__tests__/frame-chain.unit.test.ts +26 -0
- package/src/__tests__/frame-observation.contract.test.ts +103 -0
- package/src/__tests__/glyph-text-layout-recovery.unit.test.ts +172 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +347 -0
- package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +12 -0
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +16 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +609 -0
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +90 -0
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +192 -0
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +128 -0
- package/src/__tests__/gpu-driven-view.browser.test.ts +19 -0
- package/src/__tests__/gpu-driven-view.dawn.test.ts +17 -0
- package/src/__tests__/gpu-driven-view.unit.test.ts +455 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +59 -0
- package/src/__tests__/gpu-scene-field-type-owner.test-d.ts +27 -0
- package/src/__tests__/gpu-scene-render-graph-gpu.ts +309 -0
- package/src/__tests__/gpu-scene-render-graph.browser.test.ts +19 -0
- package/src/__tests__/gpu-scene-render-graph.dawn.test.ts +19 -0
- package/src/__tests__/gpu-scene-schema.unit.test.ts +16 -0
- package/src/__tests__/gpu-scene.dawn.test.ts +209 -0
- package/src/__tests__/gpu-scene.unit.test.ts +161 -0
- package/src/__tests__/hdrp-pipeline.unit.test.ts +100 -0
- package/src/__tests__/ibl/ibl-fallback.unit.test.ts +23 -0
- package/src/__tests__/infinite-grid-no-vertex-probe.unit.test.ts +124 -0
- package/src/__tests__/injection-kind-owner.test-d.ts +14 -0
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +719 -0
- package/src/__tests__/light-buffer-layout.unit.test.ts +85 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +24 -0
- package/src/__tests__/material-cooked-projection.unit.test.ts +177 -0
- package/src/__tests__/material-derived-error-stop-draw.integration.test.ts +69 -0
- package/src/__tests__/material-derived-payload.integration.test.ts +164 -0
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +58 -0
- package/src/__tests__/material-static-dynamic-route.unit.test.ts +113 -0
- package/src/__tests__/material-stride-surface.unit.test.ts +32 -0
- package/src/__tests__/materials.unit.test.ts +25 -0
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +107 -0
- package/src/__tests__/mesh-material-bindings.unit.test.ts +89 -0
- package/src/__tests__/mesh-stride-surface.unit.test.ts +16 -0
- package/src/__tests__/morph-culling-reentry.dawn.test.ts +166 -0
- package/src/__tests__/morph-feature-gpu-work.integration.test.ts +78 -0
- package/src/__tests__/morph-visual-evidence.integration.test.ts +66 -0
- package/src/__tests__/nineslice-handle-surface.unit.test.ts +14 -0
- package/src/__tests__/param-schema-projection-census.unit.test.ts +40 -0
- package/src/__tests__/persistent-render-scene.unit.test.ts +1311 -0
- package/src/__tests__/pipeline-error-policy-owner.unit.test.ts +167 -0
- package/src/__tests__/pipeline-pass-trace.test.ts +92 -0
- package/src/__tests__/pipeline-stage-owner.test-d.ts +13 -0
- package/src/__tests__/plugin.test.ts +25 -0
- package/src/__tests__/post-process-error-policy-owner.unit.test.ts +208 -0
- package/src/__tests__/prepared-buffer-kind-owner.test-d.ts +29 -0
- package/src/__tests__/prepared-graphics-backend-matrix.unit.test.ts +129 -0
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +140 -0
- package/src/__tests__/prepared-graphics-generation.unit.test.ts +175 -0
- package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +206 -0
- package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +29 -0
- package/src/__tests__/prepared-graphics-resolver-recording.unit.test.ts +180 -0
- package/src/__tests__/prepared-graphics-resolver.unit.test.ts +287 -0
- package/src/__tests__/prepared-graphics-snapshot.unit.test.ts +105 -0
- package/src/__tests__/prepared-graphics-store.unit.test.ts +154 -0
- package/src/__tests__/prepared-graphics-validation.unit.test.ts +176 -0
- package/src/__tests__/profiler-default-off.test.ts +22 -0
- package/src/__tests__/profiler-phase-catalog.test.ts +66 -0
- package/src/__tests__/profiler-phase-integration.test.ts +70 -0
- package/src/__tests__/profiler-phase-token.test.ts +84 -0
- package/src/__tests__/public-pipeline-id.test-d.ts +6 -0
- package/src/__tests__/public-surface.test-d.ts +32 -0
- package/src/__tests__/recover-error-policy-owner.unit.test.ts +127 -0
- package/src/__tests__/render-dispatch-membership.unit.test.ts +117 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +115 -0
- package/src/__tests__/render-error-detail-ssot.test-d.ts +234 -0
- package/src/__tests__/render-error-exhaustive.test-d.ts +84 -0
- package/src/__tests__/render-feature-assembly.test-d.ts +51 -0
- package/src/__tests__/render-feature-construction.unit.test.ts +124 -0
- package/src/__tests__/render-feature-context.test-d.ts +81 -0
- package/src/__tests__/render-feature-contract.test-d.ts +58 -0
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +151 -0
- package/src/__tests__/render-feature-docs.unit.test.ts +88 -0
- package/src/__tests__/render-feature-error-code-owner.test-d.ts +27 -0
- package/src/__tests__/render-feature-errors.unit.test.ts +47 -0
- package/src/__tests__/render-feature-gpu-buffer-usage-owner.test-d.ts +46 -0
- package/src/__tests__/render-feature-gpu-work.integration.test.ts +377 -0
- package/src/__tests__/render-feature-graph.integration.test.ts +205 -0
- package/src/__tests__/render-feature-graphics-staging.unit.test.ts +200 -0
- package/src/__tests__/render-feature-order.unit.test.ts +66 -0
- package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +101 -0
- package/src/__tests__/render-feature-prepared-errors.test-d.ts +82 -0
- package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +141 -0
- package/src/__tests__/render-feature-prepared-graphics-isolation.unit.test.ts +122 -0
- package/src/__tests__/render-feature-prepared-graphics-negative.test-d.ts +59 -0
- package/src/__tests__/render-feature-prepared-graphics-recording.unit.test.ts +107 -0
- package/src/__tests__/render-feature-prepared-graphics.test-d.ts +96 -0
- package/src/__tests__/render-feature-prepared-graphics.unit.test.ts +121 -0
- package/src/__tests__/render-feature-public-surface.test-d.ts +75 -0
- package/src/__tests__/render-feature-retry.unit.test.ts +128 -0
- package/src/__tests__/render-feature-scheduling.unit.test.ts +122 -0
- package/src/__tests__/render-feature-stage-failed-policy-owner.unit.test.ts +146 -0
- package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +236 -0
- package/src/__tests__/render-feature-staging.unit.test.ts +94 -0
- package/src/__tests__/render-feature-visibility-context.test-d.ts +38 -0
- package/src/__tests__/render-feature-visibility-context.unit.test.ts +38 -0
- package/src/__tests__/render-feature-zero-work.unit.test.ts +82 -0
- package/src/__tests__/render-graph-compute-raster-gpu.ts +342 -0
- package/src/__tests__/render-graph-compute-raster.browser.test.ts +16 -0
- package/src/__tests__/render-graph-compute-raster.dawn.test.ts +22 -0
- package/src/__tests__/render-graph-hzb-gpu.ts +239 -0
- package/src/__tests__/render-graph-hzb.browser.test.ts +16 -0
- package/src/__tests__/render-graph-hzb.dawn.test.ts +23 -0
- package/src/__tests__/render-graph-primitives.unit.test.ts +22 -0
- package/src/__tests__/render-graph-storage-indirect-gpu.ts +162 -0
- package/src/__tests__/render-graph-storage-indirect.browser.test.ts +21 -0
- package/src/__tests__/render-graph-storage-indirect.dawn.test.ts +28 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +206 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +125 -0
- package/src/__tests__/renderer-lifecycle.integration.test.ts +10 -0
- package/src/__tests__/renderer-render-scene-public.test-d.ts +27 -0
- package/src/__tests__/rhi-backend-package-boundary.unit.test.ts +11 -0
- package/src/__tests__/scene-temporal-coverage.unit.test.ts +259 -0
- package/src/__tests__/scriptable-pack-consumer.test-d.ts +14 -0
- package/src/__tests__/shader-stage-surface.unit.test.ts +38 -0
- package/src/__tests__/ssao-kernel-surface.unit.test.ts +15 -0
- package/src/__tests__/sun-snapshot-consumers.test.ts +35 -0
- package/src/__tests__/surface-backend-kind-owner.test-d.ts +42 -0
- package/src/__tests__/surface-configuration.unit.test.ts +92 -0
- package/src/__tests__/taa-history-store.unit.test.ts +196 -0
- package/src/__tests__/temporal-frame-transaction.integration.test.ts +537 -0
- package/src/__tests__/temporal-inspection.unit.test.ts +138 -0
- package/src/__tests__/texture-usage-surface.unit.test.ts +61 -0
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +389 -0
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +52 -0
- package/src/__tests__/urp-pipeline.unit.test.ts +14 -0
- package/src/__tests__/vertex-color-pipeline.unit.test.ts +124 -0
- package/src/__tests__/vertex-layout-consumer.unit.test.ts +25 -0
- package/src/__tests__/visibility-diagnostics.integration.test.ts +66 -0
- package/src/__tests__/visibility-extract.integration.test.ts +89 -0
- package/src/__tests__/visibility-extract.perf.test.ts +96 -0
- package/src/__tests__/visibility-feature-dedup.integration.test.ts +57 -0
- package/src/__tests__/visibility-hidden-report.unit.test.ts +37 -0
- package/src/__tests__/visibility-instances.integration.test.ts +50 -0
- package/src/__tests__/visibility-multi-world.integration.test.ts +54 -0
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +191 -0
- package/src/__tests__/visibility-producer-matrix.unit.test.ts +96 -0
- package/src/__tests__/visibility-public-surface.test-d.ts +26 -0
- package/src/__tests__/visibility-resolver.unit.test.ts +84 -0
- package/src/__tests__/visibility-snapshot-contract.unit.test.ts +59 -0
- package/src/__tests__/vocabulary.unit.test.ts +21 -0
- package/src/assets/__tests__/asset-decoders.unit.test.ts +92 -0
- package/src/assets/__tests__/mipmap-generator.unit.test.ts +52 -0
- package/src/assets/__tests__/render-asset-port.unit.test.ts +54 -0
- package/src/assets/__tests__/resolve-render-asset.unit.test.ts +47 -0
- package/src/assets/asset-decoders.ts +158 -0
- package/src/assets/render-asset-port.ts +44 -0
- package/src/assets/resolve-render-asset.ts +13 -0
- package/src/authoring.ts +24 -0
- package/src/cluster-binner.ts +700 -0
- package/src/components/__tests__/atmosphere-red.test.ts +51 -0
- package/src/components/__tests__/atmosphere.test.ts +79 -0
- package/src/components/__tests__/fog.test-d.ts +49 -0
- package/src/components/__tests__/fog.test.ts +60 -0
- package/src/components/__tests__/schema-parity.unit.test.ts +25 -0
- package/src/components/__tests__/visibility-schema.unit.test.ts +35 -0
- package/src/components/atmosphere.ts +64 -0
- package/src/components/camera.ts +512 -0
- package/src/components/directional-light.ts +120 -0
- package/src/components/environment.ts +206 -0
- package/src/components/glyph-text.ts +63 -0
- package/src/components/index.ts +49 -0
- package/src/components/instances.ts +207 -0
- package/src/components/layer.ts +69 -0
- package/src/components/light-helpers.ts +188 -0
- package/src/components/mesh-filter.ts +59 -0
- package/src/components/mesh-renderer.ts +61 -0
- package/src/components/point-light-shadow.ts +43 -0
- package/src/components/point-light.ts +65 -0
- package/src/components/post-process-params.ts +35 -0
- package/src/components/scene-instance.ts +193 -0
- package/src/components/sort-key.ts +75 -0
- package/src/components/spot-light.ts +124 -0
- package/src/components/sprite-animation.ts +169 -0
- package/src/components/sprite-instances.ts +179 -0
- package/src/components/sprite-playback-mode.ts +73 -0
- package/src/components/sprite-region-override.ts +106 -0
- package/src/components/tile-layer.ts +161 -0
- package/src/components/tilemap.ts +48 -0
- package/src/components/visibility.ts +53 -0
- package/src/construct-renderer.ts +4 -0
- package/src/debug-draw-glue.ts +169 -0
- package/src/deferred-lighting.ts +92 -0
- package/src/dynamic-texture-store.ts +111 -0
- package/src/engine-metrics.ts +89 -0
- package/src/environment/README.md +76 -0
- package/src/environment/__tests__/failure-injection.test.ts +50 -0
- package/src/environment/__tests__/generation-red.test.ts +64 -0
- package/src/environment/__tests__/generation.test.ts +37 -0
- package/src/environment/__tests__/graph-transaction.test.ts +85 -0
- package/src/environment/__tests__/inspection-red.test.ts +53 -0
- package/src/environment/__tests__/lifecycle-evidence.test.ts +40 -0
- package/src/environment/__tests__/pipeline-topology.test.ts +33 -0
- package/src/environment/__tests__/readiness.test.ts +42 -0
- package/src/environment/__tests__/recovery.test.ts +62 -0
- package/src/environment/__tests__/resize-dispose.test.ts +30 -0
- package/src/environment/__tests__/signature-red.test.ts +45 -0
- package/src/environment/__tests__/signature.test.ts +60 -0
- package/src/environment/descriptors.ts +7 -0
- package/src/environment/extracted-environment.ts +239 -0
- package/src/environment/generation.ts +158 -0
- package/src/environment/gpu-bundle.ts +144 -0
- package/src/environment/graph.ts +588 -0
- package/src/environment/inspection.ts +107 -0
- package/src/environment/lifecycle.ts +124 -0
- package/src/environment/readiness.ts +76 -0
- package/src/environment/signature.ts +185 -0
- package/src/errors/ecs-validation.ts +16 -0
- package/src/errors/index.ts +3 -0
- package/src/errors/recover.ts +119 -0
- package/src/errors/render.ts +1244 -0
- package/src/extract/__tests__/directional-csm-domain.unit.test.ts +391 -0
- package/src/extract/__tests__/environment-source.test.ts +105 -0
- package/src/extract/__tests__/schema-readers.unit.test.ts +16 -0
- package/src/extract/directional-csm.ts +959 -0
- package/src/extract/index.ts +10 -0
- package/src/extract/material-interface.ts +604 -0
- package/src/extract/schema-readers.ts +27 -0
- package/src/extract/visibility.ts +120 -0
- package/src/features/graph-contribution.ts +577 -0
- package/src/features/host.ts +1097 -0
- package/src/features/index.ts +100 -0
- package/src/features/morph/index.ts +24 -0
- package/src/features/morph/morph-bounds.ts +123 -0
- package/src/features/morph/morph-feature.ts +287 -0
- package/src/features/prepared-gpu-work.ts +902 -0
- package/src/features/prepared-graphics-store.ts +435 -0
- package/src/features/prepared-graphics.ts +479 -0
- package/src/features/render-graph-compute.ts +60 -0
- package/src/features/render-graph-contribution.ts +95 -0
- package/src/features/render-graph-raster.ts +308 -0
- package/src/features/render-graph-resources.ts +36 -0
- package/src/features/scene-temporal.ts +274 -0
- package/src/features/taa-resolve.ts +244 -0
- package/src/features/targets.ts +83 -0
- package/src/features/types.ts +291 -0
- package/src/frame-chain.ts +21 -0
- package/src/fullscreen-post-process-pass.ts +406 -0
- package/src/glyph-text-layout-system.ts +447 -0
- package/src/gpu-driven/batch-topology.ts +423 -0
- package/src/gpu-driven/production-raster.ts +1705 -0
- package/src/gpu-driven/view-gpu.ts +849 -0
- package/src/gpu-driven/view-reference.ts +110 -0
- package/src/gpu-resource-store.ts +1921 -0
- package/src/gpu-resource.ts +159 -0
- package/src/gpu-scene-schema.ts +224 -0
- package/src/gpu-scene.ts +855 -0
- package/src/gpu-stage.ts +9 -0
- package/src/gpu-texture-usage.ts +12 -0
- package/src/gpu-usage.ts +14 -0
- package/src/hdrp-buffers.ts +689 -0
- package/src/hdrp-cluster-membership.ts +70 -0
- package/src/hdrp-pipeline.ts +525 -0
- package/src/ibl/IblPipelineCache.ts +1246 -0
- package/src/ibl/cubemap-projection.ts +60 -0
- package/src/ibl/face-uniforms.ts +150 -0
- package/src/ibl/skylight-bind-group.ts +513 -0
- package/src/index.ts +271 -0
- package/src/instance-buffer-cache.ts +123 -0
- package/src/internal.ts +88 -0
- package/src/lifecycle.ts +123 -0
- package/src/light-buffer-layout.ts +346 -0
- package/src/materials.ts +236 -0
- package/src/mesh-material-bindings.ts +104 -0
- package/src/mesh-update-errors.ts +113 -0
- package/src/mipmap-generator.ts +244 -0
- package/src/param-schema-projection-census.ts +73 -0
- package/src/pbr-pipeline.ts +749 -0
- package/src/persistent-render-scene.ts +1752 -0
- package/src/pipeline/index.ts +40 -0
- package/src/pipeline-builder.ts +386 -0
- package/src/pipeline-errors.ts +172 -0
- package/src/pipeline-spec.ts +1768 -0
- package/src/plugin.ts +137 -0
- package/src/post-process-errors.ts +304 -0
- package/src/prepare/__tests__/schema-readers.unit.test.ts +16 -0
- package/src/prepare/index.ts +8 -0
- package/src/prepare/prepared-graphics-resolver.ts +455 -0
- package/src/prepare/schema-readers.ts +20 -0
- package/src/record/__tests__/environment-record.test.ts +35 -0
- package/src/record/__tests__/frame-targets.unit.test.ts +54 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +41 -0
- package/src/record/__tests__/material-slot-plan.unit.test.ts +76 -0
- package/src/record/__tests__/membership-timing.unit.test.ts +524 -0
- package/src/record/__tests__/render-submission.integration.test.ts +76 -0
- package/src/record/__tests__/render-submission.perf.test.ts +141 -0
- package/src/record/__tests__/shadow-submit-mode.unit.test.ts +88 -0
- package/src/record/__tests__/video-texture-view.unit.test.ts +90 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +101 -0
- package/src/record/frame-lighting.ts +1183 -0
- package/src/record/frame-observation.ts +122 -0
- package/src/record/frame-snapshot.ts +515 -0
- package/src/record/frame-targets.ts +372 -0
- package/src/record/frame.ts +1874 -0
- package/src/record/helpers.ts +289 -0
- package/src/record/index.ts +15 -0
- package/src/record/main-pass-geometry.ts +1014 -0
- package/src/record/main-pass-material.ts +716 -0
- package/src/record/main-pass-skin.ts +51 -0
- package/src/record/main-pass-sprite-draws.ts +1056 -0
- package/src/record/main-pass-sprite.ts +166 -0
- package/src/record/main-pass.ts +588 -0
- package/src/record/material-payload.ts +292 -0
- package/src/record/material-slot-plan.ts +68 -0
- package/src/record/membership-timing.ts +1012 -0
- package/src/record/mesh-ssbo.ts +406 -0
- package/src/record/shadow-caster-uniform.ts +37 -0
- package/src/record/shadow-pass.ts +2387 -0
- package/src/record/shadow-submit-mode.ts +277 -0
- package/src/record/skybox-post-pass.ts +594 -0
- package/src/record/typed-frame-graph.ts +499 -0
- package/src/record/view-ubo.ts +206 -0
- package/src/render-data.ts +385 -0
- package/src/render-dispatch-membership.ts +155 -0
- package/src/render-graph-primitives.ts +1586 -0
- package/src/render-pipeline-context.ts +332 -0
- package/src/render-pipeline-target.ts +96 -0
- package/src/render-pipeline.ts +343 -0
- package/src/render-scene-projection.ts +1738 -0
- package/src/render-system-extract.ts +5203 -0
- package/src/render-system-fold.ts +531 -0
- package/src/render-system.ts +3258 -0
- package/src/renderer/asset-service.ts +32 -0
- package/src/renderer/backend-selection.ts +121 -0
- package/src/renderer/environment-classify.ts +30 -0
- package/src/renderer/environment-error.ts +19 -0
- package/src/renderer/material/assembly.ts +53 -0
- package/src/renderer/material/pipeline-projection.ts +140 -0
- package/src/renderer/renderer-factory.ts +9062 -0
- package/src/renderer.ts +940 -0
- package/src/scene-instances/post-spawn-resolve-joints.ts +168 -0
- package/src/scene-utils/collect-subtree.ts +40 -0
- package/src/shadow-atlas.ts +244 -0
- package/src/ssao-buffers.ts +175 -0
- package/src/ssao-config.ts +61 -0
- package/src/ssao-data.ts +106 -0
- package/src/surface-format.ts +37 -0
- package/src/systems/active-camera.ts +116 -0
- package/src/systems/pass-selector.ts +49 -0
- package/src/systems/skin-palette-allocator.ts +294 -0
- package/src/systems/transparent-sort-config.ts +211 -0
- package/src/taa-history-store.ts +429 -0
- package/src/temporal-coverage.ts +106 -0
- package/src/temporal-frame-transaction.ts +301 -0
- package/src/temporal-inspection.ts +194 -0
- package/src/temporal-view.ts +174 -0
- package/src/tilemap/resolve-tileset-runtime.ts +72 -0
- package/src/tilemap-chunk-extract-system.ts +1307 -0
- package/src/typed-render-graph-primitives.ts +530 -0
- package/src/typed-shadow-passes.ts +195 -0
- package/src/urp-pipeline.ts +340 -0
|
@@ -0,0 +1,1586 @@
|
|
|
1
|
+
// @forgeax/engine-runtime - public render-graph primitives
|
|
2
|
+
// (feat-20260604-resource-owning-render-graph-and-fullscreen-postpr M3 / w19).
|
|
3
|
+
//
|
|
4
|
+
// These factory functions are the AI-user-facing public vocabulary for assembling
|
|
5
|
+
// a render pipeline's per-frame graph. The urp pipeline (the engine
|
|
6
|
+
// builtin) and any custom pipeline use the SAME functions — the dogfood proof
|
|
7
|
+
// (AC-12 / AC-18). The internal recordXxxPass closures that do the actual GPU
|
|
8
|
+
// recording are package-private (no longer exported from
|
|
9
|
+
// `render-system-record.ts`); they are referenced here as the implementation
|
|
10
|
+
// detail of addScenePass / addFullscreenPass etc., satisfying plan-strategy D-5
|
|
11
|
+
// "per-entity logic stays as the addScenePass implementation detail; do NOT
|
|
12
|
+
// migrate it into the render-graph package (that would pollute its RHI-pure
|
|
13
|
+
// boundary)".
|
|
14
|
+
//
|
|
15
|
+
// API surface (the only nouns/verbs a pipeline author touches):
|
|
16
|
+
// - addColorTarget(name, desc) — allocate a graph-owned RT (M1)
|
|
17
|
+
// - addColorTargetAlias(name, src) — fold a logical key onto an existing RT
|
|
18
|
+
// - addScenePass(g, name, opts) — render the ECS scene into a colour target
|
|
19
|
+
// - addShadowPass(g, name, opts) — render shadow casters into a depth target
|
|
20
|
+
// - addSkyboxPass(g, name, opts) — render the skybox cube into a colour target
|
|
21
|
+
// - addBloomPasses(g, opts) — bloom bright + 2 blur + composite chain
|
|
22
|
+
// - addSsaoPasses(g, opts) — SSAO calc + blur chain (feat-20260612-hdrp-ssao)
|
|
23
|
+
// - addTonemapPass(g, name, opts) — HDR -> LDR tonemap
|
|
24
|
+
// - addFullscreenPass(g, name, opts) — generic fullscreen post-process
|
|
25
|
+
//
|
|
26
|
+
// PIPELINE ROLE: urp-pipeline.buildGraph composes these in the
|
|
27
|
+
// canonical 9-pass order; a custom pipeline picks any subset / order.
|
|
28
|
+
//
|
|
29
|
+
// ─── EXTENSION-POINT MAP (F-5 doc-clarify) ───────────────────────────────
|
|
30
|
+
//
|
|
31
|
+
// Of the eight primitives above, EXACTLY ONE is an AI-user extension point;
|
|
32
|
+
// the other seven are engine-built-ins that DO NOT accept user-supplied
|
|
33
|
+
// execute closures.
|
|
34
|
+
//
|
|
35
|
+
// addScenePass | engine-built-in | execute = recordMainPass (private)
|
|
36
|
+
// addShadowPass | engine-built-in | execute = recordShadowPass (private)
|
|
37
|
+
// addSkyboxPass | engine-built-in | execute = recordSkyboxPass (private)
|
|
38
|
+
// addBloomPasses | engine-built-in | execute = 4× private record* closures
|
|
39
|
+
// addSsaoPasses | engine-built-in | execute = 2× private record* closures
|
|
40
|
+
// addTonemapPass | engine-built-in | execute = dispatchFullscreenPass('forgeax::tonemap')
|
|
41
|
+
// addColorTarget | engine-built-in (resource decl)
|
|
42
|
+
// addColorTargetAlias | engine-built-in (resource decl)
|
|
43
|
+
// addFullscreenPass | EXTENSION POINT (the only one)
|
|
44
|
+
//
|
|
45
|
+
// AI users wanting to add a CUSTOM SCENE pass (a per-entity geometry walk
|
|
46
|
+
// with their own shading model) write `graph.addPass(name, {reads, writes,
|
|
47
|
+
// execute: theirOwnClosure})` directly through the `@forgeax/engine-render-graph`
|
|
48
|
+
// `RenderGraph` API. addScenePass is intentionally NOT a customisation
|
|
49
|
+
// hook — it is the engine's urp main pass, full stop.
|
|
50
|
+
//
|
|
51
|
+
// AI users wanting to add a FULLSCREEN POST-PROCESS pass (e.g. a custom
|
|
52
|
+
// vignette, chromatic aberration, color grading LUT) take the two-step
|
|
53
|
+
// extension idiom:
|
|
54
|
+
//
|
|
55
|
+
// // 1. Register the shader's WGSL source under a unique id (engine
|
|
56
|
+
// // builtins use `forgeax::` prefix; AI users use `<package>::<id>`).
|
|
57
|
+
// // Same-id re-register THROWS (programmer error, fail-fast).
|
|
58
|
+
// renderer.postProcess.register('mypkg::vignette', {
|
|
59
|
+
// source: vignetteWGSL, // composed WGSL fragment stage
|
|
60
|
+
// params: { byteSize: 16, defaultValue: ... }, // optional UBO
|
|
61
|
+
// reads: ['hdrComposited'], // optional graph resource keys
|
|
62
|
+
// });
|
|
63
|
+
//
|
|
64
|
+
// // 2. Reference the registered id from a custom pipeline's buildGraph.
|
|
65
|
+
// // The dispatcher looks the id up via runtime.lookupPostProcess;
|
|
66
|
+
// // a stale id THROWS PostProcessError{code:'post-process-not-found'}
|
|
67
|
+
// // inside the per-frame execute closure (charter P3 fail-fast).
|
|
68
|
+
// addFullscreenPass(graph, 'vignette', {
|
|
69
|
+
// program: { module: 'mypkg::vignette' },
|
|
70
|
+
// color: 'rt', // graph-owned scratch target
|
|
71
|
+
// reads: ['hdrComposited'],
|
|
72
|
+
// });
|
|
73
|
+
//
|
|
74
|
+
// The `'fxaa'` id is the engine-built-in special case: dispatcher delegates
|
|
75
|
+
// to `recordFxaaPass`, which samples graph-owned LDR and writes the surface.
|
|
76
|
+
// `addFullscreenPass(g, 'fxaa', ...)` is the
|
|
77
|
+
// canonical engine call site (used by urp-pipeline.buildGraph),
|
|
78
|
+
// not an AI user customisation lever.
|
|
79
|
+
|
|
80
|
+
import { mat4 } from '@forgeax/engine-math';
|
|
81
|
+
import type { RenderGraph, ResolveContext } from '@forgeax/engine-render-graph';
|
|
82
|
+
import {
|
|
83
|
+
type Buffer,
|
|
84
|
+
RhiError,
|
|
85
|
+
type RhiRenderPassEncoder,
|
|
86
|
+
type Sampler,
|
|
87
|
+
type TextureView,
|
|
88
|
+
} from '@forgeax/engine-rhi';
|
|
89
|
+
import type { PassSelector } from '@forgeax/engine-types';
|
|
90
|
+
import {
|
|
91
|
+
buildFullscreenPostProcessPass,
|
|
92
|
+
createFullscreenBindGroup,
|
|
93
|
+
entryHasDepthRead,
|
|
94
|
+
} from './fullscreen-post-process-pass';
|
|
95
|
+
import { getOrCreateSsaoFallbackTexture } from './hdrp-buffers';
|
|
96
|
+
import { buildBeginRenderPassDescriptor } from './pipeline-spec';
|
|
97
|
+
import { PostProcessError } from './post-process-errors';
|
|
98
|
+
import {
|
|
99
|
+
computeProjectionMatrix,
|
|
100
|
+
computeViewMatrix,
|
|
101
|
+
getOrCreateFromChain,
|
|
102
|
+
recordBloomBlurHPass,
|
|
103
|
+
recordBloomBlurVPass,
|
|
104
|
+
recordBloomBrightPass,
|
|
105
|
+
recordBloomCompositePass,
|
|
106
|
+
recordFxaaPass,
|
|
107
|
+
recordMainPass,
|
|
108
|
+
recordPointShadowPass,
|
|
109
|
+
recordShadowPass,
|
|
110
|
+
recordSkyboxPass,
|
|
111
|
+
recordSpotShadowPass,
|
|
112
|
+
} from './record';
|
|
113
|
+
import type {
|
|
114
|
+
_InternalRenderPipelineContext,
|
|
115
|
+
RenderPipelineContext,
|
|
116
|
+
} from './render-pipeline-context';
|
|
117
|
+
import { getOrCreateSsaoBuffers } from './ssao-buffers';
|
|
118
|
+
import {
|
|
119
|
+
getSsaoParameters,
|
|
120
|
+
type ResolvedSsaoParameters,
|
|
121
|
+
resolveSsaoParameters,
|
|
122
|
+
} from './ssao-config';
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Selects which passes of a material asset are rendered by addScenePass / addShadowPass.
|
|
126
|
+
*
|
|
127
|
+
* An empty selector `{}` matches every pass. The selector is pipeline-specific:
|
|
128
|
+
* the built-in URP uses `{ LightMode: ['Forward'] }` / `{ LightMode: ['ShadowCaster'] }`;
|
|
129
|
+
* a custom pipeline can define its own tag keys and values.
|
|
130
|
+
*
|
|
131
|
+
* Matching rule: every key in the selector must exist in the pass's `tags` and the
|
|
132
|
+
* pass's tag value must be in the selector's value list.
|
|
133
|
+
*/
|
|
134
|
+
|
|
135
|
+
export interface AddScenePassOptions {
|
|
136
|
+
/** Graph colour target to write (declared via g.addColorTarget). */
|
|
137
|
+
readonly color: string;
|
|
138
|
+
/** Graph depth target to write (declared via g.addColorTarget). */
|
|
139
|
+
readonly depth: string;
|
|
140
|
+
/**
|
|
141
|
+
* Optional single-sample resolve target for a multisample colour target.
|
|
142
|
+
* When `_routeFromOpts` is true and the active camera has MSAA enabled,
|
|
143
|
+
* `recordMainPass` resolves `color` into this graph-owned target before a
|
|
144
|
+
* downstream fullscreen pass samples it. Pass `null` to explicitly disable
|
|
145
|
+
* the default resolve in a custom-pipeline falsifier; omit it for
|
|
146
|
+
* single-sample scenes or to preserve the URP-owned resolve.
|
|
147
|
+
*/
|
|
148
|
+
readonly resolve?: string | null | undefined;
|
|
149
|
+
/** Resource keys this pass samples (typically 'shadowDepth' + an upstream colour). */
|
|
150
|
+
readonly reads?: readonly string[] | undefined;
|
|
151
|
+
/**
|
|
152
|
+
* Pass selector — a pipeline-specific filter for which material passes are
|
|
153
|
+
* rendered. An empty selector `{}` matches every pass. The built-in URP uses
|
|
154
|
+
* `{ LightMode: ['Forward'] }`; a custom pipeline defines its own tag keys.
|
|
155
|
+
*/
|
|
156
|
+
readonly selector: PassSelector;
|
|
157
|
+
/**
|
|
158
|
+
* @internal — feat-20260609 framebuffers demo M5 / T-12-a opt-in flag.
|
|
159
|
+
*
|
|
160
|
+
* When `true`, the pass execute closure resolves `opts.color` / `opts.depth`
|
|
161
|
+
* through the graph's resolveCtx and overrides the recordMainPass ctx so
|
|
162
|
+
* the geometry pass renders into those graph-owned views. When `false` (or
|
|
163
|
+
* unset, the default), recordMainPass picks the per-frame
|
|
164
|
+
* `geometryColorView` / `geometryDepthView` set by recordFrame's URP
|
|
165
|
+
* state-machine — this preserves byte-equivalence for urp-pipeline,
|
|
166
|
+
* which encodes its own MSAA / LDR-no-MSAA / HDR routing in recordFrame
|
|
167
|
+
* (where opts.color is a logical ordering token, not the physical write
|
|
168
|
+
* target).
|
|
169
|
+
*
|
|
170
|
+
* AI-user-defined custom pipelines declaring their own offscreen RT (the
|
|
171
|
+
* AC-11 "render scene to graph-owned colour + depth" contract) MUST set
|
|
172
|
+
* this flag to opt out of the URP state-machine and route opts.color
|
|
173
|
+
* directly. A future feat that migrates urp-pipeline off the recordFrame
|
|
174
|
+
* state-machine flips the default and removes this flag.
|
|
175
|
+
*/
|
|
176
|
+
readonly _routeFromOpts?: boolean | undefined;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* AC-11: render the ECS scene into a graph-owned colour + depth target.
|
|
181
|
+
*
|
|
182
|
+
* Adds a graph pass that, when executed, walks the per-frame validated
|
|
183
|
+
* renderable list and dispatches geometry into `opts.color` (with `opts.depth`
|
|
184
|
+
* as the depth attachment). The implementation detail (4-BGL chain, per-entity
|
|
185
|
+
* material UBO packing, pipeline cache lookup, MSAA variant selection) is
|
|
186
|
+
* package-private (`recordMainPass`); plan-strategy D-5 keeps it inside runtime
|
|
187
|
+
* so the render-graph package stays RHI-pure.
|
|
188
|
+
*
|
|
189
|
+
* The `reads` array threads dependency edges into the graph (so shadow ->
|
|
190
|
+
* skybox -> main is expressed in declaration order). The two writes are `opts.color`
|
|
191
|
+
* and `opts.depth`.
|
|
192
|
+
*/
|
|
193
|
+
export function addScenePass(
|
|
194
|
+
graph: RenderGraph<RenderPipelineContext>,
|
|
195
|
+
name: string,
|
|
196
|
+
opts: AddScenePassOptions,
|
|
197
|
+
): void {
|
|
198
|
+
graph.addPass(name, {
|
|
199
|
+
reads: opts.reads ?? [],
|
|
200
|
+
writes: [
|
|
201
|
+
opts.color,
|
|
202
|
+
opts.depth,
|
|
203
|
+
...(opts.resolve === undefined || opts.resolve === null ? [] : [opts.resolve]),
|
|
204
|
+
],
|
|
205
|
+
// feat-20260609 framebuffers demo M5 / T-12-a: route opts.color/opts.depth
|
|
206
|
+
// through the resolveCtx and override the geometry view fields on the ctx
|
|
207
|
+
// handed to recordMainPass when the caller is a non-URP custom pipeline.
|
|
208
|
+
// Without this routing, recordMainPass picks `c.geometryColorView` whose
|
|
209
|
+
// default (set by recordFrame) is the swap-chain `view`, only re-routed
|
|
210
|
+
// onto graph-owned targets via the URP state-machine
|
|
211
|
+
// (tonemapActive -> 'hdrColor' / msaaActive -> 'msaaColor' / etc.).
|
|
212
|
+
//
|
|
213
|
+
// URP byte-equivalence: urp-pipeline passes opts.color values that are
|
|
214
|
+
// logical ordering tokens whose actual physical view is selected per
|
|
215
|
+
// frame by recordFrame's state-machine (e.g. opts.color='hdrColor' but
|
|
216
|
+
// recordFrame may select hdrColorMsaa, msaaColor, or the swap-chain
|
|
217
|
+
// depending on tonemap+MSAA flags). Overriding from opts.color would
|
|
218
|
+
// drop those MSAA-specific / LDR-swap-chain RT picks. The discriminator
|
|
219
|
+
// is: URP keeps its state-machine because urp-pipeline does NOT pass
|
|
220
|
+
// `_routeFromOpts: true`; a non-URP custom pipeline declaring its own
|
|
221
|
+
// graph-owned RT opts in via the internal flag below.
|
|
222
|
+
//
|
|
223
|
+
// feat-20260609 selector: opts.selector is forwarded to recordMainPass for
|
|
224
|
+
// pass-tag filtering (e.g. URP's `{ LightMode: ['Forward'] }`).
|
|
225
|
+
execute: (ctx: RenderPipelineContext, resolveCtx?: ResolveContext) => {
|
|
226
|
+
const internalCtx = ctx as _InternalRenderPipelineContext;
|
|
227
|
+
if (!opts._routeFromOpts) {
|
|
228
|
+
recordMainPass(internalCtx, opts.selector);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const colorView = resolveCtx?.resolve(opts.color) as TextureView | undefined;
|
|
232
|
+
const depthView = resolveCtx?.resolve(opts.depth) as TextureView | undefined;
|
|
233
|
+
const resolveView =
|
|
234
|
+
opts.resolve === undefined
|
|
235
|
+
? undefined
|
|
236
|
+
: opts.resolve === null
|
|
237
|
+
? null
|
|
238
|
+
: (resolveCtx?.resolve(opts.resolve) as TextureView | undefined);
|
|
239
|
+
const overridden: _InternalRenderPipelineContext = {
|
|
240
|
+
...internalCtx,
|
|
241
|
+
geometryColorView: colorView ?? internalCtx.geometryColorView,
|
|
242
|
+
geometryDepthView: depthView ?? internalCtx.geometryDepthView,
|
|
243
|
+
...(resolveView !== undefined ? { geometryColorResolveView: resolveView } : {}),
|
|
244
|
+
};
|
|
245
|
+
recordMainPass(overridden, opts.selector);
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface AddShadowPassOptions {
|
|
251
|
+
/** Graph depth target to write (declared via g.addColorTarget with depth format). */
|
|
252
|
+
readonly depth: string;
|
|
253
|
+
/**
|
|
254
|
+
* Pass selector — a pipeline-specific filter for which material passes are
|
|
255
|
+
* rendered as shadow casters. The built-in URP uses
|
|
256
|
+
* `{ LightMode: ['ShadowCaster'] }`.
|
|
257
|
+
*/
|
|
258
|
+
readonly selector: PassSelector;
|
|
259
|
+
/**
|
|
260
|
+
* Optional viewport for the shadow render pass. When set, the pass calls
|
|
261
|
+
* `setViewport(x, y, w, h, 0, 1)` before dispatch so the depth rasterization
|
|
262
|
+
* is clipped to the given sub-rectangle of the depth target. Undefined
|
|
263
|
+
* preserves the pre-CSM behavior (full-RT viewport). Used by the cascaded
|
|
264
|
+
* shadow map atlas: each cascade pass writes to one tile.
|
|
265
|
+
*
|
|
266
|
+
* @example viewport: { x: 0, y: 0, w: 2048, h: 2048 }
|
|
267
|
+
*/
|
|
268
|
+
readonly viewport?:
|
|
269
|
+
| { readonly x: number; readonly y: number; readonly w: number; readonly h: number }
|
|
270
|
+
| undefined;
|
|
271
|
+
/**
|
|
272
|
+
* Cascade index this pass renders into (0..3). The runtime writes the
|
|
273
|
+
* value to `shadowCasterCascadeBuffer` immediately before submit; the
|
|
274
|
+
* shadow_caster vertex shader reads it to pick the matching
|
|
275
|
+
* `view.lightViewProj_X`. Defaults to 0 when unset (preserves the
|
|
276
|
+
* single-cascade pre-CSM behaviour for any caller still calling
|
|
277
|
+
* addShadowPass without the field; the URP per-cascade loop sets it
|
|
278
|
+
* explicitly).
|
|
279
|
+
*
|
|
280
|
+
* @example cascadeIndex: 0 // first cascade (lightViewProj_A)
|
|
281
|
+
*/
|
|
282
|
+
readonly cascadeIndex?: number;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Render shadow casters into a depth-only graph target. Implementation detail:
|
|
287
|
+
* `recordShadowPass` (package-private) iterates DirectionalLight + caster
|
|
288
|
+
* renderables under their light-view + light-proj and writes the depth-32-float
|
|
289
|
+
* target consumed by `addScenePass.reads`.
|
|
290
|
+
*/
|
|
291
|
+
export function addShadowPass(
|
|
292
|
+
graph: RenderGraph<RenderPipelineContext>,
|
|
293
|
+
name: string,
|
|
294
|
+
opts: AddShadowPassOptions,
|
|
295
|
+
): void {
|
|
296
|
+
const cascadeIndex = opts.cascadeIndex ?? 0;
|
|
297
|
+
graph.addPass(name, {
|
|
298
|
+
reads: [],
|
|
299
|
+
writes: [opts.depth],
|
|
300
|
+
execute: (c: RenderPipelineContext) =>
|
|
301
|
+
recordShadowPass(
|
|
302
|
+
c as Parameters<typeof recordShadowPass>[0],
|
|
303
|
+
opts.selector,
|
|
304
|
+
opts.viewport,
|
|
305
|
+
cascadeIndex,
|
|
306
|
+
),
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* feat-20260612-point-light-shadows-urp-hdrp M3 / T-M3-4 (plan-strategy §D-1
|
|
312
|
+
* + AC-04 + AC-09). Render the 6 x N point-light shadow caster passes into
|
|
313
|
+
* the cube_array atlas owned by `frameState.pointShadowAtlas`. Implementation
|
|
314
|
+
* detail: `recordPointShadowPass` (package-private) iterates
|
|
315
|
+
* `frameState.pointShadowSnapshots` and emits one independent render pass
|
|
316
|
+
* per (layer, face), opening / submitting each on its own command encoder
|
|
317
|
+
* (RD-4 manual barrier between depth-write and the URP forward pass's
|
|
318
|
+
* cube_array sample).
|
|
319
|
+
*
|
|
320
|
+
* Resource model: the cube_array atlas is a runtime-owned resource (NOT a
|
|
321
|
+
* graph color target) because its size is `4 * 6 * faceSize^2` and per-face
|
|
322
|
+
* 2D views must be created with explicit `baseArrayLayer` indexing — the
|
|
323
|
+
* existing `addColorTarget` vocabulary is single-attachment-only. The pass
|
|
324
|
+
* therefore declares no `writes` (the dependency between this pass and the
|
|
325
|
+
* URP forward pass is enforced by the `addScenePass.reads` order — both
|
|
326
|
+
* sample shadowAtlas, and graph declaration order keeps shadow before
|
|
327
|
+
* forward). A future render-graph extension may model the cube_array as a
|
|
328
|
+
* first-class resource; for now the manual command-encoder boundary is the
|
|
329
|
+
* synchronization point.
|
|
330
|
+
*
|
|
331
|
+
* AC-09 zero-shadow zero-pass: the URP `buildGraph` gates the call to
|
|
332
|
+
* `addPointShadowPass` on `frameState.pointShadowSnapshots.length > 0` so
|
|
333
|
+
* the graph itself never declares the pass when no PointLightShadow exists.
|
|
334
|
+
* `recordPointShadowPass` re-checks at execute time as defence in depth.
|
|
335
|
+
*/
|
|
336
|
+
export function addPointShadowPass(graph: RenderGraph<RenderPipelineContext>, name: string): void {
|
|
337
|
+
graph.addPass(name, {
|
|
338
|
+
reads: [],
|
|
339
|
+
writes: [],
|
|
340
|
+
execute: recordPointShadowPass as (c: RenderPipelineContext) => void,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export interface AddSpotShadowPassOptions {
|
|
345
|
+
/** Graph depth target (depth32float 2x2 tile atlas) the spot casters write. */
|
|
346
|
+
readonly depth: string;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* feat-20260625-spot-light-shadow-mapping M2 / w9 + w11 (D-1 + D-2). Render the
|
|
351
|
+
* spot-light shadow caster passes into the graph-owned `spotShadowDepth` atlas
|
|
352
|
+
* (a single 2D depth32float texture of 2x2 tiles — NOT a 2d-array). One graph
|
|
353
|
+
* pass NODE; the execute closure (`recordSpotShadowPass`) loops the per-frame
|
|
354
|
+
* `frameState.spotShadowSnapshots`, rendering each castShadow spot's perspective
|
|
355
|
+
* depth into its tile (viewport keyed on `shadowAtlasTile`) with first-tile
|
|
356
|
+
* clear / rest load (independent of the directional cascadeIndex; D-2). Unlike
|
|
357
|
+
* `addPointShadowPass` the spot atlas IS a graph color target, so the pass
|
|
358
|
+
* declares `writes: [opts.depth]` — `addScenePass.reads` lists the same key to
|
|
359
|
+
* order spot-shadow -> main. The single-node-with-internal-loop shape keeps the
|
|
360
|
+
* memoized graph from rebuilding on spot-count drift (AC-03 zero-spot scenes
|
|
361
|
+
* record zero passes via the early-return inside recordSpotShadowPass).
|
|
362
|
+
*/
|
|
363
|
+
export function addSpotShadowPass(
|
|
364
|
+
graph: RenderGraph<RenderPipelineContext>,
|
|
365
|
+
name: string,
|
|
366
|
+
opts: AddSpotShadowPassOptions,
|
|
367
|
+
): void {
|
|
368
|
+
graph.addPass(name, {
|
|
369
|
+
reads: [],
|
|
370
|
+
writes: [opts.depth],
|
|
371
|
+
execute: recordSpotShadowPass as (c: RenderPipelineContext) => void,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export interface AddSkyboxPassOptions {
|
|
376
|
+
/** Graph colour target the skybox writes (typically the same target the scene pass writes). */
|
|
377
|
+
readonly color: string;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Render a skybox cube into the declared colour target. Implementation detail:
|
|
382
|
+
* `recordSkyboxPass` (package-private) emits a single cube draw with a
|
|
383
|
+
* skybox-view matrix derived from the camera. Writes `opts.color` so the
|
|
384
|
+
* scene pass can declare it under `reads` to enforce skybox -> main order.
|
|
385
|
+
*/
|
|
386
|
+
export function addSkyboxPass(
|
|
387
|
+
graph: RenderGraph<RenderPipelineContext>,
|
|
388
|
+
name: string,
|
|
389
|
+
opts: AddSkyboxPassOptions,
|
|
390
|
+
): void {
|
|
391
|
+
graph.addPass(name, {
|
|
392
|
+
reads: [],
|
|
393
|
+
writes: [opts.color],
|
|
394
|
+
execute: recordSkyboxPass as (c: RenderPipelineContext) => void,
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export interface AddBloomPassesOptions {
|
|
399
|
+
/** HDR colour target the bright-extract reads + the composite reads back. */
|
|
400
|
+
readonly hdrColor: string;
|
|
401
|
+
/** Logical key the composite WRITES (typically an alias of hdrColor). */
|
|
402
|
+
readonly hdrComposited: string;
|
|
403
|
+
/** Half-res bright target. */
|
|
404
|
+
readonly bright: string;
|
|
405
|
+
/** Half-res H blur target. */
|
|
406
|
+
readonly blurH: string;
|
|
407
|
+
/** Half-res V blur target. */
|
|
408
|
+
readonly blurV: string;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Wire the 4-pass bloom chain (bright -> blur-h -> blur-v -> composite). All
|
|
413
|
+
* intermediate targets are half-resolution; the composite reads hdrColor +
|
|
414
|
+
* blurV and writes the alias `hdrComposited` (declared via
|
|
415
|
+
* `g.addColorTargetAlias` to fold onto the actual hdrColor texture, KB-1).
|
|
416
|
+
*/
|
|
417
|
+
export function addBloomPasses(
|
|
418
|
+
graph: RenderGraph<RenderPipelineContext>,
|
|
419
|
+
opts: AddBloomPassesOptions,
|
|
420
|
+
): void {
|
|
421
|
+
graph.addPass('bloom-bright', {
|
|
422
|
+
reads: [opts.hdrColor],
|
|
423
|
+
writes: [opts.bright],
|
|
424
|
+
colorConnections: [{ source: opts.hdrColor, destination: opts.bright }],
|
|
425
|
+
execute: recordBloomBrightPass as (c: RenderPipelineContext) => void,
|
|
426
|
+
});
|
|
427
|
+
graph.addPass('bloom-blur-h', {
|
|
428
|
+
reads: [opts.bright],
|
|
429
|
+
writes: [opts.blurH],
|
|
430
|
+
colorConnections: [{ source: opts.bright, destination: opts.blurH }],
|
|
431
|
+
execute: recordBloomBlurHPass as (c: RenderPipelineContext) => void,
|
|
432
|
+
});
|
|
433
|
+
graph.addPass('bloom-blur-v', {
|
|
434
|
+
reads: [opts.blurH],
|
|
435
|
+
writes: [opts.blurV],
|
|
436
|
+
colorConnections: [{ source: opts.blurH, destination: opts.blurV }],
|
|
437
|
+
execute: recordBloomBlurVPass as (c: RenderPipelineContext) => void,
|
|
438
|
+
});
|
|
439
|
+
graph.addPass('bloom-composite', {
|
|
440
|
+
reads: [opts.hdrColor, opts.blurV],
|
|
441
|
+
writes: [opts.hdrComposited],
|
|
442
|
+
colorConnections: [
|
|
443
|
+
{ source: opts.hdrColor, destination: opts.hdrComposited },
|
|
444
|
+
{ source: opts.blurV, destination: opts.hdrComposited },
|
|
445
|
+
],
|
|
446
|
+
execute: recordBloomCompositePass as (c: RenderPipelineContext) => void,
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* feat-20260612-hdrp-ssao M3 / w15: SSAO pass parameters.
|
|
452
|
+
*
|
|
453
|
+
* Defaults: radius=0.5, bias=0.025, intensity=1.0.
|
|
454
|
+
* Non-positive radius or negative bias triggers fail-fast PostProcessError
|
|
455
|
+
* inside the per-frame record closure (w16 boundary impl).
|
|
456
|
+
*/
|
|
457
|
+
export interface AddSsaoPassesParams {
|
|
458
|
+
/** SSAO sample radius in view-space units (default 0.5). */
|
|
459
|
+
readonly radius?: number | undefined;
|
|
460
|
+
/** SSAO depth bias to avoid self-occlusion (default 0.025). */
|
|
461
|
+
readonly bias?: number | undefined;
|
|
462
|
+
/** SSAO intensity blend factor (default 1.0). */
|
|
463
|
+
readonly intensity?: number | undefined;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export type { ResolvedSsaoParameters, SsaoParameterConfig } from './ssao-config';
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Options for `addSsaoPasses` (plan-strategy D-5, D-2).
|
|
470
|
+
*
|
|
471
|
+
* The caller (hdrp-pipeline.buildGraph) declares the color targets
|
|
472
|
+
* (ssaoRaw / ssaoBlurred as half-swapchain r8unorm) and passes their
|
|
473
|
+
* graph resource keys here. `gbuf0` and `hdrDepth` are g-buffer
|
|
474
|
+
* resources declared by the pipeline.
|
|
475
|
+
*/
|
|
476
|
+
export interface AddSsaoPassesOptions {
|
|
477
|
+
/** G-buffer RT0 (normal.rgb + roughness.a), rgba16float, swapchain. */
|
|
478
|
+
readonly gbuf0: string;
|
|
479
|
+
/** Hardware depth target, depth24plus-stencil8, swapchain. */
|
|
480
|
+
readonly hdrDepth: string;
|
|
481
|
+
/** SSAO calc output: half-res r8unorm transient target. */
|
|
482
|
+
readonly ssaoRaw: string;
|
|
483
|
+
/** SSAO blur output: half-res r8unorm transient target. */
|
|
484
|
+
readonly ssaoBlurred: string;
|
|
485
|
+
/** SSAO parameters (radius, bias, intensity). */
|
|
486
|
+
readonly params?: AddSsaoPassesParams | undefined;
|
|
487
|
+
/** Pipeline context for lazy SSAO buffer resolution. */
|
|
488
|
+
readonly ctx: RenderPipelineContext;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Wire the 2-pass SSAO chain (calc -> blur) into the render graph.
|
|
493
|
+
*
|
|
494
|
+
* plan-strategy D-2: exactly 2 pass (ssao-calc + ssao-blur).
|
|
495
|
+
* plan-strategy D-4: g-buffer missing -> graph-level skip.
|
|
496
|
+
* plan-strategy D-5: signature matches addBloomPasses pattern.
|
|
497
|
+
*
|
|
498
|
+
* ssao-calc: reads gbuf0 + hdrDepth + ssao-noise + ssao-kernel + ssao-uniform,
|
|
499
|
+
* writes ssaoRaw (half-res r8unorm).
|
|
500
|
+
* ssao-blur: reads ssaoRaw, writes ssaoBlurred (half-res r8unorm).
|
|
501
|
+
*
|
|
502
|
+
* Fail-fast: when SSAO buffers are unavailable (g-buffer not declared or
|
|
503
|
+
* kernel/noise generation fails), the
|
|
504
|
+
* function returns without wiring any pass nodes (graph-level skip).
|
|
505
|
+
* Param validation happens in the record closure (w16 boundary impl).
|
|
506
|
+
*/
|
|
507
|
+
export function addSsaoPasses(
|
|
508
|
+
graph: RenderGraph<RenderPipelineContext>,
|
|
509
|
+
opts: AddSsaoPassesOptions,
|
|
510
|
+
): void {
|
|
511
|
+
const ctx = opts.ctx as _InternalRenderPipelineContext;
|
|
512
|
+
|
|
513
|
+
// plan-strategy D-4: g-buffer missing -> graph-level skip.
|
|
514
|
+
// Check that gbuf0 + hdrDepth are declared as graph color targets.
|
|
515
|
+
const resources = graph.listResources();
|
|
516
|
+
const hasGbuf0 = resources.some((r) => r.key === opts.gbuf0);
|
|
517
|
+
const hasHdrDepth = resources.some((r) => r.key === opts.hdrDepth);
|
|
518
|
+
if (!hasGbuf0 || !hasHdrDepth) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Check SSAO buffers are available (allocation only; the kernel is a UBO so
|
|
523
|
+
// this path is valid on WebGL2).
|
|
524
|
+
const ssaoBufs = getOrCreateSsaoBuffers(ctx.runtime);
|
|
525
|
+
if (ssaoBufs === null) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Validate parameters (fail-fast on illegal values).
|
|
530
|
+
const params = resolveSsaoParameters(opts.params);
|
|
531
|
+
if (!params.ok) throw params.error;
|
|
532
|
+
|
|
533
|
+
// Pass 1: SSAO calculation — fullscreen pass that samples g-buffer
|
|
534
|
+
// RT0 + depth, computes 64-sample hemisphere occlusion, writes
|
|
535
|
+
// single-channel R8 result to half-resolution target.
|
|
536
|
+
// Kernel SSBO / noise texture / uniform UBO are runtime-owned
|
|
537
|
+
// (getOrCreateSsaoBuffers) and bound at record time, not
|
|
538
|
+
// through the graph resource system.
|
|
539
|
+
graph.addPass('ssao-calc', {
|
|
540
|
+
reads: [opts.gbuf0, opts.hdrDepth],
|
|
541
|
+
writes: [opts.ssaoRaw],
|
|
542
|
+
execute: (_c: RenderPipelineContext, resolveCtx?: ResolveContext) => {
|
|
543
|
+
const internalCtx = _c as _InternalRenderPipelineContext;
|
|
544
|
+
recordSsaoCalcPass(
|
|
545
|
+
internalCtx,
|
|
546
|
+
resolveCtx,
|
|
547
|
+
opts.ssaoRaw,
|
|
548
|
+
opts.gbuf0,
|
|
549
|
+
opts.hdrDepth,
|
|
550
|
+
undefined,
|
|
551
|
+
undefined,
|
|
552
|
+
params.value,
|
|
553
|
+
);
|
|
554
|
+
},
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
// Pass 2: SSAO blur — fullscreen pass that reads the half-res R8
|
|
558
|
+
// ssaoRaw texture, applies a 4x4 box blur (16 taps), writes the
|
|
559
|
+
// blurred result to ssaoBlurred.
|
|
560
|
+
//
|
|
561
|
+
// M8 / w38: gbuf0 + hdrDepth declared as reads even though the blur
|
|
562
|
+
// shader does not sample them. Reason: the SSAO BGL is shared with the
|
|
563
|
+
// calc pass (9 entries 0-8); WebGPU requires every BGL slot to carry a
|
|
564
|
+
// valid resource, so the blur bind group must bind real gbuffer_normal +
|
|
565
|
+
// hdr_depth views at slots 4 + 5 — declaring them as graph reads is the
|
|
566
|
+
// mechanism that makes resolveCtx return their views here.
|
|
567
|
+
graph.addPass('ssao-blur', {
|
|
568
|
+
reads: [opts.ssaoRaw, opts.gbuf0, opts.hdrDepth],
|
|
569
|
+
writes: [opts.ssaoBlurred],
|
|
570
|
+
execute: (_c: RenderPipelineContext, resolveCtx?: ResolveContext) => {
|
|
571
|
+
const internalCtx = _c as _InternalRenderPipelineContext;
|
|
572
|
+
recordSsaoBlurPass(
|
|
573
|
+
internalCtx,
|
|
574
|
+
resolveCtx,
|
|
575
|
+
opts.ssaoBlurred,
|
|
576
|
+
opts.ssaoRaw,
|
|
577
|
+
opts.gbuf0,
|
|
578
|
+
opts.hdrDepth,
|
|
579
|
+
);
|
|
580
|
+
},
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Lazy-allocate the three constant SSAO record companions the first time the
|
|
586
|
+
* calc / blur closure runs: a filtering sampler (binding 3 + 8), a
|
|
587
|
+
* non-filtering depth sampler (binding 6, paired with hdr_depth — WebGPU
|
|
588
|
+
* validation rejects depth + filtering), and a 1x1 r8unorm fallback view bound
|
|
589
|
+
* at ssaoRaw (binding 7) in the calc pass (the calc shader never samples
|
|
590
|
+
* ssaoRaw, but the BGL still requires a valid view).
|
|
591
|
+
*
|
|
592
|
+
* Returns null if any underlying allocation fires a structured error onto
|
|
593
|
+
* runtime.errorRegistry; the caller then skips the pass.
|
|
594
|
+
*/
|
|
595
|
+
/**
|
|
596
|
+
* Resolve a depth-only view of a graph color target by key.
|
|
597
|
+
*
|
|
598
|
+
* On dawn the BindGroup validation rejects a default-view (aspect=all on a
|
|
599
|
+
* depth+stencil texture) with "Multiple aspects (Depth|Stencil) selected".
|
|
600
|
+
* A separate createTextureView({aspect:'depth-only'}) is required.
|
|
601
|
+
*
|
|
602
|
+
* @param internals - internal render pipeline context
|
|
603
|
+
* @param key - graph color-target key to resolve depth from
|
|
604
|
+
* @param label - debug label for the depth-only TextureView
|
|
605
|
+
* @returns a depth-only TextureView, or null if the graph / texture is absent
|
|
606
|
+
* or creation fires a structured error
|
|
607
|
+
*/
|
|
608
|
+
export function resolveDepthOnlyView(
|
|
609
|
+
internals: _InternalRenderPipelineContext,
|
|
610
|
+
key: string,
|
|
611
|
+
label: string,
|
|
612
|
+
preferredKey?: string | null,
|
|
613
|
+
): TextureView | null {
|
|
614
|
+
const graph = (
|
|
615
|
+
internals.frameState as unknown as {
|
|
616
|
+
readonly perFrameGraph?: {
|
|
617
|
+
getColorTargetTexture(key: string): unknown;
|
|
618
|
+
} | null;
|
|
619
|
+
}
|
|
620
|
+
).perFrameGraph;
|
|
621
|
+
if (graph === null || graph === undefined) return null;
|
|
622
|
+
const preferredTexture =
|
|
623
|
+
preferredKey === null || preferredKey === undefined
|
|
624
|
+
? undefined
|
|
625
|
+
: graph.getColorTargetTexture(preferredKey);
|
|
626
|
+
const tex = preferredTexture ?? graph.getColorTargetTexture(key);
|
|
627
|
+
if (tex === undefined) return null;
|
|
628
|
+
const res = internals.runtime.device.createTextureView(tex as never, {
|
|
629
|
+
label,
|
|
630
|
+
dimension: '2d',
|
|
631
|
+
aspect: 'depth-only',
|
|
632
|
+
baseMipLevel: 0,
|
|
633
|
+
mipLevelCount: 1,
|
|
634
|
+
baseArrayLayer: 0,
|
|
635
|
+
arrayLayerCount: 1,
|
|
636
|
+
});
|
|
637
|
+
if (!res.ok) {
|
|
638
|
+
internals.runtime.errorRegistry.fire(res.error);
|
|
639
|
+
return null;
|
|
640
|
+
}
|
|
641
|
+
return res.value;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Resolve a depth-only view of the graph's hdrDepth texture.
|
|
646
|
+
*
|
|
647
|
+
* Thin delegate to {@link resolveDepthOnlyView} (plan-strategy D-5: extract
|
|
648
|
+
* the shared depth-only view helper, SSAO delegates). Behaviour is byte-identical
|
|
649
|
+
* to the pre-extraction inline version. The SSAO BGL / bindings / sampler are
|
|
650
|
+
* untouched (OOS-4).
|
|
651
|
+
*/
|
|
652
|
+
function resolveHdrDepthDepthOnlyView(
|
|
653
|
+
internals: _InternalRenderPipelineContext,
|
|
654
|
+
hdrDepthKey: string,
|
|
655
|
+
): TextureView | null {
|
|
656
|
+
return resolveDepthOnlyView(internals, hdrDepthKey, 'ssao-hdr-depth-only-view');
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
function ensureSsaoRecordCompanions(internals: _InternalRenderPipelineContext): {
|
|
660
|
+
filteringSampler: Sampler;
|
|
661
|
+
depthSampler: Sampler;
|
|
662
|
+
fallbackRawView: TextureView;
|
|
663
|
+
} | null {
|
|
664
|
+
const pp = internals.pipelineState.perPassResources;
|
|
665
|
+
if (
|
|
666
|
+
pp.ssaoFilteringSampler !== null &&
|
|
667
|
+
pp.ssaoDepthSampler !== null &&
|
|
668
|
+
pp.ssaoFallbackRawView !== null
|
|
669
|
+
) {
|
|
670
|
+
return {
|
|
671
|
+
filteringSampler: pp.ssaoFilteringSampler,
|
|
672
|
+
depthSampler: pp.ssaoDepthSampler,
|
|
673
|
+
fallbackRawView: pp.ssaoFallbackRawView as TextureView,
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
const device = internals.runtime.device;
|
|
678
|
+
|
|
679
|
+
if (pp.ssaoFilteringSampler === null) {
|
|
680
|
+
// Despite the field name, this sampler is non-filtering (NEAREST):
|
|
681
|
+
// bindings 3 (noise sampler) + 8 (ssaoSampler) pair with unfilterable
|
|
682
|
+
// float textures (rgba32float noise / r8unorm ssaoRaw on dawn without
|
|
683
|
+
// float32-filterable). The "filtering" label in the field name predates
|
|
684
|
+
// the sampler-type split; the resource itself is non-filtering.
|
|
685
|
+
const res = device.createSampler({
|
|
686
|
+
label: 'ssao-noise-sampler',
|
|
687
|
+
magFilter: 'nearest',
|
|
688
|
+
minFilter: 'nearest',
|
|
689
|
+
mipmapFilter: 'nearest',
|
|
690
|
+
addressModeU: 'repeat',
|
|
691
|
+
addressModeV: 'repeat',
|
|
692
|
+
});
|
|
693
|
+
if (!res.ok) {
|
|
694
|
+
internals.runtime.errorRegistry.fire(res.error);
|
|
695
|
+
return null;
|
|
696
|
+
}
|
|
697
|
+
pp.ssaoFilteringSampler = res.value;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
if (pp.ssaoDepthSampler === null) {
|
|
701
|
+
const res = device.createSampler({
|
|
702
|
+
label: 'ssao-depth-sampler',
|
|
703
|
+
magFilter: 'nearest',
|
|
704
|
+
minFilter: 'nearest',
|
|
705
|
+
mipmapFilter: 'nearest',
|
|
706
|
+
addressModeU: 'clamp-to-edge',
|
|
707
|
+
addressModeV: 'clamp-to-edge',
|
|
708
|
+
});
|
|
709
|
+
if (!res.ok) {
|
|
710
|
+
internals.runtime.errorRegistry.fire(res.error);
|
|
711
|
+
return null;
|
|
712
|
+
}
|
|
713
|
+
pp.ssaoDepthSampler = res.value;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
if (pp.ssaoFallbackRawView === null) {
|
|
717
|
+
const fb = getOrCreateSsaoFallbackTexture(internals.runtime);
|
|
718
|
+
if (fb === null) return null;
|
|
719
|
+
pp.ssaoFallbackRawView = fb.view;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
return {
|
|
723
|
+
filteringSampler: pp.ssaoFilteringSampler,
|
|
724
|
+
depthSampler: pp.ssaoDepthSampler,
|
|
725
|
+
fallbackRawView: pp.ssaoFallbackRawView as TextureView,
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Pack the 256B SSAO uniform payload from the camera + config.ssao.intensity.
|
|
731
|
+
*
|
|
732
|
+
* Layout (plan-strategy D-1 + D-C):
|
|
733
|
+
* floats [0..15] view mat4
|
|
734
|
+
* floats [16..31] projection mat4
|
|
735
|
+
* floats [32..47] inverseProjection mat4
|
|
736
|
+
* floats [48..51] intensityPad vec4 (x=intensity, yzw=0 padding)
|
|
737
|
+
* floats [52..63] trailing zero-pad to round to 256B / 64f UBO alignment.
|
|
738
|
+
*/
|
|
739
|
+
function buildSsaoUniformPayload(
|
|
740
|
+
internals: _InternalRenderPipelineContext,
|
|
741
|
+
parameters?: ResolvedSsaoParameters,
|
|
742
|
+
): Float32Array {
|
|
743
|
+
const { camera, frameState } = internals;
|
|
744
|
+
const sProj = computeProjectionMatrix(camera);
|
|
745
|
+
const sView = computeViewMatrix(camera);
|
|
746
|
+
const invProj = mat4.create();
|
|
747
|
+
mat4.invert(invProj, sProj);
|
|
748
|
+
|
|
749
|
+
const out = new Float32Array(64);
|
|
750
|
+
out.set(sView as unknown as Float32Array, 0);
|
|
751
|
+
out.set(sProj as unknown as Float32Array, 16);
|
|
752
|
+
out.set(invProj as unknown as Float32Array, 32);
|
|
753
|
+
|
|
754
|
+
const ssaoConfig = frameState.installedPipelineConfig?.ssao;
|
|
755
|
+
const resolved =
|
|
756
|
+
parameters ??
|
|
757
|
+
getSsaoParameters(
|
|
758
|
+
ssaoConfig !== undefined && ssaoConfig.enabled === true ? ssaoConfig : undefined,
|
|
759
|
+
);
|
|
760
|
+
out[48] = resolved.intensity;
|
|
761
|
+
out[49] = resolved.radius;
|
|
762
|
+
out[50] = resolved.bias;
|
|
763
|
+
return out;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
/**
|
|
767
|
+
* recordSsaoCalcPass — fullscreen SSAO occlusion calculation (M8 / w38).
|
|
768
|
+
*
|
|
769
|
+
* Resolves the graph-owned half-resolution ssaoRaw color target, writes the
|
|
770
|
+
* 256 B SSAO uniform (view/proj/invProj/intensity) once per frame, then runs
|
|
771
|
+
* a 3-vertex fullscreen-triangle draw with fs_ssao_calc.
|
|
772
|
+
*
|
|
773
|
+
* Bind group entries (must match the 9-entry SSAO BGL declared in
|
|
774
|
+
* createRenderer.ts; see hdrp-ssao.wgsl §BGL layout):
|
|
775
|
+
* 0 ssao_uniform UBO 5 hdr_depth view
|
|
776
|
+
* 1 ssao_kernel UBO 6 ssao_depth_sampler (non-filtering)
|
|
777
|
+
* 2 ssao_noise_texture 7 fallback ssaoRaw view (calc never samples)
|
|
778
|
+
* 3 ssao_noise_sampler 8 ssaoSampler (unused by calc, BGL slot)
|
|
779
|
+
* 4 gbuffer_normal view
|
|
780
|
+
*
|
|
781
|
+
* Skips with no GPU work when the optional SSAO pipelines are unavailable
|
|
782
|
+
* (manifest without hdrp-ssao.wgsl), when the dedicated BGL is null, when
|
|
783
|
+
* the SSAO buffers fail to allocate, or when the graph cannot resolve the
|
|
784
|
+
* required views.
|
|
785
|
+
*/
|
|
786
|
+
export interface SsaoCalcPassViews {
|
|
787
|
+
readonly output: TextureView;
|
|
788
|
+
readonly normal: TextureView;
|
|
789
|
+
readonly depth: TextureView;
|
|
790
|
+
readonly depthCacheKey: TextureView;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
export function recordSsaoCalcPass(
|
|
794
|
+
_c: _InternalRenderPipelineContext,
|
|
795
|
+
resolveCtx?: ResolveContext,
|
|
796
|
+
ssaoRawKey?: string,
|
|
797
|
+
gbuf0Key?: string,
|
|
798
|
+
hdrDepthKey?: string,
|
|
799
|
+
graphPass?: RhiRenderPassEncoder,
|
|
800
|
+
graphViews?: SsaoCalcPassViews,
|
|
801
|
+
parameters?: ResolvedSsaoParameters,
|
|
802
|
+
): void {
|
|
803
|
+
const { runtime, pipelineState, encoder } = _c;
|
|
804
|
+
const pp = pipelineState.perPassResources;
|
|
805
|
+
|
|
806
|
+
if (pp.ssaoCalcPipeline === null || pp.ssaoBgl === null) return;
|
|
807
|
+
if (graphViews === undefined && (resolveCtx === undefined || ssaoRawKey === undefined)) return;
|
|
808
|
+
|
|
809
|
+
const ssaoRawView =
|
|
810
|
+
graphViews?.output ?? (resolveCtx?.resolve(ssaoRawKey as string) as TextureView | undefined);
|
|
811
|
+
const gbuf0View =
|
|
812
|
+
graphViews?.normal ??
|
|
813
|
+
(gbuf0Key !== undefined
|
|
814
|
+
? (resolveCtx?.resolve(gbuf0Key) as TextureView | undefined)
|
|
815
|
+
: undefined);
|
|
816
|
+
if (!ssaoRawView || !gbuf0View || (graphViews === undefined && hdrDepthKey === undefined)) return;
|
|
817
|
+
|
|
818
|
+
// hdrDepth needs a depth-only view (BGL binding 5 sampleType=depth);
|
|
819
|
+
// resolveCtx returns a default all-aspects view that dawn rejects when
|
|
820
|
+
// paired with a depth sampler.
|
|
821
|
+
const hdrDepthView = graphViews?.depth ?? resolveHdrDepthDepthOnlyView(_c, hdrDepthKey as string);
|
|
822
|
+
if (hdrDepthView === null) return;
|
|
823
|
+
|
|
824
|
+
// Cache key: the graph's pooled hdrDepth view (stable object per size, new
|
|
825
|
+
// object on resize). The depth-only view above is created fresh every frame
|
|
826
|
+
// so it cannot key the cache; the pooled all-aspects view co-varies with it
|
|
827
|
+
// (both are views of the same transient hdrDepth texture) and changes exactly
|
|
828
|
+
// on resize. Used only as a WeakMap key, never bound.
|
|
829
|
+
const hdrDepthPooledView =
|
|
830
|
+
graphViews?.depthCacheKey ??
|
|
831
|
+
(resolveCtx?.resolve(hdrDepthKey as string) as TextureView | undefined);
|
|
832
|
+
if (hdrDepthPooledView === undefined) return;
|
|
833
|
+
|
|
834
|
+
const ssaoBufs = getOrCreateSsaoBuffers(runtime);
|
|
835
|
+
if (ssaoBufs === null) return;
|
|
836
|
+
|
|
837
|
+
const noiseViewRes = runtime.device.createTextureView(ssaoBufs.noiseTexture, {
|
|
838
|
+
label: 'hdrp-ssao-noise-view',
|
|
839
|
+
format: 'rgba32float',
|
|
840
|
+
dimension: '2d',
|
|
841
|
+
aspect: 'all',
|
|
842
|
+
baseMipLevel: 0,
|
|
843
|
+
mipLevelCount: 1,
|
|
844
|
+
baseArrayLayer: 0,
|
|
845
|
+
arrayLayerCount: 1,
|
|
846
|
+
});
|
|
847
|
+
if (!noiseViewRes.ok) {
|
|
848
|
+
runtime.errorRegistry.fire(noiseViewRes.error);
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
const companions = ensureSsaoRecordCompanions(_c);
|
|
853
|
+
if (companions === null) return;
|
|
854
|
+
|
|
855
|
+
// Per-frame uniform write (D-C: view+proj+invProj+intensity at one queue
|
|
856
|
+
// call). 256 B Float32Array (64 f32) lands in ssao_uniform UBO offset 0.
|
|
857
|
+
const payload = buildSsaoUniformPayload(_c, parameters);
|
|
858
|
+
const writeRes = runtime.device.queue.writeBuffer(ssaoBufs.uniformBuffer, 0, payload);
|
|
859
|
+
if (!writeRes.ok) {
|
|
860
|
+
runtime.errorRegistry.fire(writeRes.error);
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
// Identity-cached bind group: 9 entries mirror the BGL declared in
|
|
865
|
+
// createRenderer. Keyed on the graph-pooled gbuf0 + hdrDepth views (both
|
|
866
|
+
// retire + reallocate on resize), so the WeakMap misses after a resize and
|
|
867
|
+
// rebuilds against the live textures. The noise / depth-only views bound
|
|
868
|
+
// below are created fresh each frame but back stable textures; keying on the
|
|
869
|
+
// resize-varying graph views is what makes invalidation correct. Replaces
|
|
870
|
+
// the prior `=== null` slot cache that submitted a destroyed gbuf0/hdrDepth
|
|
871
|
+
// after resize.
|
|
872
|
+
const ssaoBgl = pp.ssaoBgl;
|
|
873
|
+
const bindGroup = getOrCreateFromChain(
|
|
874
|
+
_c.frameState.postProcessBgCache,
|
|
875
|
+
[gbuf0View as unknown as object, hdrDepthPooledView as unknown as object],
|
|
876
|
+
'ssao-calc',
|
|
877
|
+
() => {
|
|
878
|
+
const bgRes = runtime.device.createBindGroup({
|
|
879
|
+
label: 'ssao-calc-bg',
|
|
880
|
+
layout: ssaoBgl,
|
|
881
|
+
entries: [
|
|
882
|
+
{ binding: 0, resource: { kind: 'buffer', value: { buffer: ssaoBufs.uniformBuffer } } },
|
|
883
|
+
{ binding: 1, resource: { kind: 'buffer', value: { buffer: ssaoBufs.kernelBuffer } } },
|
|
884
|
+
{ binding: 2, resource: { kind: 'textureView', value: noiseViewRes.value } },
|
|
885
|
+
{
|
|
886
|
+
binding: 3,
|
|
887
|
+
resource: { kind: 'sampler', value: companions.filteringSampler },
|
|
888
|
+
},
|
|
889
|
+
{ binding: 4, resource: { kind: 'textureView', value: gbuf0View } },
|
|
890
|
+
{ binding: 5, resource: { kind: 'textureView', value: hdrDepthView } },
|
|
891
|
+
{ binding: 6, resource: { kind: 'sampler', value: companions.depthSampler } },
|
|
892
|
+
{ binding: 7, resource: { kind: 'textureView', value: companions.fallbackRawView } },
|
|
893
|
+
{ binding: 8, resource: { kind: 'sampler', value: companions.filteringSampler } },
|
|
894
|
+
],
|
|
895
|
+
});
|
|
896
|
+
if (!bgRes.ok) throw bgRes.error;
|
|
897
|
+
return bgRes.value;
|
|
898
|
+
},
|
|
899
|
+
_c.bindGroupCounts,
|
|
900
|
+
);
|
|
901
|
+
|
|
902
|
+
const pass: RhiRenderPassEncoder =
|
|
903
|
+
graphPass ??
|
|
904
|
+
encoder.beginRenderPass(
|
|
905
|
+
buildBeginRenderPassDescriptor(
|
|
906
|
+
{ colorFormats: ['r8unorm'], depthFormat: undefined, sampleCount: 1 },
|
|
907
|
+
{ colorViews: [ssaoRawView] },
|
|
908
|
+
'post-process',
|
|
909
|
+
) as never,
|
|
910
|
+
);
|
|
911
|
+
pass.setPipeline(pp.ssaoCalcPipeline);
|
|
912
|
+
pass.setBindGroup(0, bindGroup);
|
|
913
|
+
pass.draw(3, 1, 0, 0);
|
|
914
|
+
if (graphPass === undefined) pass.end();
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* recordSsaoBlurPass — fullscreen SSAO 4x4 box blur (M8 / w38).
|
|
919
|
+
*
|
|
920
|
+
* Reads the half-resolution ssaoRaw (R8), applies a 16-tap box blur, writes
|
|
921
|
+
* the blurred result to ssaoBlurred. The BGL is the same 9-entry SSAO BGL
|
|
922
|
+
* as the calc pass; the only difference is binding 7 carries the real
|
|
923
|
+
* ssaoRaw view (vs the 1x1 fallback the calc pass binds).
|
|
924
|
+
*/
|
|
925
|
+
export interface SsaoBlurPassViews extends SsaoCalcPassViews {
|
|
926
|
+
readonly raw: TextureView;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
export function recordSsaoBlurPass(
|
|
930
|
+
_c: _InternalRenderPipelineContext,
|
|
931
|
+
resolveCtx?: ResolveContext,
|
|
932
|
+
ssaoBlurredKey?: string,
|
|
933
|
+
ssaoRawKey?: string,
|
|
934
|
+
gbuf0Key?: string,
|
|
935
|
+
hdrDepthKey?: string,
|
|
936
|
+
graphPass?: RhiRenderPassEncoder,
|
|
937
|
+
graphViews?: SsaoBlurPassViews,
|
|
938
|
+
): void {
|
|
939
|
+
const { runtime, pipelineState, encoder } = _c;
|
|
940
|
+
const pp = pipelineState.perPassResources;
|
|
941
|
+
|
|
942
|
+
if (pp.ssaoBlurPipeline === null || pp.ssaoBgl === null) return;
|
|
943
|
+
if (
|
|
944
|
+
graphViews === undefined &&
|
|
945
|
+
(resolveCtx === undefined || ssaoBlurredKey === undefined || ssaoRawKey === undefined)
|
|
946
|
+
)
|
|
947
|
+
return;
|
|
948
|
+
|
|
949
|
+
const ssaoBlurredView =
|
|
950
|
+
graphViews?.output ??
|
|
951
|
+
(resolveCtx?.resolve(ssaoBlurredKey as string) as TextureView | undefined);
|
|
952
|
+
const ssaoRawView =
|
|
953
|
+
graphViews?.raw ?? (resolveCtx?.resolve(ssaoRawKey as string) as TextureView | undefined);
|
|
954
|
+
const gbuf0View =
|
|
955
|
+
graphViews?.normal ??
|
|
956
|
+
(gbuf0Key !== undefined
|
|
957
|
+
? (resolveCtx?.resolve(gbuf0Key) as TextureView | undefined)
|
|
958
|
+
: undefined);
|
|
959
|
+
if (!ssaoBlurredView || !ssaoRawView) return;
|
|
960
|
+
|
|
961
|
+
// hdrDepth depth-only view (see recordSsaoCalcPass).
|
|
962
|
+
const hdrDepthView =
|
|
963
|
+
graphViews?.depth ??
|
|
964
|
+
(hdrDepthKey !== undefined ? resolveHdrDepthDepthOnlyView(_c, hdrDepthKey) : null);
|
|
965
|
+
// Pooled hdrDepth view for the cache key (the depth-only view above is
|
|
966
|
+
// recreated every frame; see recordSsaoCalcPass).
|
|
967
|
+
const hdrDepthPooledView =
|
|
968
|
+
graphViews?.depthCacheKey ??
|
|
969
|
+
(hdrDepthKey !== undefined
|
|
970
|
+
? (resolveCtx?.resolve(hdrDepthKey) as TextureView | undefined)
|
|
971
|
+
: undefined);
|
|
972
|
+
|
|
973
|
+
const ssaoBufs = getOrCreateSsaoBuffers(runtime);
|
|
974
|
+
if (ssaoBufs === null) return;
|
|
975
|
+
|
|
976
|
+
const noiseViewRes = runtime.device.createTextureView(ssaoBufs.noiseTexture, {
|
|
977
|
+
label: 'hdrp-ssao-noise-view',
|
|
978
|
+
format: 'rgba32float',
|
|
979
|
+
dimension: '2d',
|
|
980
|
+
aspect: 'all',
|
|
981
|
+
baseMipLevel: 0,
|
|
982
|
+
mipLevelCount: 1,
|
|
983
|
+
baseArrayLayer: 0,
|
|
984
|
+
arrayLayerCount: 1,
|
|
985
|
+
});
|
|
986
|
+
if (!noiseViewRes.ok) {
|
|
987
|
+
runtime.errorRegistry.fire(noiseViewRes.error);
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
const companions = ensureSsaoRecordCompanions(_c);
|
|
992
|
+
if (companions === null) return;
|
|
993
|
+
|
|
994
|
+
// The blur reads ssaoRaw via binding 7 + ssaoSampler at binding 8. The
|
|
995
|
+
// remaining slots 0..6 are bound for BGL completeness (BGL is shared with
|
|
996
|
+
// the calc pass): WebGPU requires every BGL slot carry a valid resource
|
|
997
|
+
// even when the active fragment entry does not statically reference it.
|
|
998
|
+
// gbuf0 + hdr_depth views are resolved from the graph; they must exist
|
|
999
|
+
// because addSsaoPasses declares them as `reads` on the blur node.
|
|
1000
|
+
if (gbuf0View === undefined || hdrDepthView === null || hdrDepthPooledView === undefined) return;
|
|
1001
|
+
// Identity-cached bind group keyed on the graph-pooled ssaoRaw + gbuf0 +
|
|
1002
|
+
// hdrDepth views (all retire + reallocate on resize). Replaces the prior
|
|
1003
|
+
// `=== null` slot cache that submitted destroyed transients after resize.
|
|
1004
|
+
const ssaoBgl = pp.ssaoBgl;
|
|
1005
|
+
const bindGroup = getOrCreateFromChain(
|
|
1006
|
+
_c.frameState.postProcessBgCache,
|
|
1007
|
+
[
|
|
1008
|
+
ssaoRawView as unknown as object,
|
|
1009
|
+
gbuf0View as unknown as object,
|
|
1010
|
+
hdrDepthPooledView as unknown as object,
|
|
1011
|
+
],
|
|
1012
|
+
'ssao-blur',
|
|
1013
|
+
() => {
|
|
1014
|
+
const bgRes = runtime.device.createBindGroup({
|
|
1015
|
+
label: 'ssao-blur-bg',
|
|
1016
|
+
layout: ssaoBgl,
|
|
1017
|
+
entries: [
|
|
1018
|
+
{ binding: 0, resource: { kind: 'buffer', value: { buffer: ssaoBufs.uniformBuffer } } },
|
|
1019
|
+
{ binding: 1, resource: { kind: 'buffer', value: { buffer: ssaoBufs.kernelBuffer } } },
|
|
1020
|
+
{ binding: 2, resource: { kind: 'textureView', value: noiseViewRes.value } },
|
|
1021
|
+
{
|
|
1022
|
+
binding: 3,
|
|
1023
|
+
resource: { kind: 'sampler', value: companions.filteringSampler },
|
|
1024
|
+
},
|
|
1025
|
+
{ binding: 4, resource: { kind: 'textureView', value: gbuf0View } },
|
|
1026
|
+
{ binding: 5, resource: { kind: 'textureView', value: hdrDepthView } },
|
|
1027
|
+
{ binding: 6, resource: { kind: 'sampler', value: companions.depthSampler } },
|
|
1028
|
+
{ binding: 7, resource: { kind: 'textureView', value: ssaoRawView } },
|
|
1029
|
+
{ binding: 8, resource: { kind: 'sampler', value: companions.filteringSampler } },
|
|
1030
|
+
],
|
|
1031
|
+
});
|
|
1032
|
+
if (!bgRes.ok) throw bgRes.error;
|
|
1033
|
+
return bgRes.value;
|
|
1034
|
+
},
|
|
1035
|
+
_c.bindGroupCounts,
|
|
1036
|
+
);
|
|
1037
|
+
|
|
1038
|
+
const pass: RhiRenderPassEncoder =
|
|
1039
|
+
graphPass ??
|
|
1040
|
+
encoder.beginRenderPass(
|
|
1041
|
+
buildBeginRenderPassDescriptor(
|
|
1042
|
+
{ colorFormats: ['r8unorm'], depthFormat: undefined, sampleCount: 1 },
|
|
1043
|
+
{ colorViews: [ssaoBlurredView] },
|
|
1044
|
+
'post-process',
|
|
1045
|
+
) as never,
|
|
1046
|
+
);
|
|
1047
|
+
pass.setPipeline(pp.ssaoBlurPipeline);
|
|
1048
|
+
pass.setBindGroup(0, bindGroup);
|
|
1049
|
+
pass.draw(3, 1, 0, 0);
|
|
1050
|
+
if (graphPass === undefined) pass.end();
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
export interface AddTonemapPassOptions {
|
|
1054
|
+
/** Logical HDR resource tonemap reads when bloom is on (the bloom composite output). */
|
|
1055
|
+
readonly hdrComposited: string;
|
|
1056
|
+
/**
|
|
1057
|
+
* Logical HDR resource tonemap reads when bloom is OFF (the bloom composite
|
|
1058
|
+
* pass is gated off and never writes hdrComposited). Defaults to
|
|
1059
|
+
* `hdrComposited` for pipelines where the two are the same texture (e.g.
|
|
1060
|
+
* HDRP passes `hdrColor` for both). URP passes `hdrColor` here so that with
|
|
1061
|
+
* bloom off, tonemap reads the main-rendered scene directly instead of an
|
|
1062
|
+
* unwritten hdrComposited target (bug-20260625).
|
|
1063
|
+
*/
|
|
1064
|
+
readonly hdrColorWhenBloomOff?: string;
|
|
1065
|
+
/** Logical LDR output; defaults to the swap-chain. */
|
|
1066
|
+
readonly color?: string;
|
|
1067
|
+
/** Run the final linear-LDR -> display-encoded output without tone mapping. */
|
|
1068
|
+
readonly outputOnly?: boolean;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* Reserved post-process id for the engine built-in tonemap (feat-20260621 M-A3
|
|
1073
|
+
* / D-5). Registered at boot via `postProcess.register(TONEMAP_POST_PROCESS_ID,
|
|
1074
|
+
* { source, params })`; the extract stage bridges `Camera.exposure / whitePoint
|
|
1075
|
+
* / tonemap` onto the params channel under this key (render-system-extract.ts).
|
|
1076
|
+
*/
|
|
1077
|
+
export const TONEMAP_POST_PROCESS_ID = 'forgeax::tonemap';
|
|
1078
|
+
|
|
1079
|
+
/**
|
|
1080
|
+
* HDR -> LDR tonemap fullscreen pass. feat-20260621 M-A3 (D-5): the built-in
|
|
1081
|
+
* tonemap now flows through the SAME unified fullscreen post-process channel as
|
|
1082
|
+
* any custom post-process — registered at boot via `postProcess.register(
|
|
1083
|
+
* 'forgeax::tonemap', { source, params })`, its exposure/whitePoint/mode bridged
|
|
1084
|
+
* onto the per-frame params channel by the extract stage, and dispatched here
|
|
1085
|
+
* through `dispatchFullscreenPass`. This wrapper preserves two behaviours the
|
|
1086
|
+
* generic `addFullscreenPass` lacks:
|
|
1087
|
+
* - the per-frame `tonemapActive` gate (`camera.tonemap === 'none'` ->
|
|
1088
|
+
* zero-overhead skip), and
|
|
1089
|
+
* - graceful degradation (charter §9) on the empty-manifest path: when
|
|
1090
|
+
* `forgeax::tonemap` was never registered (Camera-only world, no manifest)
|
|
1091
|
+
* fire a structured `shader-compile-failed` instead of letting the
|
|
1092
|
+
* dispatcher throw `post-process-not-found`.
|
|
1093
|
+
* The output is a graph resource when FXAA is active, otherwise the reserved
|
|
1094
|
+
* `'swapchain'` key resolves to the current surface view.
|
|
1095
|
+
*/
|
|
1096
|
+
export function addTonemapPass(
|
|
1097
|
+
graph: RenderGraph<RenderPipelineContext>,
|
|
1098
|
+
name: string,
|
|
1099
|
+
opts: AddTonemapPassOptions,
|
|
1100
|
+
): void {
|
|
1101
|
+
// Declare both potential read sources so validation preserves tonemap after
|
|
1102
|
+
// BOTH the composite writer (hdrComposited) and the main writer (hdrColor),
|
|
1103
|
+
// regardless of which one the dispatch resolves at record time. resolveCtx
|
|
1104
|
+
// exposes every compiled texture, so the runtime pick below always resolves.
|
|
1105
|
+
const hdrColorWhenBloomOff = opts.hdrColorWhenBloomOff ?? opts.hdrComposited;
|
|
1106
|
+
const tonemapReads =
|
|
1107
|
+
hdrColorWhenBloomOff === opts.hdrComposited
|
|
1108
|
+
? [opts.hdrComposited]
|
|
1109
|
+
: [opts.hdrComposited, hdrColorWhenBloomOff];
|
|
1110
|
+
graph.addPass(name, {
|
|
1111
|
+
reads: tonemapReads,
|
|
1112
|
+
writes: [opts.color ?? 'swapchain'],
|
|
1113
|
+
...(opts.color !== undefined && opts.color !== 'swapchain'
|
|
1114
|
+
? {
|
|
1115
|
+
colorConnections: [
|
|
1116
|
+
{
|
|
1117
|
+
source: hdrColorWhenBloomOff,
|
|
1118
|
+
destination: opts.color,
|
|
1119
|
+
conversion: { kind: 'tone-map' as const },
|
|
1120
|
+
},
|
|
1121
|
+
],
|
|
1122
|
+
}
|
|
1123
|
+
: {}),
|
|
1124
|
+
execute: (ctx: RenderPipelineContext, resolveCtx?: ResolveContext) => {
|
|
1125
|
+
// Tonemap mode `none` still needs the final output encode when the scene
|
|
1126
|
+
// was rendered into the graph-owned linear-LDR target.
|
|
1127
|
+
if (ctx.camera.tonemap === 'none' && opts.outputOnly !== true) return;
|
|
1128
|
+
const registered = ctx.runtime.lookupPostProcess?.(TONEMAP_POST_PROCESS_ID);
|
|
1129
|
+
if (registered === undefined) {
|
|
1130
|
+
ctx.runtime.errorRegistry.fire(
|
|
1131
|
+
new RhiError({
|
|
1132
|
+
code: 'shader-compile-failed',
|
|
1133
|
+
expected:
|
|
1134
|
+
'manifest entries include pbr.wgsl + unlit.wgsl + tonemap.wgsl (engine SSOT triple)',
|
|
1135
|
+
hint: 'verify @forgeax/engine-vite-plugin-shader emits manifest.json with the 3 engine entries; check vite plugin engineEntries option',
|
|
1136
|
+
}),
|
|
1137
|
+
);
|
|
1138
|
+
return;
|
|
1139
|
+
}
|
|
1140
|
+
// Pick the read source by bloom state: when bloom is on the composite
|
|
1141
|
+
// pass wrote hdrComposited; when off it was gated and never ran, so read
|
|
1142
|
+
// the main-rendered hdrColor instead (bug-20260625). Same texture for
|
|
1143
|
+
// pipelines that pass identical keys (e.g. HDRP).
|
|
1144
|
+
const src =
|
|
1145
|
+
opts.outputOnly === true
|
|
1146
|
+
? hdrColorWhenBloomOff
|
|
1147
|
+
: ctx.camera.bloom === 'on'
|
|
1148
|
+
? opts.hdrComposited
|
|
1149
|
+
: hdrColorWhenBloomOff;
|
|
1150
|
+
dispatchFullscreenPass(
|
|
1151
|
+
ctx,
|
|
1152
|
+
name,
|
|
1153
|
+
TONEMAP_POST_PROCESS_ID,
|
|
1154
|
+
opts.color ?? 'swapchain',
|
|
1155
|
+
[src],
|
|
1156
|
+
resolveCtx,
|
|
1157
|
+
false,
|
|
1158
|
+
opts.outputOnly === true,
|
|
1159
|
+
);
|
|
1160
|
+
},
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
export interface AddFullscreenPassOptions {
|
|
1165
|
+
/**
|
|
1166
|
+
* Registered post-process shader id (via renderer.postProcess.register). The
|
|
1167
|
+
* built-in `'fxaa'` id is a hardwired dispatcher branch; any other id is an
|
|
1168
|
+
* AI-user effect whose WGSL declares `vs_main` + `fs_main` and samples the
|
|
1169
|
+
* input at `@group(1) @binding(0)` texture + `@binding(1)` sampler. With
|
|
1170
|
+
* `compositeOverSwapchain` this is how an effect layers over URP's final image
|
|
1171
|
+
* (see RenderPipelineAsset.config.postEffects).
|
|
1172
|
+
*/
|
|
1173
|
+
readonly shader: string;
|
|
1174
|
+
/** Graph resource key the pass writes (intermediate scratch RT for FXAA / the composite scratch). */
|
|
1175
|
+
readonly color: string;
|
|
1176
|
+
/** Graph resource keys the pass samples. Empty = use the current surface view. */
|
|
1177
|
+
readonly reads?: readonly string[] | undefined;
|
|
1178
|
+
/**
|
|
1179
|
+
* feat-20260621 M4': composite-over-swap-chain mode. When true, the pass
|
|
1180
|
+
* copies the CURRENT swap-chain into the `color` scratch target (so the effect
|
|
1181
|
+
* samples the already-composited final image), samples that scratch, then
|
|
1182
|
+
* writes the result back into the swap-chain through its non-srgb storage view
|
|
1183
|
+
* (R-COLORSPACE: the swap-chain is already sRGB-encoded, so writing through the
|
|
1184
|
+
* srgb view would double-encode). This is the generalisation of the built-in
|
|
1185
|
+
* `'fxaa'` copy idiom to AI-user effects — the mechanism that lets a built-in
|
|
1186
|
+
* pipeline layer a registered effect on top of its final image WITHOUT
|
|
1187
|
+
* replacing the pipeline (and dropping its shadow / tonemap passes). `color`
|
|
1188
|
+
* MUST be a `graph.addColorTarget` declared with the swap-chain storage format
|
|
1189
|
+
* + COPY_DST | TEXTURE_BINDING usage (it is both copy dst and sampled input);
|
|
1190
|
+
* `reads` stays empty.
|
|
1191
|
+
*
|
|
1192
|
+
* WebGPU backend only: the mid-frame swap-chain copy + non-srgb storage-view
|
|
1193
|
+
* write are not supported on the WebGL2 fallback swap-chain (no COPY_SRC, no
|
|
1194
|
+
* non-srgb reinterpret view) — the same constraint `recordFxaaPass` carries.
|
|
1195
|
+
*/
|
|
1196
|
+
readonly compositeOverSwapchain?: boolean | undefined;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
/**
|
|
1200
|
+
* AC-06 / AC-07: declare a generic fullscreen post-process pass. The shader is
|
|
1201
|
+
* looked up from `renderer.postProcess.register(shader, …)`; the primitive
|
|
1202
|
+
* builds the input-texture BGL + sampler + pipeline + ping-pong wiring. For
|
|
1203
|
+
* the FXAA case the implementation detail is `recordFxaaPass`
|
|
1204
|
+
* (package-private), which owns the graph-input-to-surface-output attachment
|
|
1205
|
+
* route.
|
|
1206
|
+
*
|
|
1207
|
+
* If `opts.reads` is empty the pass uses the current surface view (default).
|
|
1208
|
+
* Post-processes that read a graph-owned texture
|
|
1209
|
+
* (e.g. tonemap rebuilt as a fullscreen pass, OOS-3) will declare reads
|
|
1210
|
+
* explicitly.
|
|
1211
|
+
*
|
|
1212
|
+
* F-3 topology refactor (2026-06-08): the FXAA path now flows through this
|
|
1213
|
+
* dispatcher (`addFullscreenPass(g, 'fxaa', ...)` -> `dispatchFullscreenPass` ->
|
|
1214
|
+
* `recordFxaaPass`). The two-branch dispatcher is the load-bearing AC-09
|
|
1215
|
+
* "FXAA refactored as the first post-process instance" claim: at the
|
|
1216
|
+
* topology layer FXAA is a special-cased shader id; at the record layer
|
|
1217
|
+
* recordFxaaPass owns the backend-aware output attachment. The
|
|
1218
|
+
* dispatcher is extracted as a named function (`dispatchFullscreenPass`)
|
|
1219
|
+
* so an AI user reading the per-pass execute closure sees a single call
|
|
1220
|
+
* site — the if/else fan-out is in one place, not duplicated across
|
|
1221
|
+
* future fullscreen passes.
|
|
1222
|
+
*/
|
|
1223
|
+
export function addFullscreenPass(
|
|
1224
|
+
graph: RenderGraph<RenderPipelineContext>,
|
|
1225
|
+
name: string,
|
|
1226
|
+
opts: AddFullscreenPassOptions,
|
|
1227
|
+
): void {
|
|
1228
|
+
const reads = opts.reads ?? [];
|
|
1229
|
+
graph.addPass(name, {
|
|
1230
|
+
reads,
|
|
1231
|
+
writes: [opts.color],
|
|
1232
|
+
execute: (ctx: RenderPipelineContext, resolveCtx?: ResolveContext) => {
|
|
1233
|
+
dispatchFullscreenPass(
|
|
1234
|
+
ctx,
|
|
1235
|
+
name,
|
|
1236
|
+
opts.shader,
|
|
1237
|
+
opts.color,
|
|
1238
|
+
reads,
|
|
1239
|
+
resolveCtx,
|
|
1240
|
+
opts.compositeOverSwapchain ?? false,
|
|
1241
|
+
);
|
|
1242
|
+
},
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
/**
|
|
1247
|
+
* F-3 fix-up + feat-20260609 M1 / T-3 patch: per-frame fullscreen-post-process
|
|
1248
|
+
* dispatcher.
|
|
1249
|
+
*
|
|
1250
|
+
* Two-branch fan-out by shader id:
|
|
1251
|
+
* - `'fxaa'` (engine-built-in hardwire): delegate to `recordFxaaPass`. The
|
|
1252
|
+
* FXAA implementation owns its graph input view, surface output attachment,
|
|
1253
|
+
* pipeline cache, and bindgroup-resize invalidation; that mechanics is engine-internal and
|
|
1254
|
+
* not expressible through the generic public primitive. recordFxaaPass's
|
|
1255
|
+
* body is intentionally unchanged across this refactor to preserve the
|
|
1256
|
+
* AC-09 dualPassDiff=1069 (hello-fxaa) / 768 (learn-render-4-10-MSAA)
|
|
1257
|
+
* byte-equivalence with the pre-feat baseline.
|
|
1258
|
+
* - any other id (AI-user path): the M1 patch wires `reads[0]` through the
|
|
1259
|
+
* render-graph `resolveCtx` so the bind group samples the upstream
|
|
1260
|
+
* graph-owned color target (e.g. `addScenePass` writes `'offscreenColor'`,
|
|
1261
|
+
* a custom post-process pass declares `reads: ['offscreenColor']`).
|
|
1262
|
+
* Failure modes (charter P3 fail-fast):
|
|
1263
|
+
* - `lookupPostProcess(shader) === undefined` -> throw
|
|
1264
|
+
* `PostProcessError({code:'post-process-not-found'})`
|
|
1265
|
+
* - `reads.length > 0` but `resolveCtx.resolve(reads[0]) === undefined`
|
|
1266
|
+
* -> throw `PostProcessError({code:'fullscreen-input-not-found',
|
|
1267
|
+
* detail:{readsKey, passName}})`. AI users read err.detail.readsKey
|
|
1268
|
+
* to find the missing graph.addColorTarget declaration.
|
|
1269
|
+
* On success the dispatcher builds the input-texture BGL + sampler via
|
|
1270
|
+
* `buildFullscreenPostProcessPass`, composes the per-frame bind group
|
|
1271
|
+
* via `createFullscreenBindGroup`, opens a render pass writing the
|
|
1272
|
+
* declared `color` (resolved through the graph's color-target view, or
|
|
1273
|
+
* the swap-chain `ctx.view` when the graph has not allocated a target),
|
|
1274
|
+
* binds the input bind group at slot 1 (the 0 slot is reserved for
|
|
1275
|
+
* future view bind groups), and calls `handle.draw(pass)` which
|
|
1276
|
+
* internally does `setPipeline(pipeline)` + `draw(3, 1, 0, 0)` over the
|
|
1277
|
+
* fullscreen-triangle vertex shader.
|
|
1278
|
+
*
|
|
1279
|
+
* Extracted from the addPass execute closure so the topology fan-out is in
|
|
1280
|
+
* one named place; an AI user reading addFullscreenPass sees the single
|
|
1281
|
+
* call site, and future post-process branches (e.g. tonemap migrated onto
|
|
1282
|
+
* this dispatcher per OOS-3) extend this function rather than the addPass
|
|
1283
|
+
* inline closure.
|
|
1284
|
+
*/
|
|
1285
|
+
function dispatchFullscreenPass(
|
|
1286
|
+
ctx: RenderPipelineContext,
|
|
1287
|
+
name: string,
|
|
1288
|
+
shader: string,
|
|
1289
|
+
color: string,
|
|
1290
|
+
reads: readonly string[],
|
|
1291
|
+
resolveCtx?: ResolveContext,
|
|
1292
|
+
compositeOverSwapchain = false,
|
|
1293
|
+
rawSwapchainOutput = false,
|
|
1294
|
+
graphPass?: RhiRenderPassEncoder,
|
|
1295
|
+
graphOutputFormat?: GPUTextureFormat,
|
|
1296
|
+
graphDepthView?: TextureView,
|
|
1297
|
+
): void {
|
|
1298
|
+
if (shader === 'fxaa') {
|
|
1299
|
+
if (resolveCtx === undefined) {
|
|
1300
|
+
throw new PostProcessError({
|
|
1301
|
+
code: 'fullscreen-input-not-found',
|
|
1302
|
+
detail: { readsKey: reads[0] ?? 'ldrColor', passName: name },
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
recordFxaaPass(ctx as unknown as _InternalRenderPipelineContext, resolveCtx, graphPass);
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
const lookup = ctx.runtime.lookupPostProcess;
|
|
1309
|
+
const entry = lookup === undefined ? undefined : lookup(shader);
|
|
1310
|
+
if (entry === undefined) {
|
|
1311
|
+
throw new PostProcessError({
|
|
1312
|
+
code: 'post-process-not-found',
|
|
1313
|
+
detail: { id: shader },
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
// feat-20260621 M4' composite-over-swap-chain: copy the current swap-chain
|
|
1318
|
+
// into the `color` scratch target BEFORE sampling, so the effect reads the
|
|
1319
|
+
// already-composited final image (shadows + tonemap + fxaa). Generalises the
|
|
1320
|
+
// built-in FXAA copy idiom. The `color` key is BOTH the copy dst and the
|
|
1321
|
+
// sampled input (resolve its GPU texture via `${color}::tex` for the copy,
|
|
1322
|
+
// its TextureView via `${color}` for the bind group).
|
|
1323
|
+
let inputView: TextureView | null;
|
|
1324
|
+
if (compositeOverSwapchain) {
|
|
1325
|
+
const scratchTex = resolveCtx?.resolve(`${color}::tex`);
|
|
1326
|
+
const scratchView = resolveCtx?.resolve(color);
|
|
1327
|
+
if (scratchTex === undefined || scratchView === undefined) {
|
|
1328
|
+
throw new PostProcessError({
|
|
1329
|
+
code: 'fullscreen-input-not-found',
|
|
1330
|
+
detail: { readsKey: color, passName: name },
|
|
1331
|
+
});
|
|
1332
|
+
}
|
|
1333
|
+
ctx.encoder.copyTextureToTexture(
|
|
1334
|
+
{ texture: ctx.currentTexture as never, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },
|
|
1335
|
+
{ texture: scratchTex as never, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },
|
|
1336
|
+
{ width: ctx.targetW, height: ctx.targetH, depthOrArrayLayers: 1 },
|
|
1337
|
+
);
|
|
1338
|
+
inputView = scratchView as TextureView;
|
|
1339
|
+
} else if (reads.length === 0) {
|
|
1340
|
+
// reads === [] preserves the legacy swap-chain sample path (used by
|
|
1341
|
+
// tonemap-style passes that read the framebuffer directly).
|
|
1342
|
+
inputView = ctx.view;
|
|
1343
|
+
} else {
|
|
1344
|
+
// reads with a key MUST resolve through the graph compile output, otherwise
|
|
1345
|
+
// the dispatcher throws fullscreen-input-not-found (charter P3 fail-fast).
|
|
1346
|
+
const readsKey = reads[0] as string;
|
|
1347
|
+
const resolved = resolveCtx?.resolve(readsKey);
|
|
1348
|
+
if (resolved === undefined) {
|
|
1349
|
+
throw new PostProcessError({
|
|
1350
|
+
code: 'fullscreen-input-not-found',
|
|
1351
|
+
detail: { readsKey, passName: name },
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
inputView = resolved as TextureView;
|
|
1355
|
+
}
|
|
1356
|
+
if (inputView === null) return;
|
|
1357
|
+
|
|
1358
|
+
// ── BGL/Pipeline build (before depth resolution so built.depthSampler is
|
|
1359
|
+
// available for the depth threading block below; ctx.msaaActive selects
|
|
1360
|
+
// the multisampled depth BGL when the scene target uses sample=4) ───────
|
|
1361
|
+
const built = buildFullscreenPostProcessPass(
|
|
1362
|
+
{ device: ctx.runtime.device, errorRegistry: ctx.runtime.errorRegistry },
|
|
1363
|
+
entry,
|
|
1364
|
+
ctx.msaaActive,
|
|
1365
|
+
);
|
|
1366
|
+
if (built === null) return;
|
|
1367
|
+
|
|
1368
|
+
// ── plan-strategy D-6: depth read resolution (pipeline-agnostic, AC-02) ────
|
|
1369
|
+
// Iterate entry.reads looking for sampleType:'depth' entries. For each depth
|
|
1370
|
+
// entry, resolve a depth-only TextureView from the graph via
|
|
1371
|
+
// resolveDepthOnlyView, fail-fast on unresolvable keys. The depth sampler
|
|
1372
|
+
// is produced by buildFullscreenPostProcessPass (via createDepthSampler,
|
|
1373
|
+
// plan-strategy D-2: non-filtering nearest+clamp-to-edge).
|
|
1374
|
+
//
|
|
1375
|
+
// Both composite and non-composite branches handle depth symmetrically —
|
|
1376
|
+
// the depth resolution block is branch-agnostic (AC-02: no URP/HDRP
|
|
1377
|
+
// discrimination). Color input logic is unchanged (AC-03 zero-regression).
|
|
1378
|
+
let depthTexView: TextureView | null = graphDepthView ?? null;
|
|
1379
|
+
let depthSampler: Sampler | null = null;
|
|
1380
|
+
if (entry.reads && entry.reads.length > 0) {
|
|
1381
|
+
const internals = ctx as unknown as _InternalRenderPipelineContext;
|
|
1382
|
+
for (const read of entry.reads) {
|
|
1383
|
+
if (typeof read !== 'string' && read.sampleType === 'depth') {
|
|
1384
|
+
const depthKey = read.key;
|
|
1385
|
+
depthTexView ??= resolveDepthOnlyView(
|
|
1386
|
+
internals,
|
|
1387
|
+
depthKey,
|
|
1388
|
+
'post-process-scene-depth-only-view',
|
|
1389
|
+
internals.geometryDepthKey,
|
|
1390
|
+
);
|
|
1391
|
+
if (depthTexView === null) {
|
|
1392
|
+
throw new PostProcessError({
|
|
1393
|
+
code: 'fullscreen-input-not-found',
|
|
1394
|
+
detail: { readsKey: depthKey, passName: name },
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
depthSampler = built.depthSampler;
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
const gbufferReadKeys = (entry.reads ?? [])
|
|
1403
|
+
.map((read) => (typeof read === 'string' ? read : read.key))
|
|
1404
|
+
.filter((key) => key === 'gbuffer-normal-roughness' || key === 'gbuffer-emissive-ao');
|
|
1405
|
+
const gbufferViews = gbufferReadKeys.map((key) => {
|
|
1406
|
+
const resolved = resolveCtx?.resolve(key);
|
|
1407
|
+
if (resolved === undefined) {
|
|
1408
|
+
throw new PostProcessError({
|
|
1409
|
+
code: 'fullscreen-input-not-found',
|
|
1410
|
+
detail: { readsKey: key, passName: name },
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1413
|
+
return resolved as TextureView;
|
|
1414
|
+
});
|
|
1415
|
+
|
|
1416
|
+
// feat-20260621 M4' composite-over-swap-chain write target: the swap-chain's
|
|
1417
|
+
// NON-srgb storage view (R-COLORSPACE — the scratch holds an already-sRGB-
|
|
1418
|
+
// encoded copy, so writing through the srgb view would double-encode; mirrors
|
|
1419
|
+
// recordFxaaPass). Otherwise resolve the declared color through the graph and
|
|
1420
|
+
// fall back to ctx.view (swap-chain srgb view) for normal post passes.
|
|
1421
|
+
let writeView: TextureView | null | undefined;
|
|
1422
|
+
// The attachment format follows the actual write target. Graph-owned
|
|
1423
|
+
// targets may be linear HDR/LDR textures (for example rgba16float), while
|
|
1424
|
+
// the swap-chain path uses the backend-selected surface view format.
|
|
1425
|
+
let writeFormat = ctx.pipelineState?.colorAttachmentFormat ?? 'rgba8unorm-srgb';
|
|
1426
|
+
if (graphPass !== undefined) {
|
|
1427
|
+
writeView = (resolveCtx?.resolve(color) as TextureView | undefined) ?? ctx.view;
|
|
1428
|
+
writeFormat = graphOutputFormat ?? writeFormat;
|
|
1429
|
+
} else if (rawSwapchainOutput && color === 'swapchain') {
|
|
1430
|
+
const rawViewRes = ctx.runtime.device.createTextureView(ctx.currentTexture, {});
|
|
1431
|
+
if (!rawViewRes.ok) {
|
|
1432
|
+
ctx.runtime.errorRegistry.fire(rawViewRes.error);
|
|
1433
|
+
return;
|
|
1434
|
+
}
|
|
1435
|
+
writeView = rawViewRes.value;
|
|
1436
|
+
writeFormat = ctx.pipelineState?.format ?? 'rgba8unorm';
|
|
1437
|
+
} else if (compositeOverSwapchain) {
|
|
1438
|
+
const storageViewRes = ctx.runtime.device.createTextureView(ctx.currentTexture, {});
|
|
1439
|
+
if (!storageViewRes.ok) {
|
|
1440
|
+
ctx.runtime.errorRegistry.fire(storageViewRes.error);
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
writeView = storageViewRes.value;
|
|
1444
|
+
writeFormat = ctx.pipelineState?.format ?? 'rgba8unorm';
|
|
1445
|
+
} else {
|
|
1446
|
+
const internalCtx = ctx as unknown as Partial<_InternalRenderPipelineContext>;
|
|
1447
|
+
const legacyGraph = (
|
|
1448
|
+
internalCtx.frameState as unknown as
|
|
1449
|
+
| {
|
|
1450
|
+
readonly perFrameGraph?: {
|
|
1451
|
+
getColorTargetDescriptor(key: string): { readonly format: string } | undefined;
|
|
1452
|
+
getColorTargetView(key: string): TextureView | undefined;
|
|
1453
|
+
} | null;
|
|
1454
|
+
}
|
|
1455
|
+
| undefined
|
|
1456
|
+
)?.perFrameGraph;
|
|
1457
|
+
const graphColorFormat = legacyGraph?.getColorTargetDescriptor(color)?.format;
|
|
1458
|
+
if (graphColorFormat !== undefined) writeFormat = graphColorFormat;
|
|
1459
|
+
const resolvedColor = (resolveCtx?.resolve(color) as TextureView | undefined) ?? null;
|
|
1460
|
+
writeView = legacyGraph?.getColorTargetView(color) ?? resolvedColor ?? ctx.view;
|
|
1461
|
+
}
|
|
1462
|
+
if (writeView === null || writeView === undefined) return;
|
|
1463
|
+
|
|
1464
|
+
// feat-20260621 M-A2 / w8: per-frame data-driven params channel. When the
|
|
1465
|
+
// entry declares params, look up the per-id eager-created UBO + the per-frame
|
|
1466
|
+
// bytes from the PostProcessParams snapshot, fail-fast on a byteLength
|
|
1467
|
+
// mismatch, then writeBuffer + bind the UBO at group(1) binding(2). When
|
|
1468
|
+
// entry.params is undefined this whole block is skipped and the BGL degrades
|
|
1469
|
+
// to 2-entry (param-less zero-regression, R-A7).
|
|
1470
|
+
let paramsBuffer: Buffer | null = null;
|
|
1471
|
+
if (entry.params !== undefined) {
|
|
1472
|
+
const ubo = ctx.runtime.getPostProcessParamsBuffer?.(shader);
|
|
1473
|
+
if (ubo !== undefined) {
|
|
1474
|
+
const data = ctx.postProcessParams.get(shader);
|
|
1475
|
+
if (data !== undefined) {
|
|
1476
|
+
if (data.byteLength !== entry.params.byteSize) {
|
|
1477
|
+
throw new PostProcessError({
|
|
1478
|
+
code: 'params-update-size-mismatch',
|
|
1479
|
+
detail: { byteSize: entry.params.byteSize, actualLength: data.byteLength },
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
const writeResult = ctx.runtime.device.queue.writeBuffer(ubo, 0, data);
|
|
1483
|
+
if (!writeResult.ok) return;
|
|
1484
|
+
} else {
|
|
1485
|
+
const writeResult = ctx.runtime.device.queue.writeBuffer(ubo, 0, entry.params.defaultValue);
|
|
1486
|
+
if (!writeResult.ok) return;
|
|
1487
|
+
}
|
|
1488
|
+
paramsBuffer = ubo;
|
|
1489
|
+
}
|
|
1490
|
+
} else if (entryHasDepthRead(entry)) {
|
|
1491
|
+
// D-3: a param-less depth entry still binds the minimal UBO auto-allocated
|
|
1492
|
+
// at register (the 'fullscreen-post-with-scene-depth' BGL always declares
|
|
1493
|
+
// params@2). No per-frame write -- the buffer stays zero-filled.
|
|
1494
|
+
paramsBuffer = ctx.runtime.getPostProcessParamsBuffer?.(shader) ?? null;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
const bindGroup = createFullscreenBindGroup(
|
|
1498
|
+
ctx.runtime.device,
|
|
1499
|
+
built.bindGroupLayout,
|
|
1500
|
+
inputView,
|
|
1501
|
+
built.sampler,
|
|
1502
|
+
paramsBuffer,
|
|
1503
|
+
depthTexView,
|
|
1504
|
+
depthSampler,
|
|
1505
|
+
gbufferViews[0] ?? null,
|
|
1506
|
+
gbufferViews[1] ?? null,
|
|
1507
|
+
);
|
|
1508
|
+
if (bindGroup === null) return;
|
|
1509
|
+
|
|
1510
|
+
// Pipeline source-of-truth (M4 / T-10-a, solving M1 CONCERN-1):
|
|
1511
|
+
// RenderSystemRuntime.getPostProcessPipeline is the sync wrapper over the
|
|
1512
|
+
// shared shader-module adapter (1-frame warmup). First frame after
|
|
1513
|
+
// postProcess.register: shader compile is in flight -> returns null -> we
|
|
1514
|
+
// skip the pass for that frame. Second frame onward: cached pipeline is
|
|
1515
|
+
// returned synchronously.
|
|
1516
|
+
//
|
|
1517
|
+
// Color format SSOT: graph-owned writes use their resolved descriptor format;
|
|
1518
|
+
// swap-chain writes use the backend-aware surface format in pipelineState.
|
|
1519
|
+
// This keeps the PSO target and render-pass attachment identical when a
|
|
1520
|
+
// fullscreen pass writes an intermediate rgba16float target (for example
|
|
1521
|
+
// tonemap -> FXAA), while preserving the native surface storage/sRGB split.
|
|
1522
|
+
const lookupPipeline = ctx.runtime.getPostProcessPipeline;
|
|
1523
|
+
if (lookupPipeline === undefined) return;
|
|
1524
|
+
const postColorFormat = writeFormat as unknown as GPUTextureFormat;
|
|
1525
|
+
const pipeline = lookupPipeline(shader, built.bindGroupLayout, postColorFormat);
|
|
1526
|
+
if (pipeline === null) return;
|
|
1527
|
+
const handle = built.createHandle(name, pipeline, paramsBuffer);
|
|
1528
|
+
|
|
1529
|
+
// Open a render pass writing into the resolved color target. Fullscreen
|
|
1530
|
+
// post-process passes are non-MSAA, depth-less, single-attachment.
|
|
1531
|
+
// setBindGroup(1, ...) (group=1 reserved per plan-strategy convention;
|
|
1532
|
+
// group=0 is reserved for future view bind groups, mirroring the
|
|
1533
|
+
// recordTonemap / recordSkybox pattern that uses slot 0 only when the
|
|
1534
|
+
// pipeline declares a single bind group at slot 0).
|
|
1535
|
+
const pass =
|
|
1536
|
+
graphPass ??
|
|
1537
|
+
ctx.encoder.beginRenderPass(
|
|
1538
|
+
buildBeginRenderPassDescriptor(
|
|
1539
|
+
{
|
|
1540
|
+
colorFormats: [writeFormat as unknown as GPUTextureFormat],
|
|
1541
|
+
depthFormat: undefined,
|
|
1542
|
+
sampleCount: 1,
|
|
1543
|
+
},
|
|
1544
|
+
{ colorViews: [writeView] },
|
|
1545
|
+
'post-process',
|
|
1546
|
+
) as never,
|
|
1547
|
+
);
|
|
1548
|
+
if (
|
|
1549
|
+
/@group\(0\)\s*@binding\(0\)\s*var<uniform>\s+view\b/.test(entry.source) &&
|
|
1550
|
+
ctx.viewBindGroup
|
|
1551
|
+
) {
|
|
1552
|
+
pass.setBindGroup(0, ctx.viewBindGroup);
|
|
1553
|
+
}
|
|
1554
|
+
pass.setBindGroup(1, bindGroup);
|
|
1555
|
+
handle.draw(pass, inputView);
|
|
1556
|
+
if (graphPass === undefined) pass.end();
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
export function encodeFullscreenPass(
|
|
1560
|
+
ctx: RenderPipelineContext,
|
|
1561
|
+
pass: RhiRenderPassEncoder,
|
|
1562
|
+
input: {
|
|
1563
|
+
readonly name: string;
|
|
1564
|
+
readonly shader: string;
|
|
1565
|
+
readonly color: string;
|
|
1566
|
+
readonly reads: readonly string[];
|
|
1567
|
+
readonly resolve: ResolveContext;
|
|
1568
|
+
readonly outputFormat: GPUTextureFormat;
|
|
1569
|
+
readonly rawSwapchainOutput?: boolean | undefined;
|
|
1570
|
+
readonly depthView?: TextureView | undefined;
|
|
1571
|
+
},
|
|
1572
|
+
): void {
|
|
1573
|
+
dispatchFullscreenPass(
|
|
1574
|
+
ctx,
|
|
1575
|
+
input.name,
|
|
1576
|
+
input.shader,
|
|
1577
|
+
input.color,
|
|
1578
|
+
input.reads,
|
|
1579
|
+
input.resolve,
|
|
1580
|
+
false,
|
|
1581
|
+
input.rawSwapchainOutput ?? false,
|
|
1582
|
+
pass,
|
|
1583
|
+
input.outputFormat,
|
|
1584
|
+
input.depthView,
|
|
1585
|
+
);
|
|
1586
|
+
}
|