@forgeax/engine-render 0.1.20 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +365 -29
- package/dist/assembly/backend-contract.d.ts +13 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -1
- package/dist/assembly/device-feature-admission.d.ts +18 -0
- package/dist/assembly/device-feature-admission.d.ts.map +1 -0
- package/dist/assembly/directional-shadow-inspection.d.ts +38 -0
- package/dist/assembly/directional-shadow-inspection.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +30 -19
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +19 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/render-target-host.d.ts +46 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -0
- package/dist/assets/render-asset-port.d.ts.map +1 -1
- package/dist/authoring.mjs +4 -1
- package/dist/authoring.mjs.map +1 -1
- package/dist/capture/cube-views.d.ts +21 -0
- package/dist/capture/cube-views.d.ts.map +1 -0
- package/dist/capture/scheduler.d.ts +54 -0
- package/dist/capture/scheduler.d.ts.map +1 -0
- package/dist/{chunk-PCHBPYML.mjs → chunk-4L3P6DT5.mjs} +2 -2
- package/dist/chunk-4L3P6DT5.mjs.map +1 -0
- package/dist/{chunk-VFPLTKCU.mjs → chunk-4NPUASZR.mjs} +15 -4
- package/dist/chunk-4NPUASZR.mjs.map +1 -0
- package/dist/chunk-DIYW3M5D.mjs +5085 -0
- package/dist/chunk-DIYW3M5D.mjs.map +1 -0
- package/dist/chunk-FBC4R44J.mjs +1003 -0
- package/dist/chunk-FBC4R44J.mjs.map +1 -0
- package/dist/{chunk-CDTWTHZR.mjs → chunk-FF7K3FSO.mjs} +474 -168
- package/dist/chunk-FF7K3FSO.mjs.map +1 -0
- package/dist/chunk-HZUPSYW7.mjs +1104 -0
- package/dist/chunk-HZUPSYW7.mjs.map +1 -0
- package/dist/{chunk-TBQJOK2L.mjs → chunk-QODA5UKU.mjs} +321 -269
- package/dist/chunk-QODA5UKU.mjs.map +1 -0
- package/dist/chunk-YALPS44A.mjs +296 -0
- package/dist/chunk-YALPS44A.mjs.map +1 -0
- package/dist/{chunk-4XINDLAY.mjs → chunk-ZUWKAZ2I.mjs} +1963 -2178
- package/dist/chunk-ZUWKAZ2I.mjs.map +1 -0
- package/dist/cluster-binner.d.ts +5 -0
- package/dist/cluster-binner.d.ts.map +1 -1
- package/dist/components/camera.d.ts +1 -0
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/cube-camera.d.ts +20 -0
- package/dist/components/cube-camera.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +11 -2
- package/dist/components/directional-light.d.ts.map +1 -1
- package/dist/components/directional-shadow-filter.d.ts +25 -0
- package/dist/components/directional-shadow-filter.d.ts.map +1 -0
- package/dist/components/index.d.ts +5 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts +4 -0
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/light-probe.d.ts +9 -0
- package/dist/components/light-probe.d.ts.map +1 -0
- package/dist/components/rect-area-light.d.ts +12 -0
- package/dist/components/rect-area-light.d.ts.map +1 -0
- package/dist/components/reflection-probe.d.ts +17 -0
- package/dist/components/reflection-probe.d.ts.map +1 -0
- package/dist/components/scene-instance.d.ts +4 -0
- package/dist/components/scene-instance.d.ts.map +1 -1
- package/dist/components/spot-light.d.ts +3 -0
- package/dist/components/spot-light.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +14836 -9620
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +8 -1
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/device/lifecycle-transaction.d.ts +2 -0
- package/dist/device/lifecycle-transaction.d.ts.map +1 -0
- package/dist/environment/frame.d.ts.map +1 -1
- package/dist/environment/lifecycle.d.ts +5 -0
- package/dist/environment/lifecycle.d.ts.map +1 -1
- package/dist/errors/gpu-driven.d.ts +26 -0
- package/dist/errors/gpu-driven.d.ts.map +1 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/recover.d.ts +9 -1
- package/dist/errors/recover.d.ts.map +1 -1
- package/dist/errors/render.d.ts +166 -93
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/directional-shadow-projection.d.ts +23 -0
- package/dist/extract/directional-shadow-projection.d.ts.map +1 -0
- package/dist/extract/environment.d.ts +14 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/extract/gpu-driven.d.ts +50 -0
- package/dist/extract/gpu-driven.d.ts.map +1 -0
- package/dist/extract/visibility.d.ts.map +1 -1
- package/dist/features/fullscreen.d.ts.map +1 -1
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +10 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +13 -2
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +34 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/prepared-draw.d.ts +63 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +97 -2
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/view-gpu.d.ts +64 -1
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene-schema.d.ts +14 -0
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +8 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/gpu-usage.d.ts +0 -1
- package/dist/gpu-usage.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +21 -19
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +4 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/kernel-cache.d.ts +36 -0
- package/dist/ibl/kernel-cache.d.ts.map +1 -0
- package/dist/index.d.ts +39 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +91 -6
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +214 -1
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +50 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -0
- package/dist/internal.d.ts +9 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +23 -2
- package/dist/internal.mjs.map +1 -1
- package/dist/light-buffer-layout.d.ts +58 -140
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/materials.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +54 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +38 -14
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts +2 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/errors.d.ts +4 -0
- package/dist/pipeline/standard-lighting/errors.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/graph.d.ts +24 -0
- package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts +38 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/layout.d.ts +28 -0
- package/dist/pipeline/standard-lighting/layout.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts +33 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/membership.d.ts +14 -0
- package/dist/pipeline/standard-lighting/membership.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts +16 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/topology.d.ts +45 -0
- package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/transport.d.ts +36 -0
- package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts +4 -13
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +5 -26
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +2 -0
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +40 -7
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/point-shadow-inspection.d.ts +21 -0
- package/dist/point-shadow-inspection.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/ltc-resources.d.ts +31 -0
- package/dist/prepare/extended-lighting/ltc-resources.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/resources.d.ts +72 -0
- package/dist/prepare/extended-lighting/resources.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/spot-modifiers.d.ts +42 -0
- package/dist/prepare/extended-lighting/spot-modifiers.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/state.d.ts +24 -0
- package/dist/prepare/extended-lighting/state.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +33 -36
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +78 -24
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts +5 -0
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +16 -6
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-pass-timing/contract.d.ts +96 -0
- package/dist/record/gpu-pass-timing/contract.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/errors.d.ts +18 -0
- package/dist/record/gpu-pass-timing/errors.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/index.d.ts +8 -0
- package/dist/record/gpu-pass-timing/index.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/parser.d.ts +11 -0
- package/dist/record/gpu-pass-timing/parser.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/session.d.ts +43 -0
- package/dist/record/gpu-pass-timing/session.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +20 -3
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/helpers.d.ts +0 -20
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +6 -1
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +25 -2
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +2 -0
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +98 -6
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +119 -4
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +7 -5
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/reflection/filter.d.ts +22 -0
- package/dist/reflection/filter.d.ts.map +1 -0
- package/dist/reflection/gpu-table.d.ts +25 -0
- package/dist/reflection/gpu-table.d.ts.map +1 -0
- package/dist/reflection/inspection.d.ts +10 -0
- package/dist/reflection/inspection.d.ts.map +1 -0
- package/dist/reflection/projection.d.ts +140 -0
- package/dist/reflection/projection.d.ts.map +1 -0
- package/dist/reflection/record-owner.d.ts +60 -0
- package/dist/reflection/record-owner.d.ts.map +1 -0
- package/dist/render-contract.d.ts +62 -14
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +49 -2
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +160 -31
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +28 -2
- package/dist/render-system.d.ts.map +1 -1
- package/dist/renderer.d.ts +43 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/scene/probe-blend-record.d.ts +22 -0
- package/dist/scene/probe-blend-record.d.ts.map +1 -0
- package/dist/scene/probe-blend.d.ts +142 -0
- package/dist/scene/probe-blend.d.ts.map +1 -0
- package/dist/scene/render-scene-types.d.ts +0 -6
- package/dist/scene/render-scene-types.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +117 -9
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/visibility/bounds.d.ts +20 -0
- package/dist/scene/visibility/bounds.d.ts.map +1 -0
- package/dist/scene/visibility/budget.d.ts +16 -0
- package/dist/scene/visibility/budget.d.ts.map +1 -0
- package/dist/scene/visibility/facet.d.ts +73 -0
- package/dist/scene/visibility/facet.d.ts.map +1 -0
- package/dist/scene/visibility/gpu-frame-timing.d.ts +41 -0
- package/dist/scene/visibility/gpu-frame-timing.d.ts.map +1 -0
- package/dist/scene/visibility/gpu-lod.d.ts +46 -0
- package/dist/scene/visibility/gpu-lod.d.ts.map +1 -0
- package/dist/scene/visibility/inspection.d.ts +132 -0
- package/dist/scene/visibility/inspection.d.ts.map +1 -0
- package/dist/scene/visibility/lod-selector.d.ts +25 -0
- package/dist/scene/visibility/lod-selector.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-confidence.d.ts +81 -0
- package/dist/scene/visibility/occlusion-confidence.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-pass.d.ts +57 -0
- package/dist/scene/visibility/occlusion-pass.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-query-pool.d.ts +57 -0
- package/dist/scene/visibility/occlusion-query-pool.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-runtime.d.ts +96 -0
- package/dist/scene/visibility/occlusion-runtime.d.ts.map +1 -0
- package/dist/scene/visibility/types.d.ts +34 -0
- package/dist/scene/visibility/types.d.ts.map +1 -0
- package/dist/shadow-atlas.d.ts +3 -3
- package/dist/shadow-atlas.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +3 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/ssr/admission.d.ts +122 -0
- package/dist/ssr/admission.d.ts.map +1 -0
- package/dist/ssr/composition.d.ts +32 -0
- package/dist/ssr/composition.d.ts.map +1 -0
- package/dist/ssr/errors.d.ts +39 -0
- package/dist/ssr/errors.d.ts.map +1 -0
- package/dist/ssr/identity.d.ts +13 -0
- package/dist/ssr/identity.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +1 -1
- package/dist/targets/contracts.d.ts +66 -0
- package/dist/targets/contracts.d.ts.map +1 -0
- package/dist/targets/graph-projection.d.ts +29 -0
- package/dist/targets/graph-projection.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +34 -0
- package/dist/targets/material-source.d.ts.map +1 -0
- package/dist/targets/owner.d.ts +32 -0
- package/dist/targets/owner.d.ts.map +1 -0
- package/dist/targets/physical.d.ts +18 -0
- package/dist/targets/physical.d.ts.map +1 -0
- package/dist/targets/readback.d.ts +39 -0
- package/dist/targets/readback.d.ts.map +1 -0
- package/dist/temporal/frame-coordinator.d.ts +13 -0
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +2 -0
- package/dist/temporal/frame.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -5
- package/dist/temporal/view.d.ts +7 -0
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/tilemap-chunk-extract-system.d.ts +1 -1
- package/dist/typed-render-graph-primitives.d.ts +5 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +1 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +9 -5
- package/dist/volume/passes.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/__tests__/bloom-exact-zero.unit.test.ts +48 -19
- package/src/__tests__/bloom-lifecycle.integration.test.ts +41 -13
- package/src/__tests__/camera-target-consumption.unit.test.ts +53 -0
- package/src/__tests__/cluster-binner.unit.test.ts +35 -0
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +12 -2
- package/src/__tests__/cube-camera-scheduler.unit.test.ts +70 -0
- package/src/__tests__/cube-camera-single-submit.perf.test.ts +75 -0
- package/src/__tests__/cube-camera-view-matrices.unit.test.ts +41 -0
- package/src/__tests__/cube-camera-vocabulary.unit.test.ts +47 -0
- package/src/__tests__/cube-camera.integration.test.ts +42 -0
- package/src/__tests__/detached-inspection.integration.test.ts +6 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +85 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +62 -6
- package/src/__tests__/docs-gate-green.unit.test.ts +38 -0
- package/src/__tests__/environment-generation.integration.test.ts +16 -0
- package/src/__tests__/evidence-identity.ts +13 -0
- package/src/__tests__/evidence-identity.unit.test.ts +24 -0
- package/src/__tests__/extended-lighting-recovery.browser.test.ts +14 -0
- package/src/__tests__/extended-lighting-recovery.dawn.test.ts +14 -0
- package/src/__tests__/extended-lighting-recovery.integration.test.ts +81 -0
- package/src/__tests__/extended-lighting-resources.unit.test.ts +51 -0
- package/src/__tests__/extended-lighting-zero-feature.integration.test.ts +52 -0
- package/src/__tests__/factory-contract.integration.test.ts +288 -29
- package/src/__tests__/fog-component.unit.test.ts +67 -0
- package/src/__tests__/fog.integration.test.ts +86 -0
- package/src/__tests__/frame-observation.contract.test.ts +15 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +37 -0
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +10 -8
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +18 -1
- package/src/__tests__/gpu-driven-production.integration.test.ts +579 -17
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +66 -2
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +26 -1
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +101 -6
- package/src/__tests__/gpu-driven-view.browser.test.ts +3 -3
- package/src/__tests__/gpu-driven-view.dawn.test.ts +3 -3
- package/src/__tests__/gpu-driven-view.unit.test.ts +50 -0
- package/src/__tests__/gpu-lod-evidence.ts +188 -0
- package/src/__tests__/gpu-lod-fallback.integration.test.ts +10 -0
- package/src/__tests__/gpu-lod-indirect.integration.test.ts +40 -0
- package/src/__tests__/gpu-lod-parity.dawn.test.ts +29 -0
- package/src/__tests__/gpu-lod-readiness.integration.test.ts +52 -0
- package/src/__tests__/gpu-lod-schema.unit.test.ts +66 -0
- package/src/__tests__/gpu-lod-selector.unit.test.ts +28 -0
- package/src/__tests__/gpu-lod-silhouette.browser.test.ts +13 -0
- package/src/__tests__/gpu-pass-timing-browser-runner.ts +281 -0
- package/src/__tests__/gpu-pass-timing-coexistence.integration.test.ts +80 -0
- package/src/__tests__/gpu-pass-timing-contract.unit.test.ts +243 -0
- package/src/__tests__/gpu-pass-timing-exact-zero.unit.test.ts +131 -0
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +230 -0
- package/src/__tests__/gpu-pass-timing-observation.unit.test.ts +233 -0
- package/src/__tests__/gpu-pass-timing-session.unit.test.ts +438 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +26 -0
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +125 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +66 -1
- package/src/__tests__/gpu-scene.dawn.test.ts +8 -1
- package/src/__tests__/gpu-scene.unit.test.ts +49 -3
- package/src/__tests__/hdrp-group2-visibility.unit.test.ts +24 -0
- package/src/__tests__/instances-culling.integration.test.ts +94 -0
- package/src/__tests__/instances-derived-bounds.unit.test.ts +118 -0
- package/src/__tests__/light-buffer-layout.unit.test.ts +113 -3
- package/src/__tests__/light-inspection.unit.test.ts +55 -0
- package/src/__tests__/light-resource-error.unit.test.ts +43 -0
- package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +109 -0
- package/src/__tests__/lod-bounds.unit.test.ts +42 -0
- package/src/__tests__/lod-cpu-lane.integration.test.ts +55 -0
- package/src/__tests__/lod-cpu-no-change.perf.test.ts +19 -0
- package/src/__tests__/lod-gpu-frame-timing.unit.test.ts +49 -0
- package/src/__tests__/lod-multi-view.integration.test.ts +63 -0
- package/src/__tests__/lod-occlusion-device-loss.integration.test.ts +27 -0
- package/src/__tests__/lod-occlusion-final-decision.integration.test.ts +47 -0
- package/src/__tests__/lod-occlusion-inspection.integration.test.ts +217 -0
- package/src/__tests__/lod-occlusion-inspection.schema.test-d.ts +14 -0
- package/src/__tests__/lod-occlusion-inspection.unit.test.ts +72 -0
- package/src/__tests__/lod-occlusion-visual-evidence.ts +91 -0
- package/src/__tests__/lod-occlusion.browser.test.ts +15 -0
- package/src/__tests__/lod-occlusion.dawn.test.ts +20 -0
- package/src/__tests__/lod-selector.profile.test.ts +35 -0
- package/src/__tests__/lod-selector.unit.test.ts +68 -0
- package/src/__tests__/lod-visibility-identity.unit.test.ts +198 -0
- package/src/__tests__/lod-visibility-lifecycle.integration.test.ts +132 -0
- package/src/__tests__/ltc-resources.unit.test.ts +32 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +17 -0
- package/src/__tests__/material-observation.integration.test.ts +101 -0
- package/src/__tests__/occlusion-confidence.unit.test.ts +168 -0
- package/src/__tests__/occlusion-invalidation.integration.test.ts +37 -0
- package/src/__tests__/occlusion-pass-routing.unit.test.ts +16 -0
- package/src/__tests__/occlusion-pass.dawn.test.ts +20 -0
- package/src/__tests__/occlusion-pass.integration.test.ts +43 -0
- package/src/__tests__/occlusion-pass.rhi-null.test.ts +22 -0
- package/src/__tests__/occlusion-query-pool.rhi-null.test.ts +21 -0
- package/src/__tests__/occlusion-query-pool.unit.test.ts +95 -0
- package/src/__tests__/occlusion-query-ticket.integration.test.ts +47 -0
- package/src/__tests__/occlusion-query.dawn.test.ts +16 -0
- package/src/__tests__/occlusion-query.evidence.ts +178 -0
- package/src/__tests__/occlusion-query.rhi-null.test.ts +31 -0
- package/src/__tests__/occlusion-runtime.unit.test.ts +120 -0
- package/src/__tests__/pbr-view-layout.unit.test.ts +16 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +60 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
- package/src/__tests__/probe-bindings.unit.test.ts +200 -0
- package/src/__tests__/probe-blend-numeric.unit.test.ts +67 -0
- package/src/__tests__/probe-blend-oracle.unit.test.ts +136 -0
- package/src/__tests__/probe-capacity.integration.test.ts +97 -0
- package/src/__tests__/probe-recovery.integration.test.ts +104 -0
- package/src/__tests__/probe-scene-dirty.integration.test.ts +211 -0
- package/src/__tests__/profiler-phase-catalog.test.ts +4 -1
- package/src/__tests__/profiler-phase-token.test.ts +1 -0
- package/src/__tests__/public-surface.test-d.ts +10 -0
- package/src/__tests__/rect-area-boundary.unit.test.ts +24 -0
- package/src/__tests__/reflection-fallback-graph.unit.test.ts +67 -0
- package/src/__tests__/reflection-fallback-inspection.unit.test.ts +77 -0
- package/src/__tests__/reflection-fallback-lifecycle.integration.test.ts +21 -0
- package/src/__tests__/reflection-fallback-projection.unit.test.ts +90 -0
- package/src/__tests__/reflection-fallback-source.unit.test.ts +32 -0
- package/src/__tests__/reflection-probe-authoring.unit.test.ts +71 -0
- package/src/__tests__/reflection-probe-filter.unit.test.ts +54 -0
- package/src/__tests__/reflection-probe-ibl-topology.unit.test.ts +45 -0
- package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
- package/src/__tests__/reflection-probe-pass-encode.integration.test.ts +101 -0
- package/src/__tests__/reflection-probe-performance.perf.test.ts +60 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
- package/src/__tests__/reflection-probe-recovery.integration.test.ts +55 -0
- package/src/__tests__/reflection-probe-selection.unit.test.ts +46 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +19 -3
- package/src/__tests__/render-feature-docs.unit.test.ts +12 -7
- package/src/__tests__/render-graph-fallback.integration.test.ts +24 -0
- package/src/__tests__/render-perf/extended-lighting.bench.test.ts +66 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +447 -18
- package/src/__tests__/render-target-admission.unit.test.ts +80 -0
- package/src/__tests__/render-target-graph-projection.unit.test.ts +102 -0
- package/src/__tests__/render-target-inspection.unit.test.ts +52 -0
- package/src/__tests__/render-target-material-source.test-d.ts +30 -0
- package/src/__tests__/render-target-material-source.unit.test.ts +97 -0
- package/src/__tests__/render-target-owner-placement.unit.test.ts +203 -0
- package/src/__tests__/render-target-owner.unit.test.ts +122 -0
- package/src/__tests__/render-target-probe-soak.perf.test.ts +94 -0
- package/src/__tests__/render-target-public-schema.json +107 -0
- package/src/__tests__/render-target-public-schema.unit.test.ts +91 -0
- package/src/__tests__/render-target-public-surface.test-d.ts +83 -0
- package/src/__tests__/render-target-readback.integration.test.ts +90 -0
- package/src/__tests__/render-target-recovery.integration.test.ts +85 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +124 -0
- package/src/__tests__/renderer-lifecycle.integration.test.ts +14 -0
- package/src/__tests__/shader-stage-surface.unit.test.ts +19 -4
- package/src/__tests__/skin-motion-regression.unit.test.ts +154 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +13 -4
- package/src/__tests__/spot-modifier-projection.unit.test.ts +70 -0
- package/src/__tests__/ssr-admission-matrix.integration.test.ts +206 -0
- package/src/__tests__/ssr-composition.unit.test.ts +46 -0
- package/src/__tests__/ssr-fallback-zero-work.bench.test.ts +94 -0
- package/src/__tests__/ssr-recovery-errors.unit.test.ts +58 -0
- package/src/__tests__/standard-cluster-capability.integration.test.ts +63 -0
- package/src/__tests__/standard-cluster-transport.unit.test.ts +121 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +299 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +15 -5
- package/src/__tests__/standard-lighting-inspection.integration.test.ts +138 -0
- package/src/__tests__/standard-lighting-ssot.unit.test.ts +18 -0
- package/src/__tests__/standard-lighting-write.unit.test.ts +441 -0
- package/src/__tests__/standard-lighting.integration.test.ts +67 -0
- package/src/__tests__/standard-pipeline.dawn.test.ts +206 -5
- package/src/__tests__/standard-pipeline.integration.test.ts +181 -150
- package/src/__tests__/standard-probe-binding.unit.test.ts +25 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +23 -38
- package/src/__tests__/temporal-fallback-generation.integration.test.ts +16 -0
- package/src/__tests__/temporal-view.unit.test.ts +3 -3
- package/src/__tests__/transmission-prewarm.unit.test.ts +69 -0
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +395 -14
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +2 -2
- package/src/__tests__/visibility-budget.integration.test.ts +140 -0
- package/src/__tests__/visibility-budget.unit.test.ts +70 -0
- package/src/__tests__/visibility-extract.integration.test.ts +11 -6
- package/src/__tests__/visibility-resolver.unit.test.ts +15 -0
- package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +6 -3
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +31 -28
- package/src/assembly/backend-contract.ts +13 -0
- package/src/assembly/device-feature-admission.ts +80 -0
- package/src/assembly/directional-shadow-inspection.ts +122 -0
- package/src/assembly/factory.ts +1411 -366
- package/src/assembly/host-contract.ts +35 -0
- package/src/assembly/render-target-host.ts +847 -0
- package/src/assets/asset-decoders.ts +1 -1
- package/src/assets/render-asset-port.ts +7 -1
- package/src/capture/cube-views.ts +69 -0
- package/src/capture/scheduler.ts +265 -0
- package/src/cluster-binner.ts +31 -0
- package/src/components/__tests__/lighting-authoring.unit.test.ts +39 -0
- package/src/components/__tests__/rect-area-light.unit.test.ts +33 -0
- package/src/components/__tests__/schema-contract.unit.test.ts +12 -0
- package/src/components/__tests__/schema-parity.unit.test.ts +9 -0
- package/src/components/camera.ts +4 -0
- package/src/components/cube-camera.ts +52 -0
- package/src/components/directional-light.ts +22 -2
- package/src/components/directional-shadow-filter.ts +57 -0
- package/src/components/index.ts +5 -0
- package/src/components/light-helpers.ts +133 -8
- package/src/components/light-probe.ts +13 -0
- package/src/components/rect-area-light.ts +15 -0
- package/src/components/reflection-probe.ts +49 -0
- package/src/components/scene-instance.ts +6 -0
- package/src/components/spot-light.ts +3 -0
- package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
- package/src/device/gpu-residency.ts +140 -9
- package/src/device/lifecycle-transaction.ts +12 -0
- package/src/environment/frame.ts +6 -24
- package/src/environment/lifecycle.ts +20 -1
- package/src/errors/gpu-driven.ts +92 -0
- package/src/errors/index.ts +1 -0
- package/src/errors/recover.ts +32 -0
- package/src/errors/render.ts +341 -143
- package/src/extract/camera.ts +3 -3
- package/src/extract/directional-shadow-projection.ts +61 -0
- package/src/extract/environment.ts +57 -0
- package/src/extract/gpu-driven.ts +108 -0
- package/src/extract/visibility.ts +2 -1
- package/src/features/fullscreen.ts +3 -0
- package/src/features/targets.ts +4 -1
- package/src/features/types.ts +10 -0
- package/src/fullscreen-post-process-pass.ts +43 -2
- package/src/gpu-driven/batch-topology.ts +207 -28
- package/src/gpu-driven/prepared-draw.ts +208 -0
- package/src/gpu-driven/production-raster.ts +953 -43
- package/src/gpu-driven/view-gpu.ts +411 -29
- package/src/gpu-scene-schema.ts +13 -0
- package/src/gpu-scene.ts +140 -64
- package/src/gpu-usage.ts +0 -1
- package/src/hdrp-buffers.ts +169 -63
- package/src/ibl/IblPipelineCache.ts +11 -0
- package/src/ibl/kernel-cache.ts +88 -0
- package/src/index.ts +222 -0
- package/src/inspection-types.ts +276 -1
- package/src/instances-derived-bounds.ts +171 -0
- package/src/internal.ts +38 -0
- package/src/light-buffer-layout.ts +155 -310
- package/src/materials.ts +16 -2
- package/src/mesh-material-bindings.ts +132 -0
- package/src/pbr-pipeline.ts +255 -60
- package/src/pipeline/standard-forward-lane.ts +93 -16
- package/src/pipeline/standard-lighting/errors.ts +6 -0
- package/src/pipeline/standard-lighting/graph.ts +158 -0
- package/src/pipeline/standard-lighting/inspection.ts +88 -0
- package/src/pipeline/standard-lighting/layout.ts +31 -0
- package/src/pipeline/standard-lighting/light-frame.ts +35 -0
- package/src/pipeline/standard-lighting/membership.ts +43 -0
- package/src/pipeline/standard-lighting/prepare.ts +37 -0
- package/src/pipeline/standard-lighting/topology.ts +120 -0
- package/src/pipeline/standard-lighting/transport.ts +78 -0
- package/src/pipeline/standard-pipeline.ts +124 -193
- package/src/pipeline/standard-post.ts +26 -7
- package/src/pipeline/standard-profile.ts +17 -47
- package/src/pipeline-builder.ts +5 -2
- package/src/pipeline-spec.ts +95 -21
- package/src/plugin.ts +4 -0
- package/src/point-shadow-inspection.ts +55 -0
- package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +56 -0
- package/src/prepare/extended-lighting/ltc-resources.ts +136 -0
- package/src/prepare/extended-lighting/resources.ts +389 -0
- package/src/prepare/extended-lighting/spot-modifiers.ts +194 -0
- package/src/prepare/extended-lighting/state.ts +92 -0
- package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
- package/src/record/__tests__/temporal-payload.unit.test.ts +64 -1
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +73 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +20 -1
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +40 -0
- package/src/record/frame-lighting.ts +591 -452
- package/src/record/frame-snapshot.ts +92 -39
- package/src/record/frame-targets.ts +17 -0
- package/src/record/frame.ts +662 -158
- package/src/record/gpu-pass-timing/contract.ts +180 -0
- package/src/record/gpu-pass-timing/errors.ts +34 -0
- package/src/record/gpu-pass-timing/index.ts +37 -0
- package/src/record/gpu-pass-timing/parser.ts +97 -0
- package/src/record/gpu-pass-timing/session.ts +938 -0
- package/src/record/gpu-timing.ts +112 -39
- package/src/record/helpers.ts +0 -58
- package/src/record/main-pass-geometry.ts +324 -119
- package/src/record/main-pass-material.ts +103 -10
- package/src/record/main-pass-sprite-draws.ts +99 -103
- package/src/record/main-pass.ts +71 -15
- package/src/record/mesh-ssbo.ts +47 -36
- package/src/record/render-context.ts +136 -3
- package/src/record/shadow-pass.ts +83 -68
- package/src/record/skybox-post-pass.ts +20 -4
- package/src/record/typed-frame-graph.ts +1034 -43
- package/src/record/view-ubo.ts +72 -47
- package/src/reflection/filter.ts +81 -0
- package/src/reflection/gpu-table.ts +44 -0
- package/src/reflection/inspection.ts +67 -0
- package/src/reflection/projection.ts +476 -0
- package/src/reflection/record-owner.ts +1283 -0
- package/src/render-contract.ts +93 -10
- package/src/render-graph-primitives.ts +9 -4
- package/src/render-pipeline.ts +122 -2
- package/src/render-system-extract.ts +1041 -225
- package/src/render-system.ts +1310 -85
- package/src/renderer.ts +222 -0
- package/src/scene/__tests__/changed-block-summary.candidate.test.ts +36 -0
- package/src/scene/probe-blend-record.ts +54 -0
- package/src/scene/probe-blend.ts +813 -0
- package/src/scene/render-scene-types.ts +0 -7
- package/src/scene/render-scene.ts +942 -171
- package/src/scene/visibility/bounds.ts +57 -0
- package/src/scene/visibility/budget.ts +40 -0
- package/src/scene/visibility/facet.ts +400 -0
- package/src/scene/visibility/gpu-frame-timing.ts +101 -0
- package/src/scene/visibility/gpu-lod.ts +119 -0
- package/src/scene/visibility/inspection.ts +313 -0
- package/src/scene/visibility/lod-selector.ts +84 -0
- package/src/scene/visibility/occlusion-confidence.ts +478 -0
- package/src/scene/visibility/occlusion-pass.ts +165 -0
- package/src/scene/visibility/occlusion-query-pool.ts +178 -0
- package/src/scene/visibility/occlusion-runtime.ts +672 -0
- package/src/scene/visibility/types.ts +50 -0
- package/src/shadow-atlas.ts +5 -5
- package/src/ssao-buffers.ts +9 -2
- package/src/ssr/admission.ts +451 -0
- package/src/ssr/composition.ts +73 -0
- package/src/ssr/errors.ts +76 -0
- package/src/ssr/identity.ts +12 -0
- package/src/systems/skin-palette-allocator.ts +1 -1
- package/src/targets/contracts.ts +182 -0
- package/src/targets/graph-projection.ts +169 -0
- package/src/targets/material-source.ts +143 -0
- package/src/targets/owner.ts +214 -0
- package/src/targets/physical.ts +18 -0
- package/src/targets/readback.ts +153 -0
- package/src/temporal/frame-coordinator.ts +26 -0
- package/src/temporal/frame.ts +14 -1
- package/src/temporal/view.ts +11 -0
- package/src/tilemap-chunk-extract-system.ts +4 -4
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +59 -20
- package/src/typed-render-graph-primitives.ts +53 -3
- package/src/typed-shadow-passes.ts +46 -40
- package/src/volume/passes.ts +61 -58
- package/dist/.tsbuildinfo +0 -1
- package/dist/chunk-4XINDLAY.mjs.map +0 -1
- package/dist/chunk-CDTWTHZR.mjs.map +0 -1
- package/dist/chunk-M2MP4ZOU.mjs +0 -73
- package/dist/chunk-M2MP4ZOU.mjs.map +0 -1
- package/dist/chunk-PCHBPYML.mjs.map +0 -1
- package/dist/chunk-TBQJOK2L.mjs.map +0 -1
- package/dist/chunk-VFPLTKCU.mjs.map +0 -1
|
@@ -5,6 +5,11 @@ import type {
|
|
|
5
5
|
} from '@forgeax/engine-render-graph';
|
|
6
6
|
import { err, ok, type Result } from '@forgeax/engine-types';
|
|
7
7
|
import { SceneDataUnavailableError } from '../errors/render';
|
|
8
|
+
import {
|
|
9
|
+
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
10
|
+
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,
|
|
11
|
+
GPU_TEXTURE_USAGE_TEXTURE_BINDING,
|
|
12
|
+
} from '../gpu-texture-usage';
|
|
8
13
|
import type {
|
|
9
14
|
RenderPipeline,
|
|
10
15
|
RenderPipelineBuildContext,
|
|
@@ -29,12 +34,19 @@ import {
|
|
|
29
34
|
transmissionDemandForTopology,
|
|
30
35
|
} from '../transmission/backdrop';
|
|
31
36
|
import {
|
|
37
|
+
addReflectionFallbackObservationPass,
|
|
32
38
|
addTypedFrameObservationPass,
|
|
33
39
|
addTypedScenePass,
|
|
34
40
|
addTypedSkyboxPass,
|
|
35
41
|
} from '../typed-render-graph-primitives';
|
|
36
42
|
import { addTypedShadowPasses } from '../typed-shadow-passes';
|
|
37
43
|
import { addAuthoredVolumetricFogPasses } from '../volume/passes';
|
|
44
|
+
import {
|
|
45
|
+
addStandardClusterMembershipPass,
|
|
46
|
+
importStandardClusterBuffers,
|
|
47
|
+
standardClusterReadAccesses,
|
|
48
|
+
} from './standard-lighting/graph';
|
|
49
|
+
import type { StandardTopologyInputValue } from './standard-lighting/topology';
|
|
38
50
|
import { addStandardPost } from './standard-post';
|
|
39
51
|
|
|
40
52
|
function target(
|
|
@@ -48,6 +60,7 @@ function target(
|
|
|
48
60
|
function buildUrp(
|
|
49
61
|
context: RenderPipelineBuildContext<RenderPipelineFrame>,
|
|
50
62
|
topology: RenderPipelineTopology,
|
|
63
|
+
lighting: StandardTopologyInputValue,
|
|
51
64
|
): ReturnType<RenderPipeline['build']> {
|
|
52
65
|
const graph = context.graph;
|
|
53
66
|
const surface = importRenderPipelineSurface(graph, topology);
|
|
@@ -60,16 +73,14 @@ function buildUrp(
|
|
|
60
73
|
const fxaa = !clearOnly && topology.camera.antialias === 'fxaa';
|
|
61
74
|
const taa = !clearOnly && topology.camera.antialias === 'taa';
|
|
62
75
|
const rawOnly = !clearOnly && topology.surface.profile?.kind === 'raw-only';
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
// remain float even when tone mapping is disabled. This prevents an
|
|
67
|
-
// eight-bit quantization before the OETF/display-encoded boundary.
|
|
76
|
+
// Every non-clear lane keeps a linear float scene target until the shared
|
|
77
|
+
// Output Transform. This includes no-AA and the no-storage fallback: the
|
|
78
|
+
// final dither and display encoding must have one graph-owned boundary.
|
|
68
79
|
// MSAA resolves into a separate linear target before presentation. Treat
|
|
69
80
|
// that resolved target like linear LDR so the shared Output Transform owns
|
|
70
81
|
// its write into the surface storage view; without this, the resolve is
|
|
71
82
|
// never presented and MSAA is indistinguishable from the no-AA path.
|
|
72
|
-
const linearLdr = !clearOnly &&
|
|
83
|
+
const linearLdr = !clearOnly && !hdr;
|
|
73
84
|
const temporalDemand = aggregateTemporalDemand({
|
|
74
85
|
taa,
|
|
75
86
|
motionBlur: !clearOnly && topology.temporal?.motionBlur === true,
|
|
@@ -88,7 +99,14 @@ function buildUrp(
|
|
|
88
99
|
if (!depth.ok) return depth;
|
|
89
100
|
|
|
90
101
|
const sceneResolved = clearOnly
|
|
91
|
-
?
|
|
102
|
+
? surface.value.display === undefined
|
|
103
|
+
? target(graph, 'scene-color', {
|
|
104
|
+
format: topology.surface.storageFormat,
|
|
105
|
+
size: 'surface',
|
|
106
|
+
sampleCount: 1,
|
|
107
|
+
domain: 'display-encoded',
|
|
108
|
+
})
|
|
109
|
+
: ok(surface.value.display)
|
|
92
110
|
: hdr || fxaa || linearLdr || msaa || rawOnly || needsTemporalIntermediate
|
|
93
111
|
? target(graph, 'scene-color', {
|
|
94
112
|
format: sceneFormat,
|
|
@@ -123,9 +141,48 @@ function buildUrp(
|
|
|
123
141
|
: sceneResolved;
|
|
124
142
|
if (!scene.ok) return scene;
|
|
125
143
|
|
|
144
|
+
const reflectionFallback = topology.reflectionFallback?.enabled
|
|
145
|
+
? target(graph, 'reflection-fallback-linear-hdr', {
|
|
146
|
+
format: 'rgba16float',
|
|
147
|
+
size: 'surface',
|
|
148
|
+
sampleCount: scene.value.sampleCount,
|
|
149
|
+
domain: 'linear-hdr',
|
|
150
|
+
usage:
|
|
151
|
+
GPU_TEXTURE_USAGE_COPY_SRC |
|
|
152
|
+
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |
|
|
153
|
+
GPU_TEXTURE_USAGE_TEXTURE_BINDING,
|
|
154
|
+
})
|
|
155
|
+
: ok(undefined);
|
|
156
|
+
if (!reflectionFallback.ok) return reflectionFallback;
|
|
157
|
+
if (reflectionFallback.value !== undefined) {
|
|
158
|
+
const initialized = graph.addRasterPass('reflection-fallback-clear', {
|
|
159
|
+
accesses: [{ resource: reflectionFallback.value.view, usage: 'color-attachment' }],
|
|
160
|
+
colorAttachments: [
|
|
161
|
+
{
|
|
162
|
+
view: reflectionFallback.value.view,
|
|
163
|
+
loadOp: 'clear',
|
|
164
|
+
storeOp: 'store',
|
|
165
|
+
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
encode: () => {},
|
|
169
|
+
});
|
|
170
|
+
if (!initialized.ok) return initialized;
|
|
171
|
+
}
|
|
172
|
+
|
|
126
173
|
const shadows = addTypedShadowPasses(graph, topology);
|
|
127
174
|
if (!shadows.ok) return shadows;
|
|
128
175
|
|
|
176
|
+
const clusterBuffers = clearOnly ? ok(null) : importStandardClusterBuffers(graph, lighting);
|
|
177
|
+
if (!clusterBuffers.ok) return clusterBuffers;
|
|
178
|
+
const clusterMembership =
|
|
179
|
+
clusterBuffers.value === null
|
|
180
|
+
? ok(undefined)
|
|
181
|
+
: addStandardClusterMembershipPass(graph, lighting, clusterBuffers.value);
|
|
182
|
+
if (!clusterMembership.ok) return clusterMembership;
|
|
183
|
+
const clusterReads =
|
|
184
|
+
clusterBuffers.value === null ? [] : standardClusterReadAccesses(clusterBuffers.value);
|
|
185
|
+
|
|
129
186
|
const skybox = addTypedSkyboxPass(graph, scene.value);
|
|
130
187
|
if (!skybox.ok) return skybox;
|
|
131
188
|
const gpuDriven = context.projectGpuDriven({
|
|
@@ -141,25 +198,30 @@ function buildUrp(
|
|
|
141
198
|
const main = addTypedScenePass(graph, {
|
|
142
199
|
name: 'main',
|
|
143
200
|
color: scene.value,
|
|
201
|
+
...(reflectionFallback.value === undefined
|
|
202
|
+
? {}
|
|
203
|
+
: { colorTargets: [scene.value, reflectionFallback.value] }),
|
|
144
204
|
depth: depth.value,
|
|
145
205
|
...(msaa ? { resolve: sceneResolved.value } : {}),
|
|
146
206
|
sampled: [
|
|
147
|
-
shadows.value.directional,
|
|
207
|
+
...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
|
|
148
208
|
shadows.value.spot,
|
|
149
209
|
...(shadows.value.point === undefined ? [] : [shadows.value.point]),
|
|
150
210
|
],
|
|
151
|
-
|
|
211
|
+
...(shadows.value.directional === undefined
|
|
212
|
+
? {}
|
|
213
|
+
: { directionalShadow: shadows.value.directional }),
|
|
152
214
|
spotShadow: shadows.value.spot,
|
|
153
215
|
selector: { LightMode: ['Forward'] },
|
|
154
216
|
colorLoadOp: 'load',
|
|
217
|
+
extraAccesses: clusterReads,
|
|
155
218
|
...(transmissionActive ? { recordMode: 'opaque' as const } : {}),
|
|
156
219
|
...(gpuDriven.value === undefined ? {} : { gpuDriven: gpuDriven.value }),
|
|
220
|
+
...(context.occlusion === undefined ? {} : { occlusion: context.occlusion }),
|
|
157
221
|
});
|
|
158
222
|
if (!main.ok) return main;
|
|
159
223
|
|
|
160
|
-
const temporalLane = topology.lane.compute
|
|
161
|
-
? (topology.standardProfile?.lighting ?? 'direct')
|
|
162
|
-
: 'cpu-webgl2';
|
|
224
|
+
const temporalLane = topology.lane.compute ? 'clustered' : 'cpu-webgl2';
|
|
163
225
|
const temporalAdmission = standardTemporalLaneAdmission({
|
|
164
226
|
lane: temporalLane,
|
|
165
227
|
demand: temporalDemand,
|
|
@@ -191,6 +253,7 @@ function buildUrp(
|
|
|
191
253
|
const producer = addStandardSceneDataPass(graph, temporal.value.temporal, depth.value);
|
|
192
254
|
if (!producer.ok) return producer;
|
|
193
255
|
}
|
|
256
|
+
|
|
194
257
|
const transmission = addTransmissionBackdropPasses({
|
|
195
258
|
graph,
|
|
196
259
|
source: sceneResolved.value,
|
|
@@ -207,7 +270,7 @@ function buildUrp(
|
|
|
207
270
|
depth: depth.value,
|
|
208
271
|
...(msaa ? { resolve: sceneResolved.value } : {}),
|
|
209
272
|
sampled: [
|
|
210
|
-
shadows.value.directional,
|
|
273
|
+
...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
|
|
211
274
|
shadows.value.spot,
|
|
212
275
|
...(shadows.value.point === undefined ? [] : [shadows.value.point]),
|
|
213
276
|
],
|
|
@@ -217,6 +280,7 @@ function buildUrp(
|
|
|
217
280
|
colorLoadOp: 'load',
|
|
218
281
|
depthLoadOp: 'load',
|
|
219
282
|
recordMode: 'transmission',
|
|
283
|
+
extraAccesses: clusterReads,
|
|
220
284
|
// Inject the complete backdrop view so the Standard shader can select
|
|
221
285
|
// the producer's optional roughness mip level. mipViews[0] is only the
|
|
222
286
|
// copy destination view and intentionally exposes one level.
|
|
@@ -230,7 +294,7 @@ function buildUrp(
|
|
|
230
294
|
depth: depth.value,
|
|
231
295
|
...(msaa ? { resolve: sceneResolved.value } : {}),
|
|
232
296
|
sampled: [
|
|
233
|
-
shadows.value.directional,
|
|
297
|
+
...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
|
|
234
298
|
shadows.value.spot,
|
|
235
299
|
...(shadows.value.point === undefined ? [] : [shadows.value.point]),
|
|
236
300
|
],
|
|
@@ -240,6 +304,7 @@ function buildUrp(
|
|
|
240
304
|
colorLoadOp: 'load',
|
|
241
305
|
depthLoadOp: 'load',
|
|
242
306
|
recordMode: 'transparent',
|
|
307
|
+
extraAccesses: clusterReads,
|
|
243
308
|
});
|
|
244
309
|
if (!transparentPass.ok) return transparentPass;
|
|
245
310
|
const temporal = addTransmissionBackdropTemporalPass(graph, sceneResolved.value);
|
|
@@ -258,8 +323,9 @@ function buildUrp(
|
|
|
258
323
|
topology,
|
|
259
324
|
sceneResolved.value,
|
|
260
325
|
depthSample.value,
|
|
261
|
-
shadows.value.directional
|
|
326
|
+
shadows.value.directional?.view,
|
|
262
327
|
shadows.value.spot.view,
|
|
328
|
+
clusterBuffers.value,
|
|
263
329
|
);
|
|
264
330
|
if (!volume.ok) return volume;
|
|
265
331
|
}
|
|
@@ -292,8 +358,15 @@ function buildUrp(
|
|
|
292
358
|
);
|
|
293
359
|
if (!observation.ok) return observation;
|
|
294
360
|
}
|
|
361
|
+
if (reflectionFallback.value?.sampleCount === 1) {
|
|
362
|
+
const fallbackObservation = addReflectionFallbackObservationPass(
|
|
363
|
+
graph,
|
|
364
|
+
reflectionFallback.value,
|
|
365
|
+
);
|
|
366
|
+
if (!fallbackObservation.ok) return fallbackObservation;
|
|
367
|
+
}
|
|
295
368
|
|
|
296
|
-
|
|
369
|
+
const post = addStandardPost(
|
|
297
370
|
context,
|
|
298
371
|
topology,
|
|
299
372
|
sceneResolved.value,
|
|
@@ -301,6 +374,10 @@ function buildUrp(
|
|
|
301
374
|
surface.value,
|
|
302
375
|
temporal.value?.temporal,
|
|
303
376
|
);
|
|
377
|
+
if (!post.ok) return post;
|
|
378
|
+
const cubeCaptures = context.contributeCubeCaptures?.();
|
|
379
|
+
if (cubeCaptures !== undefined && !cubeCaptures.ok) return cubeCaptures;
|
|
380
|
+
return ok(undefined);
|
|
304
381
|
}
|
|
305
382
|
|
|
306
383
|
export const buildStandardForwardLane = buildUrp;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ClusterBinError } from '../../cluster-binner';
|
|
2
|
+
import { StandardClusterIndexOverflowError } from '../../errors/render';
|
|
3
|
+
|
|
4
|
+
export function fromClusterBinError(error: ClusterBinError): StandardClusterIndexOverflowError {
|
|
5
|
+
return new StandardClusterIndexOverflowError(error.detail.actual, error.detail.capacity);
|
|
6
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
GraphAccess,
|
|
3
|
+
GraphBuffer,
|
|
4
|
+
RenderGraphBuilder,
|
|
5
|
+
RenderGraphError,
|
|
6
|
+
} from '@forgeax/engine-render-graph';
|
|
7
|
+
import { ok, type Result } from '@forgeax/engine-types';
|
|
8
|
+
import {
|
|
9
|
+
GPU_BUFFER_USAGE_COPY_DST,
|
|
10
|
+
GPU_BUFFER_USAGE_STORAGE,
|
|
11
|
+
GPU_BUFFER_USAGE_UNIFORM,
|
|
12
|
+
} from '../../gpu-usage';
|
|
13
|
+
import { getOrCreateHdrpBuffers, type HdrpBuffers } from '../../hdrp-buffers';
|
|
14
|
+
import { BYTES_PER_DIRECT_LIGHT_SLOT } from '../../light-buffer-layout';
|
|
15
|
+
import type { _InternalRenderPipelineContext } from '../../record/render-context';
|
|
16
|
+
import type { RenderPipelineFrame } from '../../render-pipeline';
|
|
17
|
+
import type { StandardTopologyInputValue } from './topology';
|
|
18
|
+
|
|
19
|
+
/** Graph resources projected from one Standard lighting topology input. */
|
|
20
|
+
export interface StandardClusterGraphBuffers {
|
|
21
|
+
readonly lightData: GraphBuffer;
|
|
22
|
+
readonly clusterGrid: GraphBuffer;
|
|
23
|
+
readonly lightIndexList: GraphBuffer;
|
|
24
|
+
readonly clusterUniform: GraphBuffer;
|
|
25
|
+
readonly lightBounds: GraphBuffer;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Stable graph-time projection; never retain a frame's typed-array payload. */
|
|
29
|
+
interface StandardClusterGraphDescriptor {
|
|
30
|
+
readonly grid: { readonly x: number; readonly y: number; readonly z: number };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function projectDescriptor(input: StandardTopologyInputValue): StandardClusterGraphDescriptor {
|
|
34
|
+
const { x, y, z } = input.prepared.layout.grid;
|
|
35
|
+
return { grid: { x, y, z } };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function resolveBuffers(
|
|
39
|
+
frame: RenderPipelineFrame,
|
|
40
|
+
descriptor: StandardClusterGraphDescriptor,
|
|
41
|
+
): HdrpBuffers {
|
|
42
|
+
const internal = frame as _InternalRenderPipelineContext;
|
|
43
|
+
const buffers = getOrCreateHdrpBuffers(internal.runtime, descriptor.grid);
|
|
44
|
+
if (buffers === null) throw new Error('Standard persistent buffer allocation failed');
|
|
45
|
+
return buffers;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Resolve membership execution from the frame's current prepared payload. */
|
|
49
|
+
export function shouldExecuteStandardClusterMembershipPass(frame: RenderPipelineFrame): boolean {
|
|
50
|
+
const standardLighting = (frame as _InternalRenderPipelineContext).standardLighting;
|
|
51
|
+
return (
|
|
52
|
+
standardLighting?.kind === 'clustered' &&
|
|
53
|
+
standardLighting.transport.kind === 'compute-storage' &&
|
|
54
|
+
standardLighting.prepared.local.length > 0
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Import the shared Standard Cluster buffers with sizes derived from layout. */
|
|
59
|
+
export function importStandardClusterBuffers(
|
|
60
|
+
graph: RenderGraphBuilder<RenderPipelineFrame>,
|
|
61
|
+
input: StandardTopologyInputValue,
|
|
62
|
+
): Result<StandardClusterGraphBuffers | null, RenderGraphError> {
|
|
63
|
+
if (input.kind === 'no-local-lights') return ok(null);
|
|
64
|
+
const layout = input.prepared.layout;
|
|
65
|
+
const descriptor = projectDescriptor(input);
|
|
66
|
+
const usage = GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;
|
|
67
|
+
const lightData = graph.importBuffer(
|
|
68
|
+
'hdrp-light-data',
|
|
69
|
+
{ size: layout.lightDataSlotCount * BYTES_PER_DIRECT_LIGHT_SLOT, usage },
|
|
70
|
+
(frame) => resolveBuffers(frame, descriptor).lightDataBuffer,
|
|
71
|
+
);
|
|
72
|
+
if (!lightData.ok) return lightData;
|
|
73
|
+
const clusterGrid = graph.importBuffer(
|
|
74
|
+
'hdrp-cluster-grid',
|
|
75
|
+
{ size: layout.clusterGridU32Length * 4, usage },
|
|
76
|
+
(frame) => resolveBuffers(frame, descriptor).clusterGridBuffer,
|
|
77
|
+
);
|
|
78
|
+
if (!clusterGrid.ok) return clusterGrid;
|
|
79
|
+
const lightIndexList = graph.importBuffer(
|
|
80
|
+
'hdrp-light-index-list',
|
|
81
|
+
{ size: layout.lightIndexListCapacity * 4, usage },
|
|
82
|
+
(frame) => resolveBuffers(frame, descriptor).lightIndexListBuffer,
|
|
83
|
+
);
|
|
84
|
+
if (!lightIndexList.ok) return lightIndexList;
|
|
85
|
+
const clusterUniform = graph.importBuffer(
|
|
86
|
+
'hdrp-cluster-uniform',
|
|
87
|
+
{ size: 32, usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST },
|
|
88
|
+
(frame) => resolveBuffers(frame, descriptor).clusterUniformBuffer,
|
|
89
|
+
);
|
|
90
|
+
if (!clusterUniform.ok) return clusterUniform;
|
|
91
|
+
const lightBounds = graph.importBuffer(
|
|
92
|
+
'hdrp-light-bounds',
|
|
93
|
+
{ size: layout.lightBoundsInt32Length * 4, usage },
|
|
94
|
+
(frame) => resolveBuffers(frame, descriptor).lightBoundsBuffer,
|
|
95
|
+
);
|
|
96
|
+
if (!lightBounds.ok) return lightBounds;
|
|
97
|
+
return ok({
|
|
98
|
+
lightData: lightData.value,
|
|
99
|
+
clusterGrid: clusterGrid.value,
|
|
100
|
+
lightIndexList: lightIndexList.value,
|
|
101
|
+
clusterUniform: clusterUniform.value,
|
|
102
|
+
lightBounds: lightBounds.value,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Accesses used by raster consumers of the shared Cluster payload. */
|
|
107
|
+
export function standardClusterReadAccesses(
|
|
108
|
+
buffers: StandardClusterGraphBuffers,
|
|
109
|
+
): readonly GraphAccess[] {
|
|
110
|
+
return [
|
|
111
|
+
{ resource: buffers.lightData, usage: 'storage-read' },
|
|
112
|
+
{ resource: buffers.clusterGrid, usage: 'storage-read' },
|
|
113
|
+
{ resource: buffers.lightIndexList, usage: 'storage-read' },
|
|
114
|
+
{ resource: buffers.clusterUniform, usage: 'uniform-read' },
|
|
115
|
+
];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Add the sole GPU membership producer. CPU membership is already materialized
|
|
120
|
+
* in PreparedStandardLighting and therefore contributes no second pass.
|
|
121
|
+
*/
|
|
122
|
+
export function addStandardClusterMembershipPass(
|
|
123
|
+
graph: RenderGraphBuilder<RenderPipelineFrame>,
|
|
124
|
+
input: StandardTopologyInputValue,
|
|
125
|
+
buffers: StandardClusterGraphBuffers,
|
|
126
|
+
): Result<void, RenderGraphError> {
|
|
127
|
+
if (input.kind === 'no-local-lights') return ok(undefined);
|
|
128
|
+
if (input.transport.kind !== 'compute-storage') return ok(undefined);
|
|
129
|
+
const descriptor = projectDescriptor(input);
|
|
130
|
+
return graph.addComputePass('cluster-membership-producer', {
|
|
131
|
+
accesses: [
|
|
132
|
+
{ resource: buffers.clusterGrid, usage: 'storage-read' },
|
|
133
|
+
{ resource: buffers.clusterUniform, usage: 'uniform-read' },
|
|
134
|
+
{ resource: buffers.lightBounds, usage: 'storage-read' },
|
|
135
|
+
{ resource: buffers.lightIndexList, usage: 'storage-write' },
|
|
136
|
+
],
|
|
137
|
+
// Keep the clustered graph/ABI stable for a directional-only frame, but
|
|
138
|
+
// do not require a producer bind group when there is no local corpus to
|
|
139
|
+
// bin. The zero-length prepared payload is already the complete result;
|
|
140
|
+
// executing this pass would only turn an otherwise valid frame into a
|
|
141
|
+
// null-backend encode failure.
|
|
142
|
+
executeIf: shouldExecuteStandardClusterMembershipPass,
|
|
143
|
+
encode: ({ pass, frame }) => {
|
|
144
|
+
const internal = frame as _InternalRenderPipelineContext;
|
|
145
|
+
const pipeline = internal.pipelineState.hdrpClusterMembershipPipeline;
|
|
146
|
+
const bindings = internal.hdrpClusterMembershipBindGroup;
|
|
147
|
+
if (pipeline === null || bindings === null) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
'standard-cluster-transport-unavailable: selected compute Cluster producer is not ready',
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
const { x, y, z } = descriptor.grid;
|
|
153
|
+
pass.setPipeline(pipeline);
|
|
154
|
+
pass.setBindGroup(0, bindings);
|
|
155
|
+
pass.dispatchWorkgroups(Math.ceil((x * y * z) / 64));
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { StandardTopologyInputValue } from './topology';
|
|
2
|
+
import type { StandardClusterTransport } from './transport';
|
|
3
|
+
|
|
4
|
+
export interface StandardClusterTransportInspection {
|
|
5
|
+
readonly renderPath: 'forward' | 'deferred';
|
|
6
|
+
readonly transport: StandardClusterTransport['kind'];
|
|
7
|
+
readonly producer: StandardClusterTransport['producer'];
|
|
8
|
+
readonly requested: StandardClusterTransport['requestedLightCount'];
|
|
9
|
+
readonly admitted: StandardClusterTransport['admittedLightCount'];
|
|
10
|
+
readonly shadowed: number;
|
|
11
|
+
readonly maxLights: number;
|
|
12
|
+
readonly indexCount: StandardClusterTransport['membershipEntryCount'];
|
|
13
|
+
readonly occupied: StandardClusterTransport['occupiedClusterCount'];
|
|
14
|
+
readonly clusterGridBytes: number;
|
|
15
|
+
readonly lightIndexListBytes: number;
|
|
16
|
+
readonly lightDataBytes: number;
|
|
17
|
+
readonly lightBoundsBytes: number;
|
|
18
|
+
readonly grid: StandardClusterTransport['layout']['grid'];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface StandardNoLocalLightingInspection {
|
|
22
|
+
readonly renderPath: 'forward' | 'deferred';
|
|
23
|
+
readonly transport: 'not-required';
|
|
24
|
+
readonly producer: 'none';
|
|
25
|
+
readonly requested: 0;
|
|
26
|
+
readonly admitted: 0;
|
|
27
|
+
readonly shadowed: 0;
|
|
28
|
+
readonly maxLights: number;
|
|
29
|
+
readonly indexCount: 0;
|
|
30
|
+
readonly occupied: 0;
|
|
31
|
+
readonly clusterGridBytes: 0;
|
|
32
|
+
readonly lightIndexListBytes: 0;
|
|
33
|
+
readonly lightDataBytes: 0;
|
|
34
|
+
readonly lightBoundsBytes: 0;
|
|
35
|
+
readonly grid: StandardTopologyInputValue['prepared']['layout']['grid'];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type StandardLightingInspection =
|
|
39
|
+
| StandardClusterTransportInspection
|
|
40
|
+
| StandardNoLocalLightingInspection;
|
|
41
|
+
|
|
42
|
+
export function inspectStandardClusterTransport(
|
|
43
|
+
transport: StandardClusterTransport,
|
|
44
|
+
prepared: StandardTopologyInputValue['prepared'],
|
|
45
|
+
): StandardClusterTransportInspection {
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
renderPath: prepared.renderPath,
|
|
48
|
+
transport: transport.kind,
|
|
49
|
+
producer: transport.producer,
|
|
50
|
+
requested: transport.requestedLightCount,
|
|
51
|
+
admitted: transport.admittedLightCount,
|
|
52
|
+
shadowed: prepared.local.filter((light) => light.shadowed === true).length,
|
|
53
|
+
maxLights: prepared.maxLights,
|
|
54
|
+
indexCount: transport.membershipEntryCount,
|
|
55
|
+
occupied: transport.occupiedClusterCount,
|
|
56
|
+
clusterGridBytes: transport.clusterGridBytes,
|
|
57
|
+
lightIndexListBytes: transport.lightIndexListBytes,
|
|
58
|
+
lightDataBytes: transport.lightDataBytes,
|
|
59
|
+
lightBoundsBytes: transport.lightBoundsBytes,
|
|
60
|
+
// The inspection boundary is JSON-safe and detached from the mutable
|
|
61
|
+
// layout object carried by a per-frame prepared result.
|
|
62
|
+
grid: Object.freeze({ ...transport.layout.grid }),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function inspectStandardLighting(
|
|
67
|
+
input: StandardTopologyInputValue,
|
|
68
|
+
): StandardLightingInspection {
|
|
69
|
+
if (input.kind === 'no-local-lights') {
|
|
70
|
+
return Object.freeze({
|
|
71
|
+
renderPath: input.prepared.renderPath,
|
|
72
|
+
transport: 'not-required' as const,
|
|
73
|
+
producer: 'none' as const,
|
|
74
|
+
requested: 0 as const,
|
|
75
|
+
admitted: 0 as const,
|
|
76
|
+
shadowed: 0 as const,
|
|
77
|
+
maxLights: input.prepared.maxLights,
|
|
78
|
+
indexCount: 0 as const,
|
|
79
|
+
occupied: 0 as const,
|
|
80
|
+
clusterGridBytes: 0 as const,
|
|
81
|
+
lightIndexListBytes: 0 as const,
|
|
82
|
+
lightDataBytes: 0 as const,
|
|
83
|
+
lightBoundsBytes: 0 as const,
|
|
84
|
+
grid: Object.freeze({ ...input.prepared.layout.grid }),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return inspectStandardClusterTransport(input.transport, input.prepared);
|
|
88
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const DEFAULT_CLUSTER_GRID = { x: 16, y: 9, z: 24 } as const;
|
|
2
|
+
export const CLUSTER_GRID_STRIDE_U32 = 2 as const;
|
|
3
|
+
export const LIGHT_INDEX_LIST_CAPACITY = 1048576 as const;
|
|
4
|
+
export const MAX_LIGHTS = 256 as const;
|
|
5
|
+
|
|
6
|
+
export interface StandardClusterLayout {
|
|
7
|
+
readonly grid: { readonly x: number; readonly y: number; readonly z: number };
|
|
8
|
+
readonly clusterCount: number;
|
|
9
|
+
readonly clusterGridStrideU32: typeof CLUSTER_GRID_STRIDE_U32;
|
|
10
|
+
readonly clusterGridU32Length: number;
|
|
11
|
+
readonly lightIndexListCapacity: typeof LIGHT_INDEX_LIST_CAPACITY;
|
|
12
|
+
readonly lightDataSlotCount: typeof MAX_LIGHTS;
|
|
13
|
+
readonly lightBoundsInt32Length: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function createStandardClusterLayout(
|
|
17
|
+
grid: { readonly x: number; readonly y: number; readonly z: number } = DEFAULT_CLUSTER_GRID,
|
|
18
|
+
): StandardClusterLayout {
|
|
19
|
+
const clusterCount = grid.x * grid.y * grid.z;
|
|
20
|
+
return Object.freeze({
|
|
21
|
+
grid,
|
|
22
|
+
clusterCount,
|
|
23
|
+
clusterGridStrideU32: CLUSTER_GRID_STRIDE_U32,
|
|
24
|
+
clusterGridU32Length: clusterCount * CLUSTER_GRID_STRIDE_U32,
|
|
25
|
+
lightIndexListCapacity: LIGHT_INDEX_LIST_CAPACITY,
|
|
26
|
+
lightDataSlotCount: MAX_LIGHTS,
|
|
27
|
+
lightBoundsInt32Length: MAX_LIGHTS * 6,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const STANDARD_CLUSTER_LAYOUT = createStandardClusterLayout();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Mat4, Vec3 } from '@forgeax/engine-math';
|
|
2
|
+
import type {
|
|
3
|
+
DirectionalLightSnapshot,
|
|
4
|
+
PointLightSnapshot,
|
|
5
|
+
RectAreaDirectLightSnapshot,
|
|
6
|
+
SpotLightSnapshot,
|
|
7
|
+
} from '../../render-system-extract';
|
|
8
|
+
import type { StandardLightCount } from '../standard-profile';
|
|
9
|
+
|
|
10
|
+
export interface StandardLocalLightInput {
|
|
11
|
+
readonly kind: 'point' | 'spot' | 'rect-area';
|
|
12
|
+
readonly position: Vec3;
|
|
13
|
+
readonly range: number;
|
|
14
|
+
/** Whether the shadow producer admitted this local light to its atlas. */
|
|
15
|
+
readonly shadowed: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The immutable extract snapshot used by the record payload packer. Keeping
|
|
18
|
+
* it on the POD frame prevents Forward/Deferred from rebuilding a second
|
|
19
|
+
* light list while leaving hand-authored unit fixtures source-free.
|
|
20
|
+
*/
|
|
21
|
+
readonly source?: PointLightSnapshot | SpotLightSnapshot | RectAreaDirectLightSnapshot;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface StandardLightFrame {
|
|
25
|
+
readonly directional: DirectionalLightSnapshot | undefined;
|
|
26
|
+
readonly local: readonly StandardLocalLightInput[];
|
|
27
|
+
readonly view: Mat4;
|
|
28
|
+
readonly projection: Mat4;
|
|
29
|
+
readonly near: number;
|
|
30
|
+
readonly far: number;
|
|
31
|
+
readonly grid: { readonly x: number; readonly y: number; readonly z: number };
|
|
32
|
+
readonly lightCount: StandardLightCount;
|
|
33
|
+
/** Graph path carried into inspection from the active Standard profile. */
|
|
34
|
+
readonly renderPath: 'forward' | 'deferred';
|
|
35
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { err, ok, type Result } from '@forgeax/engine-types';
|
|
2
|
+
import { bin, type ClusterBinScratch, createClusterBinScratch } from '../../cluster-binner';
|
|
3
|
+
import type { RenderError } from '../../errors/render';
|
|
4
|
+
import { fromClusterBinError } from './errors';
|
|
5
|
+
import type { StandardClusterLayout } from './layout';
|
|
6
|
+
import type { StandardLightFrame } from './light-frame';
|
|
7
|
+
|
|
8
|
+
export interface StandardClusterMembership {
|
|
9
|
+
readonly clusterGrid: Uint32Array;
|
|
10
|
+
readonly lightIndexList: Uint32Array;
|
|
11
|
+
readonly lightBounds: Int32Array;
|
|
12
|
+
readonly membershipEntryCount: number;
|
|
13
|
+
readonly scratch: ClusterBinScratch;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function deriveStandardMembership(
|
|
17
|
+
frame: StandardLightFrame,
|
|
18
|
+
layout: StandardClusterLayout,
|
|
19
|
+
scratch = createClusterBinScratch(),
|
|
20
|
+
): Result<StandardClusterMembership, RenderError> {
|
|
21
|
+
const clusterGrid = new Uint32Array(layout.clusterGridU32Length);
|
|
22
|
+
const lightIndexList = new Uint32Array(layout.lightIndexListCapacity);
|
|
23
|
+
const result = bin(
|
|
24
|
+
frame.local,
|
|
25
|
+
frame.view,
|
|
26
|
+
frame.projection,
|
|
27
|
+
layout.grid,
|
|
28
|
+
frame.near,
|
|
29
|
+
frame.far,
|
|
30
|
+
clusterGrid,
|
|
31
|
+
lightIndexList,
|
|
32
|
+
layout.lightIndexListCapacity,
|
|
33
|
+
scratch,
|
|
34
|
+
);
|
|
35
|
+
if (!result.ok) return err(fromClusterBinError(result.error));
|
|
36
|
+
return ok({
|
|
37
|
+
clusterGrid,
|
|
38
|
+
lightIndexList,
|
|
39
|
+
lightBounds: scratch.lightBounds.slice(0, frame.local.length * 6),
|
|
40
|
+
membershipEntryCount: result.value,
|
|
41
|
+
scratch,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { err, ok, type Result } from '@forgeax/engine-types';
|
|
2
|
+
import { type RenderError, StandardLightBudgetExceededError } from '../../errors/render';
|
|
3
|
+
import { MAX_LIGHTS } from '../standard-profile';
|
|
4
|
+
import { createStandardClusterLayout, type StandardClusterLayout } from './layout';
|
|
5
|
+
import type { StandardLightFrame } from './light-frame';
|
|
6
|
+
import { deriveStandardMembership, type StandardClusterMembership } from './membership';
|
|
7
|
+
|
|
8
|
+
export type { StandardLightFrame } from './light-frame';
|
|
9
|
+
|
|
10
|
+
export interface PreparedStandardLighting extends StandardClusterMembership {
|
|
11
|
+
readonly directional: StandardLightFrame['directional'];
|
|
12
|
+
readonly local: StandardLightFrame['local'];
|
|
13
|
+
readonly layout: StandardClusterLayout;
|
|
14
|
+
readonly membershipLightCount: number;
|
|
15
|
+
readonly renderPath: NonNullable<StandardLightFrame['renderPath']>;
|
|
16
|
+
readonly maxLights: StandardLightFrame['lightCount'];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function prepareStandardLighting(
|
|
20
|
+
frame: StandardLightFrame,
|
|
21
|
+
): Result<PreparedStandardLighting, RenderError> {
|
|
22
|
+
if (frame.local.length > frame.lightCount || frame.local.length > MAX_LIGHTS) {
|
|
23
|
+
return err(new StandardLightBudgetExceededError(frame.local.length, frame.lightCount));
|
|
24
|
+
}
|
|
25
|
+
const layout = createStandardClusterLayout(frame.grid);
|
|
26
|
+
const membership = deriveStandardMembership(frame, layout);
|
|
27
|
+
if (!membership.ok) return membership;
|
|
28
|
+
return ok({
|
|
29
|
+
...membership.value,
|
|
30
|
+
directional: frame.directional,
|
|
31
|
+
local: frame.local,
|
|
32
|
+
layout,
|
|
33
|
+
membershipLightCount: frame.local.length,
|
|
34
|
+
renderPath: frame.renderPath,
|
|
35
|
+
maxLights: frame.lightCount,
|
|
36
|
+
});
|
|
37
|
+
}
|