@forgeax/engine-render 0.1.20 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/assembly/device-feature-admission.d.ts +18 -0
- package/dist/assembly/device-feature-admission.d.ts.map +1 -0
- package/dist/assembly/directional-shadow-inspection.d.ts +38 -0
- package/dist/assembly/directional-shadow-inspection.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +21 -18
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +9 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/render-target-host.d.ts +46 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -0
- package/dist/assets/render-asset-port.d.ts.map +1 -1
- package/dist/authoring.mjs +3 -0
- package/dist/authoring.mjs.map +1 -1
- package/dist/capture/cube-views.d.ts +21 -0
- package/dist/capture/cube-views.d.ts.map +1 -0
- package/dist/capture/scheduler.d.ts +54 -0
- package/dist/capture/scheduler.d.ts.map +1 -0
- package/dist/{chunk-4XINDLAY.mjs → chunk-5YADUCA7.mjs} +1552 -1361
- package/dist/chunk-5YADUCA7.mjs.map +1 -0
- package/dist/{chunk-TBQJOK2L.mjs → chunk-6OPXDQ2E.mjs} +364 -51
- package/dist/chunk-6OPXDQ2E.mjs.map +1 -0
- package/dist/{chunk-M2MP4ZOU.mjs → chunk-BXBQQKFQ.mjs} +3 -9
- package/dist/chunk-BXBQQKFQ.mjs.map +1 -0
- package/dist/{chunk-CDTWTHZR.mjs → chunk-FS2KNUQH.mjs} +548 -6
- package/dist/chunk-FS2KNUQH.mjs.map +1 -0
- package/dist/components/camera.d.ts +1 -0
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/cube-camera.d.ts +20 -0
- package/dist/components/cube-camera.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +11 -2
- package/dist/components/directional-light.d.ts.map +1 -1
- package/dist/components/directional-shadow-filter.d.ts +25 -0
- package/dist/components/directional-shadow-filter.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/reflection-probe.d.ts +17 -0
- package/dist/components/reflection-probe.d.ts.map +1 -0
- package/dist/construct-renderer.mjs +5826 -1003
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/environment/frame.d.ts.map +1 -1
- package/dist/environment/lifecycle.d.ts +5 -0
- package/dist/environment/lifecycle.d.ts.map +1 -1
- package/dist/errors/render.d.ts +141 -93
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/directional-shadow-projection.d.ts +23 -0
- package/dist/extract/directional-shadow-projection.d.ts.map +1 -0
- package/dist/extract/environment.d.ts +14 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/extract/visibility.d.ts.map +1 -1
- package/dist/features/fullscreen.d.ts.map +1 -1
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +10 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +13 -2
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +0 -1
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +19 -17
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +4 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/kernel-cache.d.ts +36 -0
- package/dist/ibl/kernel-cache.d.ts.map +1 -0
- package/dist/index.d.ts +28 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +51 -0
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +50 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -0
- package/dist/internal.mjs +1 -1
- package/dist/light-buffer-layout.d.ts +10 -1
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +54 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +14 -4
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts +2 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/errors.d.ts +4 -0
- package/dist/pipeline/standard-lighting/errors.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/graph.d.ts +24 -0
- package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts +38 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/layout.d.ts +28 -0
- package/dist/pipeline/standard-lighting/layout.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts +33 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/membership.d.ts +14 -0
- package/dist/pipeline/standard-lighting/membership.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts +16 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/topology.d.ts +45 -0
- package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/transport.d.ts +36 -0
- package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts +4 -13
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +5 -26
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +40 -7
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/point-shadow-inspection.d.ts +21 -0
- package/dist/point-shadow-inspection.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +27 -32
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +28 -14
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts +5 -0
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +10 -4
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-pass-timing/contract.d.ts +96 -0
- package/dist/record/gpu-pass-timing/contract.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/errors.d.ts +18 -0
- package/dist/record/gpu-pass-timing/errors.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/index.d.ts +8 -0
- package/dist/record/gpu-pass-timing/index.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/parser.d.ts +11 -0
- package/dist/record/gpu-pass-timing/parser.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/session.d.ts +43 -0
- package/dist/record/gpu-pass-timing/session.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +8 -3
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +22 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +2 -0
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +43 -2
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +72 -4
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +7 -4
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/reflection/filter.d.ts +22 -0
- package/dist/reflection/filter.d.ts.map +1 -0
- package/dist/reflection/gpu-table.d.ts +25 -0
- package/dist/reflection/gpu-table.d.ts.map +1 -0
- package/dist/reflection/projection.d.ts +91 -0
- package/dist/reflection/projection.d.ts.map +1 -0
- package/dist/render-contract.d.ts +49 -7
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +42 -2
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +58 -17
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +17 -2
- package/dist/render-system.d.ts.map +1 -1
- package/dist/renderer.d.ts +43 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/scene/render-scene.d.ts +14 -0
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/shadow-atlas.d.ts +3 -3
- package/dist/shadow-atlas.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +3 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/targets/contracts.d.ts +66 -0
- package/dist/targets/contracts.d.ts.map +1 -0
- package/dist/targets/graph-projection.d.ts +29 -0
- package/dist/targets/graph-projection.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +34 -0
- package/dist/targets/material-source.d.ts.map +1 -0
- package/dist/targets/owner.d.ts +32 -0
- package/dist/targets/owner.d.ts.map +1 -0
- package/dist/targets/physical.d.ts +18 -0
- package/dist/targets/physical.d.ts.map +1 -0
- package/dist/targets/readback.d.ts +39 -0
- package/dist/targets/readback.d.ts.map +1 -0
- package/dist/temporal/index.mjs +3 -3
- package/dist/typed-render-graph-primitives.d.ts +1 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +1 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +2 -2
- package/dist/volume/passes.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/__tests__/bloom-exact-zero.unit.test.ts +48 -19
- package/src/__tests__/bloom-lifecycle.integration.test.ts +41 -13
- package/src/__tests__/camera-target-consumption.unit.test.ts +53 -0
- package/src/__tests__/cluster-binner.unit.test.ts +35 -0
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +7 -2
- package/src/__tests__/cube-camera-scheduler.unit.test.ts +70 -0
- package/src/__tests__/cube-camera-single-submit.perf.test.ts +75 -0
- package/src/__tests__/cube-camera-view-matrices.unit.test.ts +41 -0
- package/src/__tests__/cube-camera-vocabulary.unit.test.ts +47 -0
- package/src/__tests__/cube-camera.integration.test.ts +42 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +73 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +3 -3
- package/src/__tests__/docs-gate-green.unit.test.ts +38 -0
- package/src/__tests__/factory-contract.integration.test.ts +255 -29
- package/src/__tests__/fog-component.unit.test.ts +67 -0
- package/src/__tests__/fog.integration.test.ts +86 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +37 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +10 -9
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +17 -1
- package/src/__tests__/gpu-driven-production.integration.test.ts +16 -17
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +12 -4
- package/src/__tests__/gpu-pass-timing-browser-runner.ts +281 -0
- package/src/__tests__/gpu-pass-timing-coexistence.integration.test.ts +80 -0
- package/src/__tests__/gpu-pass-timing-contract.unit.test.ts +243 -0
- package/src/__tests__/gpu-pass-timing-exact-zero.unit.test.ts +131 -0
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +230 -0
- package/src/__tests__/gpu-pass-timing-observation.unit.test.ts +233 -0
- package/src/__tests__/gpu-pass-timing-session.unit.test.ts +438 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +26 -0
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +125 -0
- package/src/__tests__/hdrp-group2-visibility.unit.test.ts +24 -0
- package/src/__tests__/instances-culling.integration.test.ts +94 -0
- package/src/__tests__/instances-derived-bounds.unit.test.ts +118 -0
- package/src/__tests__/material-observation.integration.test.ts +101 -0
- package/src/__tests__/pbr-view-layout.unit.test.ts +16 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +60 -0
- package/src/__tests__/public-surface.test-d.ts +10 -0
- package/src/__tests__/reflection-probe-authoring.unit.test.ts +71 -0
- package/src/__tests__/reflection-probe-filter.unit.test.ts +54 -0
- package/src/__tests__/reflection-probe-ibl-topology.unit.test.ts +45 -0
- package/src/__tests__/reflection-probe-pass-encode.integration.test.ts +101 -0
- package/src/__tests__/reflection-probe-performance.perf.test.ts +60 -0
- package/src/__tests__/reflection-probe-recovery.integration.test.ts +55 -0
- package/src/__tests__/reflection-probe-selection.unit.test.ts +46 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +18 -3
- package/src/__tests__/render-feature-docs.unit.test.ts +1 -1
- package/src/__tests__/render-target-admission.unit.test.ts +80 -0
- package/src/__tests__/render-target-graph-projection.unit.test.ts +102 -0
- package/src/__tests__/render-target-inspection.unit.test.ts +52 -0
- package/src/__tests__/render-target-material-source.test-d.ts +30 -0
- package/src/__tests__/render-target-material-source.unit.test.ts +97 -0
- package/src/__tests__/render-target-owner-placement.unit.test.ts +203 -0
- package/src/__tests__/render-target-owner.unit.test.ts +122 -0
- package/src/__tests__/render-target-probe-soak.perf.test.ts +94 -0
- package/src/__tests__/render-target-public-schema.json +107 -0
- package/src/__tests__/render-target-public-schema.unit.test.ts +91 -0
- package/src/__tests__/render-target-public-surface.test-d.ts +83 -0
- package/src/__tests__/render-target-readback.integration.test.ts +90 -0
- package/src/__tests__/render-target-recovery.integration.test.ts +85 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +48 -0
- package/src/__tests__/renderer-lifecycle.integration.test.ts +14 -0
- package/src/__tests__/shader-stage-surface.unit.test.ts +19 -4
- package/src/__tests__/skin-motion-regression.unit.test.ts +132 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +11 -2
- package/src/__tests__/standard-cluster-capability.integration.test.ts +63 -0
- package/src/__tests__/standard-cluster-transport.unit.test.ts +121 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +232 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +8 -5
- package/src/__tests__/standard-lighting-inspection.integration.test.ts +138 -0
- package/src/__tests__/standard-lighting-ssot.unit.test.ts +18 -0
- package/src/__tests__/standard-lighting-write.unit.test.ts +377 -0
- package/src/__tests__/standard-lighting.integration.test.ts +67 -0
- package/src/__tests__/standard-pipeline.dawn.test.ts +206 -5
- package/src/__tests__/standard-pipeline.integration.test.ts +181 -150
- package/src/__tests__/standard-probe-binding.unit.test.ts +25 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +23 -38
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +395 -14
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +2 -2
- package/src/__tests__/visibility-resolver.unit.test.ts +15 -0
- package/src/assembly/device-feature-admission.ts +73 -0
- package/src/assembly/directional-shadow-inspection.ts +122 -0
- package/src/assembly/factory.ts +877 -286
- package/src/assembly/host-contract.ts +25 -0
- package/src/assembly/render-target-host.ts +847 -0
- package/src/assets/asset-decoders.ts +1 -1
- package/src/assets/render-asset-port.ts +7 -1
- package/src/capture/cube-views.ts +69 -0
- package/src/capture/scheduler.ts +265 -0
- package/src/components/__tests__/schema-contract.unit.test.ts +12 -0
- package/src/components/__tests__/schema-parity.unit.test.ts +9 -0
- package/src/components/camera.ts +4 -0
- package/src/components/cube-camera.ts +52 -0
- package/src/components/directional-light.ts +22 -2
- package/src/components/directional-shadow-filter.ts +57 -0
- package/src/components/index.ts +2 -0
- package/src/components/light-helpers.ts +81 -7
- package/src/components/reflection-probe.ts +49 -0
- package/src/environment/frame.ts +6 -24
- package/src/environment/lifecycle.ts +12 -0
- package/src/errors/render.ts +286 -142
- package/src/extract/directional-shadow-projection.ts +61 -0
- package/src/extract/environment.ts +57 -0
- package/src/extract/visibility.ts +25 -1
- package/src/features/fullscreen.ts +3 -0
- package/src/features/targets.ts +4 -1
- package/src/features/types.ts +10 -0
- package/src/fullscreen-post-process-pass.ts +43 -2
- package/src/gpu-driven/batch-topology.ts +1 -0
- package/src/gpu-driven/production-raster.ts +1 -3
- package/src/gpu-scene.ts +8 -1
- package/src/hdrp-buffers.ts +165 -59
- package/src/ibl/IblPipelineCache.ts +11 -0
- package/src/ibl/kernel-cache.ts +88 -0
- package/src/index.ts +148 -0
- package/src/inspection-types.ts +56 -0
- package/src/instances-derived-bounds.ts +171 -0
- package/src/light-buffer-layout.ts +20 -5
- package/src/mesh-material-bindings.ts +132 -0
- package/src/pbr-pipeline.ts +106 -17
- package/src/pipeline/standard-forward-lane.ts +46 -16
- package/src/pipeline/standard-lighting/errors.ts +6 -0
- package/src/pipeline/standard-lighting/graph.ts +157 -0
- package/src/pipeline/standard-lighting/inspection.ts +88 -0
- package/src/pipeline/standard-lighting/layout.ts +31 -0
- package/src/pipeline/standard-lighting/light-frame.ts +34 -0
- package/src/pipeline/standard-lighting/membership.ts +43 -0
- package/src/pipeline/standard-lighting/prepare.ts +37 -0
- package/src/pipeline/standard-lighting/topology.ts +120 -0
- package/src/pipeline/standard-lighting/transport.ts +77 -0
- package/src/pipeline/standard-pipeline.ts +122 -193
- package/src/pipeline/standard-post.ts +26 -7
- package/src/pipeline/standard-profile.ts +17 -47
- package/src/pipeline-spec.ts +84 -21
- package/src/point-shadow-inspection.ts +55 -0
- package/src/record/__tests__/temporal-payload.unit.test.ts +42 -1
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +73 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +40 -0
- package/src/record/frame-lighting.ts +367 -427
- package/src/record/frame-snapshot.ts +35 -27
- package/src/record/frame-targets.ts +17 -0
- package/src/record/frame.ts +261 -74
- package/src/record/gpu-pass-timing/contract.ts +180 -0
- package/src/record/gpu-pass-timing/errors.ts +34 -0
- package/src/record/gpu-pass-timing/index.ts +37 -0
- package/src/record/gpu-pass-timing/parser.ts +97 -0
- package/src/record/gpu-pass-timing/session.ts +938 -0
- package/src/record/gpu-timing.ts +21 -12
- package/src/record/main-pass-geometry.ts +120 -80
- package/src/record/main-pass-material.ts +95 -9
- package/src/record/main-pass-sprite-draws.ts +54 -25
- package/src/record/main-pass.ts +71 -15
- package/src/record/render-context.ts +72 -0
- package/src/record/shadow-pass.ts +17 -28
- package/src/record/skybox-post-pass.ts +20 -4
- package/src/record/typed-frame-graph.ts +893 -44
- package/src/record/view-ubo.ts +63 -28
- package/src/reflection/filter.ts +81 -0
- package/src/reflection/gpu-table.ts +44 -0
- package/src/reflection/projection.ts +281 -0
- package/src/render-contract.ts +76 -5
- package/src/render-graph-primitives.ts +9 -4
- package/src/render-pipeline.ts +117 -2
- package/src/render-system-extract.ts +557 -100
- package/src/render-system.ts +1095 -66
- package/src/renderer.ts +222 -0
- package/src/scene/render-scene.ts +115 -9
- package/src/shadow-atlas.ts +5 -5
- package/src/ssao-buffers.ts +9 -2
- package/src/targets/contracts.ts +182 -0
- package/src/targets/graph-projection.ts +169 -0
- package/src/targets/material-source.ts +143 -0
- package/src/targets/owner.ts +214 -0
- package/src/targets/physical.ts +18 -0
- package/src/targets/readback.ts +153 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +59 -20
- package/src/typed-render-graph-primitives.ts +5 -3
- package/src/typed-shadow-passes.ts +46 -40
- package/src/volume/passes.ts +15 -9
- package/dist/chunk-4XINDLAY.mjs.map +0 -1
- package/dist/chunk-CDTWTHZR.mjs.map +0 -1
- package/dist/chunk-M2MP4ZOU.mjs.map +0 -1
- package/dist/chunk-TBQJOK2L.mjs.map +0 -1
|
@@ -28,6 +28,7 @@ import { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';
|
|
|
28
28
|
import { SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET } from '../pbr-pipeline';
|
|
29
29
|
import {
|
|
30
30
|
buildBeginRenderPassDescriptor,
|
|
31
|
+
standardTopologyVariantSet,
|
|
31
32
|
variantSetFromVertexLayoutProjection,
|
|
32
33
|
} from '../pipeline-spec';
|
|
33
34
|
import type { MaterialSnapshot, SpriteInstancesSnapshot } from '../render-system-extract';
|
|
@@ -37,6 +38,7 @@ import {
|
|
|
37
38
|
defaultViewForUserRegionField,
|
|
38
39
|
entityHasTransparentSubmesh,
|
|
39
40
|
residentTextureView,
|
|
41
|
+
selectMaterialGroup2,
|
|
40
42
|
} from './main-pass-material';
|
|
41
43
|
import {
|
|
42
44
|
extractEntryResourceHandle,
|
|
@@ -208,8 +210,13 @@ export function recordSpritePass(
|
|
|
208
210
|
ldrSpriteColorView,
|
|
209
211
|
geometryDepthView,
|
|
210
212
|
viewBindGroup,
|
|
213
|
+
meshBindGroup,
|
|
214
|
+
hdrpClusterBindGroup,
|
|
215
|
+
viewBindGroupDynamicOffset = 0,
|
|
211
216
|
splitLdrSprite,
|
|
212
217
|
} = c;
|
|
218
|
+
const clusteredLighting = c.standardLighting?.kind === 'clustered';
|
|
219
|
+
const meshGroup2 = clusteredLighting ? hdrpClusterBindGroup : meshBindGroup;
|
|
213
220
|
// The split pass is also used by the no-tone linear-LDR route. That route
|
|
214
221
|
// keeps transparent draws in the graph-owned rgba16float attachment, so
|
|
215
222
|
// sprite shaders must use their linear/HDR fragment entry point even though
|
|
@@ -260,7 +267,7 @@ export function recordSpritePass(
|
|
|
260
267
|
) as never,
|
|
261
268
|
);
|
|
262
269
|
|
|
263
|
-
spritePass.setBindGroup(0, viewBindGroup as BindGroup, [0]);
|
|
270
|
+
spritePass.setBindGroup(0, viewBindGroup as BindGroup, [viewBindGroupDynamicOffset, 0]);
|
|
264
271
|
|
|
265
272
|
// feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (D-7):
|
|
266
273
|
// sprite PSO resolution migrated from the dedicated boot-time PSO
|
|
@@ -376,7 +383,12 @@ export function recordSpritePass(
|
|
|
376
383
|
spritePremulBlend,
|
|
377
384
|
'triangle-list',
|
|
378
385
|
undefined,
|
|
379
|
-
|
|
386
|
+
// sprite-lit declares the same Standard capability axes as PBR. The
|
|
387
|
+
// boot artifact is intentionally the direct compatibility variant,
|
|
388
|
+
// so a clustered frame must request its explicit Cluster artifact;
|
|
389
|
+
// otherwise the host binds the unified group(2) while the shader
|
|
390
|
+
// still reads the now-cleared direct-light headers.
|
|
391
|
+
standardTopologyVariantSet(c.standardLighting, runtime.device.caps.storageBuffer, false),
|
|
380
392
|
'forward',
|
|
381
393
|
undefined,
|
|
382
394
|
msaaActive ? 4 : 1,
|
|
@@ -416,6 +428,7 @@ export function recordSpritePass(
|
|
|
416
428
|
materialSlotIndices,
|
|
417
429
|
sampleCount,
|
|
418
430
|
resolveMaterialBindGroup,
|
|
431
|
+
meshGroup2,
|
|
419
432
|
);
|
|
420
433
|
|
|
421
434
|
if (graphPass === undefined) spritePass.end();
|
|
@@ -448,9 +461,9 @@ function recordSpriteTransparentPbrDraws(
|
|
|
448
461
|
entityKey: number,
|
|
449
462
|
materialWorld: World,
|
|
450
463
|
) => BindGroup,
|
|
464
|
+
meshGroup2: BindGroup | null,
|
|
451
465
|
): void {
|
|
452
|
-
const { runtime, pipelineState, frameState, bindGroupCounts, validatedOrdered
|
|
453
|
-
c;
|
|
466
|
+
const { runtime, pipelineState, frameState, bindGroupCounts, validatedOrdered } = c;
|
|
454
467
|
const isHdrTarget =
|
|
455
468
|
c.tonemapActive || transparentPassColorFormat(c, pipelineState) === 'rgba16float';
|
|
456
469
|
let lastPbrSubPipelineHandle: typeof pipelineState.unlitPipeline = null;
|
|
@@ -484,7 +497,6 @@ function recordSpriteTransparentPbrDraws(
|
|
|
484
497
|
spritePass.setIndexBuffer(entry.mesh.indexBuffer.handle, entry.mesh.indexFormat);
|
|
485
498
|
lastPbrSubIndexBuffer = entry.mesh.indexBuffer;
|
|
486
499
|
}
|
|
487
|
-
spritePass.setBindGroup(2, meshBindGroup as BindGroup, [i * MESH_PER_ENTITY_STRIDE]);
|
|
488
500
|
// Identity instance BG (instanceCount=1); reuse the per-entity cache.
|
|
489
501
|
const identityInstBg: BindGroup = getOrCreatePerEntity(
|
|
490
502
|
frameState.instancesBgPerEntity,
|
|
@@ -512,9 +524,11 @@ function recordSpriteTransparentPbrDraws(
|
|
|
512
524
|
);
|
|
513
525
|
spritePass.setBindGroup(3, identityInstBg);
|
|
514
526
|
|
|
515
|
-
const subVariantSet =
|
|
516
|
-
|
|
517
|
-
|
|
527
|
+
const subVariantSet = standardTopologyVariantSet(
|
|
528
|
+
c.standardLighting,
|
|
529
|
+
runtime.device.caps.storageBuffer,
|
|
530
|
+
entry.mesh.layoutProjection.attributes.some((attribute) => attribute.key === 'color'),
|
|
531
|
+
);
|
|
518
532
|
const projectionVariantSetResult = variantSetFromVertexLayoutProjection(
|
|
519
533
|
entry.mesh.layoutProjection,
|
|
520
534
|
subVariantSet,
|
|
@@ -535,21 +549,8 @@ function recordSpriteTransparentPbrDraws(
|
|
|
535
549
|
if (submeshMaterial.transparent !== true) continue;
|
|
536
550
|
const smShaderId = submeshMaterial.materialShaderId;
|
|
537
551
|
if (smShaderId === undefined) continue;
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
// order), then resolve the PSO; a first-frame async-compile miss skips
|
|
541
|
-
// only the draw, not the BG (one transient frame, PSO flows in next).
|
|
542
|
-
const materialSlot = materialSlotIndices[i]?.[matSlotIdx] ?? materialSlotIndices[i]?.[0] ?? 0;
|
|
543
|
-
const subBg = resolveMaterialBindGroup(
|
|
544
|
-
materialSlot,
|
|
545
|
-
submeshMaterial,
|
|
546
|
-
entry.source.entityKey,
|
|
547
|
-
entry.world ?? c.world,
|
|
548
|
-
);
|
|
549
|
-
spritePass.setBindGroup(1, subBg, [materialSlot * MATERIAL_PER_ENTITY_STRIDE]);
|
|
550
|
-
|
|
551
|
-
const subPipeline =
|
|
552
|
-
runtime.getMaterialShaderPipeline?.(
|
|
552
|
+
const subPipelineEntry =
|
|
553
|
+
c.runtime.getMaterialShaderPipelineEntry?.(
|
|
553
554
|
smShaderId,
|
|
554
555
|
isHdrTarget,
|
|
555
556
|
submeshMaterial.renderState,
|
|
@@ -566,7 +567,25 @@ function recordSpriteTransparentPbrDraws(
|
|
|
566
567
|
undefined,
|
|
567
568
|
entry.mesh.layoutProjection,
|
|
568
569
|
) ?? null;
|
|
569
|
-
if (
|
|
570
|
+
if (subPipelineEntry === null) continue;
|
|
571
|
+
const submeshContract = subPipelineEntry.group2Contract;
|
|
572
|
+
const submeshGroup2 = selectMaterialGroup2(meshGroup2, c.meshBindGroup, submeshContract);
|
|
573
|
+
if (submeshGroup2 === null) continue;
|
|
574
|
+
spritePass.setBindGroup(2, submeshGroup2, [i * MESH_PER_ENTITY_STRIDE]);
|
|
575
|
+
|
|
576
|
+
// Bind the per-submesh material BG first (mirrors the geometry pass
|
|
577
|
+
// order), then resolve the PSO; a first-frame async-compile miss skips
|
|
578
|
+
// only the draw, not the BG (one transient frame, PSO flows in next).
|
|
579
|
+
const materialSlot = materialSlotIndices[i]?.[matSlotIdx] ?? materialSlotIndices[i]?.[0] ?? 0;
|
|
580
|
+
const subBg = resolveMaterialBindGroup(
|
|
581
|
+
materialSlot,
|
|
582
|
+
submeshMaterial,
|
|
583
|
+
entry.source.entityKey,
|
|
584
|
+
entry.world ?? c.world,
|
|
585
|
+
);
|
|
586
|
+
spritePass.setBindGroup(1, subBg, [materialSlot * MATERIAL_PER_ENTITY_STRIDE]);
|
|
587
|
+
|
|
588
|
+
const subPipeline = subPipelineEntry.pipeline;
|
|
570
589
|
|
|
571
590
|
if (lastPbrSubPipelineHandle !== subPipeline) {
|
|
572
591
|
spritePass.setPipeline(subPipeline);
|
|
@@ -930,6 +949,16 @@ function recordSpriteEntityDraws(
|
|
|
930
949
|
spriteInstanceBuffer = _si.buffer;
|
|
931
950
|
spriteInstanceCount = _si.count;
|
|
932
951
|
|
|
952
|
+
// sprite-lit's clustered variant declares the unified Standard group(2)
|
|
953
|
+
// contract, while the regular sprite variants keep the direct mesh
|
|
954
|
+
// contract. Select the resource from the same capability axis used to
|
|
955
|
+
// request the pipeline; binding the ordinary mesh group to the clustered
|
|
956
|
+
// sprite-lit pipeline is rejected by WebGPU before the draw is recorded.
|
|
957
|
+
const spriteGroup2 =
|
|
958
|
+
entityShaderId === 'forgeax::sprite-lit' && c.standardLighting?.kind === 'clustered'
|
|
959
|
+
? c.hdrpClusterBindGroup
|
|
960
|
+
: meshBindGroup;
|
|
961
|
+
|
|
933
962
|
// M3 / w12: LDR sprite split pass per-entity instances BG cache.
|
|
934
963
|
// Same pattern as #7.
|
|
935
964
|
const spriteInstancesBg: BindGroup = getOrCreatePerEntity(
|
|
@@ -957,7 +986,7 @@ function recordSpriteEntityDraws(
|
|
|
957
986
|
bindGroupCounts,
|
|
958
987
|
);
|
|
959
988
|
|
|
960
|
-
spritePass.setBindGroup(2,
|
|
989
|
+
spritePass.setBindGroup(2, spriteGroup2 as BindGroup, [i * MESH_PER_ENTITY_STRIDE]);
|
|
961
990
|
|
|
962
991
|
// Per-entity sprite material bind group: same standard PBR user-region
|
|
963
992
|
// layout as in the geometry pass sprite branch + Skylight merged entries
|
package/src/record/main-pass.ts
CHANGED
|
@@ -9,10 +9,13 @@ import {
|
|
|
9
9
|
import type { Handle, PassKind, PassSelector } from '@forgeax/engine-types';
|
|
10
10
|
import { createHdrpUnifiedBindGroup, getOrCreateHdrpBuffers } from '../hdrp-buffers';
|
|
11
11
|
import { getOrCreateIblCache } from '../ibl/IblPipelineCache';
|
|
12
|
-
import {
|
|
12
|
+
import type { SkylightBindGroupResources } from '../ibl/skylight-bind-group';
|
|
13
|
+
import { buildBeginRenderPassDescriptor, standardTopologyBindGroupReady } from '../pipeline-spec';
|
|
13
14
|
import { POINTS_LINES_MATERIAL_SHADER_ID } from '../points-lines/record';
|
|
15
|
+
import type { ReflectionProbeSelectionResult } from '../reflection/projection';
|
|
14
16
|
import type { RenderRecordPhase } from '../render-contract';
|
|
15
17
|
import type { MaterialSnapshot } from '../render-system-extract';
|
|
18
|
+
import { resolveReflectionProbeBinding } from './frame-lighting';
|
|
16
19
|
import { recordGeometryDraws } from './main-pass-geometry';
|
|
17
20
|
import {
|
|
18
21
|
applyMaterialTextureUvScales,
|
|
@@ -31,6 +34,12 @@ import {
|
|
|
31
34
|
buildMatchedRenderableIndices,
|
|
32
35
|
} from './shadow-pass';
|
|
33
36
|
|
|
37
|
+
export function standardReflectionProbeIndex(
|
|
38
|
+
selection: ReflectionProbeSelectionResult,
|
|
39
|
+
): number | undefined {
|
|
40
|
+
return resolveReflectionProbeBinding(selection).probeIndex;
|
|
41
|
+
}
|
|
42
|
+
|
|
34
43
|
const ZERO_SKYLIGHT_PAYLOAD = new Float32Array([0, 0, 0, 0, 0, 0, 0, 1]);
|
|
35
44
|
|
|
36
45
|
export type MainPassOptions = {
|
|
@@ -114,6 +123,7 @@ export function recordMainPass(
|
|
|
114
123
|
geometryDepthView,
|
|
115
124
|
validatedOrdered,
|
|
116
125
|
viewBindGroup,
|
|
126
|
+
viewBindGroupDynamicOffset = 0,
|
|
117
127
|
meshBindGroup,
|
|
118
128
|
frameState,
|
|
119
129
|
bindGroupCounts,
|
|
@@ -161,14 +171,26 @@ export function recordMainPass(
|
|
|
161
171
|
// copyExternalImageToTexture path (w16) is the sole route. The branch exists
|
|
162
172
|
// so the AC-09 two-path reserved hook is code-review-verifiable, not a TODO.
|
|
163
173
|
const videoHighPerfAvailable = probeVideoHighPerfUpload(runtime.device);
|
|
164
|
-
//
|
|
174
|
+
// The prepared Standard topology is the frame authority. Do not infer the
|
|
175
|
+
// shader lane from a resource that may be absent after a failed rebuild: a
|
|
176
|
+
// clustered frame with no unified group must fail closed, never fall back to
|
|
177
|
+
// a direct-lighting shader with an incompatible group(2) contract.
|
|
178
|
+
const clusteredLighting = c.standardLighting?.kind === 'clustered';
|
|
179
|
+
// A clustered topology still needs the unified group for every actual
|
|
180
|
+
// material draw. A camera-only/clear frame has no group(2) consumer yet;
|
|
181
|
+
// treating that harmless absence as a frame error would make the full
|
|
182
|
+
// clustered ABI incompatible with valid zero-renderable frames.
|
|
183
|
+
const clusteredBindGroupMissing =
|
|
184
|
+
validatedOrdered.length > 0 &&
|
|
185
|
+
!standardTopologyBindGroupReady(c.standardLighting, hdrpClusterBindGroup);
|
|
186
|
+
// Standard clustered lighting swaps the
|
|
165
187
|
// group(2) bindGroup for the unified 7-entry layout (mesh SSBO at binding 0
|
|
166
188
|
// + cluster 4 buffer at bindings 3..6). The dynamic offset
|
|
167
189
|
// (`i * MESH_PER_ENTITY_STRIDE`) stays valid because the unified BGL binds
|
|
168
190
|
// the SAME mesh SSBO at binding 0; the cluster-forward shader reads the
|
|
169
191
|
// cluster bindings off the rest of the layout. Plan D-1 (URP path zero
|
|
170
|
-
// change) is preserved — when
|
|
171
|
-
// path runs verbatim.
|
|
192
|
+
// change) is preserved — when clustered lighting is not selected the
|
|
193
|
+
// ordinary mesh bind group path runs verbatim.
|
|
172
194
|
// feat-20260612-hdrp-ssao wiring fix: when the HDRP forward pass resolved a
|
|
173
195
|
// real `ssaoBlurred` view (stashed on ctx by the pass execute closure), build
|
|
174
196
|
// the unified group(2) bind group with that view at binding 7 so fs_main reads
|
|
@@ -178,11 +200,7 @@ export function recordMainPass(
|
|
|
178
200
|
// Built per frame (the SSAO target is a graph transient, so no cross-frame
|
|
179
201
|
// cache); HDRP-only and SSAO-only, so URP and SSAO-off paths are untouched.
|
|
180
202
|
let hdrpSsaoBindGroup: BindGroup | null = null;
|
|
181
|
-
if (
|
|
182
|
-
frameState.isHdrpActive &&
|
|
183
|
-
hdrpClusterBindGroup !== null &&
|
|
184
|
-
c.hdrpSsaoBlurredView !== undefined
|
|
185
|
-
) {
|
|
203
|
+
if (clusteredLighting && hdrpClusterBindGroup !== null && c.hdrpSsaoBlurredView !== undefined) {
|
|
186
204
|
const hdrpBuffers = getOrCreateHdrpBuffers(
|
|
187
205
|
runtime,
|
|
188
206
|
frameState.installedPipelineConfig?.clusterGrid,
|
|
@@ -196,10 +214,9 @@ export function recordMainPass(
|
|
|
196
214
|
);
|
|
197
215
|
}
|
|
198
216
|
}
|
|
199
|
-
const meshGroup2: BindGroup | null =
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
: meshBindGroup;
|
|
217
|
+
const meshGroup2: BindGroup | null = clusteredLighting
|
|
218
|
+
? (hdrpSsaoBindGroup ?? hdrpClusterBindGroup)
|
|
219
|
+
: meshBindGroup;
|
|
203
220
|
// ── Geometry (main colour) pass ──────────────────────────────────
|
|
204
221
|
// D-2: tracks whether the geometry pass was explicitly ended inside
|
|
205
222
|
// the `if (validatedOrdered.length > 0)` block (sprite split path),
|
|
@@ -273,7 +290,17 @@ export function recordMainPass(
|
|
|
273
290
|
})),
|
|
274
291
|
};
|
|
275
292
|
|
|
276
|
-
if (
|
|
293
|
+
if (clusteredBindGroupMissing) {
|
|
294
|
+
runtime.errorRegistry.fire(
|
|
295
|
+
new RhiError({
|
|
296
|
+
code: 'webgpu-runtime-error',
|
|
297
|
+
expected: 'clustered Standard frame has a unified group(2) BindGroup',
|
|
298
|
+
hint: 'repair the clustered buffer/layout admission before retrying the frame; direct URP fallback is unsafe',
|
|
299
|
+
}),
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (validatedOrdered.length > 0 && !clusteredBindGroupMissing) {
|
|
277
304
|
// feat-20260518-pbr-direct-lighting-mvp M5 / w22.10 (D-4 + D-9 +
|
|
278
305
|
// AC-07 std140): per-entity material slice grew from 32 B (legacy
|
|
279
306
|
// baseColor:vec4 + metallic + roughness + 8B padding) to 48 B
|
|
@@ -432,6 +459,35 @@ export function recordMainPass(
|
|
|
432
459
|
materialSlice: MATERIAL_SLICE,
|
|
433
460
|
videoHighPerfAvailable,
|
|
434
461
|
skylightResources,
|
|
462
|
+
resolveRenderTargetTextureSource: runtime.resolveRenderTargetTextureSource,
|
|
463
|
+
resolveReflectionProbeResources: (materialWorld, entityKey) => {
|
|
464
|
+
const reflectionProbes = c.reflectionProbes;
|
|
465
|
+
if (reflectionProbes === undefined) return undefined;
|
|
466
|
+
const selection = reflectionProbes.selections.get(`${materialWorld.identity}:${entityKey}`);
|
|
467
|
+
if (selection === undefined) return undefined;
|
|
468
|
+
const binding = resolveReflectionProbeBinding(selection, reflectionProbes.table);
|
|
469
|
+
if (binding.useSkylight || binding.probeIndex === undefined) return undefined;
|
|
470
|
+
const row = reflectionProbes.table.rows.find(
|
|
471
|
+
(candidate) => candidate.index === binding.probeIndex,
|
|
472
|
+
);
|
|
473
|
+
if (
|
|
474
|
+
row?.filteredView === undefined ||
|
|
475
|
+
row.sampler === undefined ||
|
|
476
|
+
row.uniformBuffer === undefined
|
|
477
|
+
) {
|
|
478
|
+
return undefined;
|
|
479
|
+
}
|
|
480
|
+
const probeResources: SkylightBindGroupResources = {
|
|
481
|
+
irradianceView: skylightResources.irradianceView,
|
|
482
|
+
irradianceSampler: skylightResources.irradianceSampler,
|
|
483
|
+
prefilterView: row.filteredView,
|
|
484
|
+
prefilterSampler: row.sampler,
|
|
485
|
+
brdfLutView: skylightResources.brdfLutView,
|
|
486
|
+
brdfLutSampler: skylightResources.brdfLutSampler,
|
|
487
|
+
intensityBuffer: row.uniformBuffer,
|
|
488
|
+
};
|
|
489
|
+
return probeResources;
|
|
490
|
+
},
|
|
435
491
|
materialBgShared: frameState.materialBgShared,
|
|
436
492
|
materialBgAssemblyCache: c.materialBgAssemblyCache,
|
|
437
493
|
bindGroupCounts,
|
|
@@ -614,7 +670,7 @@ export function recordMainPass(
|
|
|
614
670
|
buildPerSubmeshMaterialBg(material, entityKey, materialWorld))
|
|
615
671
|
: buildPerSubmeshMaterialBg(material, entityKey, materialWorld);
|
|
616
672
|
|
|
617
|
-
pass.setBindGroup(0, viewBindGroup as BindGroup, [0]);
|
|
673
|
+
pass.setBindGroup(0, viewBindGroup as BindGroup, [viewBindGroupDynamicOffset, 0]);
|
|
618
674
|
|
|
619
675
|
// Track which (mesh-vertex-buffer, mesh-index-buffer, pipeline) combo
|
|
620
676
|
// was last bound so consecutive entities sharing the same combo skip
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
PipelineLayout,
|
|
12
12
|
Result,
|
|
13
13
|
RhiCanvasContext,
|
|
14
|
+
RhiCommandEncoder,
|
|
14
15
|
RhiDevice,
|
|
15
16
|
RenderPipeline as RhiRenderPipeline,
|
|
16
17
|
Sampler,
|
|
@@ -41,10 +42,20 @@ import {
|
|
|
41
42
|
import type { SkylightFallback } from '../ibl/skylight-bind-group';
|
|
42
43
|
import type { BloomInspection } from '../inspection-types';
|
|
43
44
|
import type { HealthListenerRegistry, RhiErrorListenerRegistry } from '../lifecycle';
|
|
45
|
+
import type { PipelineGroup2Contract } from '../pbr-pipeline';
|
|
46
|
+
import type { StandardTopologyInputValue } from '../pipeline/standard-lighting/topology';
|
|
44
47
|
import type { StandardProfile } from '../pipeline/standard-profile';
|
|
45
48
|
import type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';
|
|
46
49
|
import type { PointsLinesInspection } from '../points-lines/inspection';
|
|
47
50
|
import type { PointsLinesRecordPlan } from '../points-lines/record';
|
|
51
|
+
import type { ReflectionProbeTable } from '../reflection/gpu-table';
|
|
52
|
+
import type { ReflectionProbeSelectionResult } from '../reflection/projection';
|
|
53
|
+
import type { GpuPassTimingReason } from './gpu-pass-timing/errors';
|
|
54
|
+
import type {
|
|
55
|
+
GpuPassTimingCapture,
|
|
56
|
+
GpuPassTimingFrameIdentity,
|
|
57
|
+
GpuPassTimingSession,
|
|
58
|
+
} from './gpu-pass-timing/session';
|
|
48
59
|
|
|
49
60
|
export interface PointsLinesRecordSubmission {
|
|
50
61
|
readonly plan: PointsLinesRecordPlan;
|
|
@@ -53,6 +64,18 @@ export interface PointsLinesRecordSubmission {
|
|
|
53
64
|
readonly layoutProjection: VertexLayoutProjection;
|
|
54
65
|
}
|
|
55
66
|
|
|
67
|
+
export interface ReflectionProbeRecordState {
|
|
68
|
+
readonly table: ReflectionProbeTable;
|
|
69
|
+
readonly selections: ReadonlyMap<string, ReflectionProbeSelectionResult>;
|
|
70
|
+
readonly graph: import('./typed-frame-graph').ReflectionProbeGraphState;
|
|
71
|
+
readonly completeSubmission: (submitted: boolean, completed?: Promise<unknown>) => void;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface MaterialShaderPipelineEntry {
|
|
75
|
+
readonly pipeline: RhiRenderPipeline;
|
|
76
|
+
readonly group2Contract: PipelineGroup2Contract;
|
|
77
|
+
}
|
|
78
|
+
|
|
56
79
|
import type {
|
|
57
80
|
RenderDebugOverlay,
|
|
58
81
|
RenderPipelineContext,
|
|
@@ -66,6 +89,8 @@ import type {
|
|
|
66
89
|
SkylightSnapshot,
|
|
67
90
|
} from '../render-system-extract';
|
|
68
91
|
import type { SkinPaletteAllocator } from '../systems/skin-palette-allocator';
|
|
92
|
+
import type { RenderTarget } from '../targets/contracts';
|
|
93
|
+
import type { RenderTargetPhysical } from '../targets/physical';
|
|
69
94
|
import type {
|
|
70
95
|
BindGroupCounts,
|
|
71
96
|
BloomFrameReceipts,
|
|
@@ -102,6 +127,23 @@ export interface RenderSystemRuntime {
|
|
|
102
127
|
shaderModuleMode?: RenderFeatureShaderModuleMode,
|
|
103
128
|
layoutKindOverride?: 'pbr' | 'pbr-skin',
|
|
104
129
|
) => RhiRenderPipeline | null;
|
|
130
|
+
readonly getMaterialShaderPipelineEntry?: (
|
|
131
|
+
materialShaderId: string,
|
|
132
|
+
isHdr: boolean,
|
|
133
|
+
renderState?: MaterialRenderState,
|
|
134
|
+
topology?: PrimitiveTopology,
|
|
135
|
+
indexFormat?: 'uint16' | 'uint32',
|
|
136
|
+
variantSet?: string,
|
|
137
|
+
passKind?: PassKind,
|
|
138
|
+
meshAttributes?: VertexAttributeMap,
|
|
139
|
+
sampleCount?: number,
|
|
140
|
+
colorFormatOverride?: GPUTextureFormat,
|
|
141
|
+
shaderUvSetCount?: number,
|
|
142
|
+
depthFormatOverride?: GPUTextureFormat | null,
|
|
143
|
+
vertexLayout?: string,
|
|
144
|
+
vertexLayoutProjection?: VertexLayoutProjection,
|
|
145
|
+
shaderModuleMode?: RenderFeatureShaderModuleMode,
|
|
146
|
+
) => MaterialShaderPipelineEntry | null;
|
|
105
147
|
readonly getMaterialShaderBindingContract?: (
|
|
106
148
|
materialShaderId: string,
|
|
107
149
|
) => 'group-0' | 'group-0-resource' | 'view-only' | 'view-and-scene-depth' | 'render-material';
|
|
@@ -116,10 +158,15 @@ export interface RenderSystemRuntime {
|
|
|
116
158
|
id: string,
|
|
117
159
|
bgl: BindGroupLayout,
|
|
118
160
|
colorFormat: GPUTextureFormat,
|
|
161
|
+
entry?: import('../fullscreen-post-process-pass').PostProcessShaderEntry,
|
|
119
162
|
) => RhiRenderPipeline | null;
|
|
120
163
|
readonly clearPostProcessPipelineCache?: (id: string) => void;
|
|
121
164
|
readonly invalidateShaderModule?: (label: string) => void;
|
|
122
165
|
readonly dynamicTextureStore?: DynamicTextureStore | undefined;
|
|
166
|
+
/** Resolves a render-target source to the active generation-owned GPU view. */
|
|
167
|
+
readonly resolveRenderTargetTextureSource?: (
|
|
168
|
+
source: import('../targets/contracts').RenderTargetTextureSource,
|
|
169
|
+
) => import('../targets/material-source').RenderTargetMaterialSourceBinding | undefined;
|
|
123
170
|
}
|
|
124
171
|
|
|
125
172
|
/** Renderer-owned bridge from retained Points/Lines facts into main geometry. */
|
|
@@ -231,6 +278,8 @@ export interface BloomPersistentBundle {
|
|
|
231
278
|
}
|
|
232
279
|
|
|
233
280
|
export interface PipelineState {
|
|
281
|
+
/** Device that owns every opaque handle in this pipeline state. */
|
|
282
|
+
readonly device: RhiDevice;
|
|
234
283
|
readonly meshes: ReadonlyMap<number, MeshGpuHandles>;
|
|
235
284
|
readonly format: TextureFormat;
|
|
236
285
|
readonly colorAttachmentFormat: TextureFormat;
|
|
@@ -263,6 +312,8 @@ export interface PipelineState {
|
|
|
263
312
|
readonly hdrpClusterMembershipBindGroupLayout: BindGroupLayout | null;
|
|
264
313
|
readonly pbrSkinPipelineLayout: PipelineLayout | null;
|
|
265
314
|
readonly pbrSkinMeshBindGroupLayout: BindGroupLayout | null;
|
|
315
|
+
readonly hdrpSkinPipelineLayout: PipelineLayout | null;
|
|
316
|
+
readonly hdrpSkinMeshBindGroupLayout: BindGroupLayout | null;
|
|
266
317
|
readonly skinPaletteAllocator: SkinPaletteAllocator | null;
|
|
267
318
|
readonly defaultWhiteTextureView: TextureView;
|
|
268
319
|
readonly defaultNormalTextureView: TextureView;
|
|
@@ -280,6 +331,12 @@ export interface RenderSystemInternals extends RenderSystemRuntime {
|
|
|
280
331
|
readonly standardPipeline: RenderFrameState['activePipeline'];
|
|
281
332
|
readonly featureHost?: RenderFeatureHost | undefined;
|
|
282
333
|
readonly shaderModuleFactory?: PipelineBuilderShaderModuleFactory;
|
|
334
|
+
readonly createShaderModule?: (
|
|
335
|
+
device: import('@forgeax/engine-rhi').RhiDevice,
|
|
336
|
+
descriptor: { readonly code: string; readonly label?: string },
|
|
337
|
+
) => Promise<
|
|
338
|
+
Result<import('@forgeax/engine-rhi').ShaderModule, import('@forgeax/engine-rhi').RhiError>
|
|
339
|
+
>;
|
|
283
340
|
/** Optional handle-first factory for feature-owned generated shader programs. */
|
|
284
341
|
readonly immediateShaderModuleFactory?: PipelineBuilderShaderModuleFactory;
|
|
285
342
|
readonly profiler?: Profiler | undefined;
|
|
@@ -305,6 +362,16 @@ export interface RenderSystemInternals extends RenderSystemRuntime {
|
|
|
305
362
|
label: string,
|
|
306
363
|
) => RhiRenderPipeline | null)
|
|
307
364
|
| undefined;
|
|
365
|
+
gpuPassTimingSession?: GpuPassTimingSession | undefined;
|
|
366
|
+
gpuPassTimingCapture?: GpuPassTimingCapture | undefined;
|
|
367
|
+
gpuPassTimingSubmittedWork?: Promise<void> | undefined;
|
|
368
|
+
gpuPassTimingFrameIdentity?: GpuPassTimingFrameIdentity | undefined;
|
|
369
|
+
gpuPassTimingBeginReason?: GpuPassTimingReason | undefined;
|
|
370
|
+
readonly getRenderTargetPhysical?: (target: RenderTarget) => RenderTargetPhysical | undefined;
|
|
371
|
+
readonly encodeRenderTargetReadbacks?: (
|
|
372
|
+
encoder: RhiCommandEncoder,
|
|
373
|
+
faces?: readonly number[],
|
|
374
|
+
) => void;
|
|
308
375
|
/** Composed renderer utility sources installed atomically at build-ready. */
|
|
309
376
|
volumetricFogShaders?: VolumetricFogShaderSources | undefined;
|
|
310
377
|
}
|
|
@@ -318,6 +385,8 @@ export interface _StandardForwardSceneView {
|
|
|
318
385
|
readonly validated: readonly ValidatedRenderable[];
|
|
319
386
|
readonly validatedOrdered: readonly ValidatedRenderable[];
|
|
320
387
|
readonly viewBindGroup: BindGroup | null;
|
|
388
|
+
/** Dynamic View-UBO slot used by auxiliary cube/probe face cameras. */
|
|
389
|
+
readonly viewBindGroupDynamicOffset?: number;
|
|
321
390
|
readonly meshBindGroup: BindGroup | null;
|
|
322
391
|
readonly frameState: RenderFrameState;
|
|
323
392
|
readonly dispatchCounts: DispatchCounts;
|
|
@@ -340,6 +409,8 @@ export interface _StandardForwardSceneView {
|
|
|
340
409
|
readonly dispatch: readonly DispatchEntry[];
|
|
341
410
|
readonly hdrpClusterBindGroup: BindGroup | null;
|
|
342
411
|
readonly hdrpClusterMembershipBindGroup: BindGroup | null;
|
|
412
|
+
/** Prepared Standard lighting declaration accepted by this graph frame. */
|
|
413
|
+
readonly standardLighting?: StandardTopologyInputValue;
|
|
343
414
|
readonly foldDispatchPlan: FoldDispatchPlan | null;
|
|
344
415
|
readonly materialSlotIndices: readonly (readonly number[])[];
|
|
345
416
|
readonly materialSlots: readonly MaterialSnapshot[];
|
|
@@ -347,6 +418,7 @@ export interface _StandardForwardSceneView {
|
|
|
347
418
|
readonly materialSlotCount: number;
|
|
348
419
|
readonly pointsLines: PointsLinesRecordOwner | undefined;
|
|
349
420
|
readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;
|
|
421
|
+
readonly reflectionProbes?: ReflectionProbeRecordState;
|
|
350
422
|
materialUboPayloadCache?: {
|
|
351
423
|
readonly materialSlots: readonly MaterialSnapshot[];
|
|
352
424
|
readonly materialSlotCount: number;
|
|
@@ -18,6 +18,8 @@ import { assembleMaterialWithSkylightEntries } from '../ibl/skylight-bind-group'
|
|
|
18
18
|
import type { InstanceBufferCacheEntry } from '../instance-buffer-cache';
|
|
19
19
|
import {
|
|
20
20
|
buildPbrMaterialUserRegionEntries,
|
|
21
|
+
createPbrSkinMeshBindGroupEntries,
|
|
22
|
+
pbrSkinMeshDynamicOffsets,
|
|
21
23
|
SHADOW_CASTER_SHADER_ID,
|
|
22
24
|
shadowCasterVariantSet,
|
|
23
25
|
} from '../pbr-pipeline';
|
|
@@ -290,27 +292,12 @@ function skinnedShadowMeshBindGroup(
|
|
|
290
292
|
const created = c.runtime.device.createBindGroup({
|
|
291
293
|
label: 'shadow-pbr-skin-mesh-bg',
|
|
292
294
|
layout,
|
|
293
|
-
entries:
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
buffer: c.pipelineState.meshStorageBuffer.buffer,
|
|
300
|
-
size: c.runtime.device.caps.storageBuffer
|
|
301
|
-
? MESH_SSBO_BYTES
|
|
302
|
-
: MESH_UBO_FULL_ARRAY_BYTES,
|
|
303
|
-
},
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
|
-
{
|
|
307
|
-
binding: 1,
|
|
308
|
-
resource: {
|
|
309
|
-
kind: 'buffer',
|
|
310
|
-
value: { buffer: skin.buffer, size: allocator.bindingWindowBytes },
|
|
311
|
-
},
|
|
312
|
-
},
|
|
313
|
-
],
|
|
295
|
+
entries: createPbrSkinMeshBindGroupEntries(
|
|
296
|
+
c.pipelineState.meshStorageBuffer.buffer,
|
|
297
|
+
c.runtime.device.caps.storageBuffer ? MESH_SSBO_BYTES : MESH_UBO_FULL_ARRAY_BYTES,
|
|
298
|
+
skin.buffer,
|
|
299
|
+
allocator.bindingWindowBytes,
|
|
300
|
+
),
|
|
314
301
|
});
|
|
315
302
|
if (!created.ok) throw created.error;
|
|
316
303
|
return created.value;
|
|
@@ -338,7 +325,7 @@ export function encodeDirectionalShadowPass(
|
|
|
338
325
|
c.frameState.directionalShadowCacheRecorded = true;
|
|
339
326
|
pass.setViewport(viewport.x, viewport.y, viewport.w, viewport.h, 0, 1);
|
|
340
327
|
pass.setPipeline(pipeline);
|
|
341
|
-
pass.setBindGroup(0, viewBg, [0]);
|
|
328
|
+
pass.setBindGroup(0, viewBg, [0, 0]);
|
|
342
329
|
pass.setBindGroup(1, materialBg, [0]);
|
|
343
330
|
recordShadowCasterDraws(
|
|
344
331
|
c,
|
|
@@ -368,7 +355,7 @@ export function encodePointShadowPass(
|
|
|
368
355
|
const materialBg = ensureSpotShadowMaterialBg(c);
|
|
369
356
|
if (pipeline === null || viewBg === null || materialBg === null) return;
|
|
370
357
|
pass.setPipeline(pipeline);
|
|
371
|
-
pass.setBindGroup(0, viewBg, [0]);
|
|
358
|
+
pass.setBindGroup(0, viewBg, [0, 0]);
|
|
372
359
|
pass.setBindGroup(1, materialBg, [0]);
|
|
373
360
|
recordShadowCasterDraws(
|
|
374
361
|
c,
|
|
@@ -416,7 +403,7 @@ export function encodeSpotShadowPass(
|
|
|
416
403
|
1,
|
|
417
404
|
);
|
|
418
405
|
pass.setPipeline(pipeline);
|
|
419
|
-
pass.setBindGroup(0, viewBg, [0]);
|
|
406
|
+
pass.setBindGroup(0, viewBg, [0, 0]);
|
|
420
407
|
pass.setBindGroup(1, materialBg, [0]);
|
|
421
408
|
// Reuse the shared caster recorder. The compact spot-only loop used to
|
|
422
409
|
// depend on instance bindings created by a directional pass, so a scene
|
|
@@ -594,10 +581,11 @@ function recordShadowCasterDraws(
|
|
|
594
581
|
if (entry.source.skin !== undefined) {
|
|
595
582
|
const skinMeshBindGroup = skinnedShadowMeshBindGroup(c, entry);
|
|
596
583
|
if (skinMeshBindGroup === null) continue;
|
|
597
|
-
shadowPass.setBindGroup(
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
584
|
+
shadowPass.setBindGroup(
|
|
585
|
+
2,
|
|
586
|
+
skinMeshBindGroup,
|
|
587
|
+
pbrSkinMeshDynamicOffsets(i * MESH_PER_ENTITY_STRIDE, entry.source.skin.byteOffset),
|
|
588
|
+
);
|
|
601
589
|
} else {
|
|
602
590
|
shadowPass.setBindGroup(2, shadowMeshBindGroup, [i * MESH_PER_ENTITY_STRIDE]);
|
|
603
591
|
}
|
|
@@ -606,6 +594,7 @@ function recordShadowCasterDraws(
|
|
|
606
594
|
let shadowInstanceBuffer: Buffer = pipelineState.identityInstanceBuffer;
|
|
607
595
|
let shadowInstanceCount = 1;
|
|
608
596
|
const shadowInst = entry.source.instances;
|
|
597
|
+
if (shadowInst?.instanceCount === 0) continue;
|
|
609
598
|
if (shadowInst !== undefined) {
|
|
610
599
|
const uniformFallback = runtime.device.caps.storageBuffer === false;
|
|
611
600
|
// Over-cap uniform fallback can't fit the per-instance window — bind
|
|
@@ -2,6 +2,8 @@ import type { ResolveContext } from '@forgeax/engine-render-graph';
|
|
|
2
2
|
import { RhiError, type RhiRenderPassEncoder, type TextureView } from '@forgeax/engine-rhi';
|
|
3
3
|
import { toShared } from '@forgeax/engine-types';
|
|
4
4
|
import { buildBeginRenderPassDescriptor } from '../pipeline-spec';
|
|
5
|
+
import { FXAA_POST_PROCESS_ID } from '../render-contract';
|
|
6
|
+
import { resolveOutputDither } from '../render-pipeline';
|
|
5
7
|
import type { BloomFrameReceipts } from './frame-snapshot';
|
|
6
8
|
import { getOrCreateFromChain } from './mesh-ssbo';
|
|
7
9
|
import type { _InternalRenderPipelineContext } from './render-context';
|
|
@@ -579,19 +581,29 @@ export function recordFxaaPass(
|
|
|
579
581
|
fxaaActive &&
|
|
580
582
|
pipelineState.perPassResources.fxaaPipeline !== null &&
|
|
581
583
|
pipelineState.perPassResources.fxaaBindGroupLayout !== null &&
|
|
582
|
-
pipelineState.perPassResources.fxaaSampler !== null
|
|
584
|
+
pipelineState.perPassResources.fxaaSampler !== null &&
|
|
585
|
+
runtime.getPostProcessParamsBuffer !== undefined
|
|
583
586
|
) {
|
|
584
587
|
const inputView = resolve.resolve('ldrColor') as TextureView | undefined;
|
|
585
588
|
if (inputView === undefined) return;
|
|
586
589
|
|
|
587
|
-
|
|
590
|
+
const fxaaParams = runtime.getPostProcessParamsBuffer(FXAA_POST_PROCESS_ID);
|
|
591
|
+
if (fxaaParams === undefined) return;
|
|
592
|
+
const params = new Float32Array(4);
|
|
593
|
+
params[0] = resolveOutputDither(c.frameState.installedPipelineConfig) ? 1 : 0;
|
|
594
|
+
const paramsWrite = runtime.device.queue.writeBuffer(fxaaParams, 0, params);
|
|
595
|
+
if (!paramsWrite.ok) throw paramsWrite.error;
|
|
596
|
+
|
|
597
|
+
// Compose the 3-entry FXAA BindGroup (input texture + sampler + params).
|
|
588
598
|
// graph view identity changes when the graph reallocates on resize, so
|
|
589
|
-
// the identity-keyed cache rebuilds against the live target.
|
|
599
|
+
// the identity-keyed cache rebuilds against the live target. The params
|
|
600
|
+
// buffer is also a key so a device recovery cannot retain a bind group
|
|
601
|
+
// pointing at the retired resource.
|
|
590
602
|
const fxaaBglLayout = pipelineState.perPassResources.fxaaBindGroupLayout;
|
|
591
603
|
const fxaaSampler = pipelineState.perPassResources.fxaaSampler;
|
|
592
604
|
const fxaaBg = getOrCreateFromChain(
|
|
593
605
|
c.frameState.postProcessBgCache,
|
|
594
|
-
[inputView],
|
|
606
|
+
[inputView, fxaaParams],
|
|
595
607
|
'fxaa',
|
|
596
608
|
() => {
|
|
597
609
|
const fxaaBgRes = runtime.device.createBindGroup({
|
|
@@ -609,6 +621,10 @@ export function recordFxaaPass(
|
|
|
609
621
|
binding: 1,
|
|
610
622
|
resource: { kind: 'sampler', value: fxaaSampler },
|
|
611
623
|
},
|
|
624
|
+
{
|
|
625
|
+
binding: 2,
|
|
626
|
+
resource: { kind: 'buffer', value: { buffer: fxaaParams } },
|
|
627
|
+
},
|
|
612
628
|
],
|
|
613
629
|
});
|
|
614
630
|
if (!fxaaBgRes.ok) throw fxaaBgRes.error;
|