@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
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { TextureFormat } from '@forgeax/engine-rhi';
|
|
2
|
+
import type { VolumeRecoveryState, VolumeSelectedLightFacts } from './recovery';
|
|
3
|
+
import type { VolumetricFogResourceFacts } from './resources';
|
|
4
|
+
export type VolumetricFogInspectionStatus = 'off' | 'available' | 'unavailable' | 'degraded';
|
|
5
|
+
export type VolumetricFogResourceStage = 'none' | 'candidate' | 'accepted' | 'lkg' | 'recovering';
|
|
6
|
+
export interface VolumetricFogInspection {
|
|
7
|
+
readonly status: VolumetricFogInspectionStatus;
|
|
8
|
+
readonly resourceStage: VolumetricFogResourceStage;
|
|
9
|
+
readonly guid: string | undefined;
|
|
10
|
+
readonly generation: number | undefined;
|
|
11
|
+
readonly digest: string | undefined;
|
|
12
|
+
readonly candidateGeneration: number | undefined;
|
|
13
|
+
readonly candidateDigest: string | undefined;
|
|
14
|
+
readonly lkgGeneration: number | undefined;
|
|
15
|
+
readonly candidateFailure: VolumeRecoveryState['candidateFailure'];
|
|
16
|
+
readonly deviceEpoch: number;
|
|
17
|
+
readonly format: TextureFormat | undefined;
|
|
18
|
+
readonly passCount: number;
|
|
19
|
+
readonly sampleCount: number;
|
|
20
|
+
readonly memoryBytes: number;
|
|
21
|
+
readonly resourceFacts: VolumetricFogResourceFacts | undefined;
|
|
22
|
+
readonly selectedLight: VolumeSelectedLightFacts | undefined;
|
|
23
|
+
readonly candidateSelectedLight: VolumeSelectedLightFacts | undefined;
|
|
24
|
+
}
|
|
25
|
+
export interface VolumetricFogInspectionInput {
|
|
26
|
+
readonly authored: boolean;
|
|
27
|
+
readonly capability: 'available' | 'unavailable';
|
|
28
|
+
readonly degraded?: boolean;
|
|
29
|
+
readonly recovery?: VolumeRecoveryState;
|
|
30
|
+
readonly acceptedDigest?: string;
|
|
31
|
+
readonly format?: TextureFormat;
|
|
32
|
+
readonly passCount?: number;
|
|
33
|
+
readonly sampleCount?: number;
|
|
34
|
+
readonly memoryBytes?: number;
|
|
35
|
+
readonly resourceFacts?: VolumetricFogResourceFacts;
|
|
36
|
+
}
|
|
37
|
+
export declare function inspectVolumetricFog(input: VolumetricFogInspectionInput): VolumetricFogInspection;
|
|
38
|
+
//# sourceMappingURL=inspection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspection.d.ts","sourceRoot":"","sources":["../../src/volume/inspection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,MAAM,6BAA6B,GAAG,KAAK,GAAG,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;AAE7F,MAAM,MAAM,0BAA0B,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,KAAK,GAAG,YAAY,CAAC;AAElG,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,6BAA6B,CAAC;IAC/C,QAAQ,CAAC,aAAa,EAAE,0BAA0B,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;IACnE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,0BAA0B,GAAG,SAAS,CAAC;IAC/D,QAAQ,CAAC,aAAa,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC7D,QAAQ,CAAC,sBAAsB,EAAE,wBAAwB,GAAG,SAAS,CAAC;CACvE;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,WAAW,GAAG,aAAa,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,0BAA0B,CAAC;CACrD;AAUD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,4BAA4B,GAAG,uBAAuB,CA4BjG"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { GraphBuffer, GraphTextureView, RenderGraphBuilder, RenderGraphError } from '@forgeax/engine-render-graph';
|
|
2
|
+
import { type Result } from '@forgeax/engine-types';
|
|
3
|
+
import type { RenderPipelineFrame, RenderPipelineTarget, RenderPipelineTopology } from '../render-pipeline';
|
|
4
|
+
import type { VolumetricFogResources } from './resources';
|
|
5
|
+
import type { VolumeProjectorTuple } from './temporal';
|
|
6
|
+
export declare const VOLUMETRIC_FOG_PASS_ORDER: readonly ["volume-inject", "volume-integrate", "volume-temporal", "volume-composite"];
|
|
7
|
+
export interface VolumetricFogTopology {
|
|
8
|
+
readonly passes: readonly string[];
|
|
9
|
+
readonly resources: readonly string[];
|
|
10
|
+
readonly colorInput: 'linear-hdr';
|
|
11
|
+
readonly depthInput: 'scene-depth';
|
|
12
|
+
readonly lightKind?: 'directional' | 'point' | 'spot';
|
|
13
|
+
readonly lightEntity?: number;
|
|
14
|
+
readonly lightRevision?: number;
|
|
15
|
+
readonly projector?: Pick<VolumeProjectorTuple, 'guid' | 'generation' | 'revision'>;
|
|
16
|
+
}
|
|
17
|
+
export declare function volumetricFogTopology(enabled: boolean, selectedLight?: {
|
|
18
|
+
readonly lightKind: 'directional' | 'point' | 'spot';
|
|
19
|
+
readonly lightEntity: number;
|
|
20
|
+
readonly lightRevision: number;
|
|
21
|
+
}): VolumetricFogTopology;
|
|
22
|
+
export interface VolumetricFogPassInputs {
|
|
23
|
+
readonly resources: VolumetricFogResources;
|
|
24
|
+
readonly linearHdr: RenderPipelineTarget;
|
|
25
|
+
readonly sceneDepth: GraphTextureView;
|
|
26
|
+
readonly density: GraphTextureView;
|
|
27
|
+
readonly params: GraphBuffer;
|
|
28
|
+
readonly view: GraphBuffer;
|
|
29
|
+
readonly directionalShadow?: GraphTextureView;
|
|
30
|
+
readonly spotShadow: GraphTextureView;
|
|
31
|
+
readonly pointLights: GraphBuffer;
|
|
32
|
+
readonly spotLights: GraphBuffer;
|
|
33
|
+
readonly selectedLightKind: 'directional' | 'point' | 'spot';
|
|
34
|
+
readonly projector?: GraphTextureView;
|
|
35
|
+
}
|
|
36
|
+
export declare function addAuthoredVolumetricFogPasses(graph: RenderGraphBuilder<RenderPipelineFrame>, topology: RenderPipelineTopology, linearHdr: RenderPipelineTarget, sceneDepth: GraphTextureView, directionalShadow: GraphTextureView | undefined, spotShadow: GraphTextureView): Result<void, RenderGraphError>;
|
|
37
|
+
export declare function addVolumetricFogPasses(graph: RenderGraphBuilder<RenderPipelineFrame>, inputs: VolumetricFogPassInputs): Result<void, RenderGraphError>;
|
|
38
|
+
//# sourceMappingURL=passes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passes.d.ts","sourceRoot":"","sources":["../../src/volume/passes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAWtC,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAcxD,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAQ1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,yBAAyB,uFAK5B,CAAC;AACX,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU,CAAC,CAAC;CACrF;AACD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE;IACd,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;IACrD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,GACA,qBAAqB,CAevB;AACD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,gBAAgB,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,iBAAiB,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;IAC7D,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;CACvC;AAqLD,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,EAC9C,QAAQ,EAAE,sBAAsB,EAChC,SAAS,EAAE,oBAAoB,EAC/B,UAAU,EAAE,gBAAgB,EAC5B,iBAAiB,EAAE,gBAAgB,GAAG,SAAS,EAC/C,UAAU,EAAE,gBAAgB,GAC3B,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,CA2BhC;AACD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,EAC9C,MAAM,EAAE,uBAAuB,GAC9B,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAiXhC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { VolumeProjectorTuple } from './temporal';
|
|
2
|
+
export interface VolumeSelectedLightFacts {
|
|
3
|
+
readonly entity: number;
|
|
4
|
+
readonly kind: 'directional' | 'point' | 'spot';
|
|
5
|
+
readonly revision: number;
|
|
6
|
+
readonly shadowTile: number;
|
|
7
|
+
readonly pointLightEntity?: number;
|
|
8
|
+
readonly spotLightEntity?: number;
|
|
9
|
+
readonly projector?: VolumeProjectorTuple;
|
|
10
|
+
}
|
|
11
|
+
export interface VolumeRecoveryState {
|
|
12
|
+
readonly guid: string;
|
|
13
|
+
readonly generation: number;
|
|
14
|
+
readonly deviceEpoch: number;
|
|
15
|
+
readonly status: 'accepted' | 'candidate' | 'degraded' | 'recovering';
|
|
16
|
+
readonly candidateGeneration?: number;
|
|
17
|
+
readonly candidateDigest?: string;
|
|
18
|
+
readonly lkgGeneration?: number;
|
|
19
|
+
readonly candidateFailure?: 'submit-failed' | 'stale-generation' | 'missing-selected-light' | 'missing-shadow';
|
|
20
|
+
readonly selectedLight?: VolumeSelectedLightFacts;
|
|
21
|
+
readonly candidateSelectedLight?: VolumeSelectedLightFacts;
|
|
22
|
+
}
|
|
23
|
+
export type VolumeRecoveryEvent = {
|
|
24
|
+
readonly kind: 'submit-failed';
|
|
25
|
+
} | {
|
|
26
|
+
readonly kind: 'device-lost';
|
|
27
|
+
readonly deviceEpoch: number;
|
|
28
|
+
} | {
|
|
29
|
+
readonly kind: 'accepted';
|
|
30
|
+
readonly generation: number;
|
|
31
|
+
};
|
|
32
|
+
export declare function stageVolumetricFog(state: VolumeRecoveryState, candidate: {
|
|
33
|
+
readonly generation: number;
|
|
34
|
+
readonly digest: string;
|
|
35
|
+
readonly selectedLight?: VolumeSelectedLightFacts;
|
|
36
|
+
}): VolumeRecoveryState;
|
|
37
|
+
export declare function recoverVolumetricFog(state: VolumeRecoveryState, event: VolumeRecoveryEvent): VolumeRecoveryState;
|
|
38
|
+
//# sourceMappingURL=recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../../src/volume/recovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;IAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAC3C;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;IACtE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,gBAAgB,CAAC,EACtB,eAAe,GACf,kBAAkB,GAClB,wBAAwB,GACxB,gBAAgB,CAAC;IACrB,QAAQ,CAAC,aAAa,CAAC,EAAE,wBAAwB,CAAC;IAClD,QAAQ,CAAC,sBAAsB,CAAC,EAAE,wBAAwB,CAAC;CAC5D;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE;IACT,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,wBAAwB,CAAC;CACnD,GACA,mBAAmB,CAUrB;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,mBAAmB,GACzB,mBAAmB,CA6BrB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { CompiledRenderGraphInfo, GraphTexture, GraphTextureView, RenderGraphBuilder, RenderGraphError } from '@forgeax/engine-render-graph';
|
|
2
|
+
import { type Result } from '@forgeax/engine-types';
|
|
3
|
+
import type { RenderPipelineFrame } from '../render-pipeline';
|
|
4
|
+
export declare const VOLUME_FROXEL_FORMAT: "rgba8unorm";
|
|
5
|
+
export declare const VOLUME_HISTORY_FORMAT: "rgba16float";
|
|
6
|
+
export declare const VOLUME_RESOLVED_FORMAT: "rgba16float";
|
|
7
|
+
export declare const VOLUME_DEPTH_FORMAT: "r32float";
|
|
8
|
+
export declare const VOLUME_PACKING_Z = 4;
|
|
9
|
+
/** Renderer-owned parameter allocation shared by staging and inspection. */
|
|
10
|
+
export declare const VOLUMETRIC_FOG_PARAMS_BYTES: number;
|
|
11
|
+
export interface VolumetricFogExtent {
|
|
12
|
+
readonly width: number;
|
|
13
|
+
readonly height: number;
|
|
14
|
+
readonly depth: number;
|
|
15
|
+
}
|
|
16
|
+
/** Derive the renderer's high profile grid from the actual surface descriptor. */
|
|
17
|
+
export declare function deriveVolumetricFogExtent(surface: {
|
|
18
|
+
readonly width: number;
|
|
19
|
+
readonly height: number;
|
|
20
|
+
}, depth?: number, tileSize?: number): VolumetricFogExtent;
|
|
21
|
+
/** Derive the 2D resolve extent from the same profile tile without a second profile. */
|
|
22
|
+
export declare function deriveVolumetricFogResolvedExtent(surface: {
|
|
23
|
+
readonly width: number;
|
|
24
|
+
readonly height: number;
|
|
25
|
+
}, froxelTileSize?: number): VolumetricFogExtent;
|
|
26
|
+
export interface VolumetricFogResources {
|
|
27
|
+
readonly extent: VolumetricFogExtent;
|
|
28
|
+
readonly resolvedExtent: VolumetricFogExtent;
|
|
29
|
+
readonly froxel: GraphTexture;
|
|
30
|
+
readonly froxelView: GraphTextureView;
|
|
31
|
+
readonly resolved: GraphTexture;
|
|
32
|
+
readonly resolvedView: GraphTextureView;
|
|
33
|
+
readonly history: GraphTexture;
|
|
34
|
+
readonly historyView: GraphTextureView;
|
|
35
|
+
readonly temporal: GraphTexture;
|
|
36
|
+
readonly temporalView: GraphTextureView;
|
|
37
|
+
}
|
|
38
|
+
export interface VolumetricFogResourceFacts {
|
|
39
|
+
readonly generation: number;
|
|
40
|
+
readonly liveResourceCount: number;
|
|
41
|
+
readonly currentBytes: number;
|
|
42
|
+
readonly historyBytes: number;
|
|
43
|
+
readonly scratchBytes: number;
|
|
44
|
+
readonly bufferBytes: number;
|
|
45
|
+
readonly totalBytes: number;
|
|
46
|
+
readonly physicalResourceCount: number;
|
|
47
|
+
readonly sampleCount: number;
|
|
48
|
+
readonly resolvedPixelCount: number;
|
|
49
|
+
}
|
|
50
|
+
/** Project graph descriptors into the volume inspection without a second ledger. */
|
|
51
|
+
export interface VolumetricFogResourceInspectionOptions {
|
|
52
|
+
/** Number of non-null parameter buffers retained by the frame owner. */
|
|
53
|
+
readonly parameterBufferCount?: number;
|
|
54
|
+
}
|
|
55
|
+
export declare function inspectVolumetricFogResources(graph: CompiledRenderGraphInfo, options?: VolumetricFogResourceInspectionOptions): VolumetricFogResourceFacts;
|
|
56
|
+
export declare function createVolumetricFogResources(graph: RenderGraphBuilder<RenderPipelineFrame>, extent?: VolumetricFogExtent, resolvedExtent?: VolumetricFogExtent): Result<VolumetricFogResources, RenderGraphError>;
|
|
57
|
+
//# sourceMappingURL=resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/volume/resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,YAAY,EAEZ,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,eAAO,MAAM,oBAAoB,EAAG,YAAqB,CAAC;AAC1D,eAAO,MAAM,qBAAqB,EAAG,aAAsB,CAAC;AAC5D,eAAO,MAAM,sBAAsB,EAAG,aAAsB,CAAC;AAC7D,eAAO,MAAM,mBAAmB,EAAG,UAAmB,CAAC;AACvD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,4EAA4E;AAC5E,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAElD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,kFAAkF;AAClF,wBAAgB,yBAAyB,CACvC,OAAO,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC5D,KAAK,SAAK,EACV,QAAQ,SAAI,GACX,mBAAmB,CASrB;AAED,wFAAwF;AACxF,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC5D,cAAc,SAAI,GACjB,mBAAmB,CAOrB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;CACzC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,oFAAoF;AACpF,MAAM,WAAW,sCAAsC;IACrD,wEAAwE;IACxE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACxC;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,uBAAuB,EAC9B,OAAO,GAAE,sCAA2C,GACnD,0BAA0B,CA4D5B;AAyBD,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,EAC9C,MAAM,GAAE,mBAA0D,EAClE,cAAc,CAAC,EAAE,mBAAmB,GACnC,MAAM,CAAC,sBAAsB,EAAE,gBAAgB,CAAC,CAyDlD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface VolumeTemporalSignature {
|
|
2
|
+
readonly cameraRevision: number;
|
|
3
|
+
readonly fogRevision: number;
|
|
4
|
+
readonly lightRevision: number;
|
|
5
|
+
readonly densityGeneration: number;
|
|
6
|
+
readonly width: number;
|
|
7
|
+
readonly height: number;
|
|
8
|
+
readonly lightKind?: 'directional' | 'point' | 'spot';
|
|
9
|
+
readonly lightEntity?: number;
|
|
10
|
+
readonly pointLightEntity?: number;
|
|
11
|
+
readonly spotLightEntity?: number;
|
|
12
|
+
readonly projector?: VolumeProjectorTuple;
|
|
13
|
+
readonly lightShadowRevision?: number;
|
|
14
|
+
}
|
|
15
|
+
/** Accepted projector facts shared by surface and volume consumers. */
|
|
16
|
+
export interface VolumeProjectorTuple {
|
|
17
|
+
readonly guid: string;
|
|
18
|
+
readonly generation: number;
|
|
19
|
+
readonly view: string;
|
|
20
|
+
readonly sampler: string;
|
|
21
|
+
readonly projection: string;
|
|
22
|
+
readonly revision: number;
|
|
23
|
+
}
|
|
24
|
+
export type VolumeTemporalResetReason = 'camera-cut' | 'fog-revision' | 'light-revision' | 'density-generation' | 'resize' | 'reprojection-out-of-screen' | 'reprojection-depth-discontinuity';
|
|
25
|
+
export type VolumeTemporalReset = {
|
|
26
|
+
readonly reset: false;
|
|
27
|
+
} | {
|
|
28
|
+
readonly reset: true;
|
|
29
|
+
readonly reason: VolumeTemporalResetReason;
|
|
30
|
+
};
|
|
31
|
+
export declare function resolveVolumeTemporalReset(previous: VolumeTemporalSignature, next: VolumeTemporalSignature, options?: {
|
|
32
|
+
readonly taaEnabled?: boolean;
|
|
33
|
+
readonly reprojection?: 'out-of-screen' | 'depth-discontinuity';
|
|
34
|
+
}): VolumeTemporalReset;
|
|
35
|
+
//# sourceMappingURL=temporal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporal.d.ts","sourceRoot":"","sources":["../../src/volume/temporal.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED,uEAAuE;AACvE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,yBAAyB,GACjC,YAAY,GACZ,cAAc,GACd,gBAAgB,GAChB,oBAAoB,GACpB,QAAQ,GACR,4BAA4B,GAC5B,kCAAkC,CAAC;AAEvC,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAA;CAAE,CAAC;AAEzE,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,uBAAuB,EACjC,IAAI,EAAE,uBAAuB,EAC7B,OAAO,GAAE;IACP,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe,GAAG,qBAAqB,CAAC;CAC5D,GACL,mBAAmB,CA2CrB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeax/engine-render",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"description": "Canonical ECS render schemas and renderer boundary.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -37,27 +37,27 @@
|
|
|
37
37
|
"LICENSE"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@forgeax/engine-assets-runtime": "0.1.
|
|
41
|
-
"@forgeax/engine-audio-webaudio": "0.1.
|
|
42
|
-
"@forgeax/engine-codec": "0.1.
|
|
43
|
-
"@forgeax/engine-ecs": "0.1.
|
|
44
|
-
"@forgeax/engine-geometry": "0.1.
|
|
45
|
-
"@forgeax/engine-graphics-extras": "0.1.
|
|
46
|
-
"@forgeax/engine-math": "0.1.
|
|
47
|
-
"@forgeax/engine-pack": "0.1.
|
|
48
|
-
"@forgeax/engine-plugin": "0.1.
|
|
49
|
-
"@forgeax/engine-profiler": "0.1.
|
|
50
|
-
"@forgeax/engine-render-graph": "0.1.
|
|
51
|
-
"@forgeax/engine-rhi": "0.1.
|
|
52
|
-
"@forgeax/engine-scene": "0.1.
|
|
53
|
-
"@forgeax/engine-shader": "0.1.
|
|
54
|
-
"@forgeax/engine-skinning": "0.1.
|
|
55
|
-
"@forgeax/engine-types": "0.1.
|
|
40
|
+
"@forgeax/engine-assets-runtime": "0.1.21",
|
|
41
|
+
"@forgeax/engine-audio-webaudio": "0.1.21",
|
|
42
|
+
"@forgeax/engine-codec": "0.1.21",
|
|
43
|
+
"@forgeax/engine-ecs": "0.1.21",
|
|
44
|
+
"@forgeax/engine-geometry": "0.1.21",
|
|
45
|
+
"@forgeax/engine-graphics-extras": "0.1.21",
|
|
46
|
+
"@forgeax/engine-math": "0.1.21",
|
|
47
|
+
"@forgeax/engine-pack": "0.1.21",
|
|
48
|
+
"@forgeax/engine-plugin": "0.1.21",
|
|
49
|
+
"@forgeax/engine-profiler": "0.1.21",
|
|
50
|
+
"@forgeax/engine-render-graph": "0.1.21",
|
|
51
|
+
"@forgeax/engine-rhi": "0.1.21",
|
|
52
|
+
"@forgeax/engine-scene": "0.1.21",
|
|
53
|
+
"@forgeax/engine-shader": "0.1.21",
|
|
54
|
+
"@forgeax/engine-skinning": "0.1.21",
|
|
55
|
+
"@forgeax/engine-types": "0.1.21"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@forgeax/engine-rhi-null": "0.1.
|
|
59
|
-
"@forgeax/engine-rhi-webgpu": "0.1.
|
|
60
|
-
"@forgeax/engine-vite-plugin-shader": "0.1.
|
|
58
|
+
"@forgeax/engine-rhi-null": "0.1.21",
|
|
59
|
+
"@forgeax/engine-rhi-webgpu": "0.1.21",
|
|
60
|
+
"@forgeax/engine-vite-plugin-shader": "0.1.21"
|
|
61
61
|
},
|
|
62
62
|
"forgeax": {
|
|
63
63
|
"metrics": {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { mat4, vec3 } from '@forgeax/engine-math';
|
|
2
3
|
import { RenderGraphBuilder } from '@forgeax/engine-render-graph';
|
|
3
4
|
import type { RhiDevice } from '@forgeax/engine-rhi';
|
|
4
5
|
import { rhi } from '@forgeax/engine-rhi-null';
|
|
5
6
|
import { ok } from '@forgeax/engine-types';
|
|
6
7
|
import { beforeAll, describe, expect, it } from 'vitest';
|
|
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 { inspectStandardBloomGraph, STANDARD_BLOOM_TARGET_SPEC } from '../pipeline/standard-post';
|
|
9
13
|
import { DEFAULT_STANDARD_PROFILE, STANDARD_PIPELINE_ID } from '../pipeline/standard-profile';
|
|
@@ -19,11 +23,11 @@ beforeAll(async () => {
|
|
|
19
23
|
device = result.value;
|
|
20
24
|
});
|
|
21
25
|
|
|
22
|
-
function topology(
|
|
26
|
+
function topology(bloom: 'off' | 'on'): RenderPipelineTopology {
|
|
23
27
|
return {
|
|
24
28
|
pipelineId: STANDARD_PIPELINE_ID,
|
|
25
|
-
standardProfile:
|
|
26
|
-
config:
|
|
29
|
+
standardProfile: DEFAULT_STANDARD_PROFILE,
|
|
30
|
+
config: { ssao: { enabled: false } },
|
|
27
31
|
surface: {
|
|
28
32
|
width: 640,
|
|
29
33
|
height: 360,
|
|
@@ -32,15 +36,15 @@ function topology(lighting: 'direct' | 'clustered', bloom: 'off' | 'on'): Render
|
|
|
32
36
|
},
|
|
33
37
|
camera: { tonemap: 'aces-filmic', antialias: 'fxaa', bloom },
|
|
34
38
|
shadow: {
|
|
35
|
-
mapSize: 64,
|
|
36
|
-
|
|
39
|
+
directional: { mapSize: 64, cascadeCount: 1 },
|
|
40
|
+
spotMapSize: 64,
|
|
37
41
|
pointCount: 0,
|
|
38
42
|
pointFaceSize: 64,
|
|
39
43
|
spotCount: 0,
|
|
40
44
|
},
|
|
41
45
|
lane: {
|
|
42
|
-
compute:
|
|
43
|
-
storageBuffer:
|
|
46
|
+
compute: true,
|
|
47
|
+
storageBuffer: true,
|
|
44
48
|
multisample: false,
|
|
45
49
|
maxColorAttachments: 8,
|
|
46
50
|
},
|
|
@@ -49,15 +53,43 @@ function topology(lighting: 'direct' | 'clustered', bloom: 'off' | 'on'): Render
|
|
|
49
53
|
};
|
|
50
54
|
}
|
|
51
55
|
|
|
52
|
-
function
|
|
56
|
+
function clusteredStandardLighting() {
|
|
57
|
+
const prepared = prepareStandardLighting({
|
|
58
|
+
directional: undefined,
|
|
59
|
+
local: [{ kind: 'point' as const, shadowed: false, position: vec3.create(0, 0, -4), range: 2 }],
|
|
60
|
+
view: mat4.lookAt(mat4.create(), [0, 0, 0], [0, 0, -1], [0, 1, 0]),
|
|
61
|
+
projection: mat4.perspective(mat4.create(), Math.PI / 3, 1, 0.1, 100),
|
|
62
|
+
near: 0.1,
|
|
63
|
+
far: 100,
|
|
64
|
+
grid: { x: 4, y: 3, z: 4 },
|
|
65
|
+
lightCount: DEFAULT_STANDARD_PROFILE.lightCount,
|
|
66
|
+
renderPath: 'forward',
|
|
67
|
+
});
|
|
68
|
+
if (!prepared.ok) throw prepared.error;
|
|
69
|
+
const transport = selectStandardClusterTransport(
|
|
70
|
+
{ compute: true, storageBuffer: true, membershipPipelineReady: true },
|
|
71
|
+
prepared.value,
|
|
72
|
+
);
|
|
73
|
+
if (!transport.ok) throw transport.error;
|
|
74
|
+
const lighting = deriveStandardTopologyInput({
|
|
75
|
+
kind: 'clustered',
|
|
76
|
+
prepared: prepared.value,
|
|
77
|
+
transport: transport.value,
|
|
78
|
+
});
|
|
79
|
+
if (!lighting.ok) throw lighting.error;
|
|
80
|
+
return lighting.value;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function inspect(bloom: 'off' | 'on') {
|
|
53
84
|
const graph = new RenderGraphBuilder<RenderPipelineFrame>();
|
|
54
85
|
const built = standardPipeline.build(
|
|
55
86
|
{
|
|
56
87
|
graph,
|
|
88
|
+
standardLighting: clusteredStandardLighting(),
|
|
57
89
|
projectGpuDriven: () => ok(undefined),
|
|
58
90
|
contributeFeatures: () => ok(undefined),
|
|
59
91
|
},
|
|
60
|
-
topology(
|
|
92
|
+
topology(bloom),
|
|
61
93
|
);
|
|
62
94
|
if (!built.ok) throw built.error;
|
|
63
95
|
const compiled = graph.compile({ device, surfaceSize: { width: 640, height: 360 } });
|
|
@@ -66,11 +98,8 @@ function inspect(lighting: 'direct' | 'clustered', bloom: 'off' | 'on') {
|
|
|
66
98
|
}
|
|
67
99
|
|
|
68
100
|
describe('Standard Bloom exact-zero topology', () => {
|
|
69
|
-
it
|
|
70
|
-
'
|
|
71
|
-
'clustered',
|
|
72
|
-
] as const)('%s Bloom off declares no Bloom targets or passes', (lighting) => {
|
|
73
|
-
const info = inspect(lighting, 'off');
|
|
101
|
+
it('Bloom off declares no Bloom targets or passes', () => {
|
|
102
|
+
const info = inspect('off');
|
|
74
103
|
const bloomPasses = info.passes.filter((pass) => pass.name.startsWith('bloom-'));
|
|
75
104
|
const bloomResources = info.resources.filter((resource) => resource.label.startsWith('bloom-'));
|
|
76
105
|
expect(bloomPasses).toHaveLength(0);
|
|
@@ -120,8 +149,8 @@ describe('Standard Bloom exact-zero topology', () => {
|
|
|
120
149
|
});
|
|
121
150
|
|
|
122
151
|
it('keeps one shared Bloom chain when enabled', () => {
|
|
123
|
-
|
|
124
|
-
const info = inspect(
|
|
152
|
+
{
|
|
153
|
+
const info = inspect('on');
|
|
125
154
|
expect(inspectStandardBloomGraph(info)).toEqual({
|
|
126
155
|
status: 'valid',
|
|
127
156
|
targetCount: 4,
|
|
@@ -147,7 +176,7 @@ describe('Standard Bloom exact-zero topology', () => {
|
|
|
147
176
|
});
|
|
148
177
|
|
|
149
178
|
it('fails closed when a canonical Bloom descriptor drifts', () => {
|
|
150
|
-
const info = inspect('
|
|
179
|
+
const info = inspect('on');
|
|
151
180
|
const drifted = {
|
|
152
181
|
...info,
|
|
153
182
|
resources: info.resources.map((resource) =>
|
|
@@ -171,7 +200,7 @@ describe('Standard Bloom exact-zero topology', () => {
|
|
|
171
200
|
});
|
|
172
201
|
|
|
173
202
|
it('rejects a graph with a missing canonical Bloom target', () => {
|
|
174
|
-
const info = inspect('
|
|
203
|
+
const info = inspect('on');
|
|
175
204
|
const drifted = {
|
|
176
205
|
...info,
|
|
177
206
|
resources: info.resources.filter(
|
|
@@ -187,7 +216,7 @@ describe('Standard Bloom exact-zero topology', () => {
|
|
|
187
216
|
});
|
|
188
217
|
|
|
189
218
|
it('rejects a graph with a missing canonical Bloom pass', () => {
|
|
190
|
-
const info = inspect('
|
|
219
|
+
const info = inspect('on');
|
|
191
220
|
const drifted = {
|
|
192
221
|
...info,
|
|
193
222
|
passes: info.passes.filter((pass) => pass.name !== 'bloom-blur-h'),
|
|
@@ -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 { DeviceScope, LifecycleTransaction } from '../device/device-scope';
|
|
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 { DEFAULT_STANDARD_PROFILE, STANDARD_PIPELINE_ID } from '../pipeline/standard-profile';
|
|
9
13
|
import type { RenderPipelineFrame, RenderPipelineTopology } from '../render-pipeline';
|
|
@@ -18,11 +22,11 @@ beforeAll(async () => {
|
|
|
18
22
|
device = result.value;
|
|
19
23
|
});
|
|
20
24
|
|
|
21
|
-
function build(bloom: 'off' | 'on'
|
|
25
|
+
function build(bloom: 'off' | 'on') {
|
|
22
26
|
const topology: RenderPipelineTopology = {
|
|
23
27
|
pipelineId: STANDARD_PIPELINE_ID,
|
|
24
|
-
standardProfile:
|
|
25
|
-
config:
|
|
28
|
+
standardProfile: DEFAULT_STANDARD_PROFILE,
|
|
29
|
+
config: { ssao: { enabled: false } },
|
|
26
30
|
surface: {
|
|
27
31
|
width: 320,
|
|
28
32
|
height: 180,
|
|
@@ -31,15 +35,15 @@ function build(bloom: 'off' | 'on', lighting: 'direct' | 'clustered') {
|
|
|
31
35
|
},
|
|
32
36
|
camera: { tonemap: 'aces-filmic', antialias: 'fxaa', bloom },
|
|
33
37
|
shadow: {
|
|
34
|
-
mapSize: 64,
|
|
35
|
-
|
|
38
|
+
directional: { mapSize: 64, cascadeCount: 1 },
|
|
39
|
+
spotMapSize: 64,
|
|
36
40
|
pointCount: 0,
|
|
37
41
|
pointFaceSize: 64,
|
|
38
42
|
spotCount: 0,
|
|
39
43
|
},
|
|
40
44
|
lane: {
|
|
41
|
-
compute:
|
|
42
|
-
storageBuffer:
|
|
45
|
+
compute: true,
|
|
46
|
+
storageBuffer: true,
|
|
43
47
|
multisample: false,
|
|
44
48
|
maxColorAttachments: 8,
|
|
45
49
|
},
|
|
@@ -47,9 +51,33 @@ function build(bloom: 'off' | 'on', lighting: 'direct' | 'clustered') {
|
|
|
47
51
|
gpuDrivenTopologySignature: '',
|
|
48
52
|
};
|
|
49
53
|
const graph = new RenderGraphBuilder<RenderPipelineFrame>();
|
|
54
|
+
const prepared = prepareStandardLighting({
|
|
55
|
+
directional: undefined,
|
|
56
|
+
local: [{ kind: 'point' as const, shadowed: false, position: vec3.create(0, 0, -4), range: 2 }],
|
|
57
|
+
view: mat4.lookAt(mat4.create(), [0, 0, 0], [0, 0, -1], [0, 1, 0]),
|
|
58
|
+
projection: mat4.perspective(mat4.create(), Math.PI / 3, 1, 0.1, 100),
|
|
59
|
+
near: 0.1,
|
|
60
|
+
far: 100,
|
|
61
|
+
grid: { x: 4, y: 3, z: 4 },
|
|
62
|
+
lightCount: DEFAULT_STANDARD_PROFILE.lightCount,
|
|
63
|
+
renderPath: 'forward',
|
|
64
|
+
});
|
|
65
|
+
if (!prepared.ok) throw prepared.error;
|
|
66
|
+
const transport = selectStandardClusterTransport(
|
|
67
|
+
{ compute: true, storageBuffer: true, membershipPipelineReady: true },
|
|
68
|
+
prepared.value,
|
|
69
|
+
);
|
|
70
|
+
if (!transport.ok) throw transport.error;
|
|
71
|
+
const standardLighting = deriveStandardTopologyInput({
|
|
72
|
+
kind: 'clustered',
|
|
73
|
+
prepared: prepared.value,
|
|
74
|
+
transport: transport.value,
|
|
75
|
+
});
|
|
76
|
+
if (!standardLighting.ok) throw standardLighting.error;
|
|
50
77
|
const built = standardPipeline.build(
|
|
51
78
|
{
|
|
52
79
|
graph,
|
|
80
|
+
standardLighting: standardLighting.value,
|
|
53
81
|
projectGpuDriven: () => ok(undefined),
|
|
54
82
|
contributeFeatures: () => ok(undefined),
|
|
55
83
|
},
|
|
@@ -71,10 +99,10 @@ function bloomSummary(info: ReturnType<typeof build>) {
|
|
|
71
99
|
}
|
|
72
100
|
|
|
73
101
|
describe('Standard Bloom lifecycle contract', () => {
|
|
74
|
-
it
|
|
75
|
-
const on = bloomSummary(build('on'
|
|
76
|
-
const off = bloomSummary(build('off'
|
|
77
|
-
const recovered = bloomSummary(build('on'
|
|
102
|
+
it('supports on -> off -> on for the Standard clustered graph', () => {
|
|
103
|
+
const on = bloomSummary(build('on'));
|
|
104
|
+
const off = bloomSummary(build('off'));
|
|
105
|
+
const recovered = bloomSummary(build('on'));
|
|
78
106
|
expect(on.passes).toHaveLength(4);
|
|
79
107
|
expect(on.resources.length).toBeGreaterThan(0);
|
|
80
108
|
expect(off).toEqual({ passes: [], resources: [] });
|
|
@@ -82,7 +110,7 @@ describe('Standard Bloom lifecycle contract', () => {
|
|
|
82
110
|
});
|
|
83
111
|
|
|
84
112
|
it('keeps post order scene -> Bloom -> output transform -> FXAA -> debug', () => {
|
|
85
|
-
const names = build('on'
|
|
113
|
+
const names = build('on').passes.map((pass) => pass.name);
|
|
86
114
|
const order = [
|
|
87
115
|
'forward',
|
|
88
116
|
'bloom-bright',
|
|
@@ -117,7 +145,7 @@ describe('Standard Bloom lifecycle contract', () => {
|
|
|
117
145
|
});
|
|
118
146
|
|
|
119
147
|
it('FALSIFY rejects an injected Bloom contribution on the off path', () => {
|
|
120
|
-
const off = bloomSummary(build('off'
|
|
148
|
+
const off = bloomSummary(build('off'));
|
|
121
149
|
const injected = { ...off, passes: ['bloom-falsified'] };
|
|
122
150
|
expect(injected).not.toEqual({ passes: [], resources: [] });
|
|
123
151
|
expect(off).toEqual({ passes: [], resources: [] });
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { type CameraTargetCandidate, selectCameraTargetViews } from '../render-system-extract';
|
|
3
|
+
import type { RenderTargetDescriptor } from '../targets/contracts';
|
|
4
|
+
import { createRenderTargetOwner } from '../targets/owner';
|
|
5
|
+
|
|
6
|
+
const descriptor: RenderTargetDescriptor = {
|
|
7
|
+
shape: '2d',
|
|
8
|
+
width: 16,
|
|
9
|
+
height: 16,
|
|
10
|
+
format: 'rgba8unorm',
|
|
11
|
+
mipLevels: 1,
|
|
12
|
+
sampleCount: 1,
|
|
13
|
+
sampled: true,
|
|
14
|
+
readback: false,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function targets() {
|
|
18
|
+
const owner = createRenderTargetOwner({ rendererId: Symbol('renderer'), initialGeneration: 1 });
|
|
19
|
+
const first = owner.create(descriptor);
|
|
20
|
+
const second = owner.create(descriptor);
|
|
21
|
+
if (!first.ok) throw first.error;
|
|
22
|
+
if (!second.ok) throw second.error;
|
|
23
|
+
return [first.value, second.value] as const;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
describe('Camera target consumption', () => {
|
|
27
|
+
it('keeps display authority separate and applies stable auxiliary ordering and budget', () => {
|
|
28
|
+
const [first, second] = targets();
|
|
29
|
+
const cameras: CameraTargetCandidate[] = [
|
|
30
|
+
{ worldId: 2, entityKey: 20, target: first, requestVersion: 1, update: 'once' },
|
|
31
|
+
{ worldId: 1, entityKey: 30, target: second, requestVersion: 1, update: 'continuous' },
|
|
32
|
+
{ worldId: 1, entityKey: 10, requestVersion: 0, update: 'continuous' },
|
|
33
|
+
];
|
|
34
|
+
const selected = selectCameraTargetViews(cameras, { displayEntityKey: 10, budget: 1 });
|
|
35
|
+
expect(selected.display?.entityKey).toBe(10);
|
|
36
|
+
expect(selected.auxiliary.map((camera) => camera.entityKey)).toEqual([30]);
|
|
37
|
+
expect(selected.rejected).toHaveLength(1);
|
|
38
|
+
expect(selected.rejected[0]?.reason).toBe('budget');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('rejects a target camera selected as display and duplicate target producers', () => {
|
|
42
|
+
const [first] = targets();
|
|
43
|
+
const cameras: CameraTargetCandidate[] = [
|
|
44
|
+
{ worldId: 1, entityKey: 3, target: first, requestVersion: 1, update: 'once' },
|
|
45
|
+
{ worldId: 1, entityKey: 4, target: first, requestVersion: 2, update: 'once' },
|
|
46
|
+
];
|
|
47
|
+
const selected = selectCameraTargetViews(cameras, { displayEntityKey: 3, budget: 2 });
|
|
48
|
+
expect(selected.display).toBeUndefined();
|
|
49
|
+
expect(selected.rejected.map((entry) => entry.reason)).toEqual(
|
|
50
|
+
expect.arrayContaining(['display-target', 'duplicate-target']),
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { mat4, vec3 } from '@forgeax/engine-math';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { bin, createClusterBinScratch } from '../cluster-binner';
|
|
4
|
+
|
|
5
|
+
describe('cluster binner structured boundaries', () => {
|
|
6
|
+
it('returns a complete structured overflow without truncating output', () => {
|
|
7
|
+
const grid = { x: 4, y: 3, z: 4 };
|
|
8
|
+
const view = mat4.lookAt(mat4.create(), [0, 0, 0], [0, 0, -1], [0, 1, 0]);
|
|
9
|
+
const projection = mat4.perspective(mat4.create(), Math.PI / 3, 1, 0.1, 100);
|
|
10
|
+
const clusterGrid = new Uint32Array(grid.x * grid.y * grid.z * 2).fill(7);
|
|
11
|
+
const lightIndexList = new Uint32Array(1).fill(9);
|
|
12
|
+
const result = bin(
|
|
13
|
+
[{ position: vec3.create(0, 0, -4), range: 100 }],
|
|
14
|
+
view,
|
|
15
|
+
projection,
|
|
16
|
+
grid,
|
|
17
|
+
0.1,
|
|
18
|
+
100,
|
|
19
|
+
clusterGrid,
|
|
20
|
+
lightIndexList,
|
|
21
|
+
0,
|
|
22
|
+
createClusterBinScratch(),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
expect(result.ok).toBe(false);
|
|
26
|
+
if (result.ok) return;
|
|
27
|
+
expect(result.error.code).toBe('index-overflow');
|
|
28
|
+
expect(result.error.expected).toContain('writeCount <= 0');
|
|
29
|
+
expect(result.error.hint).toContain('reduce lights');
|
|
30
|
+
expect(result.error.detail.actual).toBeGreaterThan(0);
|
|
31
|
+
expect(result.error.detail.capacity).toBe(0);
|
|
32
|
+
expect(Array.from(clusterGrid)).toEqual(new Array(clusterGrid.length).fill(0));
|
|
33
|
+
expect(Array.from(lightIndexList)).toEqual([9]);
|
|
34
|
+
});
|
|
35
|
+
});
|