@forgeax/engine-render 0.1.29 → 0.1.31
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 +248 -21
- package/dist/assembly/atmosphere-shader-prewarm.d.ts +1 -1
- package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -1
- package/dist/assembly/device-feature-admission.d.ts +4 -3
- package/dist/assembly/device-feature-admission.d.ts.map +1 -1
- package/dist/assembly/dynamic-geometry-host.d.ts +6 -0
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +6 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts +26 -3
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/pipeline-helpers.d.ts +24 -0
- package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -0
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
- package/dist/assembly/recovery/recovery-attempt.d.ts +1 -6
- package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts +1 -0
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/shader-prewarm-policy.d.ts +1 -1
- package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready.d.ts +1 -1
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/capture/scene-projection.d.ts +41 -0
- package/dist/capture/scene-projection.d.ts.map +1 -0
- package/dist/{chunk-BQVQOQJH.mjs → chunk-7MQ3XBSP.mjs} +20 -14
- package/dist/chunk-7MQ3XBSP.mjs.map +1 -0
- package/dist/{chunk-S4DNKQYQ.mjs → chunk-C3DDSXYK.mjs} +86 -33
- package/dist/chunk-C3DDSXYK.mjs.map +1 -0
- package/dist/{chunk-BTWH7BP4.mjs → chunk-FUUO4UND.mjs} +73 -29
- package/dist/chunk-FUUO4UND.mjs.map +1 -0
- package/dist/{chunk-NRNXBLIJ.mjs → chunk-JRBDO2KB.mjs} +46 -6
- package/dist/chunk-JRBDO2KB.mjs.map +1 -0
- package/dist/{chunk-NICXSHAT.mjs → chunk-MDQJPY3T.mjs} +8 -6
- package/dist/chunk-MDQJPY3T.mjs.map +1 -0
- package/dist/{chunk-JQTSEI3Z.mjs → chunk-NO4WZCAH.mjs} +3 -3
- package/dist/chunk-NO4WZCAH.mjs.map +1 -0
- package/dist/{chunk-FUODTTIA.mjs → chunk-PSEQ6QPH.mjs} +621 -108
- package/dist/chunk-PSEQ6QPH.mjs.map +1 -0
- package/dist/{chunk-33XZFTQU.mjs → chunk-S5UE2T5P.mjs} +48 -6
- package/dist/chunk-S5UE2T5P.mjs.map +1 -0
- package/dist/components/directional-light.d.ts +2 -2
- package/dist/components/dynamic-resolution.d.ts +15 -0
- package/dist/components/dynamic-resolution.d.ts.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/reflection-probe.d.ts +1 -0
- package/dist/components/reflection-probe.d.ts.map +1 -1
- package/dist/components/skylight.d.ts +4 -1
- package/dist/components/skylight.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +2172 -796
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/device-scope.d.ts +2 -0
- package/dist/device/device-scope.d.ts.map +1 -1
- package/dist/device/gpu-residency.d.ts +2 -2
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/dynamic-geometry.d.ts.map +1 -1
- package/dist/environment/background.d.ts +3 -2
- package/dist/environment/background.d.ts.map +1 -1
- package/dist/environment/ibl.d.ts +11 -0
- package/dist/environment/ibl.d.ts.map +1 -0
- package/dist/environment/storage.d.ts +14 -0
- package/dist/environment/storage.d.ts.map +1 -0
- package/dist/errors/gpu-driven.d.ts +2 -2
- package/dist/errors/gpu-driven.d.ts.map +1 -1
- package/dist/errors/render.d.ts +35 -1
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +7 -0
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/extract/gpu-driven.d.ts +18 -1
- package/dist/extract/gpu-driven.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/material-artifacts.d.ts +24 -0
- package/dist/gpu-driven/material-artifacts.d.ts.map +1 -0
- package/dist/gpu-driven/material-bindings.d.ts +7 -0
- package/dist/gpu-driven/material-bindings.d.ts.map +1 -0
- package/dist/gpu-driven/prepared-draw.d.ts +2 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +27 -6
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-resource.d.ts +5 -2
- package/dist/gpu-resource.d.ts.map +1 -1
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +3 -0
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +2 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +3 -1
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +83 -81
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +7 -5
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +16 -1
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/internal.mjs +6 -6
- package/dist/material-row.d.ts +10 -0
- package/dist/material-row.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +3 -1
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/render-extent.d.ts +51 -0
- package/dist/pipeline/render-extent.d.ts.map +1 -0
- package/dist/pipeline/standard-build-context.d.ts +7 -0
- package/dist/pipeline/standard-build-context.d.ts.map +1 -0
- package/dist/pipeline/standard-forward-lane.d.ts +3 -2
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +2 -1
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +3 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/post-process-errors.d.ts +9 -2
- package/dist/post-process-errors.d.ts.map +1 -1
- package/dist/prepare/extended-lighting/resources.d.ts +3 -3
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +3 -8
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts +3 -2
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +7 -2
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +6 -3
- package/dist/record/main-pass-material.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/prepared-material-bindings.d.ts.map +1 -1
- package/dist/record/recovery-pipeline.d.ts +9 -1
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +34 -3
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +2 -2
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +5 -2
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/reflection/background.d.ts +14 -0
- package/dist/reflection/background.d.ts.map +1 -0
- package/dist/reflection/filter.d.ts.map +1 -1
- package/dist/reflection/projection.d.ts +1 -0
- package/dist/reflection/projection.d.ts.map +1 -1
- package/dist/reflection/record-owner.d.ts +4 -2
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +47 -32
- 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 +17 -1
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +9 -2
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +29 -2
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +2 -0
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/ssao-config.d.ts +8 -6
- package/dist/ssao-config.d.ts.map +1 -1
- package/dist/ssr/graph.d.ts.map +1 -1
- package/dist/temporal/gpu.d.ts.map +1 -1
- package/dist/temporal/index.mjs +5 -5
- package/dist/temporal/standard-scene-data.d.ts +2 -1
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/target-coverage-attachment.d.ts +15 -0
- package/dist/temporal/target-coverage-attachment.d.ts.map +1 -0
- package/dist/temporal/temporal-view.d.ts +6 -2
- package/dist/temporal/temporal-view.d.ts.map +1 -1
- package/dist/temporal/view.d.ts +6 -0
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/typed-render-graph-primitives.d.ts +6 -0
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/component.d.ts +1 -0
- package/dist/volume/component.d.ts.map +1 -1
- package/package.json +21 -21
- package/src/__tests__/capture-scene-projection.unit.test.ts +24 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +15 -24
- package/src/__tests__/device-loss-fanout.unit.test.ts +43 -0
- package/src/__tests__/dynamic-geometry-batch.unit.test.ts +157 -0
- package/src/__tests__/dynamic-geometry.unit.test.ts +36 -0
- package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +81 -0
- package/src/__tests__/factory-contract.integration.test.ts +164 -1
- package/src/__tests__/frame-observation.contract.test.ts +21 -0
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +1 -1
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +20 -1
- package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +0 -3
- package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +0 -3
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +11 -6
- package/src/__tests__/gpu-driven-production.integration.test.ts +13 -25
- package/src/__tests__/gpu-driven-view.unit.test.ts +1 -0
- package/src/__tests__/gpu-pass-timing-browser-runner.ts +15 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +14 -1
- package/src/__tests__/gpu-resource-scope.unit.test.ts +71 -0
- package/src/__tests__/gpu-scene.unit.test.ts +55 -1
- package/src/__tests__/materials-standard-contract.unit.test.ts +5 -1
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +8 -0
- package/src/__tests__/morph-neutral-admission.unit.test.ts +19 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +6 -1
- package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -5
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +216 -5
- package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +68 -1
- package/src/__tests__/reflection-probe-authoring.unit.test.ts +12 -10
- package/src/__tests__/reflection-probe-box.dawn.test.ts +71 -0
- package/src/__tests__/reflection-probe-filter.unit.test.ts +9 -0
- package/src/__tests__/reflection-probe-orientation.dawn.test.ts +294 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +5 -15
- package/src/__tests__/reflection-probe-updates.unit.test.ts +129 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +3 -0
- package/src/__tests__/render-error-detail-ssot.test-d.ts +5 -1
- package/src/__tests__/render-extent.unit.test.ts +63 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +3 -2
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +173 -9
- package/src/__tests__/shader-manifest-fixture.ts +6 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +8 -1
- package/src/__tests__/specular-environment-scale.dawn.test.ts +4 -2
- package/src/__tests__/ssao-config.unit.test.ts +7 -0
- package/src/__tests__/ssao-surface.dawn.test.ts +252 -0
- package/src/__tests__/ssr-cube-silhouette.dawn.test.ts +270 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +51 -43
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +4 -0
- package/src/__tests__/ssr-gpu-dispatch.ts +10 -5
- package/src/__tests__/ssr-graph-topology.unit.test.ts +2 -2
- package/src/__tests__/ssr-hiz.browser.test.ts +1 -1
- package/src/__tests__/ssr-hiz.dawn.test.ts +1 -1
- package/src/__tests__/ssr-spatial.integration.test.ts +1 -1
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +40 -0
- package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +238 -1
- package/src/__tests__/standard-profile-oracle.unit.test.ts +27 -0
- package/src/__tests__/taa-coverage-edge.dawn.test.ts +6 -0
- package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +5 -1
- package/src/__tests__/taa-stability-feedback.ts +1 -0
- package/src/__tests__/temporal-reset-matrix.unit.test.ts +2 -2
- package/src/__tests__/temporal-view.unit.test.ts +17 -0
- package/src/__tests__/transmission-prewarm.unit.test.ts +57 -0
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +62 -13
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +7 -7
- package/src/assembly/atmosphere-shader-prewarm.ts +3 -2
- package/src/assembly/device-feature-admission.ts +9 -4
- package/src/assembly/dynamic-geometry-host.ts +236 -163
- package/src/assembly/host-contract.ts +9 -0
- package/src/assembly/material/assembly.ts +350 -6
- package/src/assembly/material/pipeline-helpers.ts +100 -0
- package/src/assembly/material-shader-policy.ts +39 -18
- package/src/assembly/recovery/device-loss-fanout.ts +5 -0
- package/src/assembly/recovery/recovery-attempt.ts +2 -29
- package/src/assembly/recovery/renderer-recover.ts +6 -9
- package/src/assembly/renderer-facade.ts +22 -1
- package/src/assembly/shader-prewarm-policy.ts +14 -1
- package/src/assembly/webgpu-ready.ts +28 -19
- package/src/assembly/webgpu-renderer.ts +95 -95
- package/src/capture/scene-projection.ts +37 -0
- package/src/components/__tests__/dynamic-resolution-schema.unit.test.ts +65 -0
- package/src/components/__tests__/light-radius.integration.test.ts +59 -0
- package/src/components/directional-light.ts +3 -3
- package/src/components/dynamic-resolution.ts +67 -0
- package/src/components/index.ts +1 -0
- package/src/components/light-helpers.ts +6 -1
- package/src/components/reflection-probe.ts +1 -0
- package/src/components/skylight.ts +4 -1
- package/src/device/device-scope.ts +13 -7
- package/src/device/gpu-residency.ts +11 -11
- package/src/dynamic-geometry.ts +13 -8
- package/src/environment/background.ts +30 -12
- package/src/environment/ibl.ts +211 -0
- package/src/environment/storage.ts +63 -0
- package/src/errors/gpu-driven.ts +10 -3
- package/src/errors/render.ts +64 -0
- package/src/extract/camera.ts +12 -1
- package/src/extract/contracts.ts +10 -0
- package/src/extract/gpu-driven.ts +72 -17
- package/src/gpu-driven/batch-topology.ts +33 -11
- package/src/gpu-driven/material-artifacts.ts +179 -0
- package/src/gpu-driven/material-bindings.ts +41 -0
- package/src/gpu-driven/prepared-draw.ts +13 -2
- package/src/gpu-driven/production-raster.ts +681 -164
- package/src/gpu-resource.ts +21 -2
- package/src/gpu-scene-schema.ts +11 -2
- package/src/gpu-scene.ts +14 -3
- package/src/hdrp-buffers.ts +69 -0
- package/src/ibl/IblPipelineCache.ts +5 -0
- package/src/ibl/skylight-bind-group.ts +27 -17
- package/src/index.ts +92 -81
- package/src/inspection-types.ts +16 -1
- package/src/material-row.ts +60 -11
- package/src/pbr-pipeline.ts +13 -2
- package/src/pipeline/render-extent.ts +111 -0
- package/src/pipeline/standard-build-context.ts +7 -0
- package/src/pipeline/standard-forward-lane.ts +41 -24
- package/src/pipeline/standard-pipeline.ts +47 -18
- package/src/pipeline/standard-post.ts +4 -0
- package/src/pipeline/standard-profile.ts +2 -1
- package/src/pipeline-builder.ts +12 -3
- package/src/plugin.ts +4 -0
- package/src/post-process-errors.ts +26 -18
- package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +2 -2
- package/src/prepare/extended-lighting/resources.ts +3 -3
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +68 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +45 -0
- package/src/record/__tests__/material-slot-plan.unit.test.ts +9 -0
- package/src/record/__tests__/recovery-pipeline.unit.test.ts +47 -1
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +7 -3
- package/src/record/__tests__/temporal-payload.unit.test.ts +2 -0
- package/src/record/frame-lighting.ts +3 -1
- package/src/record/frame-snapshot.ts +13 -11
- package/src/record/frame.ts +150 -74
- package/src/record/main-pass-geometry.ts +60 -9
- package/src/record/main-pass-material.ts +47 -19
- package/src/record/main-pass.ts +63 -4
- package/src/record/prepared-material-bindings.ts +4 -0
- package/src/record/recovery-pipeline.ts +56 -0
- package/src/record/render-context.ts +34 -3
- package/src/record/shadow-pass.ts +187 -50
- package/src/record/typed-frame-graph.ts +60 -3
- package/src/record/view-ubo.ts +1 -1
- package/src/recovery/render-system-candidate.ts +54 -11
- package/src/reflection/background.ts +151 -0
- package/src/reflection/filter.ts +3 -0
- package/src/reflection/projection.ts +16 -6
- package/src/reflection/record-owner.ts +282 -86
- package/src/render-contract.ts +50 -32
- package/src/render-graph-primitives.ts +28 -3
- package/src/render-pipeline.ts +20 -1
- package/src/render-system-extract-tail.ts +23 -3
- package/src/render-system-extract.ts +127 -42
- package/src/render-system.ts +35 -7
- package/src/scene/render-scene.ts +8 -0
- package/src/ssao-config.ts +25 -8
- package/src/ssr/graph.ts +78 -58
- package/src/temporal/gpu.ts +5 -0
- package/src/temporal/standard-scene-data.ts +7 -1
- package/src/temporal/target-coverage-attachment.ts +72 -0
- package/src/temporal/temporal-view.ts +10 -4
- package/src/temporal/view.ts +12 -2
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +24 -9
- package/src/typed-render-graph-primitives.ts +38 -0
- package/src/volume/component.ts +1 -0
- package/src/volume/passes.ts +3 -3
- package/dist/chunk-33XZFTQU.mjs.map +0 -1
- package/dist/chunk-BQVQOQJH.mjs.map +0 -1
- package/dist/chunk-BTWH7BP4.mjs.map +0 -1
- package/dist/chunk-FUODTTIA.mjs.map +0 -1
- package/dist/chunk-JQTSEI3Z.mjs.map +0 -1
- package/dist/chunk-NICXSHAT.mjs.map +0 -1
- package/dist/chunk-NRNXBLIJ.mjs.map +0 -1
- package/dist/chunk-S4DNKQYQ.mjs.map +0 -1
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type RhiRenderPassEncoder,
|
|
10
10
|
} from '@forgeax/engine-rhi';
|
|
11
11
|
import type { MaterialRenderState, PassSelector } from '@forgeax/engine-types';
|
|
12
|
+
import { transmissionBackdropAvailable } from '../assembly/device-feature-admission';
|
|
12
13
|
import { gpuDrivenShadowDrawKey } from '../extract/gpu-driven';
|
|
13
14
|
import type { SubmissionPlan } from '../gpu-driven/batch-topology';
|
|
14
15
|
import type { GpuDrivenShadowBatchProjection } from '../gpu-driven/production-raster';
|
|
@@ -50,7 +51,9 @@ import {
|
|
|
50
51
|
prepareMaterialSkylight,
|
|
51
52
|
} from './main-pass-material';
|
|
52
53
|
import {
|
|
54
|
+
findFromChain,
|
|
53
55
|
getOrCreateFromChain,
|
|
56
|
+
getOrCreateFromChainResult,
|
|
54
57
|
INSTANCE_UBO_FULL_ARRAY_BYTES,
|
|
55
58
|
MAX_UNIFORM_INSTANCES,
|
|
56
59
|
MESH_PER_ENTITY_STRIDE,
|
|
@@ -77,8 +80,8 @@ export interface GpuDrivenShadowBatch {
|
|
|
77
80
|
readonly meshBindGroup: BindGroup;
|
|
78
81
|
readonly visibleBindGroup: BindGroup;
|
|
79
82
|
readonly deformation: 'rigid' | 'skin';
|
|
80
|
-
/**
|
|
81
|
-
readonly
|
|
83
|
+
/** Complete binding for this batch, including opaque batches after custom casters. */
|
|
84
|
+
readonly materialGroup: BindGroup;
|
|
82
85
|
readonly vertexBuffer: Buffer;
|
|
83
86
|
readonly indexBuffer?: Buffer | undefined;
|
|
84
87
|
readonly indexFormat?: 'uint16' | 'uint32' | undefined;
|
|
@@ -459,12 +462,7 @@ export function recordGpuDrivenShadowIndirect(
|
|
|
459
462
|
pass.setVertexBuffer(0, raster.vertexBuffer);
|
|
460
463
|
currentVertex = raster.vertexBuffer;
|
|
461
464
|
}
|
|
462
|
-
|
|
463
|
-
// Alpha-mask shadow variants sample the receipt-owned base-color
|
|
464
|
-
// texture. Opaque batches keep the pass-level singleton bound by the
|
|
465
|
-
// caller, so group(1) remains one stable layout for every draw.
|
|
466
|
-
pass.setBindGroup(1, raster.alphaMaskMaterialGroup, [0]);
|
|
467
|
-
}
|
|
465
|
+
pass.setBindGroup(1, raster.materialGroup, [0]);
|
|
468
466
|
if (raster.indexBuffer !== undefined) {
|
|
469
467
|
if (raster.indexFormat === undefined) {
|
|
470
468
|
throw new RhiError({
|
|
@@ -637,12 +635,22 @@ function validateShadowOwnership(
|
|
|
637
635
|
const overlap = [...claimed].filter((key) => recordedKeys.has(key));
|
|
638
636
|
const union = new Set([...claimed, ...recordedKeys]);
|
|
639
637
|
const missing = [...expectedKeys].filter((key) => !union.has(key));
|
|
640
|
-
const
|
|
641
|
-
|
|
638
|
+
const unexpectedClaims = [...claimed].filter((key) => !expectedKeys.has(key));
|
|
639
|
+
// `shadowCasterMembership` describes the concrete draws that the GPU
|
|
640
|
+
// producer is eligible to claim. A renderable that stays on the CPU lane
|
|
641
|
+
// (for example a clustered frame without a compatible GPU-driven PBR
|
|
642
|
+
// variant, or a dynamic mesh whose producer receipt is not ready) still
|
|
643
|
+
// records a valid ShadowCaster draw, but it has no membership row. Treating
|
|
644
|
+
// every CPU-only key as an "extra" made the ownership check reject that
|
|
645
|
+
// legitimate residual path and stopped the whole shadow pass. Ownership
|
|
646
|
+
// needs two invariants here: a draw is never both GPU-claimed and CPU-
|
|
647
|
+
// recorded, and every GPU-eligible membership is covered by one of those
|
|
648
|
+
// lanes. CPU-only residuals are already owned by the record path.
|
|
649
|
+
if (overlap.length === 0 && missing.length === 0 && unexpectedClaims.length === 0) return;
|
|
642
650
|
throw new RhiError({
|
|
643
651
|
code: 'internal-error',
|
|
644
652
|
expected: `disjoint ShadowCaster ownership for ${shadowViewIdentityKey(identity)}`,
|
|
645
|
-
hint: `claimed=${[...claimed].sort().join(',')} recorded=${[...recordedKeys].sort().join(',')} missing=${missing.sort().join(',')}
|
|
653
|
+
hint: `claimed=${[...claimed].sort().join(',')} recorded=${[...recordedKeys].sort().join(',')} missing=${missing.sort().join(',')} unexpectedClaims=${unexpectedClaims.sort().join(',')}`,
|
|
646
654
|
});
|
|
647
655
|
}
|
|
648
656
|
|
|
@@ -698,18 +706,35 @@ function recordGpuDrivenShadowIfPublished(
|
|
|
698
706
|
hint: 'keep shadow batch scene rows aligned with the shared SubmissionPlan',
|
|
699
707
|
});
|
|
700
708
|
}
|
|
709
|
+
const shadowArtifact = projection.shadowArtifact;
|
|
710
|
+
const shadowReceipt = shadowArtifact.receipt;
|
|
711
|
+
if (shadowReceipt === undefined) {
|
|
712
|
+
throw new RhiError({
|
|
713
|
+
code: 'rhi-not-available',
|
|
714
|
+
expected: `published shadow MaterialProgramAbi for batch ${batch.batchId}`,
|
|
715
|
+
hint: 'keep the shadow draw out of the capable lane until its producer receipt is ready',
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
const shadowVariantSet =
|
|
719
|
+
shadowArtifact.variantSet ??
|
|
720
|
+
(shadowArtifact.material === SHADOW_CASTER_SHADER_ID
|
|
721
|
+
? shadowCasterVariantSet(
|
|
722
|
+
c.runtime.device.caps.storageBuffer,
|
|
723
|
+
projection.deformation === 'skin',
|
|
724
|
+
true,
|
|
725
|
+
batch.key.admission === 'alpha-mask',
|
|
726
|
+
projection.vertexColorAvailable,
|
|
727
|
+
)
|
|
728
|
+
: undefined);
|
|
701
729
|
const pipeline = c.runtime.getMaterialShaderPipeline?.(
|
|
702
|
-
|
|
730
|
+
// A scene-index shadow artifact may retain the logical material id for
|
|
731
|
+
// batching while its specialization key owns the actual WGSL module.
|
|
732
|
+
shadowArtifact.specializationKey ?? shadowArtifact.material,
|
|
703
733
|
false,
|
|
704
734
|
shadowRasterState(undefined, identity.kind === 'point'),
|
|
705
735
|
batch.key.topology,
|
|
706
736
|
batch.key.drawKind === 'indexed' ? projection.mesh.indexFormat : undefined,
|
|
707
|
-
|
|
708
|
-
c.runtime.device.caps.storageBuffer,
|
|
709
|
-
projection.deformation === 'skin',
|
|
710
|
-
true,
|
|
711
|
-
batch.key.admission === 'alpha-mask',
|
|
712
|
-
),
|
|
737
|
+
shadowVariantSet,
|
|
713
738
|
'shadow-caster',
|
|
714
739
|
undefined,
|
|
715
740
|
undefined,
|
|
@@ -718,9 +743,15 @@ function recordGpuDrivenShadowIfPublished(
|
|
|
718
743
|
undefined,
|
|
719
744
|
undefined,
|
|
720
745
|
projection.mesh.layoutProjection,
|
|
721
|
-
|
|
746
|
+
// The shadow projection carries the producer-validated receipt. Select
|
|
747
|
+
// the immediate module adapter so a newly loaded custom Surface cannot
|
|
748
|
+
// lose its first capable shadow draw to async pre-bake warm-up.
|
|
749
|
+
'immediate',
|
|
722
750
|
projection.deformation === 'skin' ? 'gpu-driven-skin' : 'gpu-driven-pbr',
|
|
723
|
-
|
|
751
|
+
shadowReceipt.sceneIndexEntry,
|
|
752
|
+
undefined,
|
|
753
|
+
projection.shadowVertexEntry,
|
|
754
|
+
projection.shadowFragmentEntry,
|
|
724
755
|
);
|
|
725
756
|
if (pipeline === null || pipeline === undefined) {
|
|
726
757
|
throw new RhiError({
|
|
@@ -736,14 +767,25 @@ function recordGpuDrivenShadowIfPublished(
|
|
|
736
767
|
hint: 'keep the geometry residency and topology draw kind aligned before capable recording',
|
|
737
768
|
});
|
|
738
769
|
}
|
|
770
|
+
const materialGroup =
|
|
771
|
+
shadowArtifact.material !== SHADOW_CASTER_SHADER_ID
|
|
772
|
+
? ensureGpuDrivenCustomShadowMaterialBg(c, projection)
|
|
773
|
+
: batch.key.admission === 'alpha-mask'
|
|
774
|
+
? ensureGpuDrivenAlphaMaskMaterialBg(c, projection)
|
|
775
|
+
: ensureSpotShadowMaterialBg(c);
|
|
776
|
+
if (materialGroup === null) {
|
|
777
|
+
throw new RhiError({
|
|
778
|
+
code: 'rhi-not-available',
|
|
779
|
+
expected: 'material resources for every GPU shadow batch',
|
|
780
|
+
hint: 'publish the shadow material binding before recording the indirect batch',
|
|
781
|
+
});
|
|
782
|
+
}
|
|
739
783
|
batches.set(batch.batchId, {
|
|
740
784
|
pipeline,
|
|
741
785
|
meshBindGroup: projection.meshBindGroup,
|
|
742
786
|
visibleBindGroup: projection.visibleBindGroup,
|
|
743
787
|
deformation: projection.deformation,
|
|
744
|
-
|
|
745
|
-
? { alphaMaskMaterialGroup: ensureGpuDrivenAlphaMaskMaterialBg(c, projection) }
|
|
746
|
-
: {}),
|
|
788
|
+
materialGroup,
|
|
747
789
|
vertexBuffer: projection.mesh.vertexBuffer.handle,
|
|
748
790
|
...(batch.key.drawKind === 'indexed' && projection.mesh.indexBuffer !== null
|
|
749
791
|
? {
|
|
@@ -1627,6 +1669,9 @@ export function recordShadowCasterDraws(
|
|
|
1627
1669
|
skinned,
|
|
1628
1670
|
false,
|
|
1629
1671
|
Number(shadowDispatch?.paramSnapshot?.alphaCutoff ?? 0) > 0,
|
|
1672
|
+
entry.mesh.layoutProjection.attributes.some(
|
|
1673
|
+
(attribute) => attribute.key === 'color',
|
|
1674
|
+
),
|
|
1630
1675
|
),
|
|
1631
1676
|
'shadow-caster',
|
|
1632
1677
|
undefined, // meshAttributes
|
|
@@ -1733,15 +1778,31 @@ export function recordShadowCasterDraws(
|
|
|
1733
1778
|
/**
|
|
1734
1779
|
* Build (or reuse) the neutral `shadow-material-singleton` @group(1) BG for
|
|
1735
1780
|
* default casters without an authored material dispatch. Authored opaque and
|
|
1736
|
-
* masked residuals bind their own prepared material slots instead.
|
|
1737
|
-
*
|
|
1738
|
-
*
|
|
1781
|
+
* masked residuals bind their own prepared material slots instead. Directional,
|
|
1782
|
+
* point, and spot passes share bindings only while every resource identity
|
|
1783
|
+
* matches; scene-table growth or recovery must create a fresh bind group.
|
|
1739
1784
|
*/
|
|
1740
1785
|
function ensureSpotShadowMaterialBg(c: _InternalRenderPipelineContext): BindGroup | null {
|
|
1741
1786
|
const { runtime, frameState, pipelineState } = c;
|
|
1742
|
-
const cached = frameState.singletonMaterialCache.get('shadow-material-singleton');
|
|
1743
|
-
if (cached !== undefined) return cached;
|
|
1744
1787
|
const fb = pipelineState.skylightFallback;
|
|
1788
|
+
const sceneMaterialBuffer =
|
|
1789
|
+
c.gpuDrivenStandardPbrFrameResources?.sceneMaterialBuffer ??
|
|
1790
|
+
pipelineState.meshStorageBuffer.buffer;
|
|
1791
|
+
const handles = [
|
|
1792
|
+
pipelineState.materialBindGroupLayout,
|
|
1793
|
+
pipelineState.materialUniformBuffer.buffer,
|
|
1794
|
+
pipelineState.defaultSampler,
|
|
1795
|
+
pipelineState.defaultNormalTextureView,
|
|
1796
|
+
pipelineState.fallbackTextureView,
|
|
1797
|
+
sceneMaterialBuffer,
|
|
1798
|
+
...(fb === null ? [] : [fb]),
|
|
1799
|
+
];
|
|
1800
|
+
const cached = findFromChain(
|
|
1801
|
+
frameState.shadowMaterialBindGroups,
|
|
1802
|
+
handles,
|
|
1803
|
+
'shadow-material-singleton',
|
|
1804
|
+
);
|
|
1805
|
+
if (cached !== undefined) return cached;
|
|
1745
1806
|
const fallbackEntries: BindGroupEntry[] = buildPbrMaterialUserRegionEntries().map((entry) => {
|
|
1746
1807
|
if (entry.buffer !== undefined) {
|
|
1747
1808
|
return {
|
|
@@ -1775,15 +1836,21 @@ function ensureSpotShadowMaterialBg(c: _InternalRenderPipelineContext): BindGrou
|
|
|
1775
1836
|
});
|
|
1776
1837
|
const merged =
|
|
1777
1838
|
fb !== null
|
|
1778
|
-
? assembleMaterialWithSkylightEntries(
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1839
|
+
? assembleMaterialWithSkylightEntries(
|
|
1840
|
+
fallbackEntries,
|
|
1841
|
+
{
|
|
1842
|
+
irradianceView: fb.irradianceView,
|
|
1843
|
+
irradianceSampler: fb.sampler,
|
|
1844
|
+
prefilterView: fb.prefilterView,
|
|
1845
|
+
prefilterSampler: fb.sampler,
|
|
1846
|
+
brdfLutView: fb.brdfLutView,
|
|
1847
|
+
brdfLutSampler: fb.sampler,
|
|
1848
|
+
intensityBuffer: fb.intensityBuffer,
|
|
1849
|
+
},
|
|
1850
|
+
transmissionBackdropAvailable(runtime.device.limits.maxSampledTexturesPerShaderStage)
|
|
1851
|
+
? undefined
|
|
1852
|
+
: null,
|
|
1853
|
+
)
|
|
1787
1854
|
: fallbackEntries;
|
|
1788
1855
|
// Binding(46) is the optional scene-material storage table. The material
|
|
1789
1856
|
// BGL intentionally omits it on the uniform-only WebGL2 lane, so emitting
|
|
@@ -1793,26 +1860,37 @@ function ensureSpotShadowMaterialBg(c: _InternalRenderPipelineContext): BindGrou
|
|
|
1793
1860
|
// admission; this singleton only needs the optional slot when that same
|
|
1794
1861
|
// capability is present.
|
|
1795
1862
|
if (runtime.device.caps.storageBuffer) {
|
|
1863
|
+
// Scene-index shadow variants read MaterialParameters by the projected
|
|
1864
|
+
// row selected in visibleItems. The legacy singleton used the mesh SSBO
|
|
1865
|
+
// here because the old shadow vertex path never consumed binding(46); on
|
|
1866
|
+
// the capable scene-index lane that buffer is a different struct and can
|
|
1867
|
+
// make the alpha/depth fragment discard every caster. Reuse the frame's
|
|
1868
|
+
// producer-owned scene material table, with the mesh buffer only for
|
|
1869
|
+
// direct/legacy callers that do not publish one.
|
|
1796
1870
|
merged.push({
|
|
1797
1871
|
binding: 46,
|
|
1798
1872
|
resource: {
|
|
1799
1873
|
kind: 'buffer',
|
|
1800
|
-
value: { buffer:
|
|
1874
|
+
value: { buffer: sceneMaterialBuffer },
|
|
1801
1875
|
},
|
|
1802
1876
|
});
|
|
1803
1877
|
}
|
|
1804
|
-
const r =
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1878
|
+
const r = getOrCreateFromChainResult(
|
|
1879
|
+
frameState.shadowMaterialBindGroups,
|
|
1880
|
+
handles,
|
|
1881
|
+
'shadow-material-singleton',
|
|
1882
|
+
() =>
|
|
1883
|
+
runtime.device.createBindGroup({
|
|
1884
|
+
label: 'shadow-material-bg',
|
|
1885
|
+
layout: pipelineState.materialBindGroupLayout,
|
|
1886
|
+
entries: merged,
|
|
1887
|
+
}),
|
|
1888
|
+
c.bindGroupCounts,
|
|
1889
|
+
);
|
|
1809
1890
|
if (!r.ok) {
|
|
1810
1891
|
runtime.errorRegistry.fire(r.error);
|
|
1811
1892
|
return null;
|
|
1812
1893
|
}
|
|
1813
|
-
c.bindGroupCounts.createBindGroup += 1;
|
|
1814
|
-
c.bindGroupCounts.keys.push('shadow-material-singleton');
|
|
1815
|
-
frameState.singletonMaterialCache.set('shadow-material-singleton', r.value);
|
|
1816
1894
|
return r.value;
|
|
1817
1895
|
}
|
|
1818
1896
|
|
|
@@ -1834,9 +1912,6 @@ function ensureGpuDrivenAlphaMaskMaterialBg(
|
|
|
1834
1912
|
hint: 'publish the receipt-derived scene material table before the capable shadow pass',
|
|
1835
1913
|
});
|
|
1836
1914
|
}
|
|
1837
|
-
const materialKey = `shadow-material-alpha:${projection.materialEntityKey}:${projection.material.materialHandle ?? -1}:${c.store.materialResourceEpoch}`;
|
|
1838
|
-
const cached = c.frameState.singletonMaterialCache.get(materialKey);
|
|
1839
|
-
if (cached !== undefined) return cached;
|
|
1840
1915
|
const fallback = c.pipelineState.skylightFallback;
|
|
1841
1916
|
if (fallback === null) {
|
|
1842
1917
|
throw new RhiError({
|
|
@@ -1874,6 +1949,68 @@ function ensureGpuDrivenAlphaMaskMaterialBg(
|
|
|
1874
1949
|
projection.materialEntityKey,
|
|
1875
1950
|
c.world,
|
|
1876
1951
|
);
|
|
1877
|
-
|
|
1952
|
+
return bindGroup;
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
/**
|
|
1956
|
+
* Build the group(1) binding for a receipt-backed custom shadow program. The
|
|
1957
|
+
* ordinary shadow singleton is Standard-only; binding it for a custom layout
|
|
1958
|
+
* would make the pipeline appear executable while deferring a BGL mismatch to
|
|
1959
|
+
* submit. Custom resources therefore use the same material producer as the
|
|
1960
|
+
* main pass, using the selected scene-index row when the published custom ABI
|
|
1961
|
+
* declares that resource. No Standard-only alpha or shader rows are
|
|
1962
|
+
* synthesized for the custom artifact.
|
|
1963
|
+
*/
|
|
1964
|
+
function ensureGpuDrivenCustomShadowMaterialBg(
|
|
1965
|
+
c: _InternalRenderPipelineContext,
|
|
1966
|
+
projection: GpuDrivenShadowBatchProjection,
|
|
1967
|
+
): BindGroup {
|
|
1968
|
+
const shaderId = projection.shadowArtifact.material;
|
|
1969
|
+
const fallback = c.pipelineState.skylightFallback;
|
|
1970
|
+
if (fallback === null) {
|
|
1971
|
+
throw new RhiError({
|
|
1972
|
+
code: 'rhi-not-available',
|
|
1973
|
+
expected: 'skylight resources for custom shadow material binding',
|
|
1974
|
+
hint: 'publish the custom material resource owner before recording the shadow lane',
|
|
1975
|
+
});
|
|
1976
|
+
}
|
|
1977
|
+
const sceneMaterialBuffer = c.gpuDrivenStandardPbrFrameResources?.sceneMaterialBuffer;
|
|
1978
|
+
if (sceneMaterialBuffer === undefined) {
|
|
1979
|
+
throw new RhiError({
|
|
1980
|
+
code: 'rhi-not-available',
|
|
1981
|
+
expected: 'producer-owned scene material buffer for custom shadow ABI',
|
|
1982
|
+
hint: 'publish the selected shadow MaterialProgramAbi scene-index resource before recording',
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
const skylightResources = {
|
|
1986
|
+
irradianceView: fallback.irradianceView,
|
|
1987
|
+
irradianceSampler: fallback.sampler,
|
|
1988
|
+
prefilterView: fallback.prefilterView,
|
|
1989
|
+
prefilterSampler: fallback.sampler,
|
|
1990
|
+
brdfLutView: fallback.brdfLutView,
|
|
1991
|
+
brdfLutSampler: fallback.sampler,
|
|
1992
|
+
intensityBuffer: fallback.intensityBuffer,
|
|
1993
|
+
} satisfies import('../ibl/skylight-bind-group').SkylightBindGroupResources;
|
|
1994
|
+
const deps: PerSubmeshMaterialBgDeps = {
|
|
1995
|
+
runtime: c.runtime,
|
|
1996
|
+
pipelineState: c.pipelineState,
|
|
1997
|
+
world: c.world,
|
|
1998
|
+
store: c.store,
|
|
1999
|
+
materialSlice: STANDARD_PBR_UBO_SIZE,
|
|
2000
|
+
videoHighPerfAvailable: false,
|
|
2001
|
+
skylightResources,
|
|
2002
|
+
materialBgShared: c.frameState.materialBgShared,
|
|
2003
|
+
materialBgAssemblyCache: c.materialBgAssemblyCache,
|
|
2004
|
+
bindGroupCounts: c.bindGroupCounts,
|
|
2005
|
+
frameState: c.frameState,
|
|
2006
|
+
sceneMaterialBuffer,
|
|
2007
|
+
};
|
|
2008
|
+
const bindGroup = buildPerSubmeshMaterialBg(
|
|
2009
|
+
deps,
|
|
2010
|
+
projection.material,
|
|
2011
|
+
projection.materialEntityKey,
|
|
2012
|
+
c.world,
|
|
2013
|
+
shaderId,
|
|
2014
|
+
);
|
|
1878
2015
|
return bindGroup;
|
|
1879
2016
|
}
|
|
@@ -61,6 +61,7 @@ import {
|
|
|
61
61
|
import { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from '../gpu-usage';
|
|
62
62
|
import { createStandardSurfaceLightingBindGroup } from '../hdrp-buffers';
|
|
63
63
|
import type { RenderFeatureGraphInspection } from '../inspection-types';
|
|
64
|
+
import type { RenderExtent } from '../pipeline/render-extent';
|
|
64
65
|
import {
|
|
65
66
|
type StandardTopologyInputValue,
|
|
66
67
|
standardLightingTopologySignature,
|
|
@@ -76,6 +77,7 @@ import {
|
|
|
76
77
|
resetStandardLutState,
|
|
77
78
|
} from '../pipeline/standard-output/lut-state';
|
|
78
79
|
import { resolveVolumetricFogProfile, STANDARD_PIPELINE_ID } from '../pipeline/standard-profile';
|
|
80
|
+
import { type ProbeBackgroundResources, recordProbeBackground } from '../reflection/background';
|
|
79
81
|
import type { CameraSnapshot } from '../render-contract';
|
|
80
82
|
import type {
|
|
81
83
|
RenderPipelineFeatureTarget,
|
|
@@ -99,6 +101,7 @@ import {
|
|
|
99
101
|
temporalWriteIndex,
|
|
100
102
|
} from '../temporal/gpu';
|
|
101
103
|
import { isSceneDataTarget } from '../temporal/scene-data';
|
|
104
|
+
import { createTargetCoverageAttachment } from '../temporal/target-coverage-attachment';
|
|
102
105
|
import type { TransmissionDemand } from '../transmission/projection';
|
|
103
106
|
import { hasVolumetricFogCapability } from '../volume/capability';
|
|
104
107
|
import { deriveVolumetricFogExtent, deriveVolumetricFogResolvedExtent } from '../volume/resources';
|
|
@@ -491,6 +494,7 @@ export interface ReflectionProbeFilterGraphState {
|
|
|
491
494
|
}
|
|
492
495
|
|
|
493
496
|
export interface ReflectionProbeGraphWork {
|
|
497
|
+
readonly background?: ProbeBackgroundResources;
|
|
494
498
|
readonly probeIndex: number;
|
|
495
499
|
readonly rawTexture: Texture;
|
|
496
500
|
readonly rawCubeView: TextureView;
|
|
@@ -716,6 +720,7 @@ function addCubeCaptureGraphPasses(
|
|
|
716
720
|
export function addReflectionProbeGraphPasses(
|
|
717
721
|
builder: RenderGraphBuilder<RenderPipelineFrame>,
|
|
718
722
|
state: ReflectionProbeGraphState,
|
|
723
|
+
environmentCube?: import('../environment/ibl').GraphEnvironment,
|
|
719
724
|
): Result<readonly import('@forgeax/engine-render-graph').GraphAccess[], RenderGraphError> {
|
|
720
725
|
const accesses: import('@forgeax/engine-render-graph').GraphAccess[] = [];
|
|
721
726
|
for (const work of state.work) {
|
|
@@ -801,6 +806,11 @@ export function addReflectionProbeGraphPasses(
|
|
|
801
806
|
if (!depth.ok) return depth;
|
|
802
807
|
const added = builder.addRasterPass(`reflection-probe.${work.probeIndex}.capture.${face}`, {
|
|
803
808
|
accesses: [
|
|
809
|
+
...(environmentCube === undefined
|
|
810
|
+
? []
|
|
811
|
+
: [environmentCube.sky, environmentCube.irradiance, environmentCube.prefilter].map(
|
|
812
|
+
(resource) => ({ resource, usage: 'sampled-read' as const }),
|
|
813
|
+
)),
|
|
804
814
|
{ resource: view.value, usage: 'color-attachment' },
|
|
805
815
|
{ resource: depth.value, usage: 'depth-stencil-write' },
|
|
806
816
|
],
|
|
@@ -828,9 +838,35 @@ export function addReflectionProbeGraphPasses(
|
|
|
828
838
|
if (!captureColor.ok || !captureDepth.ok) return;
|
|
829
839
|
if (work.faceCamera === undefined || work.viewBindGroupDynamicOffset === undefined)
|
|
830
840
|
return;
|
|
841
|
+
recordProbeBackground(
|
|
842
|
+
work.background,
|
|
843
|
+
internal,
|
|
844
|
+
work.faceCamera,
|
|
845
|
+
pass,
|
|
846
|
+
environmentCube === undefined
|
|
847
|
+
? undefined
|
|
848
|
+
: resources.textureView(environmentCube.sky).unwrap(),
|
|
849
|
+
);
|
|
850
|
+
const captureContext = {
|
|
851
|
+
...internal,
|
|
852
|
+
...(environmentCube === undefined
|
|
853
|
+
? {}
|
|
854
|
+
: {
|
|
855
|
+
environmentIbl: {
|
|
856
|
+
irradiance: resources.textureView(environmentCube.irradiance).unwrap(),
|
|
857
|
+
prefilter: resources.textureView(environmentCube.prefilter).unwrap(),
|
|
858
|
+
},
|
|
859
|
+
}),
|
|
860
|
+
};
|
|
861
|
+
delete captureContext.reflectionProbes;
|
|
862
|
+
delete captureContext.hdrpSsaoBlurredView;
|
|
863
|
+
delete captureContext.gpuDrivenDrawKeys;
|
|
864
|
+
delete captureContext.gpuDrivenStandardPbrFrameResources;
|
|
831
865
|
encodeMainPass(
|
|
832
866
|
{
|
|
833
|
-
...
|
|
867
|
+
...captureContext,
|
|
868
|
+
dispatch: internal.captureDispatch ?? internal.dispatch,
|
|
869
|
+
foldDispatchPlan: null,
|
|
834
870
|
camera: work.faceCamera,
|
|
835
871
|
viewBindGroupDynamicOffset: work.viewBindGroupDynamicOffset,
|
|
836
872
|
geometryColorView: captureColor.value,
|
|
@@ -1325,6 +1361,7 @@ function topologyOf(
|
|
|
1325
1361
|
volumetricFog: ExtractedVolumetricFog | undefined,
|
|
1326
1362
|
standardLighting: StandardTopologyInputValue | undefined,
|
|
1327
1363
|
ssr: SsrSpatialAdmission | undefined,
|
|
1364
|
+
renderExtent: RenderExtent | undefined,
|
|
1328
1365
|
): Result<RenderPipelineTopology, RhiError> {
|
|
1329
1366
|
const cascadeCount = Math.max(1, Math.min(4, Math.round(lights.cascadeCount ?? 1))) as
|
|
1330
1367
|
| 1
|
|
@@ -1389,6 +1426,7 @@ function topologyOf(
|
|
|
1389
1426
|
clearOnly,
|
|
1390
1427
|
reflectionFallback: { enabled: frameState.reflectionFallbackDemand === true },
|
|
1391
1428
|
ssr,
|
|
1429
|
+
...(renderExtent === undefined ? {} : { extent: renderExtent }),
|
|
1392
1430
|
surface: {
|
|
1393
1431
|
width,
|
|
1394
1432
|
height,
|
|
@@ -1748,6 +1786,7 @@ export function ensureCompiledFrameGraph(
|
|
|
1748
1786
|
standardLighting?: StandardTopologyInputValue,
|
|
1749
1787
|
onRecoveryError?: (error: unknown) => void,
|
|
1750
1788
|
ssr?: SsrSpatialAdmission,
|
|
1789
|
+
renderExtent?: RenderExtent,
|
|
1751
1790
|
): CompiledRenderGraph<RenderPipelineFrame> | null {
|
|
1752
1791
|
const featureMetrics = mutableFeatureGraphInspection(internals);
|
|
1753
1792
|
featureMetrics.ensureCalls += 1;
|
|
@@ -1800,6 +1839,7 @@ export function ensureCompiledFrameGraph(
|
|
|
1800
1839
|
volumetricFog,
|
|
1801
1840
|
standardLighting,
|
|
1802
1841
|
ssr,
|
|
1842
|
+
renderExtent,
|
|
1803
1843
|
);
|
|
1804
1844
|
if (!topologyResult.ok) {
|
|
1805
1845
|
featureMetrics.buildFailures += 1;
|
|
@@ -1972,6 +2012,16 @@ export function ensureCompiledFrameGraph(
|
|
|
1972
2012
|
return lastKnownGood();
|
|
1973
2013
|
}
|
|
1974
2014
|
const taaHistory = camera.antialias === 'taa' ? importTemporalHistoryTargets(builder) : undefined;
|
|
2015
|
+
const targetCoverage =
|
|
2016
|
+
camera.dynamicResolution === undefined || topology.extent === undefined
|
|
2017
|
+
? undefined
|
|
2018
|
+
: createTargetCoverageAttachment(builder, topology.extent);
|
|
2019
|
+
if (targetCoverage !== undefined && !targetCoverage.ok) {
|
|
2020
|
+
internals.errorRegistry.fire(targetCoverage.error);
|
|
2021
|
+
featureGraphCandidate?.onRejected?.();
|
|
2022
|
+
discardPendingStandardOutput();
|
|
2023
|
+
return lastKnownGood();
|
|
2024
|
+
}
|
|
1975
2025
|
const ssrHistory = ssr?.status === 'admitted' ? importSsrHistoryTargets(builder) : undefined;
|
|
1976
2026
|
let projectedFeatures = false;
|
|
1977
2027
|
const featureProjection = createRenderFeatureProjectionState();
|
|
@@ -2006,6 +2056,7 @@ export function ensureCompiledFrameGraph(
|
|
|
2006
2056
|
capabilities: { rgba16floatRenderable: internals.device.caps.rgba16floatRenderable },
|
|
2007
2057
|
...(occlusion === undefined ? {} : { occlusion }),
|
|
2008
2058
|
...(taaHistory === undefined ? {} : { taaHistory }),
|
|
2059
|
+
...(targetCoverage?.ok === true ? { targetCoverage: targetCoverage.value } : {}),
|
|
2009
2060
|
...(ssrHistory === undefined ? {} : { ssrHistory }),
|
|
2010
2061
|
encodeTransmissionMip: ({ pass, resources, source }) => {
|
|
2011
2062
|
const sourceView = resources.textureView(source);
|
|
@@ -2016,7 +2067,12 @@ export function ensureCompiledFrameGraph(
|
|
|
2016
2067
|
projectGpuDriven: (target) => {
|
|
2017
2068
|
if (projectedGpuDriven || gpuDriven === undefined) return ok(undefined);
|
|
2018
2069
|
projectedGpuDriven = true;
|
|
2019
|
-
return gpuDriven.project(
|
|
2070
|
+
return gpuDriven.project(
|
|
2071
|
+
builder,
|
|
2072
|
+
target.format,
|
|
2073
|
+
target.sampleCount,
|
|
2074
|
+
target.additionalColorFormats,
|
|
2075
|
+
);
|
|
2020
2076
|
},
|
|
2021
2077
|
...(gpuDriven?.projectShadow === undefined
|
|
2022
2078
|
? {}
|
|
@@ -2069,10 +2125,11 @@ export function ensureCompiledFrameGraph(
|
|
|
2069
2125
|
});
|
|
2070
2126
|
return projected.ok ? ok(undefined) : projected;
|
|
2071
2127
|
},
|
|
2072
|
-
contributeCubeCaptures: () => {
|
|
2128
|
+
contributeCubeCaptures: (environmentCube) => {
|
|
2073
2129
|
const reflectionProbes = addReflectionProbeGraphPasses(
|
|
2074
2130
|
builder,
|
|
2075
2131
|
cubeCaptureState?.reflectionProbes ?? { work: [] },
|
|
2132
|
+
environmentCube,
|
|
2076
2133
|
);
|
|
2077
2134
|
if (!reflectionProbes.ok) return reflectionProbes;
|
|
2078
2135
|
return cubeCaptureState === undefined
|
package/src/record/view-ubo.ts
CHANGED
|
@@ -244,7 +244,7 @@ export function writeViewUbo(
|
|
|
244
244
|
// accepted quality union occupies the existing four-float tail [128..131].
|
|
245
245
|
// Point and Spot pcfKernelSize stay in their own snapshot paths and never
|
|
246
246
|
// enter this Directional View projection.
|
|
247
|
-
viewPayload[126] = lights.depthBias ?? 0.
|
|
247
|
+
viewPayload[126] = lights.depthBias ?? 0.00001;
|
|
248
248
|
viewPayload[127] = lights.normalBias ?? 0.05;
|
|
249
249
|
const filterCarrier = directionalShadowFilterCarrier(lights.directionalShadowQuality);
|
|
250
250
|
viewPayload[128] = filterCarrier[0] ?? 0;
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
type PostProcessShaderEntry,
|
|
28
28
|
postProcessShaderEntrySignature,
|
|
29
29
|
} from '../fullscreen-post-process-pass';
|
|
30
|
+
import { collectGpuDrivenMaterialArtifacts } from '../gpu-driven/material-artifacts';
|
|
30
31
|
import { GpuDrivenProduction } from '../gpu-driven/production-raster';
|
|
31
32
|
import { inspectStandardLighting } from '../pipeline/standard-lighting/inspection';
|
|
32
33
|
import { retireAutoExposureGpuResources } from '../pipeline/standard-output/auto-exposure/gpu';
|
|
@@ -52,7 +53,11 @@ import {
|
|
|
52
53
|
type RenderFeatureGraphCandidate,
|
|
53
54
|
} from '../record/typed-frame-graph';
|
|
54
55
|
import { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID } from '../render-contract';
|
|
55
|
-
import type {
|
|
56
|
+
import type {
|
|
57
|
+
ExtractedFrame,
|
|
58
|
+
MaterialSnapshot,
|
|
59
|
+
RenderableSnapshot,
|
|
60
|
+
} from '../render-system-extract';
|
|
56
61
|
import type { PersistentGpuDrivenCandidate, PersistentRenderScene } from '../scene/render-scene';
|
|
57
62
|
import { SHADOW_ATLAS_DEFAULT_LAYERS } from '../shadow-atlas';
|
|
58
63
|
import { createTemporalFrameTransaction } from '../temporal/frame';
|
|
@@ -271,7 +276,7 @@ export function createRenderSystemRecovery(
|
|
|
271
276
|
instancesBgShared: new WeakMap(),
|
|
272
277
|
materialBgShared: new Map(),
|
|
273
278
|
materialBgAssemblyCache: new Map(),
|
|
274
|
-
|
|
279
|
+
shadowMaterialBindGroups: new WeakMap(),
|
|
275
280
|
postProcessBgCache: new WeakMap(),
|
|
276
281
|
probeBlendBuffers: new Map(),
|
|
277
282
|
probeBlendRecordBufferCapacity: 0,
|
|
@@ -280,7 +285,11 @@ export function createRenderSystemRecovery(
|
|
|
280
285
|
};
|
|
281
286
|
|
|
282
287
|
const publishRecoveryGraphCandidate = (candidate: RecoveryGraphCandidate): void => {
|
|
283
|
-
candidate.recoveryReadiness.
|
|
288
|
+
if (candidate.recoveryReadiness.assertFirstRecoveryFrame) {
|
|
289
|
+
candidate.recoveryReadiness.assertFirstRecoveryFrame();
|
|
290
|
+
} else {
|
|
291
|
+
candidate.recoveryReadiness.assertPreparedCache();
|
|
292
|
+
}
|
|
284
293
|
const previousFeatureHost = internals.featureHost;
|
|
285
294
|
// The caller enters this method only after the active generation swap and
|
|
286
295
|
// after resetForRecover() has shed every lost-device owner. Replace the
|
|
@@ -445,11 +454,40 @@ export function createRenderSystemRecovery(
|
|
|
445
454
|
runtime.internals.device,
|
|
446
455
|
gpuDrivenShaderFactory,
|
|
447
456
|
);
|
|
448
|
-
const
|
|
449
|
-
|
|
457
|
+
const shadowProjection = persistentRenderScene.shadowCasterProjection();
|
|
458
|
+
// The retained scene owns prepared draw receipts. The extraction seed
|
|
459
|
+
// precedes GPU admission and must not stand in for that projection.
|
|
460
|
+
const preparedSnapshots = new Map(
|
|
461
|
+
candidateGpuDrivenScene.state.slots.map((slot) => [
|
|
462
|
+
`${slot.snapshot.worldId}:${slot.snapshot.entityKey}`,
|
|
463
|
+
slot.snapshot,
|
|
464
|
+
]),
|
|
450
465
|
);
|
|
451
|
-
const
|
|
452
|
-
|
|
466
|
+
const artifactRows = (renderables: readonly RenderableSnapshot[]) =>
|
|
467
|
+
renderables.map((source, renderableIndex) => ({
|
|
468
|
+
source: {
|
|
469
|
+
...source,
|
|
470
|
+
gpuDrivenDraws:
|
|
471
|
+
preparedSnapshots.get(`${source.worldId}:${source.entityKey}`)?.gpuDrivenDraws ??
|
|
472
|
+
source.gpuDrivenDraws ??
|
|
473
|
+
[],
|
|
474
|
+
},
|
|
475
|
+
renderableIndex,
|
|
476
|
+
}));
|
|
477
|
+
const { materialArtifacts, shadowMaterialArtifacts, firstArtifact, firstSkinArtifact } =
|
|
478
|
+
collectGpuDrivenMaterialArtifacts({
|
|
479
|
+
rows: artifactRows(seed.frame.renderables),
|
|
480
|
+
shadowRows: artifactRows(shadowProjection?.renderables ?? []),
|
|
481
|
+
dispatch: seed.frame.dispatch,
|
|
482
|
+
shadowDispatch: shadowProjection?.dispatch ?? seed.frame.dispatch,
|
|
483
|
+
resolve: runtime.internals.getMaterialShaderArtifact,
|
|
484
|
+
clustered:
|
|
485
|
+
seed.frame.lights.point.length +
|
|
486
|
+
seed.frame.lights.spot.length +
|
|
487
|
+
seed.frame.lights.rect.length >
|
|
488
|
+
0 || candidateFrameState.installedPipelineConfig?.ssao?.enabled === true,
|
|
489
|
+
reflectionFallback: candidateFrameState.reflectionFallbackDemand === true,
|
|
490
|
+
});
|
|
453
491
|
const prepared = candidateGpuDrivenProduction.prepare({
|
|
454
492
|
scene: candidateGpuDrivenScene.state,
|
|
455
493
|
camera,
|
|
@@ -461,10 +499,15 @@ export function createRenderSystemRecovery(
|
|
|
461
499
|
),
|
|
462
500
|
viewBindGroupLayout: runtime.pipelineState.viewBindGroupLayout,
|
|
463
501
|
meshResidencyEpoch: runtime.internals.gpuStore.meshResidencyEpoch,
|
|
464
|
-
|
|
465
|
-
...(
|
|
466
|
-
...(
|
|
467
|
-
|
|
502
|
+
|
|
503
|
+
...(firstArtifact === undefined ? {} : { materialArtifact: firstArtifact }),
|
|
504
|
+
...(firstSkinArtifact === undefined ? {} : { materialSkinArtifact: firstSkinArtifact }),
|
|
505
|
+
...(materialArtifacts.size === 0 ? {} : { materialArtifacts }),
|
|
506
|
+
...(shadowMaterialArtifacts.size === 0 ? {} : { shadowMaterialArtifacts }),
|
|
507
|
+
materialPipelineState: runtime.pipelineState,
|
|
508
|
+
...(runtime.internals.getMaterialShaderPipelineEntry === undefined
|
|
509
|
+
? {}
|
|
510
|
+
: { materialPipelineFactory: runtime.internals.getMaterialShaderPipelineEntry }),
|
|
468
511
|
});
|
|
469
512
|
if (!prepared.ok) return failed('candidate GPU-driven preparation failed', prepared.error);
|
|
470
513
|
preparedGpuDriven = prepared.value;
|