@forgeax/engine-render 0.1.33 → 0.1.35
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 +1062 -127
- package/dist/assembly/backend-contract.d.ts +2 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -1
- package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
- package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
- package/dist/assembly/canvas-draw-guard.d.ts +3 -0
- package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
- package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
- package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
- package/dist/assembly/device-feature-admission.d.ts +2 -2
- package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
- package/dist/assembly/factory.d.ts +1 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +6 -5
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
- package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
- package/dist/assembly/material-shader-policy.d.ts +16 -2
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
- package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/render-feature-post-processes.d.ts +6 -0
- package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
- package/dist/assembly/render-target-host.d.ts +5 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -1
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
- package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-inspection.d.ts +11 -0
- package/dist/assembly/renderer-inspection.d.ts.map +1 -1
- package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
- package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +1 -1
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
- package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +2 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/authoring.mjs +2 -4
- package/dist/authoring.mjs.map +1 -1
- package/dist/barrel-distortion.d.ts +47 -0
- package/dist/barrel-distortion.d.ts.map +1 -0
- package/dist/chunk-3XUBWRY2.mjs +1842 -0
- package/dist/chunk-3XUBWRY2.mjs.map +1 -0
- package/dist/{chunk-OO3DRYK7.mjs → chunk-G6HDNGY7.mjs} +2400 -1767
- package/dist/chunk-G6HDNGY7.mjs.map +1 -0
- package/dist/{chunk-ZDQWGQW7.mjs → chunk-LM5IE7GF.mjs} +4 -4
- package/dist/{chunk-ZDQWGQW7.mjs.map → chunk-LM5IE7GF.mjs.map} +1 -1
- package/dist/{chunk-VOZWDM3L.mjs → chunk-LNIUIKQ7.mjs} +1514 -498
- package/dist/chunk-LNIUIKQ7.mjs.map +1 -0
- package/dist/chunk-MXTWKZO4.mjs +3268 -0
- package/dist/chunk-MXTWKZO4.mjs.map +1 -0
- package/dist/chunk-MZ4C7EHF.mjs +6942 -0
- package/dist/chunk-MZ4C7EHF.mjs.map +1 -0
- package/dist/chunk-RIPAEGI6.mjs +48 -0
- package/dist/chunk-RIPAEGI6.mjs.map +1 -0
- package/dist/{chunk-LEAXOMYJ.mjs → chunk-SGPUJW3F.mjs} +117 -5
- package/dist/chunk-SGPUJW3F.mjs.map +1 -0
- package/dist/{chunk-PA5DRJNI.mjs → chunk-X2KA6WHM.mjs} +29 -4
- package/dist/chunk-X2KA6WHM.mjs.map +1 -0
- package/dist/{chunk-BLXGONR2.mjs → chunk-XSFB7XXQ.mjs} +51 -4
- package/dist/chunk-XSFB7XXQ.mjs.map +1 -0
- package/dist/cloud/density.d.ts +55 -0
- package/dist/cloud/density.d.ts.map +1 -0
- package/dist/cloud/extract.d.ts +25 -0
- package/dist/cloud/extract.d.ts.map +1 -0
- package/dist/cloud/feature.d.ts +57 -0
- package/dist/cloud/feature.d.ts.map +1 -0
- package/dist/cloud/frame-context.d.ts +8 -0
- package/dist/cloud/frame-context.d.ts.map +1 -0
- package/dist/cloud/inspection.d.ts +59 -0
- package/dist/cloud/inspection.d.ts.map +1 -0
- package/dist/cloud/optics.d.ts +56 -0
- package/dist/cloud/optics.d.ts.map +1 -0
- package/dist/cloud/parameters.d.ts +73 -0
- package/dist/cloud/parameters.d.ts.map +1 -0
- package/dist/cloud/resources.d.ts +60 -0
- package/dist/cloud/resources.d.ts.map +1 -0
- package/dist/cloud/shadow.d.ts +42 -0
- package/dist/cloud/shadow.d.ts.map +1 -0
- package/dist/cloud/temporal.d.ts +74 -0
- package/dist/cloud/temporal.d.ts.map +1 -0
- package/dist/components/barrel-distortion.d.ts +13 -0
- package/dist/components/barrel-distortion.d.ts.map +1 -0
- package/dist/components/cloud-layer.d.ts +29 -0
- package/dist/components/cloud-layer.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/instances.d.ts +20 -6
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/construct-renderer.d.ts +1 -1
- package/dist/construct-renderer.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +8406 -5785
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +19 -19
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/dynamic-geometry.d.ts +5 -1
- package/dist/dynamic-geometry.d.ts.map +1 -1
- package/dist/errors/cloud.d.ts +59 -0
- package/dist/errors/cloud.d.ts.map +1 -0
- package/dist/errors/render.d.ts +20 -5
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/examples/single-layer-medium-surface.d.ts +47 -0
- package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +5 -1
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/extract/material-context.d.ts +7 -0
- package/dist/extract/material-context.d.ts.map +1 -0
- package/dist/features/barrel-distortion.d.ts +29 -0
- package/dist/features/barrel-distortion.d.ts.map +1 -0
- package/dist/features/error-reporting.d.ts +6 -2
- package/dist/features/error-reporting.d.ts.map +1 -1
- package/dist/features/host.d.ts +15 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/plan.d.ts +10 -0
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +5 -0
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +1 -0
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/targets.d.ts +2 -0
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +48 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +15 -7
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/glyph-text-layout-system.d.ts +1 -1
- package/dist/glyph-text-layout-system.d.ts.map +1 -1
- package/dist/gpu-dirty-ranges.d.ts +11 -0
- package/dist/gpu-dirty-ranges.d.ts.map +1 -0
- package/dist/gpu-driven/batch-topology.d.ts +17 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/material-artifacts.d.ts +6 -0
- package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster-material.d.ts +178 -0
- package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +47 -3
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/resource-allocation.d.ts +31 -0
- package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
- package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
- package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +26 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +5 -0
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +2 -2
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/frame-resources.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +14 -5
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +30 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +780 -9
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +135 -1
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instance-buffer-cache.d.ts +4 -4
- package/dist/instance-buffer-cache.d.ts.map +1 -1
- package/dist/instances.d.ts +47 -100
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +7 -8
- package/dist/internal.mjs.map +1 -1
- package/dist/pbr-pipeline.d.ts +22 -4
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
- package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
- package/dist/pipeline/standard-output/lut-gpu.d.ts +2 -2
- package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -1
- package/dist/pipeline/standard-output/resources.d.ts +2 -2
- package/dist/pipeline/standard-output/resources.d.ts.map +1 -1
- package/dist/pipeline/standard-output/types.d.ts +4 -2
- package/dist/pipeline/standard-output/types.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +1 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/publication/contract.d.ts +77 -0
- package/dist/publication/contract.d.ts.map +1 -0
- package/dist/publication/dependencies.d.ts +7 -0
- package/dist/publication/dependencies.d.ts.map +1 -0
- package/dist/publication/prepare-geometry.d.ts +9 -0
- package/dist/publication/prepare-geometry.d.ts.map +1 -0
- package/dist/publication/programs.d.ts +5 -0
- package/dist/publication/programs.d.ts.map +1 -0
- package/dist/publication/publisher.d.ts +33 -0
- package/dist/publication/publisher.d.ts.map +1 -0
- package/dist/publication/receiver.d.ts +29 -0
- package/dist/publication/receiver.d.ts.map +1 -0
- package/dist/publication/resource-scope.d.ts +18 -0
- package/dist/publication/resource-scope.d.ts.map +1 -0
- package/dist/publication/targets.d.ts +33 -0
- package/dist/publication/targets.d.ts.map +1 -0
- package/dist/publication/video.d.ts +5 -0
- package/dist/publication/video.d.ts.map +1 -0
- package/dist/record/barrel-distortion-frame.d.ts +15 -0
- package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
- package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
- package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
- package/dist/record/fold-buckets.d.ts +95 -0
- package/dist/record/fold-buckets.d.ts.map +1 -0
- package/dist/record/fold-instance-buffer.d.ts +6 -0
- package/dist/record/fold-instance-buffer.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +1 -0
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +43 -9
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts +15 -65
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-draw-receipts.d.ts +11 -0
- package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +8 -0
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/helpers.d.ts +2 -2
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +22 -6
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +14 -10
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +3 -16
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +13 -2
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/motion-blur-receipt.d.ts +11 -0
- package/dist/record/motion-blur-receipt.d.ts.map +1 -0
- package/dist/record/prepared-material-bindings.d.ts +3 -3
- package/dist/record/prepared-material-bindings.d.ts.map +1 -1
- package/dist/record/probe-blend-buffer.d.ts +16 -0
- package/dist/record/probe-blend-buffer.d.ts.map +1 -0
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +24 -5
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +2 -0
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/sprite-instance-buffer.d.ts +31 -0
- package/dist/record/sprite-instance-buffer.d.ts.map +1 -0
- package/dist/record/target-capture-graph.d.ts +19 -0
- package/dist/record/target-capture-graph.d.ts.map +1 -0
- package/dist/record/typed-frame-graph.d.ts +24 -15
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +11 -3
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/record/volume-params.d.ts +9 -0
- package/dist/record/volume-params.d.ts.map +1 -0
- package/dist/recovery/render-system-candidate.d.ts +14 -4
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +46 -5
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +103 -2
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +3 -2
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +18 -9
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-presentation.d.ts +23 -0
- package/dist/render-system-presentation.d.ts.map +1 -0
- package/dist/render-system-producer-roots.d.ts +10 -0
- package/dist/render-system-producer-roots.d.ts.map +1 -0
- package/dist/render-system-projections.d.ts +3 -2
- package/dist/render-system-projections.d.ts.map +1 -1
- package/dist/render-system-residency.d.ts +12 -0
- package/dist/render-system-residency.d.ts.map +1 -0
- package/dist/render-system.d.ts +22 -21
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/probe-blend.d.ts +27 -0
- package/dist/scene/probe-blend.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +18 -7
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/render-source.d.ts +42 -0
- package/dist/scene/render-source.d.ts.map +1 -0
- package/dist/scene/source-systems.d.ts +6 -0
- package/dist/scene/source-systems.d.ts.map +1 -0
- package/dist/ssao-buffers.d.ts +9 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/surface/dynamic-input.d.ts +133 -0
- package/dist/surface/dynamic-input.d.ts.map +1 -0
- package/dist/surface/gpu-driven.d.ts +41 -0
- package/dist/surface/gpu-driven.d.ts.map +1 -0
- package/dist/surface/submission-observation.d.ts +136 -0
- package/dist/surface/submission-observation.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/systems/skin-palette-types.d.ts +10 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -1
- package/dist/systems/transparent-dispatch.d.ts +2 -2
- package/dist/systems/transparent-dispatch.d.ts.map +1 -1
- package/dist/systems/transparent-sort-config.d.ts +2 -1
- package/dist/systems/transparent-sort-config.d.ts.map +1 -1
- package/dist/temporal/gpu.d.ts +13 -1
- package/dist/temporal/gpu.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -7
- package/dist/temporal/inspection.d.ts.map +1 -1
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
- package/dist/transmission/single-layer-medium.d.ts +89 -0
- package/dist/transmission/single-layer-medium.d.ts.map +1 -0
- package/dist/typed-render-graph-primitives.d.ts +14 -2
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/component.d.ts +9 -4
- package/dist/volume/component.d.ts.map +1 -1
- package/dist/volume/extract.d.ts +1 -1
- package/dist/volume/extract.d.ts.map +1 -1
- package/dist/volume/inspection.d.ts +2 -0
- package/dist/volume/inspection.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +4 -1
- package/dist/volume/passes.d.ts.map +1 -1
- package/dist/volume/resources.d.ts.map +1 -1
- package/package.json +22 -21
- package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
- package/src/__tests__/auto-exposure-transaction.integration.test.ts +4 -9
- package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
- package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
- package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
- package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
- package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +3 -2
- package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
- package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
- package/src/__tests__/factory-contract.integration.test.ts +295 -45
- package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
- package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
- package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +5 -6
- package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +6 -5
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +94 -6
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
- package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
- package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
- package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
- package/src/__tests__/gpu-scene.unit.test.ts +119 -9
- package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
- package/src/__tests__/instances-culling.integration.test.ts +10 -36
- package/src/__tests__/instances-store.unit.test.ts +97 -305
- package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +4 -1
- package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +145 -0
- package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
- package/src/__tests__/materials-standard-contract.unit.test.ts +0 -1
- package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
- package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
- package/src/__tests__/motion-blur-compute.dawn.test.ts +13 -7
- package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
- package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
- package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +66 -8
- package/src/__tests__/physical-material-budget.unit.test.ts +40 -0
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
- package/src/__tests__/probe-bindings.unit.test.ts +582 -1
- package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
- package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +8 -0
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
- package/src/__tests__/render-feature-error-reporting.unit.test.ts +21 -1
- package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
- package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
- package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
- package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
- package/src/__tests__/render-scene-temporal-retry.unit.test.ts +20 -20
- package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
- package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
- package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +42 -8
- package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +26 -10
- package/src/__tests__/resource-allocation.unit.test.ts +123 -0
- package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
- package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +15 -0
- package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
- package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
- package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
- package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
- package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
- package/src/__tests__/standard-pipeline.integration.test.ts +182 -1
- package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
- package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
- package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
- package/src/__tests__/temporal-performance.integration.test.ts +3 -3
- package/src/__tests__/visibility-instances.integration.test.ts +7 -19
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
- package/src/__tests__/volume-optics-oracle.unit.test.ts +4 -2
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +30 -20
- package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
- package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
- package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +113 -9
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +5 -3
- package/src/assembly/backend-contract.ts +30 -0
- package/src/assembly/barrel-distortion-inspection.ts +22 -0
- package/src/assembly/canvas-draw-guard.ts +11 -0
- package/src/assembly/cloud-shadow-entry.ts +22 -0
- package/src/assembly/device-feature-admission.ts +2 -2
- package/src/assembly/dynamic-geometry-host.ts +65 -37
- package/src/assembly/dynamic-geometry-runtime.ts +7 -1
- package/src/assembly/factory.ts +2 -30
- package/src/assembly/host-contract.ts +8 -5
- package/src/assembly/material/assembly.ts +25 -13
- package/src/assembly/material/pipeline-helpers.ts +53 -12
- package/src/assembly/material-shader-policy.ts +55 -0
- package/src/assembly/material-shader-prewarm.ts +21 -10
- package/src/assembly/recovery/device-loss-fanout.ts +13 -0
- package/src/assembly/recovery/renderer-recover.ts +50 -18
- package/src/assembly/render-feature-post-processes.ts +54 -0
- package/src/assembly/render-target-host.ts +57 -47
- package/src/assembly/renderer-facade.ts +7 -2
- package/src/assembly/renderer-feature-inspection.ts +8 -2
- package/src/assembly/renderer-frame-transaction.ts +23 -0
- package/src/assembly/renderer-inspection.ts +28 -0
- package/src/assembly/skin-palette-owner.ts +1 -1
- package/src/assembly/temporal-post-process-prewarm.ts +3 -3
- package/src/assembly/webgpu-pbr-ready.ts +9 -1
- package/src/assembly/webgpu-ready-per-pass.ts +104 -0
- package/src/assembly/webgpu-ready.ts +116 -62
- package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
- package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
- package/src/assembly/webgpu-renderer.ts +303 -313
- package/src/assembly/webgpu-vertex-layouts.ts +1 -1
- package/src/barrel-distortion.ts +247 -0
- package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
- package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
- package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
- package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
- package/src/cloud/density.ts +600 -0
- package/src/cloud/extract.ts +110 -0
- package/src/cloud/feature.ts +1810 -0
- package/src/cloud/frame-context.ts +42 -0
- package/src/cloud/inspection.ts +130 -0
- package/src/cloud/optics.ts +285 -0
- package/src/cloud/parameters.ts +255 -0
- package/src/cloud/resources.ts +122 -0
- package/src/cloud/shadow.ts +167 -0
- package/src/cloud/temporal.ts +226 -0
- package/src/components/barrel-distortion.ts +46 -0
- package/src/components/cloud-layer.ts +47 -0
- package/src/components/index.ts +2 -0
- package/src/components/instances.ts +18 -45
- package/src/components/sprite-instances.ts +1 -1
- package/src/construct-renderer.ts +1 -1
- package/src/device/gpu-residency.ts +26 -25
- package/src/dynamic-geometry.ts +12 -1
- package/src/errors/cloud.ts +103 -0
- package/src/errors/render.ts +47 -8
- package/src/examples/single-layer-medium-surface.ts +59 -0
- package/src/extract/camera.ts +15 -1
- package/src/extract/contracts.ts +5 -0
- package/src/extract/material-context.ts +21 -0
- package/src/features/barrel-distortion.ts +172 -0
- package/src/features/error-reporting.ts +26 -6
- package/src/features/host.ts +128 -19
- package/src/features/plan.ts +10 -0
- package/src/features/render-graph-contribution.ts +9 -0
- package/src/features/render-graph-raster.ts +45 -3
- package/src/features/targets.ts +66 -0
- package/src/features/types.ts +51 -0
- package/src/fullscreen-post-process-pass.ts +41 -9
- package/src/glyph-text-layout-system.ts +2 -2
- package/src/gpu-dirty-ranges.ts +48 -0
- package/src/gpu-driven/batch-topology.ts +53 -0
- package/src/gpu-driven/material-artifacts.ts +33 -25
- package/src/gpu-driven/prepared-draw.ts +12 -4
- package/src/gpu-driven/production-raster-material.ts +1894 -0
- package/src/gpu-driven/production-raster.ts +825 -784
- package/src/gpu-driven/resource-allocation.ts +142 -0
- package/src/gpu-driven/shadow-ownership.ts +71 -0
- package/src/gpu-driven/view-gpu.ts +164 -10
- package/src/gpu-scene.ts +75 -84
- package/src/hdrp-buffers.ts +4 -3
- package/src/ibl/frame-resources.ts +0 -1
- package/src/ibl/skylight-bind-group.ts +62 -32
- package/src/index.ts +205 -9
- package/src/inspection-types.ts +162 -0
- package/src/instance-buffer-cache.ts +4 -4
- package/src/instances.ts +152 -569
- package/src/pbr-pipeline.ts +230 -30
- package/src/pipeline/single-layer-medium-passes.ts +267 -0
- package/src/pipeline/standard-forward-lane.ts +313 -57
- package/src/pipeline/standard-output/graph.ts +8 -2
- package/src/pipeline/standard-output/lut-gpu.ts +3 -3
- package/src/pipeline/standard-output/resources.ts +2 -2
- package/src/pipeline/standard-output/types.ts +12 -1
- package/src/pipeline/standard-pipeline.ts +291 -18
- package/src/pipeline/standard-post.ts +90 -24
- package/src/pipeline-builder.ts +1 -1
- package/src/plugin.ts +4 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
- package/src/prepare/prepared-graphics-resolver.ts +2 -0
- package/src/publication/__tests__/derived-geometry.integration.test.ts +177 -0
- package/src/publication/__tests__/features.integration.test.ts +122 -0
- package/src/publication/__tests__/programs.unit.test.ts +25 -0
- package/src/publication/__tests__/publication.integration.test.ts +370 -0
- package/src/publication/__tests__/targets.integration.test.ts +120 -0
- package/src/publication/__tests__/video.browser.test.ts +50 -0
- package/src/publication/contract.ts +104 -0
- package/src/publication/dependencies.ts +54 -0
- package/src/publication/prepare-geometry.ts +94 -0
- package/src/publication/programs.ts +45 -0
- package/src/publication/publisher.ts +618 -0
- package/src/publication/receiver.ts +297 -0
- package/src/publication/resource-scope.ts +31 -0
- package/src/publication/targets.ts +182 -0
- package/src/publication/video.ts +33 -0
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +15 -1
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +9 -11
- package/src/record/__tests__/temporal-payload.unit.test.ts +1 -1
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
- package/src/record/__tests__/video-texture-view.unit.test.ts +9 -9
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
- package/src/record/barrel-distortion-frame.ts +110 -0
- package/src/record/dynamic-geometry-consumption.ts +39 -9
- package/src/record/fold-buckets.ts +855 -0
- package/src/record/fold-instance-buffer.ts +51 -0
- package/src/record/frame-lighting.ts +36 -2
- package/src/record/frame-snapshot.ts +45 -9
- package/src/record/frame.ts +258 -1105
- package/src/record/gpu-draw-receipts.ts +38 -0
- package/src/record/gpu-timing.ts +48 -5
- package/src/record/helpers.ts +2 -2
- package/src/record/main-pass-geometry.ts +272 -84
- package/src/record/main-pass-material.ts +102 -36
- package/src/record/main-pass-sprite-draws.ts +13 -217
- package/src/record/main-pass.ts +164 -27
- package/src/record/motion-blur-receipt.ts +91 -0
- package/src/record/prepared-material-bindings.ts +11 -6
- package/src/record/probe-blend-buffer.ts +180 -0
- package/src/record/recovery-pipeline.ts +35 -3
- package/src/record/render-context.ts +41 -5
- package/src/record/shadow-pass.ts +30 -4
- package/src/record/skybox-post-pass.ts +28 -4
- package/src/record/sprite-instance-buffer.ts +155 -0
- package/src/record/target-capture-graph.ts +258 -0
- package/src/record/typed-frame-graph.ts +776 -340
- package/src/record/view-ubo.ts +27 -4
- package/src/record/volume-params.ts +225 -0
- package/src/recovery/render-system-candidate.ts +243 -50
- package/src/reflection/record-owner.ts +7 -3
- package/src/render-contract.ts +54 -5
- package/src/render-graph-primitives.ts +7 -1
- package/src/render-pipeline.ts +130 -0
- package/src/render-system-extract-tail.ts +90 -78
- package/src/render-system-extract.ts +76 -76
- package/src/render-system-presentation.ts +56 -0
- package/src/render-system-producer-roots.ts +96 -0
- package/src/render-system-projections.ts +3 -2
- package/src/render-system-residency.ts +159 -0
- package/src/render-system.ts +421 -408
- package/src/scene/probe-blend.ts +96 -4
- package/src/scene/render-scene.ts +416 -337
- package/src/scene/render-source.ts +90 -0
- package/src/scene/source-systems.ts +33 -0
- package/src/ssao-buffers.ts +95 -2
- package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
- package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
- package/src/surface/dynamic-input.ts +658 -0
- package/src/surface/gpu-driven.ts +147 -0
- package/src/surface/submission-observation.ts +517 -0
- package/src/systems/skin-palette-allocator.ts +5 -1
- package/src/systems/skin-palette-types.ts +11 -0
- package/src/systems/transparent-dispatch.ts +2 -2
- package/src/systems/transparent-sort-config.ts +3 -1
- package/src/temporal/gpu.ts +101 -17
- package/src/temporal/inspection.ts +7 -1
- package/src/temporal/standard-scene-data.ts +5 -0
- package/src/temporal/target-coverage-attachment.ts +4 -0
- package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
- package/src/transmission/single-layer-medium.ts +322 -0
- package/src/typed-render-graph-primitives.ts +70 -2
- package/src/volume/component.ts +10 -9
- package/src/volume/extract.ts +11 -5
- package/src/volume/inspection.ts +3 -0
- package/src/volume/passes.ts +87 -4
- package/src/volume/resources.ts +2 -1
- package/dist/chunk-3RTCJTH4.mjs +0 -1610
- package/dist/chunk-3RTCJTH4.mjs.map +0 -1
- package/dist/chunk-BLXGONR2.mjs.map +0 -1
- package/dist/chunk-ILQ5MEZF.mjs +0 -32
- package/dist/chunk-ILQ5MEZF.mjs.map +0 -1
- package/dist/chunk-LEAXOMYJ.mjs.map +0 -1
- package/dist/chunk-NB2S7ZRX.mjs +0 -1783
- package/dist/chunk-NB2S7ZRX.mjs.map +0 -1
- package/dist/chunk-NNQL7CB3.mjs +0 -1713
- package/dist/chunk-NNQL7CB3.mjs.map +0 -1
- package/dist/chunk-OO3DRYK7.mjs.map +0 -1
- package/dist/chunk-PA5DRJNI.mjs.map +0 -1
- package/dist/chunk-PLAXOOX5.mjs +0 -1907
- package/dist/chunk-PLAXOOX5.mjs.map +0 -1
- package/dist/chunk-RXZ3RGOU.mjs +0 -53
- package/dist/chunk-RXZ3RGOU.mjs.map +0 -1
- package/dist/chunk-VOZWDM3L.mjs.map +0 -1
package/src/record/main-pass.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { World } from '@forgeax/engine-ecs';
|
|
2
1
|
import { probeVideoHighPerfUpload } from '@forgeax/engine-graphics-extras';
|
|
3
2
|
import type { GraphResourceResolver } from '@forgeax/engine-render-graph';
|
|
4
3
|
import {
|
|
5
4
|
type BindGroup,
|
|
5
|
+
type Buffer,
|
|
6
6
|
RhiError,
|
|
7
7
|
type RhiRenderPassEncoder,
|
|
8
8
|
type TextureView,
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
import type { PassKind, PassSelector } from '@forgeax/engine-types';
|
|
11
11
|
import {
|
|
12
12
|
createGpuDrivenLightingBindGroup,
|
|
13
|
+
createHdrpSkinUnifiedBindGroup,
|
|
13
14
|
createHdrpUnifiedBindGroup,
|
|
14
15
|
getOrCreateHdrpBuffers,
|
|
15
16
|
} from '../hdrp-buffers';
|
|
@@ -17,10 +18,12 @@ import { getOrCreateIblCache } from '../ibl/IblPipelineCache';
|
|
|
17
18
|
import type { SkylightBindGroupResources } from '../ibl/skylight-bind-group';
|
|
18
19
|
import { buildBeginRenderPassDescriptor, standardTopologyBindGroupReady } from '../pipeline-spec';
|
|
19
20
|
import { POINTS_LINES_MATERIAL_SHADER_ID } from '../points-lines/record';
|
|
21
|
+
import type { RenderResourceScope } from '../publication/resource-scope';
|
|
20
22
|
import type { ReflectionProbeSelectionResult } from '../reflection/projection';
|
|
21
23
|
import type { RenderRecordPhase } from '../render-contract';
|
|
22
24
|
import type {
|
|
23
25
|
GpuDrivenStandardPbrFrameResources,
|
|
26
|
+
RenderPipelineGpuDrivenFilter,
|
|
24
27
|
RenderPipelineGpuDrivenProjection,
|
|
25
28
|
} from '../render-pipeline';
|
|
26
29
|
import type { MaterialSnapshot } from '../render-system-extract';
|
|
@@ -65,12 +68,28 @@ export type MainPassOptions = {
|
|
|
65
68
|
readonly depthView?: TextureView | null;
|
|
66
69
|
readonly passKind?: PassKind;
|
|
67
70
|
readonly clearColor?: readonly [number, number, number, number];
|
|
68
|
-
readonly recordMode?:
|
|
71
|
+
readonly recordMode?:
|
|
72
|
+
| 'opaque'
|
|
73
|
+
| 'transmission'
|
|
74
|
+
| 'transparent'
|
|
75
|
+
| 'single-layer-medium-nearest-layer'
|
|
76
|
+
| 'single-layer-medium-color';
|
|
77
|
+
readonly gpuDrivenFilter?: RenderPipelineGpuDrivenFilter;
|
|
78
|
+
/** Write transparent fragment depth for depth-bounded medium transport. */
|
|
79
|
+
readonly transparentDepthWrite?: boolean;
|
|
69
80
|
/** Exclude material/pass pairs already consumed by an earlier graph lane. */
|
|
70
81
|
readonly excludeSelector?: PassSelector;
|
|
71
82
|
/** Require the same material to contribute to another graph lane. */
|
|
72
83
|
readonly includeSelector?: PassSelector;
|
|
73
84
|
readonly transmissionBackdropView?: TextureView | null;
|
|
85
|
+
/** Independent sampled raw depth produced before the medium passes. */
|
|
86
|
+
readonly surfaceRawDepthView?: TextureView | null;
|
|
87
|
+
/** Nearest-layer color produced by the preceding medium pass. */
|
|
88
|
+
readonly surfaceNearestLayerView?: TextureView | null;
|
|
89
|
+
/** Nearest-layer depth produced by the preceding medium pass. */
|
|
90
|
+
readonly surfaceNearestDepthView?: TextureView | null;
|
|
91
|
+
/** Surface shader fragment entry selected by the typed pass owner. */
|
|
92
|
+
readonly fragmentEntryPoint?: string;
|
|
74
93
|
/** Select the material temporal entry's binary coverage output. */
|
|
75
94
|
readonly coverageOnly?: boolean;
|
|
76
95
|
readonly gpuDriven?: {
|
|
@@ -89,29 +108,53 @@ function isTransmissionMaterial(material: MaterialSnapshot): boolean {
|
|
|
89
108
|
|
|
90
109
|
function matchesRecordMode(
|
|
91
110
|
material: MaterialSnapshot,
|
|
92
|
-
mode:
|
|
111
|
+
mode:
|
|
112
|
+
| 'opaque'
|
|
113
|
+
| 'transmission'
|
|
114
|
+
| 'transparent'
|
|
115
|
+
| 'single-layer-medium-nearest-layer'
|
|
116
|
+
| 'single-layer-medium-color',
|
|
93
117
|
): boolean {
|
|
118
|
+
const medium =
|
|
119
|
+
material.surfaceModel === 'single-layer-medium' ||
|
|
120
|
+
material.materialShaderId === 'forgeax::single-layer-medium';
|
|
121
|
+
if (mode === 'single-layer-medium-nearest-layer' || mode === 'single-layer-medium-color') {
|
|
122
|
+
return medium;
|
|
123
|
+
}
|
|
94
124
|
const transmission = isTransmissionMaterial(material);
|
|
95
125
|
if (mode === 'transmission') return transmission;
|
|
96
|
-
if (mode === 'transparent') return material.transparent === true && !transmission;
|
|
97
|
-
return !transmission && material.transparent !== true;
|
|
126
|
+
if (mode === 'transparent') return material.transparent === true && !transmission && !medium;
|
|
127
|
+
return !transmission && material.transparent !== true && !medium;
|
|
98
128
|
}
|
|
99
129
|
|
|
100
130
|
function matchedMaterialsForRecordMode(
|
|
101
131
|
c: _InternalRenderPipelineContext,
|
|
102
132
|
matchedMaterials: ReadonlyMap<number, ReadonlySet<number>> | null,
|
|
103
|
-
mode:
|
|
133
|
+
mode:
|
|
134
|
+
| 'opaque'
|
|
135
|
+
| 'transmission'
|
|
136
|
+
| 'transparent'
|
|
137
|
+
| 'single-layer-medium-nearest-layer'
|
|
138
|
+
| 'single-layer-medium-color'
|
|
139
|
+
| undefined,
|
|
104
140
|
): ReadonlyMap<number, ReadonlySet<number>> | null {
|
|
105
141
|
if (mode === undefined) return matchedMaterials;
|
|
142
|
+
const surfaceMode =
|
|
143
|
+
mode === 'single-layer-medium-nearest-layer' || mode === 'single-layer-medium-color';
|
|
106
144
|
const filtered = new Map<number, ReadonlySet<number>>();
|
|
107
145
|
for (const entry of c.validatedOrdered) {
|
|
108
146
|
const dispatchHandles = matchedMaterials?.get(entry.renderableIndex);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
147
|
+
// Surface graph membership is owned by the resolved surface model. A
|
|
148
|
+
// Surface-authored pass does not need to duplicate the generic Forward
|
|
149
|
+
// LightMode tag: its prepared direct program already carries the pass
|
|
150
|
+
// specialization selected by the material producer.
|
|
151
|
+
if (!surfaceMode && matchedMaterials !== null && dispatchHandles === undefined) continue;
|
|
152
|
+
const candidateHandles = surfaceMode
|
|
153
|
+
? entry.source.materials.map((material) => material.materialHandle ?? 0)
|
|
154
|
+
: (dispatchHandles ??
|
|
155
|
+
(mode === 'transmission'
|
|
156
|
+
? []
|
|
157
|
+
: entry.source.materials.map((material) => material.materialHandle ?? 0)));
|
|
115
158
|
const handles = new Set<number>();
|
|
116
159
|
for (const handle of candidateHandles) {
|
|
117
160
|
const material =
|
|
@@ -173,11 +216,19 @@ export function recordMainPass(
|
|
|
173
216
|
const passKind = options?.passKind ?? 'forward';
|
|
174
217
|
const recordMode = options?.recordMode;
|
|
175
218
|
const transmissionBackdropView = options?.transmissionBackdropView;
|
|
176
|
-
|
|
219
|
+
const surfaceRawDepthView = options?.surfaceRawDepthView;
|
|
220
|
+
const surfaceNearestLayerView = options?.surfaceNearestLayerView;
|
|
221
|
+
const surfaceNearestDepthView = options?.surfaceNearestDepthView;
|
|
222
|
+
if (
|
|
223
|
+
(recordMode === 'transmission' ||
|
|
224
|
+
recordMode === 'single-layer-medium-nearest-layer' ||
|
|
225
|
+
recordMode === 'single-layer-medium-color') &&
|
|
226
|
+
transmissionBackdropView == null
|
|
227
|
+
) {
|
|
177
228
|
throw new RhiError({
|
|
178
229
|
code: 'webgpu-runtime-error',
|
|
179
|
-
expected: 'transmissionBackdropView != null for
|
|
180
|
-
hint: 'the typed Standard
|
|
230
|
+
expected: 'transmissionBackdropView != null for a backdrop-consuming record mode',
|
|
231
|
+
hint: 'the typed Standard backdrop pass must resolve its graph-paired color view',
|
|
181
232
|
});
|
|
182
233
|
}
|
|
183
234
|
const colorViews = options?.colorViews ?? [geometryColorView];
|
|
@@ -224,12 +275,11 @@ export function recordMainPass(
|
|
|
224
275
|
// fallback because the transient SSAO texture does not exist that early.
|
|
225
276
|
// Built per frame (the SSAO target is a graph transient, so no cross-frame
|
|
226
277
|
// cache); HDRP-only and SSAO-only, so URP and SSAO-off paths are untouched.
|
|
278
|
+
const hdrpBuffers = clusteredLighting
|
|
279
|
+
? getOrCreateHdrpBuffers(runtime, frameState.installedPipelineConfig?.clusterGrid)
|
|
280
|
+
: null;
|
|
227
281
|
let hdrpSsaoBindGroup: BindGroup | null = null;
|
|
228
|
-
if (
|
|
229
|
-
const hdrpBuffers = getOrCreateHdrpBuffers(
|
|
230
|
-
runtime,
|
|
231
|
-
frameState.installedPipelineConfig?.clusterGrid,
|
|
232
|
-
);
|
|
282
|
+
if (hdrpClusterBindGroup !== null && c.hdrpSsaoBlurredView !== undefined) {
|
|
233
283
|
if (hdrpBuffers !== null) {
|
|
234
284
|
hdrpSsaoBindGroup = createHdrpUnifiedBindGroup(
|
|
235
285
|
runtime,
|
|
@@ -242,6 +292,71 @@ export function recordMainPass(
|
|
|
242
292
|
const meshGroup2: BindGroup | null = clusteredLighting
|
|
243
293
|
? (hdrpSsaoBindGroup ?? hdrpClusterBindGroup)
|
|
244
294
|
: meshBindGroup;
|
|
295
|
+
if (gpuDrivenStandardPbrFrameResources !== undefined) {
|
|
296
|
+
// The GPU-driven owner prepares before transient graph resources exist;
|
|
297
|
+
// publish the actual Standard group(2) here, at the existing main-pass
|
|
298
|
+
// binding seam, immediately before indirect encoding.
|
|
299
|
+
gpuDrivenStandardPbrFrameResources.clusterBindGroup =
|
|
300
|
+
clusteredLighting && meshGroup2 !== null ? meshGroup2 : undefined;
|
|
301
|
+
if (hdrpBuffers === null) {
|
|
302
|
+
gpuDrivenStandardPbrFrameResources.clusterBindGroupForMesh = undefined;
|
|
303
|
+
gpuDrivenStandardPbrFrameResources.clusterBindGroupForSkin = undefined;
|
|
304
|
+
} else {
|
|
305
|
+
const projectedGroups = new Map<Buffer, BindGroup>();
|
|
306
|
+
gpuDrivenStandardPbrFrameResources.clusterBindGroupForMesh = (meshBuffer, bindingBytes) => {
|
|
307
|
+
const cached = projectedGroups.get(meshBuffer);
|
|
308
|
+
if (cached !== undefined) return cached;
|
|
309
|
+
const created = createHdrpUnifiedBindGroup(
|
|
310
|
+
runtime,
|
|
311
|
+
hdrpBuffers,
|
|
312
|
+
meshBuffer,
|
|
313
|
+
c.hdrpSsaoBlurredView === undefined
|
|
314
|
+
? { enabled: false }
|
|
315
|
+
: { enabled: true, ssaoBlurredView: c.hdrpSsaoBlurredView },
|
|
316
|
+
bindingBytes,
|
|
317
|
+
);
|
|
318
|
+
if (created !== null) projectedGroups.set(meshBuffer, created);
|
|
319
|
+
return created ?? undefined;
|
|
320
|
+
};
|
|
321
|
+
const projectedSkinGroups = new Map<Buffer, Map<Buffer, Map<string, BindGroup>>>();
|
|
322
|
+
gpuDrivenStandardPbrFrameResources.clusterBindGroupForSkin = (
|
|
323
|
+
meshBuffer,
|
|
324
|
+
meshBindingBytes,
|
|
325
|
+
paletteBuffer,
|
|
326
|
+
paletteBindingWindowBytes,
|
|
327
|
+
) => {
|
|
328
|
+
let meshGroups = projectedSkinGroups.get(meshBuffer);
|
|
329
|
+
if (meshGroups === undefined) {
|
|
330
|
+
meshGroups = new Map();
|
|
331
|
+
projectedSkinGroups.set(meshBuffer, meshGroups);
|
|
332
|
+
}
|
|
333
|
+
let paletteGroups = meshGroups.get(paletteBuffer);
|
|
334
|
+
if (paletteGroups === undefined) {
|
|
335
|
+
paletteGroups = new Map();
|
|
336
|
+
meshGroups.set(paletteBuffer, paletteGroups);
|
|
337
|
+
}
|
|
338
|
+
const bindingKey = `${meshBindingBytes}:${paletteBindingWindowBytes}`;
|
|
339
|
+
const cached = paletteGroups.get(bindingKey);
|
|
340
|
+
if (cached !== undefined) return cached;
|
|
341
|
+
const skinLayout = pipelineState.hdrpSkinMeshBindGroupLayout;
|
|
342
|
+
if (skinLayout === null) return undefined;
|
|
343
|
+
const created = createHdrpSkinUnifiedBindGroup(
|
|
344
|
+
runtime,
|
|
345
|
+
hdrpBuffers,
|
|
346
|
+
skinLayout,
|
|
347
|
+
meshBuffer,
|
|
348
|
+
paletteBuffer,
|
|
349
|
+
paletteBindingWindowBytes,
|
|
350
|
+
c.hdrpSsaoBlurredView === undefined
|
|
351
|
+
? { enabled: false }
|
|
352
|
+
: { enabled: true, ssaoBlurredView: c.hdrpSsaoBlurredView },
|
|
353
|
+
meshBindingBytes,
|
|
354
|
+
);
|
|
355
|
+
if (created !== null) paletteGroups.set(bindingKey, created);
|
|
356
|
+
return created ?? undefined;
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
}
|
|
245
360
|
// ── Geometry (main colour) pass ──────────────────────────────────
|
|
246
361
|
// D-2: tracks whether the geometry pass was explicitly ended inside
|
|
247
362
|
// the `if (validatedOrdered.length > 0)` block (sprite split path),
|
|
@@ -414,7 +529,7 @@ export function recordMainPass(
|
|
|
414
529
|
identities: [
|
|
415
530
|
getOpaqueResourceIdentity(skylightResources.irradianceSampler as object),
|
|
416
531
|
getOpaqueResourceIdentity(skylightResources.prefilterSampler as object),
|
|
417
|
-
getOpaqueResourceIdentity(skylightResources.
|
|
532
|
+
getOpaqueResourceIdentity(skylightResources.irradianceSampler as object),
|
|
418
533
|
],
|
|
419
534
|
},
|
|
420
535
|
resources: {
|
|
@@ -434,7 +549,9 @@ export function recordMainPass(
|
|
|
434
549
|
},
|
|
435
550
|
brdfLut: {
|
|
436
551
|
viewIdentity: getOpaqueResourceIdentity(skylightResources.brdfLutView as object),
|
|
437
|
-
samplerIdentity: getOpaqueResourceIdentity(
|
|
552
|
+
samplerIdentity: getOpaqueResourceIdentity(
|
|
553
|
+
skylightResources.irradianceSampler as object,
|
|
554
|
+
),
|
|
438
555
|
deviceGeneration: runtime.deviceScope.generation,
|
|
439
556
|
},
|
|
440
557
|
intensityBufferIdentity: getOpaqueResourceIdentity(
|
|
@@ -475,7 +592,7 @@ export function recordMainPass(
|
|
|
475
592
|
// which cannot render a PBR decal). Captures only frame-stable closure
|
|
476
593
|
// state; the caller passes the per-submesh material snapshot + entityKey
|
|
477
594
|
// (for video texture routing) and sets the dynamic UBO offset itself.
|
|
478
|
-
// Selection keys use the extracted frame index, never
|
|
595
|
+
// Selection keys use the extracted frame index, never RenderResourceScope.identity.
|
|
479
596
|
const hasProbeBindings = (c.reflectionProbes?.table.rows.length ?? 0) > 0;
|
|
480
597
|
const worldIndices = hasProbeBindings
|
|
481
598
|
? new Map(
|
|
@@ -517,7 +634,6 @@ export function recordMainPass(
|
|
|
517
634
|
skylightPrefilterView: skylightResources.prefilterView,
|
|
518
635
|
prefilterSampler: row.sampler,
|
|
519
636
|
brdfLutView: skylightResources.brdfLutView,
|
|
520
|
-
brdfLutSampler: skylightResources.brdfLutSampler,
|
|
521
637
|
intensityBuffer: row.uniformBuffer,
|
|
522
638
|
};
|
|
523
639
|
return { resources: probeResources, probeIndex: row.index };
|
|
@@ -535,11 +651,14 @@ export function recordMainPass(
|
|
|
535
651
|
gpuDrivenSceneMaterialBuffer,
|
|
536
652
|
}),
|
|
537
653
|
...(transmissionBackdropView === undefined ? {} : { transmissionBackdropView }),
|
|
654
|
+
...(surfaceRawDepthView === undefined ? {} : { surfaceRawDepthView }),
|
|
655
|
+
...(surfaceNearestLayerView === undefined ? {} : { surfaceNearestLayerView }),
|
|
656
|
+
...(surfaceNearestDepthView === undefined ? {} : { surfaceNearestDepthView }),
|
|
538
657
|
};
|
|
539
658
|
const buildPerSubmeshMaterialBg = (
|
|
540
659
|
submeshMaterial: MaterialSnapshot,
|
|
541
660
|
entityKey: number,
|
|
542
|
-
materialWorld:
|
|
661
|
+
materialWorld: RenderResourceScope = world,
|
|
543
662
|
materialShaderId: string | undefined = submeshMaterial.materialShaderId,
|
|
544
663
|
): BindGroup =>
|
|
545
664
|
buildPerSubmeshMaterialBgImpl(
|
|
@@ -558,6 +677,12 @@ export function recordMainPass(
|
|
|
558
677
|
for (let materialSlot = 0; materialSlot < materialSlotCount; materialSlot += 1) {
|
|
559
678
|
const material = materialSlots[materialSlot];
|
|
560
679
|
if (material === undefined || (material.videoTextureFields?.size ?? 0) > 0) continue;
|
|
680
|
+
// A graph scene pass owns only the materials selected by its record
|
|
681
|
+
// mode. In particular, the opaque pass runs before the raw-depth
|
|
682
|
+
// producer and must not assemble medium bindings with resources that do
|
|
683
|
+
// not exist until the later nearest-layer/color passes. Keep holes for
|
|
684
|
+
// the other lanes; the GPU encoder validates the exact slot it consumes.
|
|
685
|
+
if (recordMode !== undefined && !matchesRecordMode(material, recordMode)) continue;
|
|
561
686
|
const owner = materialSlotOwners[materialSlot];
|
|
562
687
|
if (owner === undefined) continue;
|
|
563
688
|
preparedMaterialBindGroups[materialSlot] = buildPerSubmeshMaterialBg(
|
|
@@ -624,7 +749,7 @@ export function recordMainPass(
|
|
|
624
749
|
materialSlot: number,
|
|
625
750
|
material: MaterialSnapshot,
|
|
626
751
|
entityKey: number,
|
|
627
|
-
materialWorld:
|
|
752
|
+
materialWorld: RenderResourceScope = world,
|
|
628
753
|
materialShaderId: string | undefined = material.materialShaderId,
|
|
629
754
|
): BindGroup =>
|
|
630
755
|
!hasProbeBindings &&
|
|
@@ -656,6 +781,13 @@ export function recordMainPass(
|
|
|
656
781
|
selectedDispatch,
|
|
657
782
|
colorFormats,
|
|
658
783
|
options?.coverageOnly ?? false,
|
|
784
|
+
options?.fragmentEntryPoint,
|
|
785
|
+
recordMode === 'single-layer-medium-nearest-layer'
|
|
786
|
+
? 'nearest-layer'
|
|
787
|
+
: recordMode === 'single-layer-medium-color'
|
|
788
|
+
? 'color'
|
|
789
|
+
: undefined,
|
|
790
|
+
options?.transparentDepthWrite ?? false,
|
|
659
791
|
);
|
|
660
792
|
};
|
|
661
793
|
if (c.profilePhase === undefined) {
|
|
@@ -676,7 +808,10 @@ export function recordMainPass(
|
|
|
676
808
|
hint: 'publish the current frame view/light/shadow bind group before GPU raster',
|
|
677
809
|
});
|
|
678
810
|
}
|
|
679
|
-
if (
|
|
811
|
+
if (
|
|
812
|
+
gpuDrivenStandardPbrFrameResources === undefined ||
|
|
813
|
+
gpuDrivenStandardPbrFrameResources.materialBindGroups.length === 0
|
|
814
|
+
) {
|
|
680
815
|
throw new RhiError({
|
|
681
816
|
code: 'rhi-not-available',
|
|
682
817
|
expected: 'complete main-pass Standard PBR material bind-group receipt',
|
|
@@ -688,6 +823,8 @@ export function recordMainPass(
|
|
|
688
823
|
pass,
|
|
689
824
|
options.gpuDriven.resources,
|
|
690
825
|
gpuDrivenStandardPbrFrameResources,
|
|
826
|
+
options.gpuDrivenFilter,
|
|
827
|
+
options?.fragmentEntryPoint,
|
|
691
828
|
);
|
|
692
829
|
}
|
|
693
830
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { getRenderFeaturePlanExecutionProjection } from '../features/host';
|
|
2
|
+
import type { RenderFeaturePlannedFrame } from '../features/plan';
|
|
3
|
+
import type { MotionBlurExecutionPass, MotionBlurExecutionReceipt } from '../inspection-types';
|
|
4
|
+
import type { RenderFrameState } from './frame-snapshot';
|
|
5
|
+
import type { RenderSystemInternals } from './render-context';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Project one accepted Motion Blur compute execution from the same graph and
|
|
9
|
+
* resolved dispatch objects used by the encoder. A plan/capability candidate
|
|
10
|
+
* without both executed passes deliberately returns no receipt.
|
|
11
|
+
*/
|
|
12
|
+
export function deriveMotionBlurExecutionReceipt(
|
|
13
|
+
internals: RenderSystemInternals,
|
|
14
|
+
frameState: RenderFrameState,
|
|
15
|
+
plans: readonly RenderFeaturePlannedFrame[],
|
|
16
|
+
): MotionBlurExecutionReceipt | undefined {
|
|
17
|
+
const graph = frameState.compiledFrameGraph;
|
|
18
|
+
const deviceGeneration = internals.deviceScope?.generation;
|
|
19
|
+
if (graph === null || deviceGeneration === undefined) return undefined;
|
|
20
|
+
const info = graph.inspect();
|
|
21
|
+
const graphPasses = new Map(info.passes.map((pass) => [pass.name, pass]));
|
|
22
|
+
const summaryGraphPass = graphPasses.get('motion-blur-tile-summary');
|
|
23
|
+
const reconstructGraphPass = graphPasses.get('motion-blur');
|
|
24
|
+
if (summaryGraphPass?.kind !== 'compute' || reconstructGraphPass?.kind !== 'compute') {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const planned = plans.find((candidate) => candidate.featureIdentity === 'forgeax.motion-blur');
|
|
28
|
+
const execution =
|
|
29
|
+
planned === undefined ? undefined : getRenderFeaturePlanExecutionProjection(planned);
|
|
30
|
+
if (execution === undefined || execution.featureIdentity !== 'forgeax.motion-blur') {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const executionPass = (name: 'motion-blur-tile-summary' | 'motion-blur') =>
|
|
34
|
+
execution.passes.find((pass) => pass.name === name);
|
|
35
|
+
const summary = executionPass('motion-blur-tile-summary');
|
|
36
|
+
const reconstruct = executionPass('motion-blur');
|
|
37
|
+
if (
|
|
38
|
+
summary?.gpuCompute === undefined ||
|
|
39
|
+
reconstruct?.gpuCompute === undefined ||
|
|
40
|
+
summary.resolvedGpuCompute === undefined ||
|
|
41
|
+
reconstruct.resolvedGpuCompute === undefined
|
|
42
|
+
) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
const directWorkgroups = (
|
|
46
|
+
pass: NonNullable<typeof summary.resolvedGpuCompute>,
|
|
47
|
+
): readonly [number, number, number] | undefined => {
|
|
48
|
+
const dispatch = pass.dispatches[0];
|
|
49
|
+
if (dispatch === undefined || !('workgroups' in dispatch)) return undefined;
|
|
50
|
+
return dispatch.workgroups;
|
|
51
|
+
};
|
|
52
|
+
const summaryWorkgroups = directWorkgroups(summary.resolvedGpuCompute);
|
|
53
|
+
const reconstructWorkgroups = directWorkgroups(reconstruct.resolvedGpuCompute);
|
|
54
|
+
if (summaryWorkgroups === undefined || reconstructWorkgroups === undefined) return undefined;
|
|
55
|
+
const outputResource = info.resources.find(
|
|
56
|
+
(resource) =>
|
|
57
|
+
resource.label === 'motion-blurred-color' ||
|
|
58
|
+
reconstructGraphPass.accesses.some(
|
|
59
|
+
(access) => access.resource === resource.label && access.usage === 'storage-write',
|
|
60
|
+
),
|
|
61
|
+
);
|
|
62
|
+
if (
|
|
63
|
+
outputResource?.descriptor.kind !== 'texture' ||
|
|
64
|
+
outputResource.descriptor.format !== 'rgba16float'
|
|
65
|
+
) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
const summaryReceipt: MotionBlurExecutionPass = {
|
|
69
|
+
name: 'motion-blur-tile-summary',
|
|
70
|
+
kind: 'compute',
|
|
71
|
+
entryPoint: 'tile_summary',
|
|
72
|
+
workgroups: summaryWorkgroups,
|
|
73
|
+
};
|
|
74
|
+
const reconstructReceipt: MotionBlurExecutionPass = {
|
|
75
|
+
name: 'motion-blur',
|
|
76
|
+
kind: 'compute',
|
|
77
|
+
entryPoint: 'reconstruct',
|
|
78
|
+
workgroups: reconstructWorkgroups,
|
|
79
|
+
};
|
|
80
|
+
return Object.freeze({
|
|
81
|
+
frameId: frameState.frameNumber,
|
|
82
|
+
deviceGeneration,
|
|
83
|
+
// RenderGraphBuilder generations are process-global. The renderer's
|
|
84
|
+
// frame-state generation is the identity used by inspection and by the
|
|
85
|
+
// same-frame admission check below, so retain that owner-scoped value.
|
|
86
|
+
graphGeneration: frameState.graphGeneration,
|
|
87
|
+
program: 'motion-blur-compute' as const,
|
|
88
|
+
outputFormat: 'rgba16float' as const,
|
|
89
|
+
passes: [summaryReceipt, reconstructReceipt] as const,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { resolveAssetHandle } from '@forgeax/engine-assets-runtime';
|
|
2
|
-
import type { World } from '@forgeax/engine-ecs';
|
|
3
2
|
import type { BindGroupEntry, BindGroupLayout, Buffer } from '@forgeax/engine-rhi';
|
|
4
3
|
import { err, ok } from '@forgeax/engine-rhi';
|
|
5
4
|
import {
|
|
@@ -14,6 +13,8 @@ import { transmissionBackdropAvailable } from '../assembly/device-feature-admiss
|
|
|
14
13
|
import { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from '../gpu-usage';
|
|
15
14
|
import type { SkylightBindGroupResources } from '../ibl/skylight-bind-group';
|
|
16
15
|
import { assembleMaterialWithSkylightEntries } from '../ibl/skylight-bind-group';
|
|
16
|
+
import type { RenderResourceScope } from '../publication/resource-scope';
|
|
17
|
+
import { renderAssetByGuid } from '../publication/resource-scope';
|
|
17
18
|
import {
|
|
18
19
|
applyParamSchemaDefaultsToUbo,
|
|
19
20
|
applyParamSnapshotToUbo,
|
|
@@ -28,7 +29,7 @@ export type PreparedResolverCaches = {
|
|
|
28
29
|
readonly preparedGroup0Pipelines: WeakSet<object>;
|
|
29
30
|
readonly preparedViewOnlyPipelines: WeakSet<object>;
|
|
30
31
|
readonly preparedRenderMaterialPipelines: WeakSet<object>;
|
|
31
|
-
readonly preparedAssetHandles: WeakMap<
|
|
32
|
+
readonly preparedAssetHandles: WeakMap<RenderResourceScope, Map<string, number>>;
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
export function createPreparedResolverCaches(): PreparedResolverCaches {
|
|
@@ -45,7 +46,7 @@ export function createPreparedResolverCaches(): PreparedResolverCaches {
|
|
|
45
46
|
function preparedHandle<Brand extends string>(
|
|
46
47
|
runtime: RenderSystemInternals,
|
|
47
48
|
caches: PreparedResolverCaches,
|
|
48
|
-
world:
|
|
49
|
+
world: RenderResourceScope,
|
|
49
50
|
guid: string,
|
|
50
51
|
brand: Brand,
|
|
51
52
|
): Handle<Brand, 'shared'> | undefined {
|
|
@@ -57,6 +58,8 @@ function preparedHandle<Brand extends string>(
|
|
|
57
58
|
const key = `${brand}:${guid.toLowerCase()}`;
|
|
58
59
|
const cached = handles.get(key);
|
|
59
60
|
if (cached !== undefined) return cached as Handle<Brand, 'shared'>;
|
|
61
|
+
if ('resolveAsset' in world)
|
|
62
|
+
return world.handleForGuid(guid) as Handle<Brand, 'shared'> | undefined;
|
|
60
63
|
const asset = runtime.assets.lookup(guid);
|
|
61
64
|
if (asset === undefined) return undefined;
|
|
62
65
|
const handle = world.allocSharedRef(brand, asset);
|
|
@@ -67,7 +70,7 @@ function preparedHandle<Brand extends string>(
|
|
|
67
70
|
export function preparedMaterialBindings(
|
|
68
71
|
runtime: RenderSystemInternals,
|
|
69
72
|
caches: PreparedResolverCaches,
|
|
70
|
-
worlds: readonly
|
|
73
|
+
worlds: readonly RenderResourceScope[],
|
|
71
74
|
materialShaderId: string,
|
|
72
75
|
worldIndex: number,
|
|
73
76
|
materialGuid: string,
|
|
@@ -75,7 +78,10 @@ export function preparedMaterialBindings(
|
|
|
75
78
|
skylightResources?: SkylightBindGroupResources,
|
|
76
79
|
) {
|
|
77
80
|
const world = worlds[worldIndex];
|
|
78
|
-
const material =
|
|
81
|
+
const material =
|
|
82
|
+
world === undefined
|
|
83
|
+
? undefined
|
|
84
|
+
: renderAssetByGuid<MaterialAsset>(world, runtime.assets, materialGuid);
|
|
79
85
|
const pipelineState = runtime.getPipelineState();
|
|
80
86
|
if (world === undefined || material?.kind !== 'material' || pipelineState === null) {
|
|
81
87
|
return err(new Error('prepared material asset is unavailable'));
|
|
@@ -203,7 +209,6 @@ export function preparedMaterialBindings(
|
|
|
203
209
|
prefilterView: fallback.prefilterView,
|
|
204
210
|
prefilterSampler: fallback.sampler,
|
|
205
211
|
brdfLutView: fallback.brdfLutView,
|
|
206
|
-
brdfLutSampler: fallback.sampler,
|
|
207
212
|
intensityBuffer: fallback.intensityBuffer,
|
|
208
213
|
},
|
|
209
214
|
transmissionBackdropAvailable(runtime.device.limits.maxSampledTexturesPerShaderStage)
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import type { Buffer, RhiDevice } from '@forgeax/engine-rhi';
|
|
2
|
+
import { GpuBuffer } from '../gpu-resource';
|
|
3
|
+
import {
|
|
4
|
+
GPU_BUFFER_USAGE_COPY_DST,
|
|
5
|
+
GPU_BUFFER_USAGE_STORAGE,
|
|
6
|
+
GPU_BUFFER_USAGE_UNIFORM,
|
|
7
|
+
} from '../gpu-usage';
|
|
8
|
+
import type { ProbeBlendBufferProjection } from '../scene/probe-blend';
|
|
9
|
+
import {
|
|
10
|
+
PROBE_BLEND_RECORD_STRIDE,
|
|
11
|
+
type ProbeBlendRecord,
|
|
12
|
+
probeBlendRecordOffset,
|
|
13
|
+
} from '../scene/probe-blend-record';
|
|
14
|
+
import type { RenderFrameState } from './frame-snapshot';
|
|
15
|
+
|
|
16
|
+
export interface ProbeBlendBufferRecord {
|
|
17
|
+
readonly cacheKey: number;
|
|
18
|
+
readonly record: ProbeBlendRecord;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function isProbeBlendProjection(
|
|
22
|
+
input: ProbeBlendBufferProjection | readonly ProbeBlendBufferRecord[],
|
|
23
|
+
): input is ProbeBlendBufferProjection {
|
|
24
|
+
return !Array.isArray(input);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function retireProbeBlendRecordBuffer(buffer: GpuBuffer): void {
|
|
28
|
+
const destroy = (): void => {
|
|
29
|
+
if (!buffer.isDestroyed) void buffer.destroy();
|
|
30
|
+
};
|
|
31
|
+
void buffer.device.queue.onSubmittedWorkDone().then(destroy, destroy);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function createCompleteProbeBlendBuffer(
|
|
35
|
+
device: RhiDevice,
|
|
36
|
+
requiredCapacity: number,
|
|
37
|
+
records: readonly ProbeBlendBufferRecord[],
|
|
38
|
+
): {
|
|
39
|
+
readonly buffer: GpuBuffer;
|
|
40
|
+
readonly cache: ReadonlyMap<number, { readonly generation: number; readonly bytes: Uint8Array }>;
|
|
41
|
+
} {
|
|
42
|
+
const created = device.createBuffer({
|
|
43
|
+
label: 'probe-blend-records',
|
|
44
|
+
size: requiredCapacity * PROBE_BLEND_RECORD_STRIDE,
|
|
45
|
+
usage:
|
|
46
|
+
(device.caps.storageBuffer ? GPU_BUFFER_USAGE_STORAGE : GPU_BUFFER_USAGE_UNIFORM) |
|
|
47
|
+
GPU_BUFFER_USAGE_COPY_DST,
|
|
48
|
+
mappedAtCreation: false,
|
|
49
|
+
});
|
|
50
|
+
if (!created.ok) throw created.error;
|
|
51
|
+
const candidate = new GpuBuffer(device, created.value);
|
|
52
|
+
const cache = new Map<number, { readonly generation: number; readonly bytes: Uint8Array }>();
|
|
53
|
+
try {
|
|
54
|
+
for (const { cacheKey, record } of records) {
|
|
55
|
+
const uploaded = device.queue.writeBuffer(
|
|
56
|
+
candidate.handle,
|
|
57
|
+
probeBlendRecordOffset(record.objectKey),
|
|
58
|
+
record.bytes,
|
|
59
|
+
);
|
|
60
|
+
if (!uploaded.ok) throw uploaded.error;
|
|
61
|
+
cache.set(cacheKey, {
|
|
62
|
+
generation: record.generation,
|
|
63
|
+
bytes: new Uint8Array(record.bytes),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
} catch (cause) {
|
|
67
|
+
void candidate.destroy();
|
|
68
|
+
throw cause;
|
|
69
|
+
}
|
|
70
|
+
return { buffer: candidate, cache };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Retain one device buffer for direct and scene-index ProbeBlend consumers.
|
|
75
|
+
* Capacity is settled before any upload so a growth cannot erase records
|
|
76
|
+
* written earlier in the same frame. Slot zero remains the producer sentinel;
|
|
77
|
+
* RenderScene object slot N occupies aligned record N+1.
|
|
78
|
+
*/
|
|
79
|
+
export function ensureProbeBlendRecordBuffer(
|
|
80
|
+
device: RhiDevice,
|
|
81
|
+
frameState: Pick<
|
|
82
|
+
RenderFrameState,
|
|
83
|
+
| 'probeBlendRecordBuffer'
|
|
84
|
+
| 'probeBlendRecordBufferCapacity'
|
|
85
|
+
| 'probeBlendBuffers'
|
|
86
|
+
| 'probeBlendRecordProjection'
|
|
87
|
+
>,
|
|
88
|
+
input: ProbeBlendBufferProjection | readonly ProbeBlendBufferRecord[] | undefined,
|
|
89
|
+
): Buffer | undefined {
|
|
90
|
+
const projection = input !== undefined && isProbeBlendProjection(input) ? input : undefined;
|
|
91
|
+
const records: readonly ProbeBlendBufferRecord[] =
|
|
92
|
+
input === undefined
|
|
93
|
+
? []
|
|
94
|
+
: (projection?.records ?? (input as readonly ProbeBlendBufferRecord[]));
|
|
95
|
+
let buffer = frameState.probeBlendRecordBuffer;
|
|
96
|
+
const accepted = frameState.probeBlendRecordProjection;
|
|
97
|
+
if (
|
|
98
|
+
projection !== undefined &&
|
|
99
|
+
accepted?.projection === projection &&
|
|
100
|
+
accepted.device === device
|
|
101
|
+
) {
|
|
102
|
+
if (records.length === 0) return undefined;
|
|
103
|
+
if (accepted.buffer === buffer && buffer !== undefined && !buffer.isDestroyed) {
|
|
104
|
+
return buffer.handle;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (records.length === 0) {
|
|
108
|
+
if (projection !== undefined) {
|
|
109
|
+
frameState.probeBlendBuffers.clear();
|
|
110
|
+
frameState.probeBlendRecordProjection = {
|
|
111
|
+
projection,
|
|
112
|
+
device,
|
|
113
|
+
buffer: undefined,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
const requiredCapacity =
|
|
119
|
+
projection?.capacity ??
|
|
120
|
+
records.reduce((capacity, { record }) => Math.max(capacity, record.objectKey + 2), 1);
|
|
121
|
+
const grows =
|
|
122
|
+
buffer === undefined ||
|
|
123
|
+
buffer.isDestroyed ||
|
|
124
|
+
buffer.device !== device ||
|
|
125
|
+
frameState.probeBlendRecordBufferCapacity < requiredCapacity;
|
|
126
|
+
const hasAcceptedBaseline =
|
|
127
|
+
projection !== undefined &&
|
|
128
|
+
accepted !== undefined &&
|
|
129
|
+
accepted.device === device &&
|
|
130
|
+
accepted.buffer === buffer &&
|
|
131
|
+
buffer !== undefined &&
|
|
132
|
+
!buffer.isDestroyed &&
|
|
133
|
+
accepted.projection.sourceIdentity === projection.sourceIdentity &&
|
|
134
|
+
accepted.projection.revision === projection.baseRevision;
|
|
135
|
+
const requiresCompletePublish =
|
|
136
|
+
grows ||
|
|
137
|
+
(projection !== undefined && (!hasAcceptedBaseline || projection.dirtyRecords.length > 1));
|
|
138
|
+
if (requiresCompletePublish) {
|
|
139
|
+
const candidate = createCompleteProbeBlendBuffer(device, requiredCapacity, records);
|
|
140
|
+
const previous = buffer;
|
|
141
|
+
buffer = candidate.buffer;
|
|
142
|
+
frameState.probeBlendRecordBuffer = candidate.buffer;
|
|
143
|
+
frameState.probeBlendRecordBufferCapacity = requiredCapacity;
|
|
144
|
+
frameState.probeBlendBuffers.clear();
|
|
145
|
+
for (const [key, value] of candidate.cache) frameState.probeBlendBuffers.set(key, value);
|
|
146
|
+
if (projection === undefined) delete frameState.probeBlendRecordProjection;
|
|
147
|
+
else frameState.probeBlendRecordProjection = { projection, device, buffer: candidate.buffer };
|
|
148
|
+
if (previous !== undefined) retireProbeBlendRecordBuffer(previous);
|
|
149
|
+
return candidate.buffer.handle;
|
|
150
|
+
}
|
|
151
|
+
if (buffer === undefined) return undefined;
|
|
152
|
+
const changed = projection?.dirtyRecords ?? records;
|
|
153
|
+
const cacheUpdates: [number, { readonly generation: number; readonly bytes: Uint8Array }][] = [];
|
|
154
|
+
for (const { cacheKey, record } of changed) {
|
|
155
|
+
const cached = frameState.probeBlendBuffers.get(cacheKey);
|
|
156
|
+
const unchanged =
|
|
157
|
+
cached !== undefined &&
|
|
158
|
+
cached.generation === record.generation &&
|
|
159
|
+
cached.bytes.length === record.bytes.length &&
|
|
160
|
+
cached.bytes.every((value, index) => value === record.bytes[index]);
|
|
161
|
+
if (unchanged) continue;
|
|
162
|
+
const uploaded = device.queue.writeBuffer(
|
|
163
|
+
buffer.handle,
|
|
164
|
+
probeBlendRecordOffset(record.objectKey),
|
|
165
|
+
record.bytes,
|
|
166
|
+
);
|
|
167
|
+
if (!uploaded.ok) throw uploaded.error;
|
|
168
|
+
cacheUpdates.push([
|
|
169
|
+
cacheKey,
|
|
170
|
+
{ generation: record.generation, bytes: new Uint8Array(record.bytes) },
|
|
171
|
+
]);
|
|
172
|
+
}
|
|
173
|
+
for (const [cacheKey, value] of cacheUpdates) frameState.probeBlendBuffers.set(cacheKey, value);
|
|
174
|
+
for (const cacheKey of projection?.removedCacheKeys ?? []) {
|
|
175
|
+
frameState.probeBlendBuffers.delete(cacheKey);
|
|
176
|
+
}
|
|
177
|
+
if (projection === undefined) delete frameState.probeBlendRecordProjection;
|
|
178
|
+
else frameState.probeBlendRecordProjection = { projection, device, buffer };
|
|
179
|
+
return buffer.handle;
|
|
180
|
+
}
|