@forgeax/engine-render 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/assembly/device-feature-admission.d.ts +18 -0
- package/dist/assembly/device-feature-admission.d.ts.map +1 -0
- package/dist/assembly/directional-shadow-inspection.d.ts +38 -0
- package/dist/assembly/directional-shadow-inspection.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +34 -20
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +9 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/render-target-host.d.ts +46 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -0
- package/dist/assets/render-asset-port.d.ts.map +1 -1
- package/dist/authoring.mjs +3 -0
- package/dist/authoring.mjs.map +1 -1
- package/dist/capture/cube-views.d.ts +21 -0
- package/dist/capture/cube-views.d.ts.map +1 -0
- package/dist/capture/scheduler.d.ts +54 -0
- package/dist/capture/scheduler.d.ts.map +1 -0
- package/dist/{chunk-RJRUS55L.mjs → chunk-5YADUCA7.mjs} +1896 -1624
- package/dist/chunk-5YADUCA7.mjs.map +1 -0
- package/dist/{chunk-LOSO4CTV.mjs → chunk-6OPXDQ2E.mjs} +423 -46
- package/dist/chunk-6OPXDQ2E.mjs.map +1 -0
- package/dist/{chunk-IPXCABEP.mjs → chunk-BXBQQKFQ.mjs} +3 -9
- package/dist/chunk-BXBQQKFQ.mjs.map +1 -0
- package/dist/chunk-FS2KNUQH.mjs +1294 -0
- package/dist/chunk-FS2KNUQH.mjs.map +1 -0
- package/dist/components/camera.d.ts +1 -0
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/cube-camera.d.ts +20 -0
- package/dist/components/cube-camera.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +11 -2
- package/dist/components/directional-light.d.ts.map +1 -1
- package/dist/components/directional-shadow-filter.d.ts +25 -0
- package/dist/components/directional-shadow-filter.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/reflection-probe.d.ts +17 -0
- package/dist/components/reflection-probe.d.ts.map +1 -0
- package/dist/components/spot-light.d.ts +12 -0
- package/dist/components/spot-light.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +8552 -1612
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +19 -2
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/environment/frame.d.ts.map +1 -1
- package/dist/environment/lifecycle.d.ts +5 -0
- package/dist/environment/lifecycle.d.ts.map +1 -1
- package/dist/errors/render.d.ts +209 -93
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/directional-shadow-projection.d.ts +23 -0
- package/dist/extract/directional-shadow-projection.d.ts.map +1 -0
- package/dist/extract/environment.d.ts +14 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/extract/visibility.d.ts.map +1 -1
- package/dist/features/fullscreen.d.ts.map +1 -1
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +10 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +13 -2
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +0 -1
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/gpu-usage.d.ts +2 -0
- package/dist/gpu-usage.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +19 -17
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +4 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/kernel-cache.d.ts +36 -0
- package/dist/ibl/kernel-cache.d.ts.map +1 -0
- package/dist/index.d.ts +35 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +51 -0
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +50 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -0
- package/dist/internal.mjs +1 -1
- package/dist/light-buffer-layout.d.ts +30 -13
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +54 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +20 -7
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts +2 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/errors.d.ts +4 -0
- package/dist/pipeline/standard-lighting/errors.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/graph.d.ts +24 -0
- package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts +38 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/layout.d.ts +28 -0
- package/dist/pipeline/standard-lighting/layout.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts +33 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/membership.d.ts +14 -0
- package/dist/pipeline/standard-lighting/membership.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts +16 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/topology.d.ts +45 -0
- package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/transport.d.ts +36 -0
- package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts +4 -13
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +12 -20
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +40 -7
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/point-shadow-inspection.d.ts +21 -0
- package/dist/point-shadow-inspection.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +29 -32
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +65 -15
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts +5 -0
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +12 -5
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-pass-timing/contract.d.ts +96 -0
- package/dist/record/gpu-pass-timing/contract.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/errors.d.ts +18 -0
- package/dist/record/gpu-pass-timing/errors.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/index.d.ts +8 -0
- package/dist/record/gpu-pass-timing/index.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/parser.d.ts +11 -0
- package/dist/record/gpu-pass-timing/parser.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/session.d.ts +43 -0
- package/dist/record/gpu-pass-timing/session.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +37 -0
- package/dist/record/gpu-timing.d.ts.map +1 -0
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +23 -2
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +2 -0
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +48 -3
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +81 -5
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +7 -4
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/reflection/filter.d.ts +22 -0
- package/dist/reflection/filter.d.ts.map +1 -0
- package/dist/reflection/gpu-table.d.ts +25 -0
- package/dist/reflection/gpu-table.d.ts.map +1 -0
- package/dist/reflection/projection.d.ts +91 -0
- package/dist/reflection/projection.d.ts.map +1 -0
- package/dist/render-contract.d.ts +114 -7
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-data.d.ts +10 -6
- package/dist/render-data.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +78 -2
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +113 -20
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +24 -3
- package/dist/render-system.d.ts.map +1 -1
- package/dist/renderer-inspect.d.ts +29 -0
- package/dist/renderer-inspect.d.ts.map +1 -0
- package/dist/renderer.d.ts +43 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/scene/render-scene.d.ts +14 -0
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/shadow-atlas.d.ts +3 -3
- package/dist/shadow-atlas.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +3 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/targets/contracts.d.ts +66 -0
- package/dist/targets/contracts.d.ts.map +1 -0
- package/dist/targets/graph-projection.d.ts +29 -0
- package/dist/targets/graph-projection.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +34 -0
- package/dist/targets/material-source.d.ts.map +1 -0
- package/dist/targets/owner.d.ts +32 -0
- package/dist/targets/owner.d.ts.map +1 -0
- package/dist/targets/physical.d.ts +18 -0
- package/dist/targets/physical.d.ts.map +1 -0
- package/dist/targets/readback.d.ts +39 -0
- package/dist/targets/readback.d.ts.map +1 -0
- package/dist/temporal/frame.d.ts +44 -0
- package/dist/temporal/frame.d.ts.map +1 -0
- package/dist/temporal/index.mjs +3 -3
- package/dist/typed-render-graph-primitives.d.ts +6 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-atlas.d.ts +10 -0
- package/dist/typed-shadow-atlas.d.ts.map +1 -0
- package/dist/typed-shadow-passes.d.ts +1 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/capability.d.ts +57 -0
- package/dist/volume/capability.d.ts.map +1 -0
- package/dist/volume/component.d.ts +61 -0
- package/dist/volume/component.d.ts.map +1 -0
- package/dist/volume/extract.d.ts +11 -0
- package/dist/volume/extract.d.ts.map +1 -0
- package/dist/volume/inspection.d.ts +38 -0
- package/dist/volume/inspection.d.ts.map +1 -0
- package/dist/volume/passes.d.ts +38 -0
- package/dist/volume/passes.d.ts.map +1 -0
- package/dist/volume/recovery.d.ts +38 -0
- package/dist/volume/recovery.d.ts.map +1 -0
- package/dist/volume/resources.d.ts +57 -0
- package/dist/volume/resources.d.ts.map +1 -0
- package/dist/volume/temporal.d.ts +35 -0
- package/dist/volume/temporal.d.ts.map +1 -0
- package/package.json +20 -20
- package/src/__tests__/bloom-exact-zero.unit.test.ts +48 -19
- package/src/__tests__/bloom-lifecycle.integration.test.ts +41 -13
- package/src/__tests__/camera-target-consumption.unit.test.ts +53 -0
- package/src/__tests__/cluster-binner.unit.test.ts +35 -0
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +7 -2
- package/src/__tests__/cube-camera-scheduler.unit.test.ts +70 -0
- package/src/__tests__/cube-camera-single-submit.perf.test.ts +75 -0
- package/src/__tests__/cube-camera-view-matrices.unit.test.ts +41 -0
- package/src/__tests__/cube-camera-vocabulary.unit.test.ts +47 -0
- package/src/__tests__/cube-camera.integration.test.ts +42 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +73 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +3 -3
- package/src/__tests__/docs-gate-green.unit.test.ts +38 -0
- package/src/__tests__/factory-contract.integration.test.ts +255 -29
- package/src/__tests__/fog-component.unit.test.ts +67 -0
- package/src/__tests__/fog.integration.test.ts +86 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +37 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +10 -9
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +17 -1
- package/src/__tests__/gpu-driven-production.integration.test.ts +16 -17
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +12 -4
- package/src/__tests__/gpu-pass-timing-browser-runner.ts +281 -0
- package/src/__tests__/gpu-pass-timing-coexistence.integration.test.ts +80 -0
- package/src/__tests__/gpu-pass-timing-contract.unit.test.ts +243 -0
- package/src/__tests__/gpu-pass-timing-exact-zero.unit.test.ts +131 -0
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +230 -0
- package/src/__tests__/gpu-pass-timing-observation.unit.test.ts +233 -0
- package/src/__tests__/gpu-pass-timing-session.unit.test.ts +438 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +26 -0
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +125 -0
- package/src/__tests__/hdrp-group2-visibility.unit.test.ts +24 -0
- package/src/__tests__/instances-culling.integration.test.ts +94 -0
- package/src/__tests__/instances-derived-bounds.unit.test.ts +118 -0
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +14 -14
- package/src/__tests__/material-observation.integration.test.ts +101 -0
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
- package/src/__tests__/pbr-view-layout.unit.test.ts +16 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +60 -0
- package/src/__tests__/public-surface.test-d.ts +10 -0
- package/src/__tests__/reflection-probe-authoring.unit.test.ts +71 -0
- package/src/__tests__/reflection-probe-filter.unit.test.ts +54 -0
- package/src/__tests__/reflection-probe-ibl-topology.unit.test.ts +45 -0
- package/src/__tests__/reflection-probe-pass-encode.integration.test.ts +101 -0
- package/src/__tests__/reflection-probe-performance.perf.test.ts +60 -0
- package/src/__tests__/reflection-probe-recovery.integration.test.ts +55 -0
- package/src/__tests__/reflection-probe-selection.unit.test.ts +46 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +23 -3
- package/src/__tests__/render-feature-docs.unit.test.ts +1 -1
- package/src/__tests__/render-target-admission.unit.test.ts +80 -0
- package/src/__tests__/render-target-graph-projection.unit.test.ts +102 -0
- package/src/__tests__/render-target-inspection.unit.test.ts +52 -0
- package/src/__tests__/render-target-material-source.test-d.ts +30 -0
- package/src/__tests__/render-target-material-source.unit.test.ts +97 -0
- package/src/__tests__/render-target-owner-placement.unit.test.ts +203 -0
- package/src/__tests__/render-target-owner.unit.test.ts +122 -0
- package/src/__tests__/render-target-probe-soak.perf.test.ts +94 -0
- package/src/__tests__/render-target-public-schema.json +107 -0
- package/src/__tests__/render-target-public-schema.unit.test.ts +91 -0
- package/src/__tests__/render-target-public-surface.test-d.ts +83 -0
- package/src/__tests__/render-target-readback.integration.test.ts +90 -0
- package/src/__tests__/render-target-recovery.integration.test.ts +85 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +76 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +1 -1
- package/src/__tests__/renderer-lifecycle.integration.test.ts +14 -0
- package/src/__tests__/shader-stage-surface.unit.test.ts +19 -4
- package/src/__tests__/skin-motion-regression.unit.test.ts +132 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +32 -2
- package/src/__tests__/standard-cluster-capability.integration.test.ts +63 -0
- package/src/__tests__/standard-cluster-transport.unit.test.ts +121 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +232 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +8 -5
- package/src/__tests__/standard-lighting-inspection.integration.test.ts +138 -0
- package/src/__tests__/standard-lighting-ssot.unit.test.ts +18 -0
- package/src/__tests__/standard-lighting-write.unit.test.ts +377 -0
- package/src/__tests__/standard-lighting.integration.test.ts +67 -0
- package/src/__tests__/standard-pipeline.dawn.test.ts +206 -5
- package/src/__tests__/standard-pipeline.integration.test.ts +181 -150
- package/src/__tests__/standard-probe-binding.unit.test.ts +25 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +23 -36
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +395 -14
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +2 -2
- package/src/__tests__/visibility-resolver.unit.test.ts +15 -0
- package/src/__tests__/volume-optics-oracle.unit.test.ts +85 -0
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +655 -0
- package/src/__tests__/volumetric-fog-component.unit.test.ts +71 -0
- package/src/__tests__/volumetric-fog-composite-stage-readback.dawn.test.ts +376 -0
- package/src/__tests__/volumetric-fog-errors.unit.test.ts +51 -0
- package/src/__tests__/volumetric-fog-inspection.unit.test.ts +77 -0
- package/src/__tests__/volumetric-fog-light-capability.unit.test.ts +19 -0
- package/src/__tests__/volumetric-fog-light-consumers.integration.test.ts +18 -0
- package/src/__tests__/volumetric-fog-light-errors.unit.test.ts +17 -0
- package/src/__tests__/volumetric-fog-light-topology.unit.test.ts +21 -0
- package/src/__tests__/volumetric-fog-light-transaction.integration.test.ts +53 -0
- package/src/__tests__/volumetric-fog-m9-watcher.integration.test.ts +27 -0
- package/src/__tests__/volumetric-fog-point-light-owner.integration.test.ts +44 -0
- package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +49 -0
- package/src/__tests__/volumetric-fog-point-spot-contract.unit.test.ts +28 -0
- package/src/__tests__/volumetric-fog-point-spot-lkg.integration.test.ts +65 -0
- package/src/__tests__/volumetric-fog-point-spot-selection.integration.test.ts +49 -0
- package/src/__tests__/volumetric-fog-point-spot-temporal.unit.test.ts +55 -0
- package/src/__tests__/volumetric-fog-projector-contract.unit.test.ts +22 -0
- package/src/__tests__/volumetric-fog-projector-inspection.unit.test.ts +12 -0
- package/src/__tests__/volumetric-fog-projector-surface-volume.integration.test.ts +11 -0
- package/src/__tests__/volumetric-fog-projector-transaction.integration.test.ts +26 -0
- package/src/__tests__/volumetric-fog-recovery.integration.test.ts +47 -0
- package/src/__tests__/volumetric-fog-selected-light-resolution.integration.test.ts +63 -0
- package/src/__tests__/volumetric-fog-spot-closure.integration.test.ts +26 -0
- package/src/__tests__/volumetric-fog-spot-contract.test-d.ts +21 -0
- package/src/__tests__/volumetric-fog-spot-contract.unit.test.ts +27 -0
- package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +14 -0
- package/src/__tests__/volumetric-fog-spot-optics.integration.test.ts +29 -0
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +550 -0
- package/src/__tests__/volumetric-fog-temporal-selected-light.unit.test.ts +33 -0
- package/src/__tests__/volumetric-fog-temporal.unit.test.ts +45 -0
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +237 -0
- package/src/__tests__/volumetric-fog-transparent.integration.test.ts +27 -0
- package/src/assembly/device-feature-admission.ts +73 -0
- package/src/assembly/directional-shadow-inspection.ts +122 -0
- package/src/assembly/factory.ts +1093 -246
- package/src/assembly/host-contract.ts +25 -0
- package/src/assembly/render-target-host.ts +847 -0
- package/src/assets/asset-decoders.ts +1 -1
- package/src/assets/render-asset-port.ts +7 -1
- package/src/capture/cube-views.ts +69 -0
- package/src/capture/scheduler.ts +265 -0
- package/src/components/__tests__/schema-contract.unit.test.ts +12 -0
- package/src/components/__tests__/schema-parity.unit.test.ts +9 -0
- package/src/components/camera.ts +4 -0
- package/src/components/cube-camera.ts +52 -0
- package/src/components/directional-light.ts +22 -2
- package/src/components/directional-shadow-filter.ts +57 -0
- package/src/components/index.ts +2 -0
- package/src/components/light-helpers.ts +85 -7
- package/src/components/reflection-probe.ts +49 -0
- package/src/components/spot-light.ts +22 -3
- package/src/device/gpu-residency.ts +168 -58
- package/src/environment/frame.ts +6 -24
- package/src/environment/lifecycle.ts +12 -0
- package/src/errors/render.ts +405 -143
- package/src/extract/directional-shadow-projection.ts +61 -0
- package/src/extract/environment.ts +57 -0
- package/src/extract/visibility.ts +25 -1
- package/src/features/fullscreen.ts +3 -0
- package/src/features/targets.ts +4 -1
- package/src/features/types.ts +10 -0
- package/src/fullscreen-post-process-pass.ts +43 -2
- package/src/gpu-driven/batch-topology.ts +1 -0
- package/src/gpu-driven/production-raster.ts +1 -3
- package/src/gpu-scene.ts +8 -1
- package/src/gpu-usage.ts +2 -0
- package/src/hdrp-buffers.ts +165 -59
- package/src/ibl/IblPipelineCache.ts +11 -0
- package/src/ibl/kernel-cache.ts +88 -0
- package/src/index.ts +186 -1
- package/src/inspection-types.ts +56 -0
- package/src/instances-derived-bounds.ts +171 -0
- package/src/light-buffer-layout.ts +74 -26
- package/src/mesh-material-bindings.ts +132 -0
- package/src/pbr-pipeline.ts +139 -27
- package/src/pipeline/standard-forward-lane.ts +65 -15
- package/src/pipeline/standard-lighting/errors.ts +6 -0
- package/src/pipeline/standard-lighting/graph.ts +157 -0
- package/src/pipeline/standard-lighting/inspection.ts +88 -0
- package/src/pipeline/standard-lighting/layout.ts +31 -0
- package/src/pipeline/standard-lighting/light-frame.ts +34 -0
- package/src/pipeline/standard-lighting/membership.ts +43 -0
- package/src/pipeline/standard-lighting/prepare.ts +37 -0
- package/src/pipeline/standard-lighting/topology.ts +120 -0
- package/src/pipeline/standard-lighting/transport.ts +77 -0
- package/src/pipeline/standard-pipeline.ts +141 -192
- package/src/pipeline/standard-post.ts +26 -7
- package/src/pipeline/standard-profile.ts +23 -30
- package/src/pipeline-spec.ts +84 -21
- package/src/point-shadow-inspection.ts +55 -0
- package/src/record/__tests__/temporal-payload.unit.test.ts +42 -1
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +73 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +40 -0
- package/src/record/frame-lighting.ts +470 -516
- package/src/record/frame-snapshot.ts +76 -28
- package/src/record/frame-targets.ts +23 -2
- package/src/record/frame.ts +1169 -79
- package/src/record/gpu-pass-timing/contract.ts +180 -0
- package/src/record/gpu-pass-timing/errors.ts +34 -0
- package/src/record/gpu-pass-timing/index.ts +37 -0
- package/src/record/gpu-pass-timing/parser.ts +97 -0
- package/src/record/gpu-pass-timing/session.ts +938 -0
- package/src/record/gpu-timing.ts +233 -0
- package/src/record/main-pass-geometry.ts +120 -80
- package/src/record/main-pass-material.ts +101 -11
- package/src/record/main-pass-sprite-draws.ts +54 -25
- package/src/record/main-pass.ts +71 -15
- package/src/record/render-context.ts +77 -0
- package/src/record/shadow-pass.ts +104 -66
- package/src/record/skybox-post-pass.ts +20 -4
- package/src/record/typed-frame-graph.ts +1016 -32
- package/src/record/view-ubo.ts +63 -28
- package/src/reflection/filter.ts +81 -0
- package/src/reflection/gpu-table.ts +44 -0
- package/src/reflection/projection.ts +281 -0
- package/src/render-contract.ts +147 -4
- package/src/render-data.ts +50 -22
- package/src/render-graph-primitives.ts +9 -4
- package/src/render-pipeline.ts +161 -2
- package/src/render-system-extract.ts +886 -103
- package/src/render-system.ts +1174 -66
- package/src/renderer-inspect.ts +66 -0
- package/src/renderer.ts +222 -0
- package/src/scene/render-scene.ts +117 -9
- package/src/shadow-atlas.ts +5 -5
- package/src/ssao-buffers.ts +9 -2
- package/src/targets/contracts.ts +182 -0
- package/src/targets/graph-projection.ts +169 -0
- package/src/targets/material-source.ts +143 -0
- package/src/targets/owner.ts +214 -0
- package/src/targets/physical.ts +18 -0
- package/src/targets/readback.ts +153 -0
- package/src/temporal/frame.ts +128 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +61 -23
- package/src/typed-render-graph-primitives.ts +34 -2
- package/src/typed-shadow-atlas.ts +17 -0
- package/src/typed-shadow-passes.ts +47 -40
- package/src/volume/capability.ts +173 -0
- package/src/volume/component.ts +110 -0
- package/src/volume/extract.ts +21 -0
- package/src/volume/inspection.ts +78 -0
- package/src/volume/passes.ts +686 -0
- package/src/volume/recovery.ts +86 -0
- package/src/volume/resources.ts +236 -0
- package/src/volume/temporal.ts +89 -0
- package/dist/chunk-IPXCABEP.mjs.map +0 -1
- package/dist/chunk-LOSO4CTV.mjs.map +0 -1
- package/dist/chunk-RJRUS55L.mjs.map +0 -1
- package/dist/chunk-YTQ5C7YQ.mjs +0 -584
- package/dist/chunk-YTQ5C7YQ.mjs.map +0 -1
|
@@ -40,9 +40,16 @@ import {
|
|
|
40
40
|
type SkylightBindGroupResources,
|
|
41
41
|
type TransmissionBindGroupResources,
|
|
42
42
|
} from '../ibl/skylight-bind-group';
|
|
43
|
+
import type { PipelineGroup2Contract } from '../pbr-pipeline';
|
|
43
44
|
import { isStandardPbrMaterialShader } from '../pbr-pipeline';
|
|
44
45
|
import { deriveTextureExtent } from '../render-data';
|
|
45
46
|
import type { MaterialSnapshot } from '../render-system-extract';
|
|
47
|
+
import type { RenderTargetTextureSource } from '../targets/contracts';
|
|
48
|
+
import {
|
|
49
|
+
type RenderTargetMaterialSourceBinding,
|
|
50
|
+
resolveRenderTargetMaterialSource,
|
|
51
|
+
} from '../targets/material-source';
|
|
52
|
+
import type { StandardReflectionProbeBinding } from './frame-lighting';
|
|
46
53
|
import type { BindGroupCounts, MaterialBgAssemblyCacheEntry } from './frame-snapshot';
|
|
47
54
|
import { extractEntryResourceHandle, getOrCreatePerEntity } from './mesh-ssbo';
|
|
48
55
|
import {
|
|
@@ -51,6 +58,23 @@ import {
|
|
|
51
58
|
STANDARD_PBR_UBO_SIZE,
|
|
52
59
|
} from './render-context';
|
|
53
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Resolve the group(2) resource layout from the material shader contract.
|
|
63
|
+
* Standard clustered PBR consumes the unified cluster bind group; every other
|
|
64
|
+
* material consumes the ordinary mesh bind group. Missing ordinary resources
|
|
65
|
+
* remain missing so the caller can skip the draw rather than violate layout
|
|
66
|
+
* compatibility by binding a cluster group.
|
|
67
|
+
*/
|
|
68
|
+
export function selectMaterialGroup2(
|
|
69
|
+
clusterGroup: BindGroup | null,
|
|
70
|
+
meshGroup: BindGroup | null,
|
|
71
|
+
group2Contract: PipelineGroup2Contract,
|
|
72
|
+
): BindGroup | null {
|
|
73
|
+
if (group2Contract === 'cluster') return clusterGroup;
|
|
74
|
+
if (group2Contract === 'mesh') return meshGroup;
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
54
78
|
// Param schemas are immutable runtime contracts: the shader registry installs
|
|
55
79
|
// them once and material snapshots only retain the same array reference. Keep
|
|
56
80
|
// the expensive pure derivation on that identity so the per-submesh record
|
|
@@ -412,12 +436,31 @@ const DEFAULT_STANDARD_TEXTURE_COORDINATES = new Float32Array([
|
|
|
412
436
|
0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
|
|
413
437
|
]);
|
|
414
438
|
|
|
439
|
+
export interface StandardReflectionProbeMaterialProjection {
|
|
440
|
+
readonly probeIndex: number | undefined;
|
|
441
|
+
readonly fallbackToSkylight: boolean;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/** Projects the selected scene row into the Standard material lane. */
|
|
445
|
+
export function projectReflectionProbeMaterialBinding(
|
|
446
|
+
binding: StandardReflectionProbeBinding,
|
|
447
|
+
): StandardReflectionProbeMaterialProjection {
|
|
448
|
+
return {
|
|
449
|
+
probeIndex: binding.probeIndex,
|
|
450
|
+
fallbackToSkylight: binding.useSkylight,
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
415
454
|
/** Derives the logical-content UV scale for an uploaded material texture. */
|
|
416
455
|
export function materialTextureUvScale(
|
|
417
|
-
texture: Pick<TextureAsset, '
|
|
456
|
+
texture: Pick<TextureAsset, 'shape' | 'format'> | undefined,
|
|
418
457
|
): readonly [number, number] {
|
|
419
458
|
if (texture === undefined) return [1, 1];
|
|
420
|
-
return deriveTextureExtent(
|
|
459
|
+
return deriveTextureExtent(
|
|
460
|
+
texture.format,
|
|
461
|
+
texture.shape.extent.width,
|
|
462
|
+
texture.shape.extent.height,
|
|
463
|
+
).uvScale;
|
|
421
464
|
}
|
|
422
465
|
|
|
423
466
|
function materialTextureForField(
|
|
@@ -429,6 +472,18 @@ function materialTextureForField(
|
|
|
429
472
|
return material.textureHandles?.get(field);
|
|
430
473
|
}
|
|
431
474
|
|
|
475
|
+
/** Resolve a renderer-local target source without entering AssetRegistry. */
|
|
476
|
+
export function materialRenderTargetSourceForField(
|
|
477
|
+
material: MaterialSnapshot,
|
|
478
|
+
field: string,
|
|
479
|
+
resolveSource?: RenderSystemRuntime['resolveRenderTargetTextureSource'],
|
|
480
|
+
): RenderTargetMaterialSourceBinding | undefined {
|
|
481
|
+
const source = material.textureSources?.get(field) as RenderTargetTextureSource | undefined;
|
|
482
|
+
return source === undefined
|
|
483
|
+
? undefined
|
|
484
|
+
: (resolveSource?.(source) ?? resolveRenderTargetMaterialSource(source));
|
|
485
|
+
}
|
|
486
|
+
|
|
432
487
|
/**
|
|
433
488
|
* Appends the engine-owned scale for every built-in material texture binding.
|
|
434
489
|
* Asset dimensions remain logical; this is the sole record-stage projection
|
|
@@ -579,7 +634,15 @@ export function userRegionTextureFieldOrder(
|
|
|
579
634
|
export function defaultViewForUserRegionField(
|
|
580
635
|
field: string,
|
|
581
636
|
pipelineState: PipelineState,
|
|
637
|
+
schema?: readonly ParamSchemaEntry[],
|
|
582
638
|
): TextureView {
|
|
639
|
+
const parameter = schema?.find((entry) => entry.name === field);
|
|
640
|
+
if (parameter?.type === 'texture_cube') {
|
|
641
|
+
// The renderer already owns a valid white cube for the Skylight fallback.
|
|
642
|
+
// Use it until a receipt-promoted RenderTarget source becomes available;
|
|
643
|
+
// binding a 2D view here would invalidate the custom cube material BGL.
|
|
644
|
+
return pipelineState.skylightFallback?.prefilterView ?? pipelineState.defaultWhiteTextureView;
|
|
645
|
+
}
|
|
583
646
|
if (field === 'normalTexture') return pipelineState.defaultNormalTextureView;
|
|
584
647
|
if (field === 'baseColorTexture') return pipelineState.fallbackTextureView;
|
|
585
648
|
return pipelineState.defaultWhiteTextureView;
|
|
@@ -881,6 +944,11 @@ export interface PerSubmeshMaterialBgDeps {
|
|
|
881
944
|
readonly materialSlice: number;
|
|
882
945
|
readonly videoHighPerfAvailable: boolean;
|
|
883
946
|
readonly skylightResources: SkylightBindGroupResources;
|
|
947
|
+
readonly resolveRenderTargetTextureSource?: RenderSystemRuntime['resolveRenderTargetTextureSource'];
|
|
948
|
+
readonly resolveReflectionProbeResources?: (
|
|
949
|
+
materialWorld: World,
|
|
950
|
+
entityKey: number,
|
|
951
|
+
) => SkylightBindGroupResources | undefined;
|
|
884
952
|
readonly materialBgShared: Map<string, WeakMap<object, unknown>>;
|
|
885
953
|
/** Cross-frame final BG reuse keyed by the stable source material handle. */
|
|
886
954
|
readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;
|
|
@@ -928,11 +996,15 @@ export function buildPerSubmeshMaterialBg(
|
|
|
928
996
|
materialSlice,
|
|
929
997
|
videoHighPerfAvailable,
|
|
930
998
|
skylightResources,
|
|
999
|
+
resolveRenderTargetTextureSource,
|
|
1000
|
+
resolveReflectionProbeResources,
|
|
931
1001
|
materialBgShared,
|
|
932
1002
|
materialBgAssemblyCache,
|
|
933
1003
|
transmissionBackdropView,
|
|
934
1004
|
bindGroupCounts,
|
|
935
1005
|
} = deps;
|
|
1006
|
+
const effectiveSkylightResources =
|
|
1007
|
+
resolveReflectionProbeResources?.(materialWorld, entityKey) ?? skylightResources;
|
|
936
1008
|
const smMaterialHandle = submeshMaterial.materialHandle;
|
|
937
1009
|
const materialCacheKey =
|
|
938
1010
|
smMaterialHandle === undefined ? undefined : `${materialWorld.identity}:${smMaterialHandle}`;
|
|
@@ -951,7 +1023,7 @@ export function buildPerSubmeshMaterialBg(
|
|
|
951
1023
|
submeshMaterial,
|
|
952
1024
|
smMaterialBgl,
|
|
953
1025
|
pipelineState.materialUniformBuffer.buffer,
|
|
954
|
-
|
|
1026
|
+
effectiveSkylightResources,
|
|
955
1027
|
store.materialResourceEpoch,
|
|
956
1028
|
transmissionBackdropView,
|
|
957
1029
|
)
|
|
@@ -999,11 +1071,25 @@ export function buildPerSubmeshMaterialBg(
|
|
|
999
1071
|
const textureBinding = samplerBinding + 1;
|
|
1000
1072
|
let smView: TextureView =
|
|
1001
1073
|
field !== undefined
|
|
1002
|
-
? defaultViewForUserRegionField(field, pipelineState)
|
|
1074
|
+
? defaultViewForUserRegionField(field, pipelineState, smSchema)
|
|
1003
1075
|
: pipelineState.defaultWhiteTextureView;
|
|
1004
1076
|
const smVideoClip =
|
|
1005
1077
|
field !== undefined ? submeshMaterial.videoTextureFields?.get(field) : undefined;
|
|
1006
|
-
|
|
1078
|
+
const smTargetSource =
|
|
1079
|
+
field === undefined
|
|
1080
|
+
? undefined
|
|
1081
|
+
: materialRenderTargetSourceForField(
|
|
1082
|
+
submeshMaterial,
|
|
1083
|
+
field,
|
|
1084
|
+
resolveRenderTargetTextureSource,
|
|
1085
|
+
);
|
|
1086
|
+
if (smTargetSource !== undefined) {
|
|
1087
|
+
// The Renderer host resolves the generation-checked physical view. A
|
|
1088
|
+
// candidate is never exposed here; until its matching FrameReceipt
|
|
1089
|
+
// completes, the material remains on the neutral fallback.
|
|
1090
|
+
if (smTargetSource.textureView !== undefined) smView = smTargetSource.textureView;
|
|
1091
|
+
else materialResourcesResident = false;
|
|
1092
|
+
} else if (smVideoClip !== undefined) {
|
|
1007
1093
|
const view = videoTextureView(
|
|
1008
1094
|
materialWorld,
|
|
1009
1095
|
runtime.dynamicTextureStore,
|
|
@@ -1045,12 +1131,16 @@ export function buildPerSubmeshMaterialBg(
|
|
|
1045
1131
|
// authored UV textures and is not a backdrop sampler.
|
|
1046
1132
|
const transmissionSampler =
|
|
1047
1133
|
transmissionBackdropView != null
|
|
1048
|
-
?
|
|
1134
|
+
? effectiveSkylightResources.prefilterSampler
|
|
1049
1135
|
: pipelineState.defaultSampler;
|
|
1050
|
-
const smMergedEntries = assembleMaterialWithSkylightEntries(
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1136
|
+
const smMergedEntries = assembleMaterialWithSkylightEntries(
|
|
1137
|
+
smBaseEntries,
|
|
1138
|
+
effectiveSkylightResources,
|
|
1139
|
+
{
|
|
1140
|
+
sampler: transmissionSampler,
|
|
1141
|
+
...(transmissionBackdropView === undefined ? {} : { backdropView: transmissionBackdropView }),
|
|
1142
|
+
} satisfies TransmissionBindGroupResources,
|
|
1143
|
+
);
|
|
1054
1144
|
const createBindGroup = (): BindGroup => {
|
|
1055
1145
|
const result = runtime.device.createBindGroup({
|
|
1056
1146
|
label: 'pbr-material-skylight-bg',
|
|
@@ -1082,7 +1172,7 @@ export function buildPerSubmeshMaterialBg(
|
|
|
1082
1172
|
materialResourceEpoch: store.materialResourceEpoch,
|
|
1083
1173
|
materialBgl: smMaterialBgl,
|
|
1084
1174
|
materialBuffer: pipelineState.materialUniformBuffer.buffer,
|
|
1085
|
-
skylightResources,
|
|
1175
|
+
skylightResources: effectiveSkylightResources,
|
|
1086
1176
|
bindGroup: smBindGroup,
|
|
1087
1177
|
});
|
|
1088
1178
|
}
|
|
@@ -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
|