@forgeax/engine-render 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/assembly/device-feature-admission.d.ts +18 -0
- package/dist/assembly/device-feature-admission.d.ts.map +1 -0
- package/dist/assembly/directional-shadow-inspection.d.ts +38 -0
- package/dist/assembly/directional-shadow-inspection.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +34 -20
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +9 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/render-target-host.d.ts +46 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -0
- package/dist/assets/render-asset-port.d.ts.map +1 -1
- package/dist/authoring.mjs +3 -0
- package/dist/authoring.mjs.map +1 -1
- package/dist/capture/cube-views.d.ts +21 -0
- package/dist/capture/cube-views.d.ts.map +1 -0
- package/dist/capture/scheduler.d.ts +54 -0
- package/dist/capture/scheduler.d.ts.map +1 -0
- package/dist/{chunk-RJRUS55L.mjs → chunk-5YADUCA7.mjs} +1896 -1624
- package/dist/chunk-5YADUCA7.mjs.map +1 -0
- package/dist/{chunk-LOSO4CTV.mjs → chunk-6OPXDQ2E.mjs} +423 -46
- package/dist/chunk-6OPXDQ2E.mjs.map +1 -0
- package/dist/{chunk-IPXCABEP.mjs → chunk-BXBQQKFQ.mjs} +3 -9
- package/dist/chunk-BXBQQKFQ.mjs.map +1 -0
- package/dist/chunk-FS2KNUQH.mjs +1294 -0
- package/dist/chunk-FS2KNUQH.mjs.map +1 -0
- package/dist/components/camera.d.ts +1 -0
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/cube-camera.d.ts +20 -0
- package/dist/components/cube-camera.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +11 -2
- package/dist/components/directional-light.d.ts.map +1 -1
- package/dist/components/directional-shadow-filter.d.ts +25 -0
- package/dist/components/directional-shadow-filter.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/reflection-probe.d.ts +17 -0
- package/dist/components/reflection-probe.d.ts.map +1 -0
- package/dist/components/spot-light.d.ts +12 -0
- package/dist/components/spot-light.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +8552 -1612
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +19 -2
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/environment/frame.d.ts.map +1 -1
- package/dist/environment/lifecycle.d.ts +5 -0
- package/dist/environment/lifecycle.d.ts.map +1 -1
- package/dist/errors/render.d.ts +209 -93
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/directional-shadow-projection.d.ts +23 -0
- package/dist/extract/directional-shadow-projection.d.ts.map +1 -0
- package/dist/extract/environment.d.ts +14 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/extract/visibility.d.ts.map +1 -1
- package/dist/features/fullscreen.d.ts.map +1 -1
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +10 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +13 -2
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +0 -1
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/gpu-usage.d.ts +2 -0
- package/dist/gpu-usage.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +19 -17
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +4 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/kernel-cache.d.ts +36 -0
- package/dist/ibl/kernel-cache.d.ts.map +1 -0
- package/dist/index.d.ts +35 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +51 -0
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +50 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -0
- package/dist/internal.mjs +1 -1
- package/dist/light-buffer-layout.d.ts +30 -13
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +54 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +20 -7
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts +2 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/errors.d.ts +4 -0
- package/dist/pipeline/standard-lighting/errors.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/graph.d.ts +24 -0
- package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts +38 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/layout.d.ts +28 -0
- package/dist/pipeline/standard-lighting/layout.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts +33 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/membership.d.ts +14 -0
- package/dist/pipeline/standard-lighting/membership.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts +16 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/topology.d.ts +45 -0
- package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/transport.d.ts +36 -0
- package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts +4 -13
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +12 -20
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +40 -7
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/point-shadow-inspection.d.ts +21 -0
- package/dist/point-shadow-inspection.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +29 -32
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +65 -15
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts +5 -0
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +12 -5
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-pass-timing/contract.d.ts +96 -0
- package/dist/record/gpu-pass-timing/contract.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/errors.d.ts +18 -0
- package/dist/record/gpu-pass-timing/errors.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/index.d.ts +8 -0
- package/dist/record/gpu-pass-timing/index.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/parser.d.ts +11 -0
- package/dist/record/gpu-pass-timing/parser.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/session.d.ts +43 -0
- package/dist/record/gpu-pass-timing/session.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +37 -0
- package/dist/record/gpu-timing.d.ts.map +1 -0
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +23 -2
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +2 -0
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +48 -3
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +81 -5
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +7 -4
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/reflection/filter.d.ts +22 -0
- package/dist/reflection/filter.d.ts.map +1 -0
- package/dist/reflection/gpu-table.d.ts +25 -0
- package/dist/reflection/gpu-table.d.ts.map +1 -0
- package/dist/reflection/projection.d.ts +91 -0
- package/dist/reflection/projection.d.ts.map +1 -0
- package/dist/render-contract.d.ts +114 -7
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-data.d.ts +10 -6
- package/dist/render-data.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +78 -2
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +113 -20
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +24 -3
- package/dist/render-system.d.ts.map +1 -1
- package/dist/renderer-inspect.d.ts +29 -0
- package/dist/renderer-inspect.d.ts.map +1 -0
- package/dist/renderer.d.ts +43 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/scene/render-scene.d.ts +14 -0
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/shadow-atlas.d.ts +3 -3
- package/dist/shadow-atlas.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +3 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/targets/contracts.d.ts +66 -0
- package/dist/targets/contracts.d.ts.map +1 -0
- package/dist/targets/graph-projection.d.ts +29 -0
- package/dist/targets/graph-projection.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +34 -0
- package/dist/targets/material-source.d.ts.map +1 -0
- package/dist/targets/owner.d.ts +32 -0
- package/dist/targets/owner.d.ts.map +1 -0
- package/dist/targets/physical.d.ts +18 -0
- package/dist/targets/physical.d.ts.map +1 -0
- package/dist/targets/readback.d.ts +39 -0
- package/dist/targets/readback.d.ts.map +1 -0
- package/dist/temporal/frame.d.ts +44 -0
- package/dist/temporal/frame.d.ts.map +1 -0
- package/dist/temporal/index.mjs +3 -3
- package/dist/typed-render-graph-primitives.d.ts +6 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-atlas.d.ts +10 -0
- package/dist/typed-shadow-atlas.d.ts.map +1 -0
- package/dist/typed-shadow-passes.d.ts +1 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/capability.d.ts +57 -0
- package/dist/volume/capability.d.ts.map +1 -0
- package/dist/volume/component.d.ts +61 -0
- package/dist/volume/component.d.ts.map +1 -0
- package/dist/volume/extract.d.ts +11 -0
- package/dist/volume/extract.d.ts.map +1 -0
- package/dist/volume/inspection.d.ts +38 -0
- package/dist/volume/inspection.d.ts.map +1 -0
- package/dist/volume/passes.d.ts +38 -0
- package/dist/volume/passes.d.ts.map +1 -0
- package/dist/volume/recovery.d.ts +38 -0
- package/dist/volume/recovery.d.ts.map +1 -0
- package/dist/volume/resources.d.ts +57 -0
- package/dist/volume/resources.d.ts.map +1 -0
- package/dist/volume/temporal.d.ts +35 -0
- package/dist/volume/temporal.d.ts.map +1 -0
- package/package.json +20 -20
- package/src/__tests__/bloom-exact-zero.unit.test.ts +48 -19
- package/src/__tests__/bloom-lifecycle.integration.test.ts +41 -13
- package/src/__tests__/camera-target-consumption.unit.test.ts +53 -0
- package/src/__tests__/cluster-binner.unit.test.ts +35 -0
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +7 -2
- package/src/__tests__/cube-camera-scheduler.unit.test.ts +70 -0
- package/src/__tests__/cube-camera-single-submit.perf.test.ts +75 -0
- package/src/__tests__/cube-camera-view-matrices.unit.test.ts +41 -0
- package/src/__tests__/cube-camera-vocabulary.unit.test.ts +47 -0
- package/src/__tests__/cube-camera.integration.test.ts +42 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +73 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +3 -3
- package/src/__tests__/docs-gate-green.unit.test.ts +38 -0
- package/src/__tests__/factory-contract.integration.test.ts +255 -29
- package/src/__tests__/fog-component.unit.test.ts +67 -0
- package/src/__tests__/fog.integration.test.ts +86 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +37 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +10 -9
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +17 -1
- package/src/__tests__/gpu-driven-production.integration.test.ts +16 -17
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +12 -4
- package/src/__tests__/gpu-pass-timing-browser-runner.ts +281 -0
- package/src/__tests__/gpu-pass-timing-coexistence.integration.test.ts +80 -0
- package/src/__tests__/gpu-pass-timing-contract.unit.test.ts +243 -0
- package/src/__tests__/gpu-pass-timing-exact-zero.unit.test.ts +131 -0
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +230 -0
- package/src/__tests__/gpu-pass-timing-observation.unit.test.ts +233 -0
- package/src/__tests__/gpu-pass-timing-session.unit.test.ts +438 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +26 -0
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +125 -0
- package/src/__tests__/hdrp-group2-visibility.unit.test.ts +24 -0
- package/src/__tests__/instances-culling.integration.test.ts +94 -0
- package/src/__tests__/instances-derived-bounds.unit.test.ts +118 -0
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +14 -14
- package/src/__tests__/material-observation.integration.test.ts +101 -0
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
- package/src/__tests__/pbr-view-layout.unit.test.ts +16 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +60 -0
- package/src/__tests__/public-surface.test-d.ts +10 -0
- package/src/__tests__/reflection-probe-authoring.unit.test.ts +71 -0
- package/src/__tests__/reflection-probe-filter.unit.test.ts +54 -0
- package/src/__tests__/reflection-probe-ibl-topology.unit.test.ts +45 -0
- package/src/__tests__/reflection-probe-pass-encode.integration.test.ts +101 -0
- package/src/__tests__/reflection-probe-performance.perf.test.ts +60 -0
- package/src/__tests__/reflection-probe-recovery.integration.test.ts +55 -0
- package/src/__tests__/reflection-probe-selection.unit.test.ts +46 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +23 -3
- package/src/__tests__/render-feature-docs.unit.test.ts +1 -1
- package/src/__tests__/render-target-admission.unit.test.ts +80 -0
- package/src/__tests__/render-target-graph-projection.unit.test.ts +102 -0
- package/src/__tests__/render-target-inspection.unit.test.ts +52 -0
- package/src/__tests__/render-target-material-source.test-d.ts +30 -0
- package/src/__tests__/render-target-material-source.unit.test.ts +97 -0
- package/src/__tests__/render-target-owner-placement.unit.test.ts +203 -0
- package/src/__tests__/render-target-owner.unit.test.ts +122 -0
- package/src/__tests__/render-target-probe-soak.perf.test.ts +94 -0
- package/src/__tests__/render-target-public-schema.json +107 -0
- package/src/__tests__/render-target-public-schema.unit.test.ts +91 -0
- package/src/__tests__/render-target-public-surface.test-d.ts +83 -0
- package/src/__tests__/render-target-readback.integration.test.ts +90 -0
- package/src/__tests__/render-target-recovery.integration.test.ts +85 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +76 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +1 -1
- package/src/__tests__/renderer-lifecycle.integration.test.ts +14 -0
- package/src/__tests__/shader-stage-surface.unit.test.ts +19 -4
- package/src/__tests__/skin-motion-regression.unit.test.ts +132 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +32 -2
- package/src/__tests__/standard-cluster-capability.integration.test.ts +63 -0
- package/src/__tests__/standard-cluster-transport.unit.test.ts +121 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +232 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +8 -5
- package/src/__tests__/standard-lighting-inspection.integration.test.ts +138 -0
- package/src/__tests__/standard-lighting-ssot.unit.test.ts +18 -0
- package/src/__tests__/standard-lighting-write.unit.test.ts +377 -0
- package/src/__tests__/standard-lighting.integration.test.ts +67 -0
- package/src/__tests__/standard-pipeline.dawn.test.ts +206 -5
- package/src/__tests__/standard-pipeline.integration.test.ts +181 -150
- package/src/__tests__/standard-probe-binding.unit.test.ts +25 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +23 -36
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +395 -14
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +2 -2
- package/src/__tests__/visibility-resolver.unit.test.ts +15 -0
- package/src/__tests__/volume-optics-oracle.unit.test.ts +85 -0
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +655 -0
- package/src/__tests__/volumetric-fog-component.unit.test.ts +71 -0
- package/src/__tests__/volumetric-fog-composite-stage-readback.dawn.test.ts +376 -0
- package/src/__tests__/volumetric-fog-errors.unit.test.ts +51 -0
- package/src/__tests__/volumetric-fog-inspection.unit.test.ts +77 -0
- package/src/__tests__/volumetric-fog-light-capability.unit.test.ts +19 -0
- package/src/__tests__/volumetric-fog-light-consumers.integration.test.ts +18 -0
- package/src/__tests__/volumetric-fog-light-errors.unit.test.ts +17 -0
- package/src/__tests__/volumetric-fog-light-topology.unit.test.ts +21 -0
- package/src/__tests__/volumetric-fog-light-transaction.integration.test.ts +53 -0
- package/src/__tests__/volumetric-fog-m9-watcher.integration.test.ts +27 -0
- package/src/__tests__/volumetric-fog-point-light-owner.integration.test.ts +44 -0
- package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +49 -0
- package/src/__tests__/volumetric-fog-point-spot-contract.unit.test.ts +28 -0
- package/src/__tests__/volumetric-fog-point-spot-lkg.integration.test.ts +65 -0
- package/src/__tests__/volumetric-fog-point-spot-selection.integration.test.ts +49 -0
- package/src/__tests__/volumetric-fog-point-spot-temporal.unit.test.ts +55 -0
- package/src/__tests__/volumetric-fog-projector-contract.unit.test.ts +22 -0
- package/src/__tests__/volumetric-fog-projector-inspection.unit.test.ts +12 -0
- package/src/__tests__/volumetric-fog-projector-surface-volume.integration.test.ts +11 -0
- package/src/__tests__/volumetric-fog-projector-transaction.integration.test.ts +26 -0
- package/src/__tests__/volumetric-fog-recovery.integration.test.ts +47 -0
- package/src/__tests__/volumetric-fog-selected-light-resolution.integration.test.ts +63 -0
- package/src/__tests__/volumetric-fog-spot-closure.integration.test.ts +26 -0
- package/src/__tests__/volumetric-fog-spot-contract.test-d.ts +21 -0
- package/src/__tests__/volumetric-fog-spot-contract.unit.test.ts +27 -0
- package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +14 -0
- package/src/__tests__/volumetric-fog-spot-optics.integration.test.ts +29 -0
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +550 -0
- package/src/__tests__/volumetric-fog-temporal-selected-light.unit.test.ts +33 -0
- package/src/__tests__/volumetric-fog-temporal.unit.test.ts +45 -0
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +237 -0
- package/src/__tests__/volumetric-fog-transparent.integration.test.ts +27 -0
- package/src/assembly/device-feature-admission.ts +73 -0
- package/src/assembly/directional-shadow-inspection.ts +122 -0
- package/src/assembly/factory.ts +1093 -246
- package/src/assembly/host-contract.ts +25 -0
- package/src/assembly/render-target-host.ts +847 -0
- package/src/assets/asset-decoders.ts +1 -1
- package/src/assets/render-asset-port.ts +7 -1
- package/src/capture/cube-views.ts +69 -0
- package/src/capture/scheduler.ts +265 -0
- package/src/components/__tests__/schema-contract.unit.test.ts +12 -0
- package/src/components/__tests__/schema-parity.unit.test.ts +9 -0
- package/src/components/camera.ts +4 -0
- package/src/components/cube-camera.ts +52 -0
- package/src/components/directional-light.ts +22 -2
- package/src/components/directional-shadow-filter.ts +57 -0
- package/src/components/index.ts +2 -0
- package/src/components/light-helpers.ts +85 -7
- package/src/components/reflection-probe.ts +49 -0
- package/src/components/spot-light.ts +22 -3
- package/src/device/gpu-residency.ts +168 -58
- package/src/environment/frame.ts +6 -24
- package/src/environment/lifecycle.ts +12 -0
- package/src/errors/render.ts +405 -143
- package/src/extract/directional-shadow-projection.ts +61 -0
- package/src/extract/environment.ts +57 -0
- package/src/extract/visibility.ts +25 -1
- package/src/features/fullscreen.ts +3 -0
- package/src/features/targets.ts +4 -1
- package/src/features/types.ts +10 -0
- package/src/fullscreen-post-process-pass.ts +43 -2
- package/src/gpu-driven/batch-topology.ts +1 -0
- package/src/gpu-driven/production-raster.ts +1 -3
- package/src/gpu-scene.ts +8 -1
- package/src/gpu-usage.ts +2 -0
- package/src/hdrp-buffers.ts +165 -59
- package/src/ibl/IblPipelineCache.ts +11 -0
- package/src/ibl/kernel-cache.ts +88 -0
- package/src/index.ts +186 -1
- package/src/inspection-types.ts +56 -0
- package/src/instances-derived-bounds.ts +171 -0
- package/src/light-buffer-layout.ts +74 -26
- package/src/mesh-material-bindings.ts +132 -0
- package/src/pbr-pipeline.ts +139 -27
- package/src/pipeline/standard-forward-lane.ts +65 -15
- package/src/pipeline/standard-lighting/errors.ts +6 -0
- package/src/pipeline/standard-lighting/graph.ts +157 -0
- package/src/pipeline/standard-lighting/inspection.ts +88 -0
- package/src/pipeline/standard-lighting/layout.ts +31 -0
- package/src/pipeline/standard-lighting/light-frame.ts +34 -0
- package/src/pipeline/standard-lighting/membership.ts +43 -0
- package/src/pipeline/standard-lighting/prepare.ts +37 -0
- package/src/pipeline/standard-lighting/topology.ts +120 -0
- package/src/pipeline/standard-lighting/transport.ts +77 -0
- package/src/pipeline/standard-pipeline.ts +141 -192
- package/src/pipeline/standard-post.ts +26 -7
- package/src/pipeline/standard-profile.ts +23 -30
- package/src/pipeline-spec.ts +84 -21
- package/src/point-shadow-inspection.ts +55 -0
- package/src/record/__tests__/temporal-payload.unit.test.ts +42 -1
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +73 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +40 -0
- package/src/record/frame-lighting.ts +470 -516
- package/src/record/frame-snapshot.ts +76 -28
- package/src/record/frame-targets.ts +23 -2
- package/src/record/frame.ts +1169 -79
- package/src/record/gpu-pass-timing/contract.ts +180 -0
- package/src/record/gpu-pass-timing/errors.ts +34 -0
- package/src/record/gpu-pass-timing/index.ts +37 -0
- package/src/record/gpu-pass-timing/parser.ts +97 -0
- package/src/record/gpu-pass-timing/session.ts +938 -0
- package/src/record/gpu-timing.ts +233 -0
- package/src/record/main-pass-geometry.ts +120 -80
- package/src/record/main-pass-material.ts +101 -11
- package/src/record/main-pass-sprite-draws.ts +54 -25
- package/src/record/main-pass.ts +71 -15
- package/src/record/render-context.ts +77 -0
- package/src/record/shadow-pass.ts +104 -66
- package/src/record/skybox-post-pass.ts +20 -4
- package/src/record/typed-frame-graph.ts +1016 -32
- package/src/record/view-ubo.ts +63 -28
- package/src/reflection/filter.ts +81 -0
- package/src/reflection/gpu-table.ts +44 -0
- package/src/reflection/projection.ts +281 -0
- package/src/render-contract.ts +147 -4
- package/src/render-data.ts +50 -22
- package/src/render-graph-primitives.ts +9 -4
- package/src/render-pipeline.ts +161 -2
- package/src/render-system-extract.ts +886 -103
- package/src/render-system.ts +1174 -66
- package/src/renderer-inspect.ts +66 -0
- package/src/renderer.ts +222 -0
- package/src/scene/render-scene.ts +117 -9
- package/src/shadow-atlas.ts +5 -5
- package/src/ssao-buffers.ts +9 -2
- package/src/targets/contracts.ts +182 -0
- package/src/targets/graph-projection.ts +169 -0
- package/src/targets/material-source.ts +143 -0
- package/src/targets/owner.ts +214 -0
- package/src/targets/physical.ts +18 -0
- package/src/targets/readback.ts +153 -0
- package/src/temporal/frame.ts +128 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +61 -23
- package/src/typed-render-graph-primitives.ts +34 -2
- package/src/typed-shadow-atlas.ts +17 -0
- package/src/typed-shadow-passes.ts +47 -40
- package/src/volume/capability.ts +173 -0
- package/src/volume/component.ts +110 -0
- package/src/volume/extract.ts +21 -0
- package/src/volume/inspection.ts +78 -0
- package/src/volume/passes.ts +686 -0
- package/src/volume/recovery.ts +86 -0
- package/src/volume/resources.ts +236 -0
- package/src/volume/temporal.ts +89 -0
- package/dist/chunk-IPXCABEP.mjs.map +0 -1
- package/dist/chunk-LOSO4CTV.mjs.map +0 -1
- package/dist/chunk-RJRUS55L.mjs.map +0 -1
- package/dist/chunk-YTQ5C7YQ.mjs +0 -584
- package/dist/chunk-YTQ5C7YQ.mjs.map +0 -1
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import { mat4, vec3 } from '@forgeax/engine-math';
|
|
1
2
|
import { RenderGraphBuilder } from '@forgeax/engine-render-graph';
|
|
2
3
|
import type { RhiDevice } from '@forgeax/engine-rhi';
|
|
3
4
|
import { rhi } from '@forgeax/engine-rhi-null';
|
|
4
5
|
import { ok } from '@forgeax/engine-types';
|
|
5
6
|
import { beforeAll, describe, expect, it } from 'vitest';
|
|
6
7
|
import { createRenderSurfaceError, type RenderSurfaceExpectedError } from '../errors/render';
|
|
8
|
+
import { prepareStandardLighting } from '../pipeline/standard-lighting/prepare';
|
|
9
|
+
import { deriveStandardTopologyInput } from '../pipeline/standard-lighting/topology';
|
|
10
|
+
import { selectStandardClusterTransport } from '../pipeline/standard-lighting/transport';
|
|
7
11
|
import { standardPipeline } from '../pipeline/standard-pipeline';
|
|
8
12
|
import {
|
|
9
13
|
DEFAULT_STANDARD_PROFILE,
|
|
@@ -45,8 +49,8 @@ function topology(
|
|
|
45
49
|
},
|
|
46
50
|
camera: { tonemap: 'aces-filmic', antialias: 'fxaa', bloom: 'on' },
|
|
47
51
|
shadow: {
|
|
48
|
-
mapSize: 64,
|
|
49
|
-
|
|
52
|
+
directional: { mapSize: 64, cascadeCount: 1 },
|
|
53
|
+
spotMapSize: 64,
|
|
50
54
|
pointCount: 0,
|
|
51
55
|
pointFaceSize: 64,
|
|
52
56
|
spotCount: 0,
|
|
@@ -73,12 +77,45 @@ beforeAll(async () => {
|
|
|
73
77
|
device = created.value;
|
|
74
78
|
});
|
|
75
79
|
|
|
80
|
+
function standardLightingFor(resolvedTopology: RenderPipelineTopology) {
|
|
81
|
+
const prepared = prepareStandardLighting({
|
|
82
|
+
directional: undefined,
|
|
83
|
+
local: [{ kind: 'point', shadowed: false, position: vec3.create(0, 0, -4), range: 2 }],
|
|
84
|
+
view: mat4.create(),
|
|
85
|
+
projection: mat4.create(),
|
|
86
|
+
near: 0.1,
|
|
87
|
+
far: 100,
|
|
88
|
+
grid: resolvedTopology.config?.clusterGrid ?? { x: 4, y: 3, z: 4 },
|
|
89
|
+
lightCount: resolvedTopology.standardProfile?.lightCount ?? DEFAULT_STANDARD_PROFILE.lightCount,
|
|
90
|
+
renderPath: resolvedTopology.standardProfile?.renderPath ?? DEFAULT_STANDARD_PROFILE.renderPath,
|
|
91
|
+
});
|
|
92
|
+
if (!prepared.ok) return prepared;
|
|
93
|
+
const transport = selectStandardClusterTransport(
|
|
94
|
+
{
|
|
95
|
+
compute: resolvedTopology.lane.compute,
|
|
96
|
+
storageBuffer: resolvedTopology.lane.storageBuffer,
|
|
97
|
+
membershipPipelineReady: resolvedTopology.lane.compute,
|
|
98
|
+
},
|
|
99
|
+
prepared.value,
|
|
100
|
+
);
|
|
101
|
+
if (!transport.ok) return transport;
|
|
102
|
+
const standardLighting = deriveStandardTopologyInput({
|
|
103
|
+
prepared: prepared.value,
|
|
104
|
+
kind: 'clustered',
|
|
105
|
+
transport: transport.value,
|
|
106
|
+
});
|
|
107
|
+
return standardLighting;
|
|
108
|
+
}
|
|
109
|
+
|
|
76
110
|
async function build(profile: StandardProfile, overrides?: Partial<RenderPipelineTopology>) {
|
|
77
111
|
const graph = new RenderGraphBuilder<RenderPipelineFrame>();
|
|
78
112
|
const resolvedTopology = topology(profile, overrides);
|
|
113
|
+
const standardLighting = standardLightingFor(resolvedTopology);
|
|
114
|
+
if (!standardLighting.ok) return standardLighting;
|
|
79
115
|
const built = standardPipeline.build(
|
|
80
116
|
{
|
|
81
117
|
graph,
|
|
118
|
+
standardLighting: standardLighting.value,
|
|
82
119
|
encodeTransmissionMip: ({ pass }) => pass.draw(3, 1, 0, 0),
|
|
83
120
|
projectGpuDriven: () => ok(undefined),
|
|
84
121
|
contributeFeatures: () => ok(undefined),
|
|
@@ -123,21 +160,31 @@ function importedTaaHistory(graph: RenderGraphBuilder<RenderPipelineFrame>) {
|
|
|
123
160
|
async function buildTaa(profile: StandardProfile, overrides?: Partial<RenderPipelineTopology>) {
|
|
124
161
|
const graph = new RenderGraphBuilder<RenderPipelineFrame>();
|
|
125
162
|
const history = importedTaaHistory(graph);
|
|
163
|
+
const resolvedTopology = topology(profile, overrides);
|
|
164
|
+
const standardLighting = standardLightingFor(resolvedTopology);
|
|
165
|
+
if (!standardLighting.ok) return standardLighting;
|
|
126
166
|
const built = standardPipeline.build(
|
|
127
167
|
{
|
|
128
168
|
graph,
|
|
169
|
+
standardLighting: standardLighting.value,
|
|
129
170
|
capabilities: { rgba16floatRenderable: true },
|
|
130
171
|
taaHistory: history,
|
|
131
172
|
projectGpuDriven: () => ok(undefined),
|
|
132
173
|
contributeFeatures: () => ok(undefined),
|
|
133
174
|
},
|
|
134
|
-
|
|
175
|
+
resolvedTopology,
|
|
135
176
|
);
|
|
136
177
|
if (!built.ok) return built;
|
|
137
178
|
return graph.compile({ device, surfaceSize: { width: 1, height: 1 } });
|
|
138
179
|
}
|
|
139
180
|
|
|
140
181
|
describe('forgeax::standard graph', () => {
|
|
182
|
+
it('does not admit an unsupported four-light budget', async () => {
|
|
183
|
+
const profile = { ...DEFAULT_STANDARD_PROFILE, lightCount: 4 } as unknown as StandardProfile;
|
|
184
|
+
const result = await build(profile);
|
|
185
|
+
expect(result.ok).toBe(false);
|
|
186
|
+
});
|
|
187
|
+
|
|
141
188
|
it('keeps the last-known-good graph for each explicit surface failure', () => {
|
|
142
189
|
let activeGraph = 'last-known-good';
|
|
143
190
|
const failures = ['allocation', 'attachment', 'sampled-read', 'raw-endpoint'] as const;
|
|
@@ -160,9 +207,9 @@ describe('forgeax::standard graph', () => {
|
|
|
160
207
|
});
|
|
161
208
|
|
|
162
209
|
it.each([
|
|
163
|
-
['
|
|
164
|
-
['
|
|
165
|
-
['
|
|
210
|
+
['forward-1', { ...DEFAULT_STANDARD_PROFILE, lightCount: 1, renderPath: 'forward' }],
|
|
211
|
+
['forward-32', { ...DEFAULT_STANDARD_PROFILE, lightCount: 32, renderPath: 'forward' }],
|
|
212
|
+
['deferred-256', { ...DEFAULT_STANDARD_PROFILE, lightCount: 256, renderPath: 'deferred' }],
|
|
166
213
|
] as const)('preserves the %s light lane under one identity', async (_name, profile) => {
|
|
167
214
|
const result = await build(profile);
|
|
168
215
|
expect(result.ok).toBe(true);
|
|
@@ -172,7 +219,7 @@ describe('forgeax::standard graph', () => {
|
|
|
172
219
|
|
|
173
220
|
it('keeps Bloom a no-op when TAA has no active tone mapper', async () => {
|
|
174
221
|
const result = await buildTaa(
|
|
175
|
-
{ ...DEFAULT_STANDARD_PROFILE,
|
|
222
|
+
{ ...DEFAULT_STANDARD_PROFILE, renderPath: 'forward' },
|
|
176
223
|
{ camera: { tonemap: 'none', antialias: 'taa', bloom: 'on' } },
|
|
177
224
|
);
|
|
178
225
|
expect(result.ok).toBe(true);
|
|
@@ -187,7 +234,7 @@ describe('forgeax::standard graph', () => {
|
|
|
187
234
|
});
|
|
188
235
|
|
|
189
236
|
it('keeps shadow, lighting, post, and debug work in one ordered graph', async () => {
|
|
190
|
-
const result = await build({ ...DEFAULT_STANDARD_PROFILE,
|
|
237
|
+
const result = await build({ ...DEFAULT_STANDARD_PROFILE, renderPath: 'deferred' });
|
|
191
238
|
expect(result.ok).toBe(true);
|
|
192
239
|
if (!result.ok) return;
|
|
193
240
|
const names = result.value.inspect().passes.map((pass) => pass.name);
|
|
@@ -206,15 +253,27 @@ describe('forgeax::standard graph', () => {
|
|
|
206
253
|
}
|
|
207
254
|
});
|
|
208
255
|
|
|
209
|
-
it('
|
|
256
|
+
it('keeps one clustered resource layout when compute admission is unavailable', async () => {
|
|
210
257
|
const result = await build(
|
|
211
|
-
{ ...DEFAULT_STANDARD_PROFILE,
|
|
258
|
+
{ ...DEFAULT_STANDARD_PROFILE, renderPath: 'forward' },
|
|
212
259
|
{
|
|
213
|
-
|
|
214
|
-
|
|
260
|
+
lane: {
|
|
261
|
+
compute: false,
|
|
262
|
+
storageBuffer: true,
|
|
263
|
+
multisample: false,
|
|
264
|
+
maxColorAttachments: 4,
|
|
265
|
+
},
|
|
215
266
|
},
|
|
216
267
|
);
|
|
217
268
|
expect(result.ok).toBe(true);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('routes a no-camera clear-only frame directly to the surface', async () => {
|
|
272
|
+
const result = await build(DEFAULT_STANDARD_PROFILE, {
|
|
273
|
+
clearOnly: true,
|
|
274
|
+
camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
|
|
275
|
+
});
|
|
276
|
+
expect(result.ok).toBe(true);
|
|
218
277
|
if (!result.ok) return;
|
|
219
278
|
const info = result.value.inspect();
|
|
220
279
|
const names = info.passes.map((pass) => pass.name);
|
|
@@ -229,9 +288,9 @@ describe('forgeax::standard graph', () => {
|
|
|
229
288
|
expect(info.resources.map((resource) => resource.label)).not.toContain('scene-color');
|
|
230
289
|
});
|
|
231
290
|
|
|
232
|
-
it('
|
|
291
|
+
it('refuses the clustered transport when storage is unavailable', async () => {
|
|
233
292
|
const result = await build(
|
|
234
|
-
{ ...DEFAULT_STANDARD_PROFILE,
|
|
293
|
+
{ ...DEFAULT_STANDARD_PROFILE, renderPath: 'forward' },
|
|
235
294
|
{
|
|
236
295
|
lane: {
|
|
237
296
|
compute: false,
|
|
@@ -241,27 +300,19 @@ describe('forgeax::standard graph', () => {
|
|
|
241
300
|
},
|
|
242
301
|
},
|
|
243
302
|
);
|
|
244
|
-
expect(result.ok).toBe(
|
|
245
|
-
if (
|
|
246
|
-
|
|
247
|
-
expect(names).not.toContain('cluster-membership-producer');
|
|
248
|
-
expect(result.value.inspect().resources.map((resource) => resource.label)).not.toContain(
|
|
249
|
-
'hdrp-light-index-list',
|
|
250
|
-
);
|
|
303
|
+
expect(result.ok).toBe(false);
|
|
304
|
+
if (result.ok) return;
|
|
305
|
+
expect(result.error.code).toBe('standard-cluster-transport-unavailable');
|
|
251
306
|
});
|
|
252
307
|
|
|
253
308
|
it.each([
|
|
254
|
-
['
|
|
255
|
-
['
|
|
256
|
-
['
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const result = await build(
|
|
262
|
-
{ ...DEFAULT_STANDARD_PROFILE, lighting },
|
|
263
|
-
{ camera: { tonemap, antialias, bloom: 'on' } },
|
|
264
|
-
);
|
|
309
|
+
['aces-filmic', 'fxaa'],
|
|
310
|
+
['none', 'fxaa'],
|
|
311
|
+
['aces-filmic', 'none'],
|
|
312
|
+
] as const)('uses one explicit post-chain contract for %s/%s', async (tonemap, antialias) => {
|
|
313
|
+
const result = await build(DEFAULT_STANDARD_PROFILE, {
|
|
314
|
+
camera: { tonemap, antialias, bloom: 'on' },
|
|
315
|
+
});
|
|
265
316
|
expect(result.ok).toBe(true);
|
|
266
317
|
if (!result.ok) return;
|
|
267
318
|
const info = result.value.inspect();
|
|
@@ -281,38 +332,31 @@ describe('forgeax::standard graph', () => {
|
|
|
281
332
|
expect(info.resources.map((resource) => resource.label)).not.toContain('ldr-color');
|
|
282
333
|
});
|
|
283
334
|
|
|
284
|
-
const routeMatrix = (['
|
|
285
|
-
(['
|
|
286
|
-
(['none', '
|
|
287
|
-
(['none', 'fxaa'] as const).map(
|
|
288
|
-
(antialias) => [lighting, surfaceKind, tonemap, antialias] as const,
|
|
289
|
-
),
|
|
290
|
-
),
|
|
335
|
+
const routeMatrix = (['dual-view', 'raw-only'] as const).flatMap((surfaceKind) =>
|
|
336
|
+
(['none', 'aces-filmic'] as const).flatMap((tonemap) =>
|
|
337
|
+
(['none', 'fxaa'] as const).map((antialias) => [surfaceKind, tonemap, antialias] as const),
|
|
291
338
|
),
|
|
292
339
|
);
|
|
293
340
|
|
|
294
341
|
it.each(
|
|
295
342
|
routeMatrix,
|
|
296
|
-
)('keeps the output route explicit for %s/%s/%s
|
|
343
|
+
)('keeps the output route explicit for %s/%s/%s', async (surfaceKind, tonemap, antialias) => {
|
|
297
344
|
const rawOnly = surfaceKind === 'raw-only';
|
|
298
|
-
const result = await build(
|
|
299
|
-
{
|
|
300
|
-
{
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
viewFormat: rawOnly ? 'rgba8unorm' : 'bgra8unorm-srgb',
|
|
307
|
-
profile: rawOnly ? rawOnlyProfile : dualViewProfile,
|
|
308
|
-
},
|
|
345
|
+
const result = await build(DEFAULT_STANDARD_PROFILE, {
|
|
346
|
+
camera: { tonemap, antialias, bloom: 'off' },
|
|
347
|
+
surface: {
|
|
348
|
+
width: 1,
|
|
349
|
+
height: 1,
|
|
350
|
+
storageFormat: rawOnly ? 'rgba8unorm' : 'bgra8unorm',
|
|
351
|
+
viewFormat: rawOnly ? 'rgba8unorm' : 'bgra8unorm-srgb',
|
|
352
|
+
profile: rawOnly ? rawOnlyProfile : dualViewProfile,
|
|
309
353
|
},
|
|
310
|
-
);
|
|
354
|
+
});
|
|
311
355
|
expect(result.ok).toBe(true);
|
|
312
356
|
if (!result.ok) return;
|
|
313
357
|
const info = result.value.inspect();
|
|
314
358
|
const names = info.passes.map((pass) => pass.name);
|
|
315
|
-
const sceneLabel =
|
|
359
|
+
const sceneLabel = 'scene-color';
|
|
316
360
|
const sceneResource = info.resources.find((resource) => resource.label === sceneLabel);
|
|
317
361
|
expect(sceneResource).toBeDefined();
|
|
318
362
|
expect(sceneResource?.derivedUsage).toBe(0x15);
|
|
@@ -338,11 +382,10 @@ describe('forgeax::standard graph', () => {
|
|
|
338
382
|
}
|
|
339
383
|
});
|
|
340
384
|
|
|
341
|
-
it('uses one linear target and one output transform for
|
|
342
|
-
const result = await build(
|
|
343
|
-
{
|
|
344
|
-
|
|
345
|
-
);
|
|
385
|
+
it('uses one linear target and one output transform for Standard storage-buffer LDR output', async () => {
|
|
386
|
+
const result = await build(DEFAULT_STANDARD_PROFILE, {
|
|
387
|
+
camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
|
|
388
|
+
});
|
|
346
389
|
expect(result.ok).toBe(true);
|
|
347
390
|
if (!result.ok) return;
|
|
348
391
|
const info = result.value.inspect();
|
|
@@ -350,47 +393,39 @@ describe('forgeax::standard graph', () => {
|
|
|
350
393
|
expect(names).toContain('output-transform');
|
|
351
394
|
expect(names).not.toContain('fxaa');
|
|
352
395
|
expect(info.resources.find((resource) => resource.label === 'scene-color')).toMatchObject({
|
|
353
|
-
descriptor: { format: 'rgba16float'
|
|
396
|
+
descriptor: { format: 'rgba16float' },
|
|
397
|
+
derivedUsage: 0x15,
|
|
354
398
|
});
|
|
355
399
|
expect(info.resources.map((resource) => resource.label)).not.toContain('standard-output-color');
|
|
356
400
|
expect(info.resources.map((resource) => resource.label)).not.toContain('ldr-color');
|
|
357
401
|
});
|
|
358
402
|
|
|
359
|
-
it('keeps the
|
|
360
|
-
const result = await build(
|
|
361
|
-
{
|
|
362
|
-
{
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
multisample: false,
|
|
368
|
-
maxColorAttachments: 4,
|
|
369
|
-
},
|
|
403
|
+
it('keeps the Standard output route when storage buffers are unavailable', async () => {
|
|
404
|
+
const result = await build(DEFAULT_STANDARD_PROFILE, {
|
|
405
|
+
camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
|
|
406
|
+
lane: {
|
|
407
|
+
compute: false,
|
|
408
|
+
storageBuffer: false,
|
|
409
|
+
multisample: false,
|
|
410
|
+
maxColorAttachments: 4,
|
|
370
411
|
},
|
|
371
|
-
);
|
|
372
|
-
expect(result.ok).toBe(
|
|
373
|
-
if (
|
|
374
|
-
|
|
375
|
-
const names = info.passes.map((pass) => pass.name);
|
|
376
|
-
expect(names).not.toContain('output-transform');
|
|
377
|
-
expect(info.resources.map((resource) => resource.label)).not.toContain('scene-color');
|
|
412
|
+
});
|
|
413
|
+
expect(result.ok).toBe(false);
|
|
414
|
+
if (result.ok) return;
|
|
415
|
+
expect(result.error.code).toBe('standard-cluster-transport-unavailable');
|
|
378
416
|
});
|
|
379
417
|
|
|
380
418
|
it('uses one linear target and one output transform for raw-only no-FXAA', async () => {
|
|
381
|
-
const result = await build(
|
|
382
|
-
{
|
|
383
|
-
{
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
viewFormat: 'rgba8unorm',
|
|
390
|
-
profile: rawOnlyProfile,
|
|
391
|
-
},
|
|
419
|
+
const result = await build(DEFAULT_STANDARD_PROFILE, {
|
|
420
|
+
camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
|
|
421
|
+
surface: {
|
|
422
|
+
width: 1,
|
|
423
|
+
height: 1,
|
|
424
|
+
storageFormat: 'rgba8unorm',
|
|
425
|
+
viewFormat: 'rgba8unorm',
|
|
426
|
+
profile: rawOnlyProfile,
|
|
392
427
|
},
|
|
393
|
-
);
|
|
428
|
+
});
|
|
394
429
|
expect(result.ok).toBe(true);
|
|
395
430
|
if (!result.ok) return;
|
|
396
431
|
const info = result.value.inspect();
|
|
@@ -405,19 +440,16 @@ describe('forgeax::standard graph', () => {
|
|
|
405
440
|
});
|
|
406
441
|
|
|
407
442
|
it('keeps raw-only FXAA in one display-encoded float intermediate', async () => {
|
|
408
|
-
const result = await build(
|
|
409
|
-
{
|
|
410
|
-
{
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
viewFormat: 'rgba8unorm',
|
|
417
|
-
profile: rawOnlyProfile,
|
|
418
|
-
},
|
|
443
|
+
const result = await build(DEFAULT_STANDARD_PROFILE, {
|
|
444
|
+
camera: { tonemap: 'none', antialias: 'fxaa', bloom: 'off' },
|
|
445
|
+
surface: {
|
|
446
|
+
width: 1,
|
|
447
|
+
height: 1,
|
|
448
|
+
storageFormat: 'rgba8unorm',
|
|
449
|
+
viewFormat: 'rgba8unorm',
|
|
450
|
+
profile: rawOnlyProfile,
|
|
419
451
|
},
|
|
420
|
-
);
|
|
452
|
+
});
|
|
421
453
|
expect(result.ok).toBe(true);
|
|
422
454
|
if (!result.ok) return;
|
|
423
455
|
const info = result.value.inspect();
|
|
@@ -436,20 +468,17 @@ describe('forgeax::standard graph', () => {
|
|
|
436
468
|
'none',
|
|
437
469
|
'fxaa',
|
|
438
470
|
] as const)('routes raw-only registered post effects through an encoded float input target (%s)', async (antialias) => {
|
|
439
|
-
const result = await build(
|
|
440
|
-
{
|
|
441
|
-
{
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
viewFormat: 'rgba8unorm',
|
|
449
|
-
profile: rawOnlyProfile,
|
|
450
|
-
},
|
|
471
|
+
const result = await build(DEFAULT_STANDARD_PROFILE, {
|
|
472
|
+
camera: { tonemap: 'none', antialias, bloom: 'off' },
|
|
473
|
+
config: { postEffects: ['test-effect'] },
|
|
474
|
+
surface: {
|
|
475
|
+
width: 1,
|
|
476
|
+
height: 1,
|
|
477
|
+
storageFormat: 'rgba8unorm',
|
|
478
|
+
viewFormat: 'rgba8unorm',
|
|
479
|
+
profile: rawOnlyProfile,
|
|
451
480
|
},
|
|
452
|
-
);
|
|
481
|
+
});
|
|
453
482
|
expect(result.ok).toBe(true);
|
|
454
483
|
if (!result.ok) return;
|
|
455
484
|
const info = result.value.inspect();
|
|
@@ -480,18 +509,15 @@ describe('forgeax::standard graph', () => {
|
|
|
480
509
|
});
|
|
481
510
|
|
|
482
511
|
it('presents a resolved no-tone MSAA scene through the shared output boundary', async () => {
|
|
483
|
-
const result = await build(
|
|
484
|
-
{
|
|
485
|
-
{
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
multisample: true,
|
|
491
|
-
maxColorAttachments: 8,
|
|
492
|
-
},
|
|
512
|
+
const result = await build(DEFAULT_STANDARD_PROFILE, {
|
|
513
|
+
camera: { tonemap: 'none', antialias: 'msaa', bloom: 'off' },
|
|
514
|
+
lane: {
|
|
515
|
+
compute: true,
|
|
516
|
+
storageBuffer: true,
|
|
517
|
+
multisample: true,
|
|
518
|
+
maxColorAttachments: 8,
|
|
493
519
|
},
|
|
494
|
-
);
|
|
520
|
+
});
|
|
495
521
|
expect(result.ok).toBe(true);
|
|
496
522
|
if (!result.ok) return;
|
|
497
523
|
const info = result.value.inspect();
|
|
@@ -506,16 +532,20 @@ describe('forgeax::standard graph', () => {
|
|
|
506
532
|
|
|
507
533
|
it('uses the live rgba16float capability for temporal admission', () => {
|
|
508
534
|
const graph = new RenderGraphBuilder<RenderPipelineFrame>();
|
|
535
|
+
const resolvedTopology = topology(DEFAULT_STANDARD_PROFILE, {
|
|
536
|
+
camera: { tonemap: 'aces-filmic', antialias: 'taa', bloom: 'off' },
|
|
537
|
+
});
|
|
538
|
+
const standardLighting = standardLightingFor(resolvedTopology);
|
|
539
|
+
if (!standardLighting.ok) throw standardLighting.error;
|
|
509
540
|
const built = standardPipeline.build(
|
|
510
541
|
{
|
|
511
542
|
graph,
|
|
543
|
+
standardLighting: standardLighting.value,
|
|
512
544
|
capabilities: { rgba16floatRenderable: false },
|
|
513
545
|
projectGpuDriven: () => ok(undefined),
|
|
514
546
|
contributeFeatures: () => ok(undefined),
|
|
515
547
|
},
|
|
516
|
-
|
|
517
|
-
camera: { tonemap: 'aces-filmic', antialias: 'taa', bloom: 'off' },
|
|
518
|
-
}),
|
|
548
|
+
resolvedTopology,
|
|
519
549
|
);
|
|
520
550
|
expect(built.ok).toBe(false);
|
|
521
551
|
if (built.ok) return;
|
|
@@ -527,21 +557,25 @@ describe('forgeax::standard graph', () => {
|
|
|
527
557
|
|
|
528
558
|
it('fails closed when the temporal capability probe is absent', () => {
|
|
529
559
|
const graph = new RenderGraphBuilder<RenderPipelineFrame>();
|
|
560
|
+
const resolvedTopology = topology(DEFAULT_STANDARD_PROFILE, {
|
|
561
|
+
surface: {
|
|
562
|
+
width: 1,
|
|
563
|
+
height: 1,
|
|
564
|
+
storageFormat: 'rgba16float',
|
|
565
|
+
viewFormat: 'rgba16float',
|
|
566
|
+
},
|
|
567
|
+
camera: { tonemap: 'aces-filmic', antialias: 'taa', bloom: 'off' },
|
|
568
|
+
});
|
|
569
|
+
const standardLighting = standardLightingFor(resolvedTopology);
|
|
570
|
+
if (!standardLighting.ok) throw standardLighting.error;
|
|
530
571
|
const built = standardPipeline.build(
|
|
531
572
|
{
|
|
532
573
|
graph,
|
|
574
|
+
standardLighting: standardLighting.value,
|
|
533
575
|
projectGpuDriven: () => ok(undefined),
|
|
534
576
|
contributeFeatures: () => ok(undefined),
|
|
535
577
|
},
|
|
536
|
-
|
|
537
|
-
surface: {
|
|
538
|
-
width: 1,
|
|
539
|
-
height: 1,
|
|
540
|
-
storageFormat: 'rgba16float',
|
|
541
|
-
viewFormat: 'rgba16float',
|
|
542
|
-
},
|
|
543
|
-
camera: { tonemap: 'aces-filmic', antialias: 'taa', bloom: 'off' },
|
|
544
|
-
}),
|
|
578
|
+
resolvedTopology,
|
|
545
579
|
);
|
|
546
580
|
expect(built.ok).toBe(false);
|
|
547
581
|
if (built.ok) return;
|
|
@@ -551,9 +585,9 @@ describe('forgeax::standard graph', () => {
|
|
|
551
585
|
});
|
|
552
586
|
});
|
|
553
587
|
|
|
554
|
-
it('keeps
|
|
555
|
-
for (const
|
|
556
|
-
const result = await build({ ...DEFAULT_STANDARD_PROFILE,
|
|
588
|
+
it('keeps both Standard render paths on one transmission topology', async () => {
|
|
589
|
+
for (const renderPath of ['forward', 'deferred'] as const) {
|
|
590
|
+
const result = await build({ ...DEFAULT_STANDARD_PROFILE, renderPath }, {
|
|
557
591
|
surface: {
|
|
558
592
|
width: 8,
|
|
559
593
|
height: 4,
|
|
@@ -577,7 +611,7 @@ describe('forgeax::standard graph', () => {
|
|
|
577
611
|
|
|
578
612
|
it('uses the resolved single-sample MSAA source for the shared backdrop', async () => {
|
|
579
613
|
const result = await build(
|
|
580
|
-
{ ...DEFAULT_STANDARD_PROFILE,
|
|
614
|
+
{ ...DEFAULT_STANDARD_PROFILE, renderPath: 'forward' },
|
|
581
615
|
{
|
|
582
616
|
surface: {
|
|
583
617
|
width: 8,
|
|
@@ -611,13 +645,13 @@ describe('forgeax::standard graph', () => {
|
|
|
611
645
|
});
|
|
612
646
|
});
|
|
613
647
|
|
|
614
|
-
it('keeps the CPU
|
|
648
|
+
it('keeps the CPU transport on the same transmission phase contract', async () => {
|
|
615
649
|
const result = await build(
|
|
616
|
-
{ ...DEFAULT_STANDARD_PROFILE,
|
|
650
|
+
{ ...DEFAULT_STANDARD_PROFILE, renderPath: 'deferred' },
|
|
617
651
|
{
|
|
618
652
|
lane: {
|
|
619
653
|
compute: false,
|
|
620
|
-
storageBuffer:
|
|
654
|
+
storageBuffer: true,
|
|
621
655
|
multisample: false,
|
|
622
656
|
maxColorAttachments: 4,
|
|
623
657
|
},
|
|
@@ -645,12 +679,9 @@ describe('forgeax::standard graph', () => {
|
|
|
645
679
|
],
|
|
646
680
|
['reversed-phase-order', (names: readonly string[]) => [...names].reverse()],
|
|
647
681
|
] as const)('dev falsifier %s rejects the two-lane phase contract', async (_name, falsify) => {
|
|
648
|
-
const result = await build(
|
|
649
|
-
{
|
|
650
|
-
|
|
651
|
-
transmissionDemand: { activeCount: 1, needsRoughMips: false },
|
|
652
|
-
},
|
|
653
|
-
);
|
|
682
|
+
const result = await build(DEFAULT_STANDARD_PROFILE, {
|
|
683
|
+
transmissionDemand: { activeCount: 1, needsRoughMips: false },
|
|
684
|
+
});
|
|
654
685
|
expect(result.ok).toBe(true);
|
|
655
686
|
if (!result.ok) return;
|
|
656
687
|
const names = result.value.inspect().passes.map((pass) => pass.name);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { resolveReflectionProbeBinding } from '../record/frame-lighting';
|
|
3
|
+
import { standardReflectionProbeIndex } from '../record/main-pass';
|
|
4
|
+
|
|
5
|
+
describe('Standard scene reflection probe binding', () => {
|
|
6
|
+
it('maps a selected scene probe to both Standard lanes', () => {
|
|
7
|
+
const selection = {
|
|
8
|
+
kind: 'probe' as const,
|
|
9
|
+
worldId: 2,
|
|
10
|
+
entityKey: 7,
|
|
11
|
+
normalizedDistance: 0.25,
|
|
12
|
+
};
|
|
13
|
+
expect(resolveReflectionProbeBinding(selection)).toEqual({ probeIndex: 7, useSkylight: false });
|
|
14
|
+
expect(standardReflectionProbeIndex(selection)).toBe(7);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('uses Skylight without a per-material probe identity', () => {
|
|
18
|
+
const selection = { kind: 'skylight' as const };
|
|
19
|
+
expect(resolveReflectionProbeBinding(selection)).toEqual({
|
|
20
|
+
probeIndex: undefined,
|
|
21
|
+
useSkylight: true,
|
|
22
|
+
});
|
|
23
|
+
expect(standardReflectionProbeIndex(selection)).toBeUndefined();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_STANDARD_PROFILE,
|
|
4
|
-
resolveStandardLane,
|
|
5
4
|
STANDARD_LIGHT_COUNTS,
|
|
6
5
|
STANDARD_PIPELINE_ID,
|
|
7
6
|
type StandardProfile,
|
|
8
7
|
} from '../pipeline/standard-profile';
|
|
9
8
|
|
|
10
9
|
describe('Standard profile oracle', () => {
|
|
10
|
+
it('requires the renderPath-only profile contract', () => {
|
|
11
|
+
const profile: StandardProfile = DEFAULT_STANDARD_PROFILE;
|
|
12
|
+
expect(profile.pipelineId).toBe('forgeax::standard');
|
|
13
|
+
expect(profile.renderPath).toBe('forward');
|
|
14
|
+
expect(profile).not.toHaveProperty('lighting');
|
|
15
|
+
expect(profile).not.toHaveProperty('fallback');
|
|
16
|
+
});
|
|
17
|
+
|
|
11
18
|
it('keeps one identity across the supported light budgets', () => {
|
|
12
19
|
expect(STANDARD_LIGHT_COUNTS).toEqual([1, 32, 256]);
|
|
13
20
|
for (const lightCount of STANDARD_LIGHT_COUNTS) {
|
|
@@ -20,34 +27,21 @@ describe('Standard profile oracle', () => {
|
|
|
20
27
|
}
|
|
21
28
|
});
|
|
22
29
|
|
|
23
|
-
it('
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
storageBuffer: true,
|
|
39
|
-
},
|
|
40
|
-
),
|
|
41
|
-
).toBe('clustered');
|
|
42
|
-
expect(
|
|
43
|
-
resolveStandardLane(
|
|
44
|
-
{ ...DEFAULT_STANDARD_PROFILE, lighting: 'clustered' },
|
|
45
|
-
{
|
|
46
|
-
compute: false,
|
|
47
|
-
storageBuffer: false,
|
|
48
|
-
},
|
|
49
|
-
),
|
|
50
|
-
).toBe('cpu-webgl2');
|
|
30
|
+
it('does not model a second lighting or fallback lane', () => {
|
|
31
|
+
const profile = DEFAULT_STANDARD_PROFILE as unknown as Record<string, unknown>;
|
|
32
|
+
expect(profile).not.toHaveProperty('lighting');
|
|
33
|
+
expect(profile).not.toHaveProperty('fallback');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('selects only the graph path; Cluster transport is capability-derived', () => {
|
|
37
|
+
expect({ ...DEFAULT_STANDARD_PROFILE, renderPath: 'forward' }).toMatchObject({
|
|
38
|
+
pipelineId: STANDARD_PIPELINE_ID,
|
|
39
|
+
renderPath: 'forward',
|
|
40
|
+
});
|
|
41
|
+
expect({ ...DEFAULT_STANDARD_PROFILE, renderPath: 'deferred' }).toMatchObject({
|
|
42
|
+
pipelineId: STANDARD_PIPELINE_ID,
|
|
43
|
+
renderPath: 'deferred',
|
|
44
|
+
});
|
|
51
45
|
});
|
|
52
46
|
|
|
53
47
|
it('keeps the color-domain stage order stable for all profiles', () => {
|
|
@@ -60,11 +54,4 @@ describe('Standard profile oracle', () => {
|
|
|
60
54
|
'present',
|
|
61
55
|
]);
|
|
62
56
|
});
|
|
63
|
-
|
|
64
|
-
it('does not duplicate Camera authoring facts in the Standard profile', () => {
|
|
65
|
-
expect(DEFAULT_STANDARD_PROFILE).not.toHaveProperty('tone');
|
|
66
|
-
expect(DEFAULT_STANDARD_PROFILE).not.toHaveProperty('antialias');
|
|
67
|
-
expect(DEFAULT_STANDARD_PROFILE).not.toHaveProperty('bloom');
|
|
68
|
-
expect(DEFAULT_STANDARD_PROFILE).not.toHaveProperty('sky');
|
|
69
|
-
});
|
|
70
57
|
});
|