@forgeax/engine-render 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +150 -29
- package/dist/assembly/backend-contract.d.ts +13 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -1
- package/dist/assembly/device-feature-admission.d.ts.map +1 -1
- package/dist/assembly/factory.d.ts +14 -6
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +10 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/authoring.mjs +1 -1
- package/dist/{chunk-PCHBPYML.mjs → chunk-4L3P6DT5.mjs} +2 -2
- package/dist/chunk-4L3P6DT5.mjs.map +1 -0
- package/dist/{chunk-VFPLTKCU.mjs → chunk-4NPUASZR.mjs} +15 -4
- package/dist/chunk-4NPUASZR.mjs.map +1 -0
- package/dist/chunk-DIYW3M5D.mjs +5085 -0
- package/dist/chunk-DIYW3M5D.mjs.map +1 -0
- package/dist/chunk-FBC4R44J.mjs +1003 -0
- package/dist/chunk-FBC4R44J.mjs.map +1 -0
- package/dist/{chunk-FS2KNUQH.mjs → chunk-FF7K3FSO.mjs} +253 -489
- package/dist/chunk-FF7K3FSO.mjs.map +1 -0
- package/dist/chunk-HZUPSYW7.mjs +1104 -0
- package/dist/chunk-HZUPSYW7.mjs.map +1 -0
- package/dist/{chunk-6OPXDQ2E.mjs → chunk-QODA5UKU.mjs} +33 -294
- package/dist/chunk-QODA5UKU.mjs.map +1 -0
- package/dist/chunk-YALPS44A.mjs +296 -0
- package/dist/chunk-YALPS44A.mjs.map +1 -0
- package/dist/{chunk-5YADUCA7.mjs → chunk-ZUWKAZ2I.mjs} +585 -991
- package/dist/chunk-ZUWKAZ2I.mjs.map +1 -0
- package/dist/cluster-binner.d.ts +5 -0
- package/dist/cluster-binner.d.ts.map +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts +4 -0
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/light-probe.d.ts +9 -0
- package/dist/components/light-probe.d.ts.map +1 -0
- package/dist/components/rect-area-light.d.ts +12 -0
- package/dist/components/rect-area-light.d.ts.map +1 -0
- package/dist/components/scene-instance.d.ts +4 -0
- package/dist/components/scene-instance.d.ts.map +1 -1
- package/dist/components/spot-light.d.ts +3 -0
- package/dist/components/spot-light.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +10437 -10044
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +8 -1
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/device/lifecycle-transaction.d.ts +2 -0
- package/dist/device/lifecycle-transaction.d.ts.map +1 -0
- package/dist/environment/lifecycle.d.ts.map +1 -1
- package/dist/errors/gpu-driven.d.ts +26 -0
- package/dist/errors/gpu-driven.d.ts.map +1 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/recover.d.ts +9 -1
- package/dist/errors/recover.d.ts.map +1 -1
- package/dist/errors/render.d.ts +26 -1
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/gpu-driven.d.ts +50 -0
- package/dist/extract/gpu-driven.d.ts.map +1 -0
- package/dist/extract/visibility.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +34 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/prepared-draw.d.ts +63 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +98 -2
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/view-gpu.d.ts +64 -1
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene-schema.d.ts +14 -0
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +8 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/gpu-usage.d.ts +0 -1
- package/dist/gpu-usage.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +3 -3
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +90 -5
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +163 -1
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/internal.d.ts +9 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +23 -2
- package/dist/internal.mjs.map +1 -1
- package/dist/light-buffer-layout.d.ts +58 -149
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/materials.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +26 -12
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/light-frame.d.ts +3 -3
- package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/topology.d.ts +1 -1
- package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +2 -0
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +1 -1
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/prepare/extended-lighting/ltc-resources.d.ts +31 -0
- package/dist/prepare/extended-lighting/ltc-resources.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/resources.d.ts +72 -0
- package/dist/prepare/extended-lighting/resources.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/spot-modifiers.d.ts +42 -0
- package/dist/prepare/extended-lighting/spot-modifiers.d.ts.map +1 -0
- package/dist/prepare/extended-lighting/state.d.ts +24 -0
- package/dist/prepare/extended-lighting/state.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +8 -6
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +50 -10
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts +7 -3
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-timing.d.ts +19 -7
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/helpers.d.ts +0 -20
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +6 -1
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +3 -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/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +57 -6
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +49 -2
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +1 -2
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/reflection/inspection.d.ts +10 -0
- package/dist/reflection/inspection.d.ts.map +1 -0
- package/dist/reflection/projection.d.ts +49 -0
- package/dist/reflection/projection.d.ts.map +1 -1
- package/dist/reflection/record-owner.d.ts +60 -0
- package/dist/reflection/record-owner.d.ts.map +1 -0
- package/dist/render-contract.d.ts +14 -8
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +7 -0
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +104 -16
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +12 -1
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/probe-blend-record.d.ts +22 -0
- package/dist/scene/probe-blend-record.d.ts.map +1 -0
- package/dist/scene/probe-blend.d.ts +142 -0
- package/dist/scene/probe-blend.d.ts.map +1 -0
- package/dist/scene/render-scene-types.d.ts +0 -6
- package/dist/scene/render-scene-types.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +103 -9
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/visibility/bounds.d.ts +20 -0
- package/dist/scene/visibility/bounds.d.ts.map +1 -0
- package/dist/scene/visibility/budget.d.ts +16 -0
- package/dist/scene/visibility/budget.d.ts.map +1 -0
- package/dist/scene/visibility/facet.d.ts +73 -0
- package/dist/scene/visibility/facet.d.ts.map +1 -0
- package/dist/scene/visibility/gpu-frame-timing.d.ts +41 -0
- package/dist/scene/visibility/gpu-frame-timing.d.ts.map +1 -0
- package/dist/scene/visibility/gpu-lod.d.ts +46 -0
- package/dist/scene/visibility/gpu-lod.d.ts.map +1 -0
- package/dist/scene/visibility/inspection.d.ts +132 -0
- package/dist/scene/visibility/inspection.d.ts.map +1 -0
- package/dist/scene/visibility/lod-selector.d.ts +25 -0
- package/dist/scene/visibility/lod-selector.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-confidence.d.ts +81 -0
- package/dist/scene/visibility/occlusion-confidence.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-pass.d.ts +57 -0
- package/dist/scene/visibility/occlusion-pass.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-query-pool.d.ts +57 -0
- package/dist/scene/visibility/occlusion-query-pool.d.ts.map +1 -0
- package/dist/scene/visibility/occlusion-runtime.d.ts +96 -0
- package/dist/scene/visibility/occlusion-runtime.d.ts.map +1 -0
- package/dist/scene/visibility/types.d.ts +34 -0
- package/dist/scene/visibility/types.d.ts.map +1 -0
- package/dist/ssr/admission.d.ts +122 -0
- package/dist/ssr/admission.d.ts.map +1 -0
- package/dist/ssr/composition.d.ts +32 -0
- package/dist/ssr/composition.d.ts.map +1 -0
- package/dist/ssr/errors.d.ts +39 -0
- package/dist/ssr/errors.d.ts.map +1 -0
- package/dist/ssr/identity.d.ts +13 -0
- package/dist/ssr/identity.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +1 -1
- package/dist/temporal/frame-coordinator.d.ts +13 -0
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +2 -0
- package/dist/temporal/frame.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -5
- package/dist/temporal/view.d.ts +7 -0
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/tilemap-chunk-extract-system.d.ts +1 -1
- package/dist/typed-render-graph-primitives.d.ts +4 -0
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +8 -4
- package/dist/volume/passes.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +5 -0
- package/src/__tests__/detached-inspection.integration.test.ts +6 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +13 -1
- package/src/__tests__/direct-light-snapshot.unit.test.ts +59 -3
- package/src/__tests__/environment-generation.integration.test.ts +16 -0
- package/src/__tests__/evidence-identity.ts +13 -0
- package/src/__tests__/evidence-identity.unit.test.ts +24 -0
- package/src/__tests__/extended-lighting-recovery.browser.test.ts +14 -0
- package/src/__tests__/extended-lighting-recovery.dawn.test.ts +14 -0
- package/src/__tests__/extended-lighting-recovery.integration.test.ts +81 -0
- package/src/__tests__/extended-lighting-resources.unit.test.ts +51 -0
- package/src/__tests__/extended-lighting-zero-feature.integration.test.ts +52 -0
- package/src/__tests__/factory-contract.integration.test.ts +33 -0
- package/src/__tests__/frame-observation.contract.test.ts +15 -0
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +1 -0
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +1 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +572 -9
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +66 -2
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +26 -1
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +89 -2
- package/src/__tests__/gpu-driven-view.browser.test.ts +3 -3
- package/src/__tests__/gpu-driven-view.dawn.test.ts +3 -3
- package/src/__tests__/gpu-driven-view.unit.test.ts +50 -0
- package/src/__tests__/gpu-lod-evidence.ts +188 -0
- package/src/__tests__/gpu-lod-fallback.integration.test.ts +10 -0
- package/src/__tests__/gpu-lod-indirect.integration.test.ts +40 -0
- package/src/__tests__/gpu-lod-parity.dawn.test.ts +29 -0
- package/src/__tests__/gpu-lod-readiness.integration.test.ts +52 -0
- package/src/__tests__/gpu-lod-schema.unit.test.ts +66 -0
- package/src/__tests__/gpu-lod-selector.unit.test.ts +28 -0
- package/src/__tests__/gpu-lod-silhouette.browser.test.ts +13 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +66 -1
- package/src/__tests__/gpu-scene.dawn.test.ts +8 -1
- package/src/__tests__/gpu-scene.unit.test.ts +49 -3
- package/src/__tests__/light-buffer-layout.unit.test.ts +113 -3
- package/src/__tests__/light-inspection.unit.test.ts +55 -0
- package/src/__tests__/light-resource-error.unit.test.ts +43 -0
- package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +109 -0
- package/src/__tests__/lod-bounds.unit.test.ts +42 -0
- package/src/__tests__/lod-cpu-lane.integration.test.ts +55 -0
- package/src/__tests__/lod-cpu-no-change.perf.test.ts +19 -0
- package/src/__tests__/lod-gpu-frame-timing.unit.test.ts +49 -0
- package/src/__tests__/lod-multi-view.integration.test.ts +63 -0
- package/src/__tests__/lod-occlusion-device-loss.integration.test.ts +27 -0
- package/src/__tests__/lod-occlusion-final-decision.integration.test.ts +47 -0
- package/src/__tests__/lod-occlusion-inspection.integration.test.ts +217 -0
- package/src/__tests__/lod-occlusion-inspection.schema.test-d.ts +14 -0
- package/src/__tests__/lod-occlusion-inspection.unit.test.ts +72 -0
- package/src/__tests__/lod-occlusion-visual-evidence.ts +91 -0
- package/src/__tests__/lod-occlusion.browser.test.ts +15 -0
- package/src/__tests__/lod-occlusion.dawn.test.ts +20 -0
- package/src/__tests__/lod-selector.profile.test.ts +35 -0
- package/src/__tests__/lod-selector.unit.test.ts +68 -0
- package/src/__tests__/lod-visibility-identity.unit.test.ts +198 -0
- package/src/__tests__/lod-visibility-lifecycle.integration.test.ts +132 -0
- package/src/__tests__/ltc-resources.unit.test.ts +32 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +17 -0
- package/src/__tests__/occlusion-confidence.unit.test.ts +168 -0
- package/src/__tests__/occlusion-invalidation.integration.test.ts +37 -0
- package/src/__tests__/occlusion-pass-routing.unit.test.ts +16 -0
- package/src/__tests__/occlusion-pass.dawn.test.ts +20 -0
- package/src/__tests__/occlusion-pass.integration.test.ts +43 -0
- package/src/__tests__/occlusion-pass.rhi-null.test.ts +22 -0
- package/src/__tests__/occlusion-query-pool.rhi-null.test.ts +21 -0
- package/src/__tests__/occlusion-query-pool.unit.test.ts +95 -0
- package/src/__tests__/occlusion-query-ticket.integration.test.ts +47 -0
- package/src/__tests__/occlusion-query.dawn.test.ts +16 -0
- package/src/__tests__/occlusion-query.evidence.ts +178 -0
- package/src/__tests__/occlusion-query.rhi-null.test.ts +31 -0
- package/src/__tests__/occlusion-runtime.unit.test.ts +120 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
- package/src/__tests__/probe-bindings.unit.test.ts +200 -0
- package/src/__tests__/probe-blend-numeric.unit.test.ts +67 -0
- package/src/__tests__/probe-blend-oracle.unit.test.ts +136 -0
- package/src/__tests__/probe-capacity.integration.test.ts +97 -0
- package/src/__tests__/probe-recovery.integration.test.ts +104 -0
- package/src/__tests__/probe-scene-dirty.integration.test.ts +211 -0
- package/src/__tests__/profiler-phase-catalog.test.ts +4 -1
- package/src/__tests__/profiler-phase-token.test.ts +1 -0
- package/src/__tests__/rect-area-boundary.unit.test.ts +24 -0
- package/src/__tests__/reflection-fallback-graph.unit.test.ts +67 -0
- package/src/__tests__/reflection-fallback-inspection.unit.test.ts +77 -0
- package/src/__tests__/reflection-fallback-lifecycle.integration.test.ts +21 -0
- package/src/__tests__/reflection-fallback-projection.unit.test.ts +90 -0
- package/src/__tests__/reflection-fallback-source.unit.test.ts +32 -0
- package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
- package/src/__tests__/render-feature-docs.unit.test.ts +12 -7
- package/src/__tests__/render-graph-fallback.integration.test.ts +24 -0
- package/src/__tests__/render-perf/extended-lighting.bench.test.ts +66 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +447 -18
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +76 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +22 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +2 -2
- package/src/__tests__/spot-modifier-projection.unit.test.ts +70 -0
- package/src/__tests__/ssr-admission-matrix.integration.test.ts +206 -0
- package/src/__tests__/ssr-composition.unit.test.ts +46 -0
- package/src/__tests__/ssr-fallback-zero-work.bench.test.ts +94 -0
- package/src/__tests__/ssr-recovery-errors.unit.test.ts +58 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +67 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +7 -0
- package/src/__tests__/standard-lighting-inspection.integration.test.ts +1 -1
- package/src/__tests__/standard-lighting-write.unit.test.ts +66 -2
- package/src/__tests__/temporal-fallback-generation.integration.test.ts +16 -0
- package/src/__tests__/temporal-view.unit.test.ts +3 -3
- package/src/__tests__/transmission-prewarm.unit.test.ts +69 -0
- package/src/__tests__/visibility-budget.integration.test.ts +140 -0
- package/src/__tests__/visibility-budget.unit.test.ts +70 -0
- package/src/__tests__/visibility-extract.integration.test.ts +11 -6
- package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +6 -3
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +31 -28
- package/src/assembly/backend-contract.ts +13 -0
- package/src/assembly/device-feature-admission.ts +16 -9
- package/src/assembly/factory.ts +547 -93
- package/src/assembly/host-contract.ts +10 -0
- package/src/cluster-binner.ts +31 -0
- package/src/components/__tests__/lighting-authoring.unit.test.ts +39 -0
- package/src/components/__tests__/rect-area-light.unit.test.ts +33 -0
- package/src/components/index.ts +3 -0
- package/src/components/light-helpers.ts +52 -1
- package/src/components/light-probe.ts +13 -0
- package/src/components/rect-area-light.ts +15 -0
- package/src/components/scene-instance.ts +6 -0
- package/src/components/spot-light.ts +3 -0
- package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
- package/src/device/gpu-residency.ts +140 -9
- package/src/device/lifecycle-transaction.ts +12 -0
- package/src/environment/lifecycle.ts +8 -1
- package/src/errors/gpu-driven.ts +92 -0
- package/src/errors/index.ts +1 -0
- package/src/errors/recover.ts +32 -0
- package/src/errors/render.ts +55 -1
- package/src/extract/camera.ts +3 -3
- package/src/extract/gpu-driven.ts +108 -0
- package/src/extract/visibility.ts +0 -23
- package/src/gpu-driven/batch-topology.ts +206 -28
- package/src/gpu-driven/prepared-draw.ts +208 -0
- package/src/gpu-driven/production-raster.ts +953 -41
- package/src/gpu-driven/view-gpu.ts +411 -29
- package/src/gpu-scene-schema.ts +13 -0
- package/src/gpu-scene.ts +134 -65
- package/src/gpu-usage.ts +0 -1
- package/src/hdrp-buffers.ts +6 -6
- package/src/index.ts +74 -0
- package/src/inspection-types.ts +220 -1
- package/src/internal.ts +38 -0
- package/src/light-buffer-layout.ts +154 -324
- package/src/materials.ts +16 -2
- package/src/pbr-pipeline.ts +151 -45
- package/src/pipeline/standard-forward-lane.ts +47 -0
- package/src/pipeline/standard-lighting/graph.ts +2 -1
- package/src/pipeline/standard-lighting/light-frame.ts +3 -2
- package/src/pipeline/standard-lighting/topology.ts +1 -1
- package/src/pipeline/standard-lighting/transport.ts +2 -1
- package/src/pipeline/standard-pipeline.ts +2 -0
- package/src/pipeline-builder.ts +5 -2
- package/src/pipeline-spec.ts +12 -1
- package/src/plugin.ts +4 -0
- package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +56 -0
- package/src/prepare/extended-lighting/ltc-resources.ts +136 -0
- package/src/prepare/extended-lighting/resources.ts +389 -0
- package/src/prepare/extended-lighting/spot-modifiers.ts +194 -0
- package/src/prepare/extended-lighting/state.ts +92 -0
- package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
- package/src/record/__tests__/temporal-payload.unit.test.ts +23 -1
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +20 -1
- package/src/record/frame-lighting.ts +252 -53
- package/src/record/frame-snapshot.ts +57 -12
- package/src/record/frame.ts +410 -93
- package/src/record/gpu-timing.ts +108 -44
- package/src/record/helpers.ts +0 -58
- package/src/record/main-pass-geometry.ts +204 -39
- package/src/record/main-pass-material.ts +8 -1
- package/src/record/main-pass-sprite-draws.ts +52 -85
- package/src/record/mesh-ssbo.ts +47 -36
- package/src/record/render-context.ts +65 -4
- package/src/record/shadow-pass.ts +66 -40
- package/src/record/typed-frame-graph.ts +225 -83
- package/src/record/view-ubo.ts +14 -24
- package/src/reflection/inspection.ts +67 -0
- package/src/reflection/projection.ts +196 -1
- package/src/reflection/record-owner.ts +1283 -0
- package/src/render-contract.ts +17 -5
- package/src/render-pipeline.ts +5 -0
- package/src/render-system-extract.ts +493 -134
- package/src/render-system.ts +811 -615
- package/src/scene/__tests__/changed-block-summary.candidate.test.ts +36 -0
- package/src/scene/probe-blend-record.ts +54 -0
- package/src/scene/probe-blend.ts +813 -0
- package/src/scene/render-scene-types.ts +0 -7
- package/src/scene/render-scene.ts +848 -183
- package/src/scene/visibility/bounds.ts +57 -0
- package/src/scene/visibility/budget.ts +40 -0
- package/src/scene/visibility/facet.ts +400 -0
- package/src/scene/visibility/gpu-frame-timing.ts +101 -0
- package/src/scene/visibility/gpu-lod.ts +119 -0
- package/src/scene/visibility/inspection.ts +313 -0
- package/src/scene/visibility/lod-selector.ts +84 -0
- package/src/scene/visibility/occlusion-confidence.ts +478 -0
- package/src/scene/visibility/occlusion-pass.ts +165 -0
- package/src/scene/visibility/occlusion-query-pool.ts +178 -0
- package/src/scene/visibility/occlusion-runtime.ts +672 -0
- package/src/scene/visibility/types.ts +50 -0
- package/src/ssr/admission.ts +451 -0
- package/src/ssr/composition.ts +73 -0
- package/src/ssr/errors.ts +76 -0
- package/src/ssr/identity.ts +12 -0
- package/src/systems/skin-palette-allocator.ts +1 -1
- package/src/temporal/frame-coordinator.ts +26 -0
- package/src/temporal/frame.ts +14 -1
- package/src/temporal/view.ts +11 -0
- package/src/tilemap-chunk-extract-system.ts +4 -4
- package/src/typed-render-graph-primitives.ts +48 -0
- package/src/volume/passes.ts +46 -49
- package/dist/.tsbuildinfo +0 -1
- package/dist/chunk-5YADUCA7.mjs.map +0 -1
- package/dist/chunk-6OPXDQ2E.mjs.map +0 -1
- package/dist/chunk-BXBQQKFQ.mjs +0 -67
- package/dist/chunk-BXBQQKFQ.mjs.map +0 -1
- package/dist/chunk-FS2KNUQH.mjs.map +0 -1
- package/dist/chunk-PCHBPYML.mjs.map +0 -1
- package/dist/chunk-VFPLTKCU.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/render-pipeline.ts","../src/light-buffer-layout.ts","../src/pipeline-spec.ts","../src/record/mesh-ssbo.ts","../src/ssao-buffers.ts","../src/hdrp-buffers.ts","../src/cluster-binner.ts","../src/pipeline/standard-lighting/errors.ts","../src/pipeline/standard-lighting/membership.ts","../src/pipeline/standard-lighting/prepare.ts","../src/pipeline/standard-lighting/transport.ts","../src/post-process-errors.ts","../src/ssao-config.ts","../src/record/helpers.ts","../src/record/view-ubo.ts","../src/record/frame-lighting.ts","../src/ibl/IblPipelineCache.ts","../src/points-lines/record.ts","../src/gpu-resource.ts","../src/ibl/skylight-bind-group.ts","../src/render-data.ts","../src/record/render-context.ts","../src/record/main-pass-material.ts","../src/record/main-pass-geometry.ts","../src/record/main-pass-sprite-draws.ts","../src/record/shadow-pass.ts","../src/record/main-pass.ts","../src/record/skybox-post-pass.ts","../src/fullscreen-post-process-pass.ts","../src/render-graph-primitives.ts","../src/temporal/gpu.ts","../src/typed-render-graph-primitives.ts","../src/temporal/standard-scene-data.ts"],"names":["ok","parts","err","cache","RhiError","mat4","vec3","hdrpBuffers","toShared","deriveVertexLayoutProjection","bytesPerRow","blockBytesPerRow","resolveAssetHandle","result","instanceDraws","shadowPipeline","buildPerSubmeshMaterialBg"],"mappings":"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;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,EAAA;AAAA;AAAA,EAE1F,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAC5F,CAAA;AAAA;AAAA,EAEA,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,EAAA;AAAA;AAAA,EAE1F,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,EAAA;AAAA,EAC3F,CAAA;AAAA;AAAA,EAEA,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,EAAA;AAAA,EAAM,EAAA;AAAA,EAAM,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,CAAA;AAAA,EAAK,EAAA;AAAA,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","file":"chunk-ZUWKAZ2I.mjs","sourcesContent":["// @forgeax/engine-render - typed render-pipeline topology contract.\n//\n// `RenderPipeline` is the typed topology contribution used by the Standard host.\n// The host owns the single active pipeline identity and its lifecycle; producers\n// contribute graph declarations through this interface instead of publishing a\n// second renderer authority.\n//\n// Naming note (requirements line 155): `RenderPipeline` here is the forgeax engine\n// concept name. The RHI GPU `RenderPipeline` handle (`@forgeax/engine-rhi`) is a\n// separate, internal opaque-handle type distinguished by module path (AGENTS.md RHI\n// form rules - \"opaque handles distinguished by module path\"); it is not exposed to\n// AI users. Files importing both alias the RHI one locally.\n//\n// Pipelines declare topology once through a typed builder. The renderer compiles,\n// executes, retires, finishes, and submits the resulting graph.\n\nimport type {\n ColorValueDomain,\n GraphAccess,\n GraphResourceResolver,\n GraphTexture,\n GraphTextureDescriptor,\n GraphTextureView,\n GraphTextureViewDescriptor,\n RenderGraphBuilder,\n RenderGraphError,\n RenderGraphFrame,\n} from '@forgeax/engine-render-graph';\nimport type {\n BindGroup,\n RhiCaps,\n RhiError,\n RhiRenderPassEncoder,\n TextureFormat,\n} from '@forgeax/engine-rhi';\nimport { ok, type Result } from '@forgeax/engine-types';\nimport type { Tonemap } from './components/camera';\nimport type { DirectionalShadowFilterLabel } from './components/directional-shadow-filter';\nimport type { RenderError } from './errors/render';\nimport type { RenderFeatureTargetKind } from './features/targets';\nimport {\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,\n} from './gpu-texture-usage';\nimport type { StandardTopologyInputValue } from './pipeline/standard-lighting/topology';\nimport { STANDARD_POST_STAGE_NAMES, type StandardProfile } from './pipeline/standard-profile';\nimport type { SurfaceProfile } from './record/render-context';\nimport type { RenderPipelineContext } from './render-contract';\nimport type { OcclusionFrameProjection } from './scene/visibility/occlusion-runtime';\nimport type { TransmissionDemand } from './transmission/projection';\n\nexport type { RenderPipelineContext } from './render-contract';\n\nexport type RenderColorDomain = 'linearHdr' | 'linearLdr' | 'displayEncoded';\n\n/** Backend admission inputs used by the existing Render candidate owner. */\nexport interface DirectionalShadowBackendAdmissionInput {\n readonly backendKind: 'webgpu' | 'wgpu-webgl2' | 'null';\n readonly requested: 'off' | DirectionalShadowFilterLabel;\n readonly candidate: 'accepted' | 'failed';\n readonly lastKnownGood?: DirectionalShadowFilterLabel | undefined;\n}\n\n/** Bounded, truthful Directional effective-profile projection. */\nexport interface DirectionalShadowBackendAdmission {\n readonly requested: 'off' | DirectionalShadowFilterLabel;\n readonly effective: 'off' | DirectionalShadowFilterLabel | 'rhi-null-structural';\n readonly status: 'accepted' | 'fallback' | 'rejected';\n readonly fallbackReason?: 'webgl2-unsupported' | 'rhi-null-structural' | 'candidate-failed';\n readonly lastKnownGood: boolean;\n readonly pixelEvidence: 'available' | 'not-available';\n}\n\n/**\n * Resolve a Directional profile only after the selected production candidate\n * has been admitted. WebGL2 and RhiNull are the sole declared fallbacks;\n * capable candidate failure retains a compatible LKG and never silently maps\n * a failed PCSS request to PCF.\n */\nexport function resolveDirectionalShadowBackendAdmission(\n input: DirectionalShadowBackendAdmissionInput,\n): DirectionalShadowBackendAdmission {\n if (input.requested === 'off') {\n return {\n requested: 'off',\n effective: 'off',\n status: 'accepted',\n lastKnownGood: false,\n pixelEvidence: 'not-available',\n };\n }\n if (input.backendKind === 'null') {\n return {\n requested: input.requested,\n effective: 'rhi-null-structural',\n status: 'fallback',\n fallbackReason: 'rhi-null-structural',\n lastKnownGood: false,\n pixelEvidence: 'not-available',\n };\n }\n if (input.backendKind === 'wgpu-webgl2') {\n const effective =\n input.requested === 'pcssMedium'\n ? 'pcf3'\n : input.requested === 'pcssHigh'\n ? 'pcf5'\n : input.requested;\n return {\n requested: input.requested,\n effective,\n status: effective === input.requested ? 'accepted' : 'fallback',\n ...(effective === input.requested ? {} : { fallbackReason: 'webgl2-unsupported' as const }),\n lastKnownGood: false,\n pixelEvidence: 'available',\n };\n }\n if (input.candidate === 'accepted') {\n return {\n requested: input.requested,\n effective: input.requested,\n status: 'accepted',\n lastKnownGood: false,\n pixelEvidence: 'available',\n };\n }\n if (input.lastKnownGood !== undefined) {\n return {\n requested: input.requested,\n effective: input.lastKnownGood,\n status: 'rejected',\n fallbackReason: 'candidate-failed',\n lastKnownGood: true,\n pixelEvidence: 'available',\n };\n }\n return {\n requested: input.requested,\n effective: input.requested,\n status: 'rejected',\n fallbackReason: 'candidate-failed',\n lastKnownGood: false,\n pixelEvidence: 'available',\n };\n}\n\nexport interface ToneOutputContract {\n readonly input: RenderColorDomain;\n readonly toneMapped: boolean;\n readonly mapped: 'linearLdr';\n readonly finalCapture: 'displayEncoded';\n readonly exposureStage: 'linearHdr' | 'none';\n}\n\nexport type RenderPostStageName = (typeof STANDARD_POST_STAGE_NAMES)[number];\nexport type RenderPostDomainStage = readonly [\n RenderPostStageName,\n ColorValueDomain,\n ColorValueDomain,\n];\n\n/**\n * Single post-stage domain contract shared by the Standard lighting lanes.\n * The selected scene domain for transparent geometry is explicit; every later\n * stage follows the same linear blend, output-transform, anti-alias, post-effect, and present sequence.\n */\nexport function resolvePostColorDomainContract(\n sceneDomain: 'linear-ldr' | 'linear-hdr',\n): readonly RenderPostDomainStage[] {\n const scene: ColorValueDomain = sceneDomain;\n const [transparentBlend, bloom, outputTransform, fxaa, postEffect, present] =\n STANDARD_POST_STAGE_NAMES;\n return [\n [transparentBlend, scene, scene],\n [bloom, 'linear-hdr', 'linear-hdr'],\n [outputTransform, scene, 'display-encoded'],\n [fxaa, 'display-encoded', 'display-encoded'],\n [postEffect, 'display-encoded', 'display-encoded'],\n [present, 'display-encoded', 'display-encoded'],\n ];\n}\n\n/**\n * Describe the built-in output stages without moving color-domain policy into\n * a mode name. Tone-enabled cameras render HDR, apply exposure and the\n * selected curve in the fullscreen pass, then reach the encoded surface.\n */\nexport function resolveToneOutputContract(tonemap: Tonemap): ToneOutputContract {\n if (tonemap === 'none') {\n return {\n input: 'linearLdr',\n toneMapped: false,\n mapped: 'linearLdr',\n finalCapture: 'displayEncoded',\n exposureStage: 'none',\n };\n }\n return {\n input: 'linearHdr',\n toneMapped: true,\n mapped: 'linearLdr',\n finalCapture: 'displayEncoded',\n exposureStage: 'linearHdr',\n };\n}\n\n/** Stable facts that may change graph topology and therefore its compiled identity. */\nexport interface RenderPipelineTopology {\n readonly pipelineId: string;\n readonly standardProfile?: StandardProfile | undefined;\n readonly config: import('@forgeax/engine-types').RenderPipelineAsset['config'];\n /**\n * The record stage had no Camera and injected the synthetic clear-only\n * snapshot. Keep that fact explicit so a normal no-tone Camera still uses\n * the float Output Transform while the empty-scene contract can write its\n * clear directly to the surface.\n */\n readonly clearOnly?: boolean | undefined;\n /** Whether Standard main draws carry the producer-owned fallback MRT. */\n readonly reflectionFallback?: { readonly enabled: boolean } | undefined;\n readonly surface: {\n readonly width: number;\n readonly height: number;\n readonly storageFormat: import('@forgeax/engine-rhi').TextureFormat;\n readonly viewFormat: import('@forgeax/engine-rhi').TextureFormat;\n readonly profile?: SurfaceProfile | undefined;\n };\n readonly camera: Pick<RenderPipelineContext['camera'], 'tonemap' | 'antialias' | 'bloom'>;\n readonly temporal?: {\n readonly taa: boolean;\n readonly motionBlur: boolean;\n };\n readonly shadow: {\n readonly directional:\n | 'disabled'\n | {\n readonly mapSize: number;\n readonly cascadeCount: 1 | 2 | 3 | 4;\n };\n readonly spotMapSize: number;\n readonly pointCount: number;\n readonly pointFaceSize: number;\n readonly spotCount: number;\n };\n /**\n * Authored volume topology facts. Identity/generation/digest are runtime\n * residency facts and deliberately do not participate in graph topology.\n */\n readonly volumetricFog?: {\n readonly enabled: boolean;\n readonly lightKind?: 'directional' | 'point' | 'spot' | undefined;\n readonly lightEntity?: number | undefined;\n readonly pointLightEntity?: number | undefined;\n readonly spotLightEntity?: number | undefined;\n readonly projector?:\n | {\n readonly guid: string;\n readonly generation: number;\n readonly revision: number;\n }\n | undefined;\n readonly format?: TextureFormat | undefined;\n readonly extent?:\n | {\n readonly width: number;\n readonly height: number;\n readonly depth: number;\n }\n | undefined;\n /** Renderer-owned froxel grid derived from the compiled surface extent. */\n readonly froxelExtent?:\n | {\n readonly width: number;\n readonly height: number;\n readonly depth: number;\n }\n | undefined;\n /** Renderer-owned 2D resolve/history extent derived from the same profile. */\n readonly resolvedExtent?:\n | {\n readonly width: number;\n readonly height: number;\n readonly depth: number;\n }\n | undefined;\n };\n readonly lane: {\n readonly compute: boolean;\n readonly storageBuffer: boolean;\n readonly multisample: boolean;\n readonly maxColorAttachments: number;\n };\n readonly featureTopologySignature: string;\n readonly gpuDrivenTopologySignature: string;\n /** Stable Cluster transport/layout facts; excludes per-frame light payloads. */\n readonly standardLightingTopologySignature?: string | undefined;\n /** Internal graph fact; renderer callers do not configure transmission demand. */\n readonly transmissionDemand?: TransmissionDemand | undefined;\n}\n\n/** Resolve the built-in final-output dither policy from the pipeline asset. */\nexport function resolveOutputDither(\n config: import('@forgeax/engine-types').RenderPipelineAsset['config'],\n): boolean {\n return config?.outputDither ?? true;\n}\n\nexport interface RenderPipelineFrame extends RenderPipelineContext, RenderGraphFrame {}\n\nexport interface RenderPipelineTarget {\n readonly texture: GraphTexture;\n readonly view: GraphTextureView;\n readonly format: TextureFormat;\n readonly sampleCount: 1 | 4;\n readonly domain?: ColorValueDomain | undefined;\n readonly resolveTarget?: GraphTextureView | undefined;\n}\n\nexport function createRenderPipelineTarget(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n label: string,\n descriptor: GraphTextureDescriptor,\n viewDescriptor: GraphTextureViewDescriptor = {},\n): Result<RenderPipelineTarget, RenderGraphError> {\n const texture = graph.createTexture(label, descriptor);\n if (!texture.ok) return texture;\n const view = graph.view(texture.value, { label: `${label}.view`, ...viewDescriptor });\n if (!view.ok) return view;\n return ok({\n texture: texture.value,\n view: view.value,\n format: viewDescriptor.format ?? descriptor.format,\n sampleCount: descriptor.sampleCount === 4 ? 4 : 1,\n ...(descriptor.domain === undefined ? {} : { domain: descriptor.domain }),\n });\n}\n\nexport function importRenderPipelineSurface(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n topology: RenderPipelineTopology,\n): Result<\n { readonly display?: RenderPipelineTarget; readonly storage: RenderPipelineTarget },\n RenderGraphError\n> {\n const texture = graph.importTexture(\n 'surface',\n {\n format: topology.surface.storageFormat,\n size: 'surface',\n // The imported surface is the final encoded endpoint. Keeping this\n // semantic fact on the graph resource lets detached inspection project\n // from the compiled graph instead of re-inferring it from format names.\n domain: 'display-encoded',\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n (topology.surface.profile?.kind === 'raw-only' ? 0 : GPU_TEXTURE_USAGE_COPY_SRC),\n viewFormats: [\n ...(topology.surface.profile?.viewFormats ??\n (topology.surface.storageFormat === topology.surface.viewFormat\n ? []\n : [topology.surface.viewFormat])),\n ],\n },\n (frame) => frame.currentTexture,\n );\n if (!texture.ok) return texture;\n const display =\n topology.surface.profile?.hasDisplayEndpoint === false\n ? undefined\n : graph.importView(\n texture.value,\n { label: 'surface.display', format: topology.surface.viewFormat },\n (frame) => frame.view,\n );\n if (display !== undefined && !display.ok) return display;\n const storage = graph.importView(\n texture.value,\n { label: 'surface.storage', format: topology.surface.storageFormat },\n (frame) => {\n if (topology.surface.storageFormat === topology.surface.viewFormat) return frame.view;\n const resolved = frame.runtime.device.createTextureView(frame.currentTexture, {\n format: topology.surface.storageFormat,\n });\n if (!resolved.ok) throw resolved.error;\n return resolved.value;\n },\n );\n if (!storage.ok) return storage;\n return ok({\n ...(display === undefined\n ? {}\n : {\n display: {\n texture: texture.value,\n view: display.value,\n format: topology.surface.viewFormat,\n sampleCount: 1 as const,\n domain: 'display-encoded' as const,\n },\n }),\n storage: {\n texture: texture.value,\n view: storage.value,\n format: topology.surface.storageFormat,\n sampleCount: 1,\n domain: 'display-encoded',\n },\n });\n}\n\nexport interface RenderPipelineFeatureTarget {\n /** Optional semantic alias when a pipeline exposes multiple color roles. */\n readonly name?: string;\n readonly kind: RenderFeatureTargetKind;\n readonly texture: GraphTexture;\n readonly view: GraphTextureView;\n readonly resolveTarget?: GraphTextureView | undefined;\n readonly format: TextureFormat;\n readonly sampleCount: 1 | 4;\n}\n\nexport interface RenderPipelineGpuDrivenProjection {\n readonly accesses: readonly GraphAccess[];\n encode(\n viewBindGroup: BindGroup,\n pass: RhiRenderPassEncoder,\n resources: GraphResourceResolver,\n ): void;\n}\n\nexport interface RenderPipelineBuildContext<FrameCtx extends RenderPipelineFrame> {\n readonly graph: RenderGraphBuilder<FrameCtx>;\n /**\n * The single prepared Standard lighting projection for this frame. The\n * Forward and Deferred adapters consume this value; they never inspect raw\n * light snapshots, cluster config, or capability facts themselves.\n */\n readonly standardLighting?: StandardTopologyInputValue;\n /**\n * Renderer-owned capability facts needed for admission decisions. The\n * Standard temporal producer must use the live device probe rather than\n * inferring rgba16float support from the selected surface format.\n */\n readonly capabilities?: Pick<RhiCaps, 'rgba16floatRenderable'>;\n /**\n * Renderer-owned TAA history targets. The graph sees only imported typed\n * targets; opaque RHI handles remain inside RenderFrameState.\n */\n readonly taaHistory?: {\n readonly currentColor: RenderPipelineTarget;\n readonly previousColor: RenderPipelineTarget;\n readonly currentTemporal: RenderPipelineTarget;\n readonly previousTemporal: RenderPipelineTarget;\n };\n /** Renderer-owned, prewarmed encoder for one graph mip level. */\n readonly encodeTransmissionMip?: (input: {\n readonly pass: RhiRenderPassEncoder;\n readonly frame: FrameCtx;\n readonly resources: GraphResourceResolver;\n readonly source: GraphTextureView;\n readonly destination: GraphTextureView;\n readonly level: number;\n }) => void;\n /** Renderer-owned occlusion query state for the primary scene pass. */\n readonly occlusion?: OcclusionFrameProjection;\n projectGpuDriven(target: {\n readonly format: TextureFormat;\n readonly sampleCount: 1 | 4;\n }): Result<RenderPipelineGpuDrivenProjection | undefined, RenderPipelineBuildError>;\n contributeFeatures(\n targets: readonly RenderPipelineFeatureTarget[],\n semanticTargets?: readonly RenderPipelineTarget[],\n namedTargets?: Readonly<Record<string, RenderPipelineTarget>>,\n ): Result<void, RenderPipelineBuildError>;\n /** Add renderer-owned cube capture work to the active pipeline graph. */\n contributeCubeCaptures?(): Result<void, RenderPipelineBuildError>;\n /** Whether a producer-owned feature is installed for this graph build. */\n hasFeature?(identity: string): boolean;\n}\n\nexport type RenderPipelineBuildError = RenderGraphError | RenderError | RhiError;\n\n/**\n * Registrable, installable, hot-swappable render topology.\n *\n * `build` declares resources and passes only. The renderer owns compilation,\n * last-known-good replacement, execution, retirement, and the single frame submit.\n * Feature contributions enter through `contributeFeatures`, so compute-produced\n * buffers and later raster reads remain inside the same typed dependency graph.\n */\nexport interface RenderPipeline<FrameCtx extends RenderPipelineFrame = RenderPipelineFrame> {\n build(\n context: RenderPipelineBuildContext<FrameCtx>,\n topology: RenderPipelineTopology,\n ): Result<void, RenderPipelineBuildError>;\n}\n","// @forgeax/engine-render - host-side DirectLightSlot ABI and buffer helpers.\n//\n// Point, Spot, and Rect snapshots share one five-row, 80-byte Cluster slot.\n// The same packer is used by the Cluster producer and every Cluster consumer;\n// this is the only local-light transport.\n\nimport { err, ok, type Result, RhiError } from '@forgeax/engine-rhi';\nimport type {\n PointLightSnapshot,\n RectAreaDirectLightSnapshot,\n SpotLightSnapshot,\n} from './render-system-extract';\n// Owns the byte-frozen std430 layout (D-S2). Point, Spot, and Rect all use the\n// same five-row DirectLightSlot; the kind and resource identities are carried\n// by the metadata row. Point uses the angular lanes as neutral values. Spot\n// uses row 3's x/y/z lanes for volume shadow receiver controls and w for the\n// extended-lighting roll angle. Rect uses row 2/3 for its two tangent axes.\n//\n// AC anchor: requirements AC-04 (c) + C-7 (16 B alignment); plan-strategy\n// section 2 D-S2 (byte-frozen layout); research Finding 2 (Bevy\n// invRangeSquared naming) + Finding 9 (Bevy storage buffer pattern).\n//\n// Cap gate: maxStorageBuffersPerShaderStage >= 4 (Cluster occupies four\n// storage entries: meshSSBO + light_data + cluster_grid + light_index_list;\n// default WebGPU minimum is 8, requirements assumption A-7 + plan R-4). The closed\n// `RhiErrorCode` union has no `'rhi-not-supported'` member; the\n// plan-strategy phrasing collapses onto the spec-aligned `'limit-exceeded'`\n// arm which already documents \"input value exceeded device.limits.<name>\"\n// (RhiError JSDoc on packages/rhi/src/errors.ts). Reusing `'limit-exceeded'`\n// keeps `RhiErrorCode` count at 18 (AGENTS.md error model evolution\n// contract: minor add-only; w20a explicitly forbids count drift).\n\n/**\n * Minimum storage-buffer count needed by the M3 record stage.\n *\n * 1. Mesh SSBO (entity_world + normalMatrix; per-renderable dynamic\n * offset, 256 B stride).\n * 2. Cluster light_data SSBO.\n * 3. Cluster membership grid SSBO.\n * 4. Cluster light-index-list SSBO.\n *\n * Cluster needs four storage-backed resources in the Standard bind group.\n * This is the complete local-light transport.\n */\nexport const STORAGE_BUFFER_MIN_REQUIRED = 4;\n\n/** Byte size of one Point/Spot/Rect DirectLightSlot. */\nexport const BYTES_PER_DIRECT_LIGHT_SLOT = 80;\n\n/**\n * Cap gate at createRenderer time: check whether the device has enough\n * storage-buffer slots for the PBR pipeline (M3 requires\n * `STORAGE_BUFFER_MIN_REQUIRED = 4`). Returns a three-way signal:\n *\n * - `Result.ok(true)` — storage buffer capable (cap >= 4);\n * - `Result.ok(false)` — no storage buffer capability at all (cap === 0);\n * consumer walks the uniform-fallback path;\n * - `Result.err(RhiError)` — cap in (0, 4); not enough storage slots to run\n * but also not a clean zero-cap uniform-fallback case (e.g. downlevel\n * adapter with 1-3 slots). The error carries `'limit-exceeded'` with\n * `LimitExceededDetail` shape.\n *\n * Uniform-fallback path decision (plan D-5): `cap === 0` is the wgpu\n * WebGL2 backend signal (`downlevel_webgl2_defaults().limits.\n * maxStorageBuffersPerShaderStage = 0`). It remains a mesh/instance fallback;\n * local-light frames require the single Cluster storage transport.\n */\n/** Closed direct-light kind carried by the unified five-row slot. */\nexport const DirectLightSlotKind = {\n POINT: 0,\n SPOT: 1,\n RECT_AREA: 2,\n} as const;\nexport type DirectLightSlotKind = 'point' | 'spot' | 'rect-area';\n\n/** Metadata identity used for absent shadow, IES, and Cookie resources. */\nexport const DIRECT_LIGHT_SLOT_METADATA_SENTINEL = 0xffffffff;\n/**\n * SpotLight projector marker carried in the shared shadow identity word. The\n * lower 30 bits retain the selected shadow tile; projector-only spots use tile\n * zero because their matrix is deliberately published in View lane zero.\n */\nexport const DIRECT_LIGHT_SLOT_PROJECTOR_FLAG = 0x40000000;\nexport const DIRECT_LIGHT_SLOT_TILE_MASK = DIRECT_LIGHT_SLOT_PROJECTOR_FLAG - 1;\n/** Byte size of the five-row Point/Spot/Rect transport slot. */\nexport const DIRECT_LIGHT_SLOT_FLOAT_COUNT =\n BYTES_PER_DIRECT_LIGHT_SLOT / Float32Array.BYTES_PER_ELEMENT;\n\n/** Five vec4 rows shared by host packing and the WGSL direct-light consumer. */\nexport const DIRECT_LIGHT_SLOT_LAYOUT = {\n byteSize: BYTES_PER_DIRECT_LIGHT_SLOT,\n rowByteOffsets: [0, 16, 32, 48, 64],\n positionOffset: 0,\n rangeOffset: 12,\n colorOffset: 16,\n firstAngleOffset: 28,\n primaryAxisOffset: 32,\n secondAngleOffset: 44,\n auxiliaryAxisOffset: 48,\n metadataByteOffset: 64,\n kindByteOffset: 64,\n shadowByteOffset: 68,\n iesProfileByteOffset: 72,\n cookieByteOffset: 76,\n /** Spot-only roll angle stored in the fourth row's w lane. */\n rollDegByteOffset: 60,\n floatCount: DIRECT_LIGHT_SLOT_FLOAT_COUNT,\n vec4Count: 5,\n} as const;\n\ntype DirectLightModifierMetadata = {\n readonly iesProfileSlice?: number;\n readonly cookieSlice?: number;\n};\n\nexport type DirectLightSnapshot =\n | (PointLightSnapshot & DirectLightModifierMetadata)\n | (SpotLightSnapshot & DirectLightModifierMetadata)\n | (RectAreaDirectLightSnapshot & DirectLightModifierMetadata);\n\nfunction directLightMetadata(value: number | undefined): number {\n return value === undefined ? DIRECT_LIGHT_SLOT_METADATA_SENTINEL : value >>> 0;\n}\n\n/**\n * Pack one Point, Spot, or Rect snapshot into the unified five-row slot.\n *\n * Row 0 is position plus inverse range. Row 1 is color plus the first\n * angular/size fact. Row 2 is the primary axis plus the second angular/size\n * fact. Row 3 is the auxiliary Rect axis. Row 4 is four u32 identities.\n */\nexport function packDirectLightSlot(\n snapshot: DirectLightSnapshot,\n projectorSelected?: boolean,\n): Float32Array {\n const out = new Float32Array(DIRECT_LIGHT_SLOT_FLOAT_COUNT);\n out[0] = snapshot.position[0] ?? 0;\n out[1] = snapshot.position[1] ?? 0;\n out[2] = snapshot.position[2] ?? 0;\n out[3] = snapshot.invRangeSquared;\n out[4] = snapshot.color[0] ?? 0;\n out[5] = snapshot.color[1] ?? 0;\n out[6] = snapshot.color[2] ?? 0;\n\n if (snapshot.kind === 'point') {\n out[7] = 1;\n } else if (snapshot.kind === 'spot') {\n out[7] = snapshot.cosInner;\n out[8] = snapshot.direction[0] ?? 0;\n out[9] = snapshot.direction[1] ?? 0;\n out[10] = snapshot.direction[2] ?? 0;\n out[11] = snapshot.cosOuter;\n // Row 3 is the Rect auxiliary axis for RectArea lights. Spot uses x/y/z\n // for its receiver controls and w for roll; the surface direct-light\n // owner only consumes w, while the volume owner consumes the full row.\n out[12] = snapshot.depthBias ?? 0.005;\n out[13] = snapshot.normalBias ?? 0.05;\n out[14] = snapshot.shadowIntensity ?? 1;\n out[15] = snapshot.rollDeg ?? 0;\n } else {\n out[7] = snapshot.halfWidth;\n out[8] = snapshot.axisY[0] ?? 0;\n out[9] = snapshot.axisY[1] ?? 0;\n out[10] = snapshot.axisY[2] ?? 0;\n out[11] = snapshot.halfHeight;\n out[12] = snapshot.axisX[0] ?? 0;\n out[13] = snapshot.axisX[1] ?? 0;\n out[14] = snapshot.axisX[2] ?? 0;\n }\n\n const metadata = new Uint32Array(out.buffer);\n metadata[16] =\n snapshot.kind === 'point'\n ? DirectLightSlotKind.POINT\n : snapshot.kind === 'spot'\n ? DirectLightSlotKind.SPOT\n : DirectLightSlotKind.RECT_AREA;\n const spotProjectorSelected =\n snapshot.kind === 'spot' &&\n (projectorSelected ??\n (snapshot.projectorAsset !== undefined && snapshot.lightViewProj !== undefined));\n const spotShadowMetadata =\n snapshot.kind === 'spot'\n ? spotProjectorSelected\n ? DIRECT_LIGHT_SLOT_PROJECTOR_FLAG |\n ((snapshot.shadowAtlasTile >= 0 ? snapshot.shadowAtlasTile : 0) &\n DIRECT_LIGHT_SLOT_TILE_MASK)\n : directLightMetadata(snapshot.shadowAtlasTile)\n : undefined;\n metadata[17] = directLightMetadata(\n snapshot.kind === 'point'\n ? snapshot.shadowAtlasLayer\n : snapshot.kind === 'spot'\n ? spotShadowMetadata\n : undefined,\n );\n metadata[18] = directLightMetadata(snapshot.iesProfileSlice);\n metadata[19] = directLightMetadata(\n spotProjectorSelected && snapshot.kind === 'spot'\n ? snapshot.projectorSlice\n : snapshot.cookieSlice,\n );\n return out;\n}\n\nexport function assertStorageBufferCap(cap: number): Result<boolean, RhiError> {\n if (cap >= STORAGE_BUFFER_MIN_REQUIRED) {\n return ok(true);\n }\n if (cap === 0) {\n return ok(false);\n }\n return err(\n new RhiError({\n code: 'limit-exceeded',\n expected: `device.limits.maxStorageBuffersPerShaderStage >= ${STORAGE_BUFFER_MIN_REQUIRED}, or exactly 0 for the mesh-only fallback`,\n hint: `device.limits.maxStorageBuffersPerShaderStage = ${cap} < ${STORAGE_BUFFER_MIN_REQUIRED} and != 0. WebGPU spec default minimum is 8; this adapter cannot run the unified Cluster local-light path.`,\n detail: {\n maxStorageBufferBindingSize: cap,\n requestedBytes: STORAGE_BUFFER_MIN_REQUIRED,\n },\n }),\n );\n}\n","// PipelineSpec 4-axis SSOT — single-file type + derive-fn + entrypoint + error model.\n//\n// feat-20260615-pipeline-spec-ssot M1: Establish PipelineSpec 4-axis type SSOT.\n// M1-T1: type definitions + KNOWN_PASS_KINDS + PipelineSpecError closed union.\n// M1-T2: 6 pure derive functions.\n// M1-T3: deriveBglShapeFromShader helper.\n// M1-T4: getOrBuildPipeline entrypoint + PipelineCache.\n// M1-T5: 12 SPEC_CONST boot-time table.\n//\n// Design axiom: PipelineSpec is business-agnostic — no 'pbr' / 'sprite' / 'skybox'\n// / 'fullscreen-*' strings appear on the type surface (plan-strategy D-7).\n// BGL shape taxonomy lives in the ShaderCatalog implementation, not in spec.\n//\n// Charter alignment:\n// F1: single file entrypoint (getOrBuildPipeline) — AI user indexes once\n// P1: progressive disclosure — types at top, fns mid, error model bottom\n// P3: explicit failure — closed PipelineSpecError union, no silent routes\n// P4: consistent abstraction — 4-axis aligns with wgpu/Bevy/Three.js\n\nimport {\n deriveVertexBufferLayout,\n deriveVertexLayoutProjection,\n type VertexLayoutProjection,\n} from '@forgeax/engine-geometry';\nimport {\n err,\n KNOWN_PASS_KINDS,\n type MaterialRenderState,\n ok,\n type PrimitiveTopology,\n type Result,\n type VertexAttributeMap,\n} from '@forgeax/engine-types';\nimport { VertexColorVariantConflictError } from './errors/render';\n\nexport {\n type BglKind,\n type BindGroupLayoutDescriptorOutput,\n buildBindGroupLayoutDescriptor,\n createHdrpBindGroupLayoutDescriptor,\n} from './pbr-pipeline';\n\n// Re-export KNOWN_PASS_KINDS from @forgeax/engine-types for single-file discoverability (charter F1).\nexport { KNOWN_PASS_KINDS };\n\n/**\n * The engine-owned deferred material target layout. `fs_gbuffer` returns\n * normal+roughness, albedo+metallic, and emissive+AO in this order.\n */\nexport const DEFERRED_COLOR_FORMATS: readonly GPUTextureFormat[] = [\n 'rgba16float',\n 'rgba8unorm',\n 'rgba16float',\n];\n\n/** Derive the color attachment shape for a material pass kind. */\nexport function colorFormatsForPassKind(\n passKind: string,\n defaultColorFormat: GPUTextureFormat,\n): readonly GPUTextureFormat[] {\n if (passKindPolicyTable[passKind]?.shape === 'depth-only') return [];\n if (passKind === 'deferred') return DEFERRED_COLOR_FORMATS;\n return [defaultColorFormat];\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// PipelineSpec — immutable 4-axis data description (D-7: business-agnostic)\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Pipeline specification — immutable 4-axis data that completely determines\n * what `device.createRenderPipeline(...)` does for a material shader pass.\n *\n * The 4 axes are:\n * - `shader`: which WGSL source + material param schema + pass kind + variant set\n * - `attachments`: color/depth/stencil formats + sample count (MSAA)\n * - `geometry`: primitive topology + vertex attribute layout + index format\n * - `renderState`: optional per-material render-state overrides (blend/cull/depth/stencil)\n *\n * Business-agnostic: no `'pbr'` / `'sprite'` / `'skybox'` strings pollute this\n * type. BGL shape taxonomy is derived from `ShaderCatalog` internal reflection\n * and never appears on the spec surface (plan-strategy D-7).\n *\n * @see plan-strategy §1 (4-axis) · D-7 (business-agnostic) · requirements §3.1\n */\nexport type { PipelineSpec } from './pipeline-spec-types';\n\nimport type { PipelineSpec } from './pipeline-spec-types';\n// ══════════════════════════════════════════════════════════════════════════════\n// PipelineSpecError — closed union (5 + 2 transit codes)\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Closed union of PipelineSpec error codes.\n *\n * 5 business codes:\n * - `'spec-inconsistent'`: axis mutual exclusion violated\n * - `'unknown-pass-kind'`: passKind not in KNOWN_PASS_KINDS or registered\n * - `'shader-bgl-reflection-mismatch'`: reflected BGL shape != shader declaration\n * - `'attachment-format-incompatible'`: depth/stencil format vs PSO mismatch\n * - `'unsupported-vertex-layout'`: vertex attributes don't match shader vs_main\n *\n * 2 transit codes:\n * - `'pipeline-build-failed'`: wraps RhiError from device.createRenderPipeline\n * - `'shader-not-registered'`: ShaderCatalog lookup returned undefined\n *\n * @see requirements §3.4 · AC-10 · charter P3\n */\nexport type PipelineSpecErrorCode =\n | 'spec-inconsistent'\n | 'unknown-pass-kind'\n | 'shader-bgl-reflection-mismatch'\n | 'attachment-format-incompatible'\n | 'unsupported-vertex-layout'\n | 'pipeline-build-failed'\n | 'shader-not-registered';\n\n/**\n * Structured pipeline-spec error — carries `.code` (discriminated union) +\n * `.detail` (narrowed per code) + `.hint` (AI-user actionable prose).\n *\n * Inherits from `Error` so it integrates with existing catch blocks; the\n * `.code` field enables exhaustive `switch` narrowing without string parsing\n * (charter P3).\n */\nexport class PipelineSpecError extends Error {\n readonly code: PipelineSpecErrorCode;\n /**\n * Narrowed detail payload — shape depends on `code`.\n *\n * - `'spec-inconsistent'`: `{ reason: string }`\n * - `'unknown-pass-kind'`: `{ expected: readonly string[]; actual: string; hint?: string }`\n * - `'shader-bgl-reflection-mismatch'`: `{ reflected: unknown; declared: unknown }`\n * - `'attachment-format-incompatible'`: `{ reason: string; expected?: string; actual?: string }`\n * - `'unsupported-vertex-layout'`: `{ specAttrs: string[]; shaderAttrs: string[] }`\n * - `'pipeline-build-failed'`: `{ gpuMessage?: string; cause?: unknown }`\n * - `'shader-not-registered'`: `{ shaderId: string; hint?: string }`\n */\n readonly detail: Record<string, unknown>;\n\n constructor(args: {\n code: PipelineSpecErrorCode;\n detail: Record<string, unknown>;\n hint?: string;\n }) {\n super(\n args.hint !== undefined\n ? `PipelineSpecError [${args.code}]: ${args.hint}`\n : `PipelineSpecError [${args.code}]`,\n );\n this.name = 'PipelineSpecError';\n this.code = args.code;\n this.detail = args.detail;\n }\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// renderStateHashSuffix — deterministic hash of MaterialRenderState\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Material snapshots hand the renderer immutable render-state objects. Keep\n * the serialized suffix by object identity just like the vertex-layout\n * digest below; the hot path otherwise sorts keys and serializes the same\n * state once per renderable. Callers must not mutate a MaterialRenderState\n * after passing it to the renderer (the PipelineSpec contract is immutable).\n */\nconst RENDER_STATE_HASH_CACHE = new WeakMap<object, string>();\n\n/**\n * Deterministic hash suffix for MaterialRenderState (sorted keys, JSON.stringify).\n *\n * Returns `''` when `renderState` is `undefined` or has zero entries,\n * preserving cache-key byte-compatibility with the pre-M1 shape.\n */\nexport function renderStateHash(renderState: MaterialRenderState | undefined): string {\n if (renderState === undefined) return '';\n const cached = RENDER_STATE_HASH_CACHE.get(renderState);\n if (cached !== undefined) return cached;\n const sorted = Object.keys(renderState).sort();\n if (sorted.length === 0) {\n RENDER_STATE_HASH_CACHE.set(renderState, '');\n return '';\n }\n const payload: Record<string, unknown> = {};\n for (const k of sorted) {\n const v = renderState[k as keyof MaterialRenderState];\n if (v !== undefined) payload[k] = v;\n }\n const result = `:${JSON.stringify(payload)}`;\n RENDER_STATE_HASH_CACHE.set(renderState, result);\n return result;\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// 6 pure derive functions (M1-T2)\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Compute a deterministic cache key from a PipelineSpec.\n *\n * The key covers all 4 axes + BGL shape hash (derived from ShaderCatalog\n * reflection via {@link deriveBglShapeFromShader}). Two specs that produce\n * the same cache key MUST produce byte-identical PSO descriptors.\n *\n * Algorithm: concatenate each axis segment with `:` separators, hash the\n * BGL shape for compactness, and emit a single cache-key string.\n *\n * @see plan-strategy §3.1 · requirements AC-02\n */\nexport function cacheKeyOf(spec: PipelineSpec): string {\n const { shader, attachments, geometry, renderState } = spec;\n const topoSegment = geometry.topology;\n const stripSegment =\n (topoSegment === 'line-strip' || topoSegment === 'triangle-strip') &&\n geometry.stripIndexFormat !== undefined\n ? `:${geometry.stripIndexFormat}`\n : '';\n\n // The geometry owner publishes one immutable projection. Legacy callers may\n // still provide only the map; derive the same projection at this boundary.\n const vlDigest =\n geometry.vertexLayoutProjection?.digest ??\n deriveVertexLayoutProjection(geometry.vertexLayout).digest;\n\n const uvSetCountSegment =\n geometry.shaderUvSetCount !== undefined ? `:uvsc${geometry.shaderUvSetCount}` : '';\n\n // bug-20260708 M2 (b): sentinel `~` distinguishes `variantSet=undefined`\n // (no-variant / default-variant request) from canonical all-true key `''`\n // (all variant axes true). Prior `?? ''` collapsed the two into the same\n // cache key, causing the first-cached pipeline to win and unrelated\n // variantSet requests to reuse its shader module (research R-11 / R-12).\n // `~` (ASCII 0x7E) is a reserved sentinel char — no legitimate\n // variantSet literal contains it; guarded by\n // `pipeline-cache-keying.unit.test.ts` sentinel-conflict assertions.\n const variantSegment = shader.variantSet === undefined ? '~' : shader.variantSet;\n return (\n [\n shader.id,\n shader.passKind,\n variantSegment,\n attachments.colorFormats.join(','),\n attachments.depthFormat ?? '',\n String(attachments.sampleCount),\n topoSegment,\n stripSegment,\n `vl:${vlDigest}`,\n renderStateHash(renderState),\n ].join(':') + uvSetCountSegment\n );\n}\n\n/**\n * Reconcile the authored vertex-color shader axis with the geometry-owned\n * projection. COLOR_0 is a geometry fact and cannot be selected independently\n * by a material variant.\n */\nexport function variantSetFromVertexLayoutProjection(\n projection: VertexLayoutProjection,\n authoredVariantSet: string | undefined,\n): Result<string, VertexColorVariantConflictError> {\n const projected = projection.attributes.some((attribute) => attribute.key === 'color');\n const axis = `VERTEX_COLOR_AVAILABLE=${projected ? 'true' : 'false'}`;\n if (authoredVariantSet === undefined) return ok(axis);\n if (projected && authoredVariantSet === '') return ok(authoredVariantSet);\n\n const authoredParts = authoredVariantSet.split('+');\n const authoredColorPart = authoredParts.find((part) =>\n part.startsWith('VERTEX_COLOR_AVAILABLE='),\n );\n if (authoredColorPart === undefined) {\n const parts = authoredParts.filter((part) => part.length > 0);\n parts.push(axis);\n return ok(parts.join('+'));\n }\n\n const authoredValue = authoredColorPart.slice('VERTEX_COLOR_AVAILABLE='.length);\n const authored = authoredValue === 'true';\n if ((authoredValue !== 'true' && authoredValue !== 'false') || authored !== projected) {\n return err(new VertexColorVariantConflictError(authoredValue, projected));\n }\n const parts = authoredParts.filter(\n (part) => part.length > 0 && !part.startsWith('VERTEX_COLOR_AVAILABLE='),\n );\n parts.push(axis);\n return ok(parts.join('+'));\n}\n\n/**\n * Derive the capability axes shared by every Standard PBR draw owner.\n *\n * The all-true key is the canonical empty key used by the shader manifest;\n * every other capability pair stays explicit so a no-local-light frame on a\n * device without storage buffers cannot accidentally select a storage-backed\n * PSO. Vertex-color is supplied here because the empty-key rule is only valid\n * when that geometry-owned axis is also true.\n */\nexport function standardCapabilityVariantSet(\n clustered: boolean,\n storageBuffer: boolean,\n vertexColorAvailable: boolean,\n): string {\n if (clustered && storageBuffer && vertexColorAvailable) return '';\n return `CLUSTER_FORWARD_AVAILABLE=${clustered}+STORAGE_BUFFER_AVAILABLE=${storageBuffer}`;\n}\n\n/**\n * Project the frame-owned Standard topology onto its material variant axes.\n *\n * `StandardTopologyInputValue.kind` is the only runtime authority for the\n * cluster axis: a frame with local lights must request the clustered artifact,\n * while the no-local-light topology requests the direct artifact. Keeping\n * this projection beside the canonical key builder prevents PBR, skin, and\n * sprite-lit record owners from independently inferring the active lane from\n * whichever bind group happened to be constructed first.\n */\nexport function standardTopologyVariantSet(\n topology: { readonly kind: 'no-local-lights' | 'clustered' } | undefined,\n storageBuffer: boolean,\n vertexColorAvailable: boolean,\n probeBlendAvailable = false,\n): string {\n const capabilityVariantSet = standardCapabilityVariantSet(\n topology?.kind === 'clustered',\n storageBuffer,\n vertexColorAvailable,\n );\n if (!probeBlendAvailable || !storageBuffer) return capabilityVariantSet;\n // The canonical empty key cannot carry the clustered=true fact through\n // resolveMaterialShaderVariantSet (an omitted cluster axis means false).\n // Expand that base before adding the object-level Probe ABI axis so shader,\n // group(3) bind group, and pipeline layout remain one exact variant.\n const explicitCapabilityVariantSet =\n capabilityVariantSet === ''\n ? 'CLUSTER_FORWARD_AVAILABLE=true+STORAGE_BUFFER_AVAILABLE=true'\n : capabilityVariantSet;\n return `${explicitCapabilityVariantSet}+PROBE_BLEND_AVAILABLE=true`;\n}\n\n/**\n * Keep a clustered frame fail-closed when its unified group(2) resource is\n * unavailable. A missing group is not evidence that the frame is direct; it\n * is an invalid prepared resource state.\n */\nexport function standardTopologyBindGroupReady(\n topology: { readonly kind: 'no-local-lights' | 'clustered' } | undefined,\n clusterBindGroup: unknown,\n): boolean {\n return (\n topology?.kind !== 'clustered' || (clusterBindGroup !== null && clusterBindGroup !== undefined)\n );\n}\n\n/** Derive the storage axis for Standard-compatible unlit material draws. */\nexport function standardStorageVariantSet(\n storageBuffer: boolean,\n vertexColorAvailable: boolean,\n): string {\n if (storageBuffer && vertexColorAvailable) return '';\n return `STORAGE_BUFFER_AVAILABLE=${storageBuffer}+VERTEX_COLOR_AVAILABLE=${vertexColorAvailable}`;\n}\n\n/**\n * Build a `GPURenderPipelineDescriptor` from a PipelineSpec + shader modules.\n *\n * Pure derivation: same (spec, modules) always produces the same descriptor.\n * Consumed by `getOrBuildPipeline` on cache miss; also available as a public\n * helper for AI users who want the descriptor shape without going through the\n * cache entrypoint.\n *\n * @param spec - the pipeline spec (4 axes)\n * @param modules - `{ vertex: GPUShaderModule; fragment: GPUShaderModule }`\n * @returns a complete WebGPU render-pipeline descriptor\n * @see plan-strategy §3.2 · requirements AC-02\n */\nexport function buildPipelineDescriptor(\n spec: PipelineSpec,\n modules: {\n vertex: unknown;\n fragment: unknown;\n vertexEntryPoint?: string;\n fragmentEntryPoint?: string;\n layout?: unknown;\n },\n): Record<string, unknown> {\n // M2-T4: derive vertex buffers from spec.geometry.vertexLayout via\n // deriveVertexBufferLayout (imported from vertex-attribute-layout.ts).\n // Empty vertexLayout (fullscreen-post passes) → [].\n // Non-empty (material shaders) → interleaved single-buffer layout.\n //\n // Entry points default to 'vs_main' / 'fs_main' for the 3 standard material\n // shaders; fullscreen-post passes (skybox 'skybox_fs', SSAO 'vs_ssao' / 'fs_ssao_calc')\n // pass custom entry points through the modules parameter.\n //\n // The optional `layout` field, when present, is forwarded to the descriptor\n // so that the provider can detect it is already set and avoid overwriting.\n\n const { attachments, geometry, renderState } = spec;\n\n // A supplied projection is the geometry owner's immutable GPU descriptor.\n // Do not re-derive it from a possibly stale attribute map.\n const vertexBuffers =\n geometry.vertexLayoutProjection === undefined\n ? deriveVertexBufferLayout(geometry.vertexLayout, {\n ...(geometry.shaderUvSetCount !== undefined\n ? { shaderUvSetCount: geometry.shaderUvSetCount }\n : {}),\n })\n : geometry.vertexLayoutProjection.attributes.length === 0\n ? []\n : [\n {\n arrayStride: geometry.vertexLayoutProjection.arrayStride,\n attributes: geometry.vertexLayoutProjection.attributes.map(\n ({ shaderLocation, offset, format }) => ({\n shaderLocation,\n offset,\n format,\n }),\n ),\n },\n ];\n\n const descriptor: Record<string, unknown> = {\n vertex: {\n module: modules.vertex,\n entryPoint: modules.vertexEntryPoint ?? 'vs_main',\n buffers: vertexBuffers,\n },\n };\n\n // Fragment stage: absent for shadow-caster (depth-only), present for forward.\n if (attachments.colorFormats.length > 0) {\n descriptor.fragment = {\n module: modules.fragment,\n entryPoint: modules.fragmentEntryPoint ?? 'fs_main',\n targets: attachments.colorFormats.map((fmt) => {\n const target: Record<string, unknown> = { format: fmt };\n if (renderState?.blend !== undefined) {\n target.blend = renderState.blend;\n }\n return target;\n }),\n };\n }\n\n // Layout: forward if provided by caller (fullscreen-post passes set it).\n if (modules.layout !== undefined) {\n descriptor.layout = modules.layout;\n }\n\n // Primitive state.\n const primitive: Record<string, unknown> = {\n topology: geometry.topology,\n cullMode: renderState?.cullMode ?? 'back',\n frontFace: renderState?.frontFace ?? 'ccw',\n };\n if (geometry.topology.endsWith('strip') && geometry.stripIndexFormat !== undefined) {\n primitive.stripIndexFormat = geometry.stripIndexFormat;\n }\n descriptor.primitive = primitive;\n\n // Depth-stencil state.\n if (attachments.depthFormat !== undefined) {\n const ds: Record<string, unknown> = {\n format: attachments.depthFormat,\n depthWriteEnabled: renderState?.depthWriteEnabled ?? true,\n depthCompare: renderState?.depthCompare ?? 'less',\n };\n if (renderState?.stencilReadMask !== undefined) {\n ds.stencilReadMask = renderState.stencilReadMask;\n }\n if (renderState?.stencilWriteMask !== undefined) {\n ds.stencilWriteMask = renderState.stencilWriteMask;\n }\n if (renderState?.stencil !== undefined) {\n ds.stencilFront = renderState.stencil;\n ds.stencilBack = renderState.stencil;\n }\n descriptor.depthStencil = ds;\n }\n\n // Multisample: absent for sampleCount=1 (undefined). For each value > 1,\n // emit { count: sampleCount } so forward-compat sample counts (2, 8, …)\n // flow through to the descriptor without requiring a type change.\n if (attachments.sampleCount > 1) {\n descriptor.multisample = {\n count: attachments.sampleCount,\n ...(renderState?.alphaToCoverageEnabled === true && { alphaToCoverageEnabled: true }),\n };\n }\n\n return descriptor;\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// passKindPolicyTable — closed map: passKind → attachment shape + default ops\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Default colour-attachment ops carried by a passKind policy.\n *\n * `clearValue` is `undefined` for `loadOp='load'` policies (no clear value\n * is emitted into the descriptor when the prior contents are loaded).\n */\nexport interface AttachmentColorOps {\n readonly loadOp: 'clear' | 'load';\n readonly storeOp: 'store' | 'discard';\n readonly clearValue: GPUColor | undefined;\n}\n\n/**\n * Default depth-attachment ops carried by a passKind policy.\n *\n * `stencilLoadOp` / `stencilStoreOp` are absent on the policy itself — the\n * stencil-op gate is auto-derived from `specAttachments.depthFormat` at call\n * time (`'depth24plus-stencil8'` → `'clear'+'discard'`; everything else\n * elides stencil ops). This collapses the R3/R5 stencil-op duplicates that\n * previously lived inline at every forward-pass beginRenderPass call site.\n */\nexport interface AttachmentDepthOps {\n readonly loadOp: 'clear' | 'load';\n readonly storeOp: 'store' | 'discard';\n readonly clearValue: number;\n}\n\n/**\n * Attachment policy for a single passKind — declares the colour / depth shape\n * the pass produces and the default load/store ops. Per-call-site overrides\n * (skybox vs main forward differing on `colorLoadOp`, sprite-split forward\n * differing on both `colorLoadOp` and `depthLoadOp`) flow through the\n * `options` parameter of {@link buildBeginRenderPassDescriptor}.\n *\n * `shape` discriminator drives which attachment slots the descriptor emits:\n * - `'depth-only'` → empty `colorAttachments[]`, `depthStencilAttachment` set\n * - `'color-only'` → populated `colorAttachments[]`, no `depthStencilAttachment`\n * - `'color-and-depth'` → both\n */\nexport interface PassKindAttachmentPolicy {\n readonly shape: 'depth-only' | 'color-only' | 'color-and-depth';\n readonly defaultColorOps: AttachmentColorOps | undefined;\n readonly defaultDepthOps: AttachmentDepthOps | undefined;\n}\n\n/**\n * Closed map of passKind → attachment policy. Covers the 10 attachment shapes\n * the runtime ships (per plan-strategy M4):\n *\n * 1. `'forward'` — main geometry pass: color+depth(+stencil-gated)\n * 2. `'deferred'` — HDRP G-Buffer geometry pass: MRT color+depth\n * 3. `'shadow-caster'` — directional shadow caster: depth-only\n * 4. `'point-shadow-caster'` — HDRP point-shadow caster: depth-only\n * 5. `'skybox'` — fullscreen skybox: color-only clear/store\n * 6. `'tonemap'` — HDR→LDR tonemap fullscreen: color-only clear/store\n * 7. `'bloom-bright'` / `'bloom-blur'` — bloom downsample/blur: color-only\n * clear/store\n * 8. `'bloom-composite'` — bloom add-back: color-only load/store (NOT clear)\n * 9. `'fxaa'` — fullscreen FXAA: color-only clear/store\n * 10. `'post-process'` — generic fullscreen primitive (SSAO, render-graph\n * fullscreen-post-process-pass dispatcher, M2 tonemap pre-warm slot):\n * color-only clear/store\n *\n * Sprite-split forward sub-pass reuses the `'forward'` policy with\n * `options.colorLoadOp='load'` + `options.depthLoadOp='load'`.\n *\n * Stencil-op gate is NOT in this table — it is derived from\n * `specAttachments.depthFormat` inside the helper (depth24plus-stencil8\n * → emit `stencilLoadOp:'clear' / stencilStoreOp:'discard'`).\n */\nexport const passKindPolicyTable: Readonly<Record<string, PassKindAttachmentPolicy>> = {\n forward: {\n shape: 'color-and-depth',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: { loadOp: 'clear', storeOp: 'store', clearValue: 1 },\n },\n deferred: {\n shape: 'color-and-depth',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n },\n defaultDepthOps: { loadOp: 'clear', storeOp: 'store', clearValue: 1 },\n },\n temporal: {\n shape: 'color-and-depth',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: -1, a: 1 },\n },\n defaultDepthOps: { loadOp: 'clear', storeOp: 'store', clearValue: 1 },\n },\n 'shadow-caster': {\n shape: 'depth-only',\n defaultColorOps: undefined,\n defaultDepthOps: { loadOp: 'clear', storeOp: 'store', clearValue: 1 },\n },\n 'point-shadow-caster': {\n shape: 'depth-only',\n defaultColorOps: undefined,\n defaultDepthOps: { loadOp: 'clear', storeOp: 'store', clearValue: 1 },\n },\n skybox: {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n tonemap: {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n 'bloom-bright': {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n 'bloom-blur': {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n 'bloom-composite': {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'load',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n fxaa: {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n 'post-process': {\n shape: 'color-only',\n defaultColorOps: {\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n defaultDepthOps: undefined,\n },\n};\n\n/**\n * Build a `GPURenderPassDescriptor` from spec attachments + resolved views +\n * a passKind policy lookup.\n *\n * The helper is the single SSOT for `device.beginRenderPass(...)` descriptor\n * shape — every record-stage call site routes through it (plan-strategy M4\n * AC-06). It dispatches on `passKindPolicyTable[passKind]` to pick the\n * attachment shape (depth-only / color-only / color-and-depth) and applies\n * default color/depth load+store ops; per-call overrides (sprite-split's\n * `loadOp:'load'`, main pass's dynamic `mainColorLoadOp`, skybox's specific\n * clearColor) flow through `options`.\n *\n * Stencil-op gate is auto-derived from `specAttachments.depthFormat`:\n * - `'depth24plus-stencil8'` → emits `stencilLoadOp:'clear', stencilStoreOp:'discard'`\n * - every other depth format → omits stencil ops entirely\n *\n * This collapses the R3/R5 stencil-op duplicates that previously lived inline\n * at every forward-pass beginRenderPass site.\n *\n * @param specAttachments - the attachments axis from a PipelineSpec\n * @param viewBindings - resolved texture views: `{ colorViews, depthView?, resolveTargets? }`\n * @param passKind - one of the keys in {@link passKindPolicyTable}\n * @param options - per-call ops overrides (loadOp / clearValue / label)\n * @returns a WebGPU render-pass descriptor\n * @throws PipelineSpecError(`'unknown-pass-kind'`) when passKind is not registered\n * @see plan-strategy M4 · requirements AC-06\n */\nexport function buildBeginRenderPassDescriptor(\n specAttachments: PipelineSpec['attachments'],\n viewBindings: {\n readonly colorViews: readonly unknown[];\n readonly resolveTargets?: readonly (unknown | undefined)[];\n readonly depthView?: unknown;\n },\n passKind: string,\n options?: {\n readonly colorLoadOp?: 'clear' | 'load';\n readonly colorStoreOp?: 'store' | 'discard';\n readonly clearColor?: GPUColor;\n readonly depthLoadOp?: 'clear' | 'load';\n readonly depthStoreOp?: 'store' | 'discard';\n readonly label?: string;\n },\n): Record<string, unknown> {\n const policy = passKindPolicyTable[passKind];\n if (policy === undefined) {\n throw new PipelineSpecError({\n code: 'unknown-pass-kind',\n detail: { expected: Object.keys(passKindPolicyTable), actual: passKind },\n hint: `passKind '${passKind}' is not in passKindPolicyTable; register an attachment policy or pick an existing one (e.g. 'post-process' for fullscreen-quad passes)`,\n });\n }\n\n const out: Record<string, unknown> = {};\n if (options?.label !== undefined) {\n out.label = options.label;\n }\n\n // Colour attachments: depth-only → empty array; otherwise iterate colorViews\n // and apply policy default ops + per-call overrides. resolveTargets[i] === undefined\n // means \"no resolve for this slot\"; only present slots emit a `resolveTarget`.\n if (policy.shape === 'depth-only') {\n out.colorAttachments = [];\n } else {\n const colorOps = policy.defaultColorOps;\n if (colorOps === undefined) {\n throw new PipelineSpecError({\n code: 'spec-inconsistent',\n detail: {\n reason: 'policy-shape-color-without-colorOps',\n actual: passKind,\n },\n hint: `passKind '${passKind}' has shape='${policy.shape}' but no defaultColorOps; fix passKindPolicyTable entry`,\n });\n }\n const loadOp = options?.colorLoadOp ?? colorOps.loadOp;\n const storeOp = options?.colorStoreOp ?? colorOps.storeOp;\n const clearValue = options?.clearColor ?? colorOps.clearValue;\n\n out.colorAttachments = viewBindings.colorViews.map((view, i) => {\n const slot: Record<string, unknown> = {\n view,\n loadOp,\n storeOp,\n };\n const resolveTarget = viewBindings.resolveTargets?.[i];\n if (resolveTarget !== undefined) {\n slot.resolveTarget = resolveTarget;\n }\n // Emit clearValue only when load is 'clear' AND a value is available.\n if (loadOp === 'clear' && clearValue !== undefined) {\n slot.clearValue = clearValue;\n }\n return slot;\n });\n }\n\n // Depth-stencil attachment: emitted iff policy declares depth ops AND\n // the spec carries a depthFormat. Stencil ops auto-derived from format.\n if (policy.shape !== 'color-only' && policy.defaultDepthOps !== undefined) {\n const dOps = policy.defaultDepthOps;\n const depthLoadOp = options?.depthLoadOp ?? dOps.loadOp;\n const depthStoreOp = options?.depthStoreOp ?? dOps.storeOp;\n const ds: Record<string, unknown> = {\n view: viewBindings.depthView,\n depthLoadOp,\n depthStoreOp,\n };\n if (depthLoadOp === 'clear') {\n ds.depthClearValue = dOps.clearValue;\n }\n // Stencil-op gate: only depth24plus-stencil8 carries a stencil aspect.\n if (specAttachments.depthFormat === 'depth24plus-stencil8') {\n ds.stencilClearValue = 0;\n ds.stencilLoadOp = 'clear';\n ds.stencilStoreOp = 'discard';\n }\n out.depthStencilAttachment = ds;\n }\n\n return out;\n}\n\n/**\n * Validate a PipelineSpec before attempting to build.\n *\n * Fail-fast checks (charter P5) covering axis mutual-exclusion rules.\n * Returns `Result<void, PipelineSpecError>` — ok for valid specs,\n * err with structured code + detail for invalid ones.\n *\n * Checks:\n * 1. `sampleCount=4` with empty `colorFormats` → `'spec-inconsistent'`\n * 2. Pass kind not in `KNOWN_PASS_KINDS` → `'unknown-pass-kind'`\n * 3. `depthFormat` undefined but `renderState` implies depth testing →\n * `'attachment-format-incompatible'`\n *\n * @see plan-strategy §3.2 · requirements AC-02 · charter P5\n */\nexport function validateSpec(\n spec: PipelineSpec,\n):\n | { ok: true }\n | { ok: false; code: PipelineSpecErrorCode; detail: Record<string, unknown>; hint?: string } {\n // Check 1: sampleCount=4 with empty colorFormats is inconsistent —\n // multisample requires a colour target to resolve to.\n if (spec.attachments.sampleCount === 4 && spec.attachments.colorFormats.length === 0) {\n return {\n ok: false,\n code: 'spec-inconsistent',\n detail: { reason: 'sample-count-format-incompatible' },\n hint: 'sampleCount=4 requires at least one colorFormat; shadow-caster (depth-only) passes should use sampleCount=1',\n };\n }\n\n // Check 2: unknown pass kind\n if (!KNOWN_PASS_KINDS.includes(spec.shader.passKind)) {\n return {\n ok: false,\n code: 'unknown-pass-kind',\n detail: { expected: KNOWN_PASS_KINDS, actual: spec.shader.passKind },\n hint: `passKind '${spec.shader.passKind}' is not in KNOWN_PASS_KINDS; register custom pass kinds via ShaderCatalog`,\n };\n }\n\n // Check 3: depth-testing renderState without a depthFormat\n const depthOnly = passKindPolicyTable[spec.shader.passKind]?.shape === 'depth-only';\n const depthRequired = !!spec.renderState?.depthCompare || depthOnly;\n if (!spec.attachments.depthFormat && depthRequired) {\n return {\n ok: false,\n code: 'attachment-format-incompatible',\n detail: {\n reason: 'depth-requirement-without-depth-format',\n expected: 'depthFormat must be set when depth testing or a depth-only pass is requested',\n actual: `depthFormat=${String(spec.attachments.depthFormat)}, depthCompare=${spec.renderState?.depthCompare}`,\n },\n hint: 'set attachments.depthFormat (e.g. depth24plus-stencil8 or depth32float) when renderState specifies depthCompare',\n };\n }\n\n return { ok: true };\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// PipelineCache — Map<string, RenderPipeline> container (D-12)\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Pipeline cache — Map from cacheKeyOf(spec) to opaque RenderPipeline handle.\n *\n * Constructed once at createRenderer boot time; shared across all call sites.\n * Consumers call `getOrBuildPipeline(spec, deviceProvider, cache)` — the\n * entrypoint does cache lookup internally; consumers never touch the Map\n * directly.\n *\n * @see plan-strategy D-12 · requirements §3.2\n */\nexport type PipelineCache = Map<string, unknown>;\n\n// ══════════════════════════════════════════════════════════════════════════════\n// getOrBuildPipeline — single entrypoint (D-12)\n// ══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Device factory interface consumed by {@link getOrBuildPipeline}.\n *\n * Slim abstraction: only `createRenderPipeline` is needed; the entrypoint\n * does not depend on the full `RhiDevice` interface so it can be tested\n * with a mock.\n */\nexport interface PipelineDeviceProvider {\n createRenderPipeline(\n descriptor: Record<string, unknown>,\n ): { ok: true; value: unknown } | { ok: false; error: unknown };\n}\n\n/**\n * Single entrypoint for obtaining a render pipeline from a spec.\n *\n * Cache-hit path: key = cacheKeyOf(spec), returns cached handle immediately.\n * Cache-miss path: validates spec → builds descriptor → calls device.createRenderPipeline\n * → caches result → returns handle.\n * Build failure: throws PipelineSpecError (charter P3 fail-fast, no silent fallback).\n *\n * Pure function: same (spec, deviceProvider, cache) always produces the same result.\n * Boot-time call site: createRenderer wires the real device; record-stage call site\n * uses ctx.runtime.device (same entrypoint, same signature).\n *\n * @param spec - immutable 4-axis pipeline specification\n * @param deviceProvider - factory with createRenderPipeline method\n * @param cache - the PipelineCache (shared across boot + record stage)\n * @returns a RenderPipeline handle (opaque, typed as unknown for M1)\n * @throws PipelineSpecError on validation failure or build failure\n * @see plan-strategy D-12 · requirements AC-03 · charter F1\n */\nexport function getOrBuildPipeline(\n spec: PipelineSpec,\n deviceProvider: PipelineDeviceProvider,\n cache: PipelineCache,\n modules?: {\n vertex: unknown;\n fragment: unknown;\n vertexEntryPoint?: string;\n fragmentEntryPoint?: string;\n layout?: unknown;\n },\n): unknown {\n const key = cacheKeyOf(spec);\n\n // Cache hit — return immediately.\n const cached = cache.get(key);\n if (cached !== undefined) return cached;\n\n // Cache miss — validate, build, cache, return.\n const validation = validateSpec(spec);\n if (!validation.ok) {\n throw new PipelineSpecError({\n code: validation.code,\n detail: validation.detail,\n ...(validation.hint !== undefined ? { hint: validation.hint } : {}),\n });\n }\n\n const descriptor = buildPipelineDescriptor(\n spec,\n modules ?? { vertex: undefined, fragment: undefined },\n );\n const result = deviceProvider.createRenderPipeline(descriptor);\n\n if (!result.ok) {\n throw new PipelineSpecError({\n code: 'pipeline-build-failed',\n detail: { cause: result.error },\n hint: 'device.createRenderPipeline failed for spec; inspect gpuMessage on the error detail',\n });\n }\n\n cache.set(key, result.value);\n return result.value;\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// SPEC_CONST_TABLE — 12 boot-time pre-warm variants (M1-T5)\n// ══════════════════════════════════════════════════════════════════════════════\n\nconst PROCEDURAL_ATTR_LAYOUT: VertexAttributeMap = {\n position: new Float32Array(0),\n normal: new Float32Array(0),\n uv: new Float32Array(0),\n tangent: new Float32Array(0),\n};\n\nconst HDR_FORMAT: GPUTextureFormat = 'rgba16float';\nconst DEPTH_DS: GPUTextureFormat = 'depth24plus-stencil8';\n\n/**\n * Default LDR view format used when callers ask for the SPEC_CONST table\n * without an explicit swap-chain format. Kept for the backward-compatible\n * `SPEC_CONST_TABLE` export consumed by unit tests that exercise the\n * spec/cache-keying layer in isolation. Runtime callers always pass the\n * format selected by `selectSwapChainFormat` (Channel 2 BGRA / Channel 3\n * RGBA / dawn-node RGBA — see bug-20260615 fix-up note in `createRenderer`).\n */\nconst DEFAULT_LDR_FORMAT: GPUTextureFormat = 'bgra8unorm-srgb';\n\nconst TRI_GEOMETRY = {\n topology: 'triangle-list' as PrimitiveTopology,\n stripIndexFormat: undefined,\n vertexLayout: PROCEDURAL_ATTR_LAYOUT,\n};\n\n// feat-city-glb multi-UV tiling: the built-in standard PBR shader now declares\n// UV sets @location(6..12), so naga reflects uvSetCount=8 for it and the URP\n// record path threads `shaderUvSetCount: 8` into every standard-pbr spec\n// (createRenderer.ts buildPipelineContext / getMaterialShaderPipeline).\n// The boot-time prewarm must match on both axes: the PSO vertex layout includes\n// all declared UV slots, and the cacheKey carries `:uvsc8`. For single-UV\n// meshes deriveVertexBufferLayout clamp-to-last aliases every missing set onto\n// the last mesh set (48-byte stride unchanged), so existing geometry remains\n// byte-stable.\n// unlit stays on TRI_GEOMETRY (its shader declares only @location(0..3)).\nconst TRI_GEOMETRY_PBR = {\n topology: 'triangle-list' as PrimitiveTopology,\n stripIndexFormat: undefined,\n vertexLayout: PROCEDURAL_ATTR_LAYOUT,\n shaderUvSetCount: 8,\n};\n\n// M6 fix-up: non-clustered boot-variant key string for the standard PBR shader.\n// Mirrors the boot-time variantSet computed at createRenderer.ts step 1b when\n// clustered lighting is not yet admitted and `storageBufferCapable=true` (the\n// surface). The default record path requests this exact string at every\n// `getMaterialShaderPipeline` call site, so seeding the table with these\n// variants keeps the default cache lookup hot from frame 1 instead of\n// skip-drawing the first ~1 frames while the async compile resolves.\nconst STANDARD_BOOT_VARIANT_SET = standardCapabilityVariantSet(false, true, false);\n\n/**\n * Build the boot-time pre-warm table: 15 standard PipelineSpec variants.\n *\n * feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (AC-12): the\n * four `forgeax::default-sprite` entries (LDR S1 + LDR S4 + HDR S1 + HDR S4)\n * are gone — sprite PSO lands lazily through the generic\n * per-MaterialShader pipeline cache. Pre-feat count was 19; post-feat 15.\n *\n * Matrix:\n * - 8 base material variants — {unlit, standard-pbr} x {LDR, HDR} x {S1, S4}\n * - 4 non-clustered standard-pbr — standard-pbr (variantSet=STANDARD_BOOT_VARIANT_SET)\n * x {LDR, HDR} x {S1, S4}; the default record path requests these specs by\n * `getMaterialShaderPipeline` keying off `cacheKeyOf` so the boot-time\n * prewarm seeds `materialShaderPipelineCache` and avoids a 1-frame\n * async-compile skip-draw (M6 fix-up; see render-system-record.ts)\n * - 3 fullscreen-post — tonemap (LDR S1) + skybox (HDR S1, HDR S4)\n *\n * Total: 15. The non-clustered variant is PBR-only because:\n * - unlit record path passes `variantSet=undefined` (the no-variant\n * boot-default entries already cover it; createRenderer.ts §unlitRsp)\n * - sprite goes through `getMaterialShaderPipeline('forgeax::sprite', ...)`\n * lazily at first transparent-LDR-split draw — no boot-time pre-warm.\n * - clustered variant (`variantSet=''` or compound `=true` form) is registered\n * lazily when the clustered Standard profile activates, not at boot — adding clustered\n * prewarm here would build PSOs against the URP layout (the boot-time\n * `pbrModule` is the non-clustered variant before a frame admits local lights)\n *\n * `ldrViewFormat` parameterises the LDR color attachment format. Callers\n * pass the runtime-resolved swap-chain view format (Channel 2 typically\n * `bgra8unorm-srgb`; Channel 3 wgpu-wasm and dawn-node typically\n * `rgba8unorm-srgb`). Hard-coding `bgra8unorm-srgb` at module load made\n * the pre-warmed PSOs incompatible with the actual RenderPass color\n * attachment on Channel 3 / dawn-node, producing whole-commandBuffer\n * invalid errors on every frame (bug-20260615 fix-up — see\n * `createRenderer` boot-time pre-warm site).\n *\n * Fullscreen passes (fxaa / bloom x 3 / SSAO x 2) are lazy-build — they\n * use the same getOrBuildPipeline entrypoint but are not in this table.\n *\n * @see plan-strategy D-4 · research R-D4 · requirements AC-16\n * @see bug-20260612-webgpu-canvas-format-prefer-bgra-shipped (same trap shape)\n */\nexport function buildSpecConstTable(\n ldrViewFormat: GPUTextureFormat,\n): readonly Readonly<PipelineSpec>[] {\n const TRI_ATTACHMENTS_LDR_S1 = {\n colorFormats: [ldrViewFormat],\n depthFormat: DEPTH_DS,\n sampleCount: 1 as const,\n };\n\n const TRI_ATTACHMENTS_LDR_S4 = {\n colorFormats: [ldrViewFormat],\n depthFormat: DEPTH_DS,\n sampleCount: 4 as const,\n };\n\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (AC-12 / D-7):\n // SPRITE_ATTACHMENTS_LDR_S1 / S4 (the dedicated non-srgb storage-format\n // attachments the sprite spec entries consumed) were deleted alongside the\n // four `forgeax::default-sprite` SPEC_CONST entries. The bgra8unorm storage\n // format itself is still enforced at the LDR sprite sub-pass attachment\n // level (the WebGPU pipeline `colorFormats` derive from the actual render\n // pass attachment view, which is built off `pipelineState.format` =\n // swap-chain storage format — see `render-system-record.ts` LDR split\n // beginRenderPass call). The triggering source migrated from the\n // spec-table id to `material.transparent` (derived by the extract stage\n // from `passes[0].renderState.blend !== undefined`, the\n // post-feat-20260626-collapse SSOT; w7 onwards).\n\n const TRI_ATTACHMENTS_HDR_S1 = {\n colorFormats: [HDR_FORMAT],\n depthFormat: DEPTH_DS,\n sampleCount: 1 as const,\n };\n\n const TRI_ATTACHMENTS_HDR_S4 = {\n colorFormats: [HDR_FORMAT],\n depthFormat: DEPTH_DS,\n sampleCount: 4 as const,\n };\n\n return [\n // unlit LDR S1\n {\n shader: { id: 'forgeax::default-unlit', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_LDR_S1,\n geometry: TRI_GEOMETRY,\n renderState: undefined,\n },\n // unlit LDR S4\n {\n shader: { id: 'forgeax::default-unlit', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_LDR_S4,\n geometry: TRI_GEOMETRY,\n renderState: undefined,\n },\n // unlit HDR S1\n {\n shader: { id: 'forgeax::default-unlit', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_HDR_S1,\n geometry: TRI_GEOMETRY,\n renderState: undefined,\n },\n // unlit HDR S4\n {\n shader: { id: 'forgeax::default-unlit', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_HDR_S4,\n geometry: TRI_GEOMETRY,\n renderState: undefined,\n },\n // standard LDR S1\n {\n shader: { id: 'forgeax::default-standard-pbr', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_LDR_S1,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard LDR S4\n {\n shader: { id: 'forgeax::default-standard-pbr', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_LDR_S4,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard HDR S1\n {\n shader: { id: 'forgeax::default-standard-pbr', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_HDR_S1,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard HDR S4\n {\n shader: { id: 'forgeax::default-standard-pbr', passKind: 'forward', variantSet: undefined },\n attachments: TRI_ATTACHMENTS_HDR_S4,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n\n // ── M6 fix-up: non-clustered standard-pbr prewarm ─────────────────────────\n // The default record path (`getMaterialShaderPipeline`) requests\n // `variantSet=STANDARD_BOOT_VARIANT_SET` for standard-shading entities; pre-M6\n // the silent `selectStandardFallbackPipeline` shim served the no-variant\n // boot prewarm during the 1-frame async-compile warmup. With M6's\n // explicit-failure surface, those requests must hit the boot prewarm\n // by their own variantSet — these 4 entries close that gap.\n\n // standard PBR URP LDR S1\n {\n shader: {\n id: 'forgeax::default-standard-pbr',\n passKind: 'forward',\n variantSet: STANDARD_BOOT_VARIANT_SET,\n },\n attachments: TRI_ATTACHMENTS_LDR_S1,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard PBR URP LDR S4\n {\n shader: {\n id: 'forgeax::default-standard-pbr',\n passKind: 'forward',\n variantSet: STANDARD_BOOT_VARIANT_SET,\n },\n attachments: TRI_ATTACHMENTS_LDR_S4,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard PBR URP HDR S1\n {\n shader: {\n id: 'forgeax::default-standard-pbr',\n passKind: 'forward',\n variantSet: STANDARD_BOOT_VARIANT_SET,\n },\n attachments: TRI_ATTACHMENTS_HDR_S1,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n // standard PBR URP HDR S4\n {\n shader: {\n id: 'forgeax::default-standard-pbr',\n passKind: 'forward',\n variantSet: STANDARD_BOOT_VARIANT_SET,\n },\n attachments: TRI_ATTACHMENTS_HDR_S4,\n geometry: TRI_GEOMETRY_PBR,\n renderState: undefined,\n },\n\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (AC-12 / D-7):\n // the four `forgeax::default-sprite` boot-time pre-warm entries (LDR S1\n // + LDR S4 + HDR S1 + HDR S4) are gone. Sprite PSO lands lazily through\n // the generic per-MaterialShader pipeline cache keyed on\n // `forgeax::sprite` + premultiplied-alpha renderState; SPEC_CONST_TABLE\n // shrinks from 19 to 15 entries (-4 boot-time PSOs).\n\n // ── M2-T4: fullscreen-post boot-time pre-warm (tonemap + skybox) ──────────\n //\n // Tonemap (LDR S1): fullscreen triangle writes to swap-chain LDR view format\n // (parameterised — `ldrViewFormat`; see buildSpecConstTable jsdoc + bug-20260615).\n // Skybox (HDR S1 + S4): fullscreen triangle writes to rgba16float; MSAA variant\n // has sampleCount=4. Both use empty vertexLayout (fullscreen triangle, no\n // attributes) and cullMode='none' (forward cull for fullscreen-quad passthrough).\n //\n // Shadow-probe / fxaa / bloom 4-stage / SSAO 2-stage are lazy-build — not in\n // SPEC_CONST_TABLE (R-D4 decision: only entries that are always-present on\n // every boot).\n\n // tonemap LDR S1 (writes to runtime-resolved swap-chain LDR view format)\n {\n shader: { id: 'forgeax::post::tonemap', passKind: 'post-process', variantSet: undefined },\n attachments: {\n colorFormats: [ldrViewFormat],\n depthFormat: undefined,\n sampleCount: 1 as const,\n },\n geometry: {\n topology: 'triangle-list' as PrimitiveTopology,\n stripIndexFormat: undefined,\n vertexLayout: {},\n },\n renderState: {\n cullMode: 'none',\n },\n },\n\n // skybox HDR S1 (writes to rgba16float, no depth)\n {\n shader: { id: 'forgeax::skybox::cube', passKind: 'skybox', variantSet: undefined },\n attachments: {\n colorFormats: [HDR_FORMAT],\n depthFormat: undefined,\n sampleCount: 1 as const,\n },\n geometry: {\n topology: 'triangle-list' as PrimitiveTopology,\n stripIndexFormat: undefined,\n vertexLayout: {},\n },\n renderState: {\n cullMode: 'none',\n },\n },\n\n // skybox HDR S4 (MSAA variant)\n {\n shader: { id: 'forgeax::skybox::cube', passKind: 'skybox', variantSet: undefined },\n attachments: {\n colorFormats: [HDR_FORMAT],\n depthFormat: undefined,\n sampleCount: 4 as const,\n },\n geometry: {\n topology: 'triangle-list' as PrimitiveTopology,\n stripIndexFormat: undefined,\n vertexLayout: {},\n },\n renderState: {\n cullMode: 'none',\n },\n },\n ];\n}\n\n/**\n * Derive the material-only pre-warm table for a native linear-LDR target.\n *\n * The regular SPEC_CONST table targets the swap-chain view, while the\n * tonemap=none path records geometry directly into the graph-owned\n * `rgba16float` target. Keep that second attachment matrix derived from the\n * same material specs so the first frame does not depend on an asynchronous\n * lazy PSO build.\n */\nexport function buildLinearLdrMaterialSpecTable(\n ldrViewFormat: GPUTextureFormat,\n): readonly Readonly<PipelineSpec>[] {\n return buildSpecConstTable(ldrViewFormat)\n .filter(\n (spec) =>\n spec.shader.passKind === 'forward' && spec.attachments.colorFormats[0] === ldrViewFormat,\n )\n .map((spec) => ({\n ...spec,\n attachments: {\n ...spec.attachments,\n colorFormats: [HDR_FORMAT],\n },\n }));\n}\n\n/**\n * Backward-compatible SPEC_CONST_TABLE — the table built with the default\n * LDR view format (`bgra8unorm-srgb`). Unit tests that exercise the\n * spec/cache-keying layer in isolation import this directly. Runtime\n * callers MUST call `buildSpecConstTable(swapChainFormats.view)` instead\n * so the pre-warmed PSO color format matches the actual RenderPass color\n * attachment on every backend (bug-20260615 fix-up).\n */\nexport const SPEC_CONST_TABLE: readonly Readonly<PipelineSpec>[] =\n buildSpecConstTable(DEFAULT_LDR_FORMAT);\n","import { mat3 } from '@forgeax/engine-math';\nimport { type BindGroup, type Buffer, RhiError, type RhiQueue } from '@forgeax/engine-rhi';\nimport type { DispatchEntry } from '../render-system-extract';\nimport {\n TRANSPARENT_SORT_MODE_LAYER_Y,\n TRANSPARENT_SORT_MODE_LAYER_Z,\n type TransparentSortConfig,\n} from '../systems/transparent-sort-config';\nimport type { ValidatedRenderable } from './frame-snapshot';\n\n/**\n * Stride between per-renderable `entity_world` mat4 slots inside the\n * shared `pipelineState.meshStorageBuffer`. The 256-byte alignment is\n * required because the storage buffer is bound with\n * `hasDynamicOffset: true` and WebGPU spec\n * `minStorageBufferOffsetAlignment` defaults to 256.\n */\nexport const MESH_PER_ENTITY_STRIDE = 256;\n\n// The storage-buffer Mesh struct also carries the temporal previous transform\n// and reactive metadata when STORAGE_BUFFER_AVAILABLE is true:\n// mat4 (64 B) + mat3 (48 B) + previous mat4 (64 B) + vec4 (16 B) = 192 B.\n// The BindGroup entry's `size` must cover the complete reflected struct, not\n// only the first world transform and normal matrix.\nexport const MESH_SSBO_BYTES = 192;\n\n// bug-20260610: WebGL2 fallback shader declares `array<Mesh, 128>` as a\n// uniform buffer; binding must cover the full array size. The storage\n// variant binds a single 112-B slot via dynamic offset, but the uniform\n// variant requires the whole 14336-B range visible to the shader.\nexport const MESH_UBO_FULL_ARRAY_BYTES = 112 * 128;\n\n// bug-20260723-webgl2-instancing-uniform-range: the WebGL2 fallback shader\n// declares `array<InstanceData, 128>` in the instances bind group. Even when\n// a draw carries fewer transforms, the buffer binding must expose the full\n// array range or wgpu rejects the draw at submit time with a late\n// min-binding-size mismatch.\nexport const INSTANCE_UBO_FULL_ARRAY_BYTES = 80 * 128;\n\nexport const MAX_UNIFORM_INSTANCES = 128;\n\n/** The storage-backed InstanceData layout is current + previous mat4. */\nexport const INSTANCE_STORAGE_STRIDE_FLOATS = 32;\n\n/**\n * Project the ECS transform snapshot into the storage-backed InstanceData\n * layout. The extract contract carries one current mat4 per instance; until\n * the ECS snapshot owns a previous-instance column, current is the honest\n * previous value as well. Uniform-backed variants keep the compact 16-float\n * payload and do not use this projection.\n */\nexport function packInstanceStorageBuffer(transforms: Float32Array): Float32Array {\n const count = Math.floor(transforms.length / 16);\n const out = new Float32Array(count * INSTANCE_STORAGE_STRIDE_FLOATS);\n for (let i = 0; i < count; i++) {\n const sourceBase = i * 16;\n const targetBase = i * INSTANCE_STORAGE_STRIDE_FLOATS;\n for (let k = 0; k < 16; k++) {\n const value = transforms[sourceBase + k] ?? 0;\n out[targetBase + k] = value;\n out[targetBase + 16 + k] = value;\n }\n }\n return out;\n}\n\n/**\n * M3 / w12: extracts the underlying GPU resource object from a bind\n * group entry descriptor. Returns the raw object reference (Buffer,\n * TextureView, or Sampler) usable as a WeakMap chain key.\n */\nexport function extractEntryResourceHandle(entry: {\n resource: { kind: string; value: unknown };\n}): object {\n const v = entry.resource.value;\n if (typeof v === 'object' && v !== null && 'buffer' in (v as Record<string, unknown>)) {\n return (v as { buffer: object }).buffer;\n }\n return v as object;\n}\n\n/**\n * feat-20260622-handle-to-id-allocator-elimination M2 / w7: walks a nested\n * WeakMap chain to find or create a BindGroup leaf. Each handle in the\n * `handles` array is a chain node; the final leaf is a Map<string, BindGroup>\n * keyed by `variant` (D-2). Chain keys are always object references, never\n * numeric ids — GC reclaims entries for dead handles automatically.\n *\n * On cache hit returns the cached BindGroup. On miss calls `factory`,\n * bumps `bindGroupCounts.createBindGroup`, stores the result at the leaf,\n * and returns it. Hit/miss accounting is observable via `bindGroupCounts`\n * (D-8: the skin probe reads `counts.createBindGroup` delta).\n */\nexport function getOrCreateFromChain(\n root: WeakMap<object, unknown>,\n handles: readonly object[],\n variant: string,\n factory: () => BindGroup,\n counts: { createBindGroup: number; keys: string[] },\n): BindGroup {\n let node = root;\n for (let i = 0; i < handles.length - 1; i++) {\n // biome-ignore lint/style/noNonNullAssertion: handles length guards the index\n const h = handles[i]!;\n let next = node.get(h) as WeakMap<object, unknown> | undefined;\n if (next === undefined) {\n next = new WeakMap();\n node.set(h, next);\n }\n node = next;\n }\n // biome-ignore lint/style/noNonNullAssertion: known non-empty at call sites\n const last = handles[handles.length - 1]!;\n let leaf = node.get(last) as Map<string, BindGroup> | undefined;\n if (leaf === undefined) {\n leaf = new Map();\n node.set(last, leaf);\n }\n const hit = leaf.get(variant);\n if (hit !== undefined) return hit;\n const bg = factory();\n counts.createBindGroup += 1;\n counts.keys.push(variant);\n leaf.set(variant, bg);\n return bg;\n}\n\n/**\n * feat-20260622-handle-to-id-allocator-elimination M2 / w8: per-entity bind\n * group lookup-or-create helper (D-2). Two-step lookup: outer Map.get(outerKey)\n * finds or lazily creates an inner WeakMap chain, then delegates to\n * `getOrCreateFromChain` for the chain walk. outerKey is `string | number`\n * to cover both per-entity (number entityKey) and material-shared\n * (string shaderId) caches (D-1 / OQ-1).\n */\nexport function getOrCreatePerEntity(\n outerMap: Map<string | number, WeakMap<object, unknown>>,\n outerKey: string | number,\n handles: readonly object[],\n variant: string,\n factory: () => BindGroup,\n counts: { createBindGroup: number; keys: string[] },\n): BindGroup {\n let inner = outerMap.get(outerKey) as WeakMap<object, unknown> | undefined;\n if (inner === undefined) {\n inner = new WeakMap();\n outerMap.set(outerKey, inner);\n }\n return getOrCreateFromChain(inner, handles, variant, factory, counts);\n}\n\n/**\n * feat-20260622-handle-to-id-allocator-elimination M2 / w8: evicts per-entity\n * cache entries whose entityKey is not in the validated set. Works on\n * Map<entityKey, WeakMap<handle, BindGroup>> by iterating the outer Map keys\n * and deleting entries for which validatedEntityKeys.has(ek) is false.\n * No string parsing, no Number / Number.isNaN — the entityKey is already a\n * number (D-1 / RD4).\n *\n * @internal — exported for unit test access (AC-08)\n */\nexport function cleanPerEntityCache(\n cache: Map<number, WeakMap<object, unknown>>,\n validatedEntityKeys: Set<number>,\n): void {\n for (const ek of cache.keys()) {\n if (!validatedEntityKeys.has(ek)) {\n cache.delete(ek);\n }\n }\n}\n\n/**\n * feat-20260608-mesh-ssbo-dynamic-grow-l1-lift-1024-entity-cap M3 / T-M3-04:\n * record-stage entry-point hook to the closure-scoped mesh-SSBO grow\n * controller (createRenderer.ts). Called once per frame, after\n * `validatedOrdered` has been finalised and BEFORE the first per-entity\n * `queue.writeBuffer`. Returns Result-like (never throws — D-5):\n *\n * - `{ ok: true }` — slotCount already covers `neededSlots` (idempotent\n * short-circuit), or the controller successfully grew\n * in this call. Caller proceeds with the frame.\n * - `{ ok: false, code, degradedToSlotCount }` — controller hit ceiling /\n * capacity and ALREADY fired the structured error\n * via errorRegistry. Caller truncates the draw\n * list to the largest complete entity prefix that\n * fits within `degradedToSlotCount` slots (graceful\n * degradation per plan-strategy D-2): renders the\n * subset that fits, discards overflow, no black\n * frame.\n *\n * This helper does NOT re-fire on `ok:false` — the controller is the single\n * fire site (createRenderer.ts grow factory), so callers see exactly one\n * structured error per ceiling event (charter P3 explicit failure: no\n * double-fire).\n *\n * Dev-mode visibility: when grow actually grew (slotCount transition) AND\n * `import.meta.env?.DEV` is truthy, a single `console.info('[mesh-ssbo] ...')`\n * line reports the before / after / requested counts. The optional-chain\n * keeps non-vite envs (dawn-node smoke, plain tsup tests) silent —\n * `import.meta.env` is undefined there, the chain short-circuits to\n * undefined, the if-guard is falsy (AC-11 + plan-strategy §2.D-3).\n *\n * Bind-group cache invalidation is automatic: on grow, the controller\n * mutates `meshSsboState.mesh.buffer` / `.material.buffer` in place\n * (wrapper-object identity preserved, inner buffer replaced — research §F8).\n * Downstream the fresh inner buffer object is a new WeakMap chain key, so\n * `getOrCreateFromChain` misses and rebuilds the BindGroup on the next frame\n * (AC-07; T-M3-03 (a) test).\n *\n * @internal — exported for unit-test access (`mesh-ssbo-grow.test.ts`\n * T-M3-01 / T-M3-02 / T-M3-03 cover idempotency, ceiling, dev info).\n */\nexport function ensureMeshSsboCapacity(\n internals: {\n readonly growMeshSsbo?:\n | ((neededSlots: number) =>\n | { readonly ok: true }\n | {\n readonly ok: false;\n readonly code: 'mesh-ssbo-ceiling-reached' | 'mesh-ssbo-capacity-exceeded';\n readonly degradedToSlotCount: number;\n })\n | undefined;\n readonly meshSsboState?: { readonly slotCount: number } | undefined;\n },\n neededSlots: number,\n):\n | { readonly ok: true }\n | {\n readonly ok: false;\n readonly code: 'mesh-ssbo-ceiling-reached' | 'mesh-ssbo-capacity-exceeded';\n readonly degradedToSlotCount: number;\n } {\n // Empty scene / no controller wired (legacy / test fixture path).\n if (neededSlots <= 0) return { ok: true };\n const grow = internals.growMeshSsbo;\n if (grow === undefined) return { ok: true };\n // Idempotent guard — current slotCount already covers neededSlots.\n // The controller's own internal guard catches this too, but bailing here\n // skips the spy / tracing overhead and matches the AC-09 contract that\n // grow runs at most once per frame transition.\n const before = internals.meshSsboState?.slotCount ?? 0;\n if (before > 0 && before >= neededSlots) return { ok: true };\n const result = grow(neededSlots);\n // Note: ok:false has already fired the structured error inside the\n // controller (createRenderer.ts grow factory). Do NOT double-fire here.\n if (!result.ok) return result;\n // Dev-mode visibility — only on a real slotCount transition (skip\n // no-op idempotent paths above; ceiling path returned early on ok:false).\n const after = internals.meshSsboState?.slotCount ?? before;\n if (after !== before) {\n // Module-local binding read (NOT `recordModule.devModeProbe`) so vitest\n // ESM-readonly export forced us to expose the probe as a settable holder\n // (`setMeshSsboDevModeProbeForTests`) instead of a `vi.spyOn` target.\n if (meshSsboDevModeProbe()) {\n // biome-ignore lint/suspicious/noConsole: AC-11 mandates a `[mesh-ssbo]` info line in dev mode (vite build dead-strips this branch via the `import.meta.env.DEV` constant fold; tsup / esbuild prod sets NODE_ENV=production).\n console.info(\n '[mesh-ssbo] grew slotCount: %d -> %d (requested=%d)',\n before,\n after,\n neededSlots,\n );\n }\n }\n return result;\n}\n\n/**\n * Test seam: a closure-local function pointer ensureMeshSsboCapacity reads\n * for the dev-mode gate. Defaults to `isMeshSsboDevMode`; tests swap it out\n * via `setMeshSsboDevModeProbeForTests` because vitest 4.x export bindings\n * are non-writable (ESM spec) and `import.meta.env.DEV` is build-time-frozen\n * by the vite transform — neither `vi.spyOn(recordModule, 'isMeshSsboDevMode')`\n * nor `vi.stubEnv('DEV', false)` toggles it at runtime.\n */\nlet meshSsboDevModeProbe: () => boolean = isMeshSsboDevMode;\n\n/**\n * @internal — test-only injection seam for `ensureMeshSsboCapacity`'s\n * dev-mode gate. Pass `undefined` to restore the production probe\n * (`isMeshSsboDevMode`). Production code paths NEVER call this.\n */\nexport function setMeshSsboDevModeProbeForTests(probe: (() => boolean) | undefined): void {\n meshSsboDevModeProbe = probe ?? isMeshSsboDevMode;\n}\n\n/**\n * Dev-mode probe for `ensureMeshSsboCapacity`'s console.info gate\n * (plan-strategy §2.D-3 + AC-11). True when the build is in dev mode:\n * - `import.meta.env?.DEV` is truthy (vite dev / vitest), OR\n * - `process.env.NODE_ENV !== 'production'` (esbuild / tsup / dawn-node).\n * Optional-chain keeps it safe in non-vite ESM envs that never inject\n * `import.meta.env` (the chain short-circuits to undefined → falsy).\n *\n * Vite's `import.meta.env.DEV` is constant-folded at build time, so the\n * production bundle dead-code-strips the entire branch even though the\n * test fall-through reads `process.env.NODE_ENV`.\n *\n * @internal — exported as a function (not a const) so unit tests can\n * `vi.spyOn(...).mockReturnValue(false)` to exercise the dev=false path\n * (vitest 4.x cannot toggle `import.meta.env.DEV` at runtime — it is\n * compile-time-frozen by the vite transform).\n */\nexport function isMeshSsboDevMode(): boolean {\n const importMetaDev = (import.meta as { env?: { DEV?: unknown } }).env?.DEV;\n if (importMetaDev) return true;\n // Fallback for tsup / esbuild / dawn-node where import.meta.env is absent:\n // NODE_ENV !== 'production' counts as dev. NODE_ENV unset (undefined)\n // also counts as dev so test envs without explicit NODE_ENV log too —\n // production builds always set NODE_ENV='production'. We read process via\n // globalThis to keep this file @types/node-free (rest of the package is\n // browser-typed; engine-runtime ships ESM into both browser + dawn-node).\n const proc = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\n if (proc !== undefined && proc.env?.NODE_ENV === 'production') return false;\n if (proc === undefined) return false;\n return true;\n}\n\n/**\n * Module-scoped reusable scratch for batched mesh-SSBO uploads (O2).\n * Grows monotonically; never shrinks. One allocation per render session\n * instead of one per entity per frame.\n *\n * @internal\n */\nlet _meshSsboScratch = new Uint8Array(0);\n/** @internal */\nlet _meshSsboScratchFloats = new Float32Array(0);\n\n/**\n * feat-20260704 M3/w21: per-renderable `entity_world` upload (batched). All N\n * mat4+normalMatrix slots are assembled into a single contiguous scratch\n * buffer, then flushed as one `writeBuffer` call instead of N individual\n * calls. Extracted verbatim from `recordFrame` (frame.ts) — the module-scoped\n * `_meshSsboScratch` let and its only reassignment site now co-locate in this\n * file so the two mesh-SSBO module lets live together (AC-06).\n *\n * feat-20260518 M3 / w14 (AC-08): each 256-byte slot carries a 16-float mat4\n * at [0..64B) and a 48-byte mat3 normalMatrix at [64..112B) (3 vec4 columns;\n * padding at indices 19/23/27 stays 0). The mat3 =\n * transpose(invert(mat3(worldFromLocal))) for correct normal transform under\n * non-uniform scale.\n *\n * feat-20260622-chunk-gpu-instancing-sprite-tilemap M1 / w4-record-swap (D-1):\n * fold-bucket heads write identity into their slot; the fold path assembles\n * per-instance world matrices into the @group(3) instances buffer instead\n * (sprite/unlit shaders ignore normals; AC-01/AC-02).\n *\n * @internal\n */\nexport function uploadMeshSsboBatch(\n queue: RhiQueue,\n meshStorageBuffer: { readonly buffer: Buffer },\n validatedOrdered: readonly ValidatedRenderable[],\n foldDispatchPlan: FoldDispatchPlan | null,\n): void {\n const slotCount = validatedOrdered.length;\n const neededBytes = slotCount * MESH_PER_ENTITY_STRIDE;\n // Grow the module-scoped scratch monotonically; zero the used range.\n if (_meshSsboScratch.length < neededBytes) {\n _meshSsboScratch = new Uint8Array(neededBytes);\n _meshSsboScratchFloats = new Float32Array(_meshSsboScratch.buffer);\n } else {\n _meshSsboScratch.fill(0, 0, neededBytes);\n }\n const normalMatrixScratch = mat3.create();\n const strideFloats = MESH_PER_ENTITY_STRIDE / Float32Array.BYTES_PER_ELEMENT;\n for (let i = 0; i < slotCount; i++) {\n const entry = validatedOrdered[i];\n if (entry === undefined) continue;\n // Address the reusable flat view directly. Constructing one typed-array\n // wrapper per visible entity made this otherwise contiguous upload create\n // tens of thousands of short-lived JS objects every frame.\n const slot = i * strideFloats;\n const isFoldHead = foldDispatchPlan?.headBuckets.has(i) === true;\n if (isFoldHead) {\n // identity mat4\n _meshSsboScratchFloats[slot] = 1;\n _meshSsboScratchFloats[slot + 5] = 1;\n _meshSsboScratchFloats[slot + 10] = 1;\n _meshSsboScratchFloats[slot + 15] = 1;\n // identity mat3 normal (cols at slot offsets 16/20/24)\n _meshSsboScratchFloats[slot + 16] = 1;\n _meshSsboScratchFloats[slot + 20] = 1;\n _meshSsboScratchFloats[slot + 24] = 1;\n // Fold heads use the instance storage path; keep the mesh temporal\n // fields deterministic for shader variants that still read the slot.\n _meshSsboScratchFloats[slot + 28] = 1;\n _meshSsboScratchFloats[slot + 33] = 1;\n _meshSsboScratchFloats[slot + 38] = 1;\n _meshSsboScratchFloats[slot + 43] = 1;\n _meshSsboScratchFloats[slot + 44] = 1;\n } else {\n const worldFromLocal = entry.source.transform.world;\n for (let k = 0; k < 16; k++) _meshSsboScratchFloats[slot + k] = worldFromLocal[k] ?? 0;\n const normal = mat3.normalMatrix(normalMatrixScratch, worldFromLocal);\n _meshSsboScratchFloats[slot + 16] = normal[0] ?? 0;\n _meshSsboScratchFloats[slot + 17] = normal[1] ?? 0;\n _meshSsboScratchFloats[slot + 18] = normal[2] ?? 0;\n _meshSsboScratchFloats[slot + 20] = normal[3] ?? 0;\n _meshSsboScratchFloats[slot + 21] = normal[4] ?? 0;\n _meshSsboScratchFloats[slot + 22] = normal[5] ?? 0;\n _meshSsboScratchFloats[slot + 24] = normal[6] ?? 0;\n _meshSsboScratchFloats[slot + 25] = normal[7] ?? 0;\n _meshSsboScratchFloats[slot + 26] = normal[8] ?? 0;\n const previousWorld = entry.source.temporal?.previousTransform.world ?? worldFromLocal;\n for (let k = 0; k < 16; k++) {\n _meshSsboScratchFloats[slot + 28 + k] = previousWorld[k] ?? 0;\n }\n let reactiveMaterial = false;\n for (const material of entry.source.materials) {\n const shader = material.materialShaderId;\n if (\n material.transparent === true ||\n shader === 'forgeax::sprite' ||\n shader === 'forgeax::sprite-lit' ||\n (shader !== undefined && !shader.startsWith('forgeax::'))\n ) {\n reactiveMaterial = true;\n break;\n }\n }\n _meshSsboScratchFloats[slot + 44] =\n entry.source.temporal?.reactive === true || reactiveMaterial ? 1 : 0;\n }\n }\n if (neededBytes > 0) {\n const meshUpload = queue.writeBuffer(\n meshStorageBuffer.buffer,\n 0,\n _meshSsboScratch,\n 0,\n neededBytes,\n );\n if (!meshUpload.ok) throw meshUpload.error;\n }\n}\n\n/**\n * Per-bucket descriptor produced by {@link foldDispatchBuckets}.\n *\n * One bucket = one fold-eligible run of consecutive DispatchEntry whose\n * `(layer, sortKey, materialHandle)` triple is equal. Singleton buckets\n * (bucketSize=1) appear when the mode bypasses fold (D-5 mode 2/3) or\n * when consecutive entries differ in one of the three keys.\n *\n * Fields:\n * - `entries` — original DispatchEntry slice for this bucket (preserves\n * the input ordering); the consumer uses these to look up per-entity\n * material BG handles, mesh handles (which are bucket-uniform by\n * construction since materialHandle key is included), etc.\n * - `bucketSize` — `entries.length`. Surfaced as a top-level field so\n * the consumer can pass it directly as `instanceCount` to\n * `drawIndexed`.\n * - `transforms` — assembled Float32Array of bucketSize world mat4s,\n * stride=16 floats per instance, column-major. Suitable for direct\n * `device.queue.writeBuffer` into an instance buffer used at @group(3).\n * - `materialHandle` / `layer` / `sortKey` — the three-tuple key for this\n * bucket. `sortKey` is mode-dependent: posZ (world[14]) for mode 0\n * (LAYER_Z), posY (world[13]) for mode 1 (LAYER_Y). Consumed by the\n * dispatch loop for bind-group selection / sort-stability invariants.\n */\nexport interface FoldBucket {\n readonly entries: readonly DispatchEntry[];\n readonly bucketSize: number;\n readonly transforms: Float32Array;\n readonly materialHandle: number;\n readonly layer: number;\n readonly sortKey: number;\n}\n\n/**\n * Minimal renderable shape consumed by the helper. The real\n * `RenderableSnapshot` carries many more fields; the helper only reads\n * `transform.world` (a Float32Array of 16 column-major floats) and\n * `material.transparent` (the LDR-split-sub-pass fold gate, see PR #502\n * fix + feat-20260625 R2 fix-up: geometry-pass entities — non-transparent\n * materials — MUST stay singleton because the sprite-pass dispatch path\n * that consumes `headBuckets` does not run for them; folding them would\n * overwrite their mesh-SSBO slot with identity and collapse 3D geometry\n * to origin).\n *\n * Production callers pass `RenderableSnapshot[]` straight through —\n * `RenderableSnapshot.material.transparent` is `boolean | undefined`\n * (derived by the extract stage from `passes[0].renderState.blend !==\n * undefined`, the post-feat-20260626-collapse SSOT; see\n * `MaterialSnapshot.transparent`), structurally compatible with this\n * minimal shape. The gate read inside the helper uses `=== true` /\n * `!== true` so both `false` and `undefined` enter the singleton branch.\n *\n * feat-20260625-refactor-sprite-as-transparent-mesh R2 fix-up: gate\n * migrated from `shadingModel === 'sprite'` (the union member was\n * removed in M3 / w15) to `transparent === true` (the new SSOT for\n * \"routes through the LDR split sub-pass\" — same predicate the\n * `splitLdrSprite` filter at render-system-record.ts:4826/5612 uses).\n */\nexport interface FoldRenderableLike {\n readonly transform: { readonly world: Float32Array };\n readonly material: { readonly transparent?: boolean | undefined };\n}\n\n/**\n * Linear-scan fold operator (plan-strategy D-1).\n *\n * Walks `orderedEntries` (must be transparent-sort-ordered when mode=0;\n * the helper trusts the input ordering and only checks adjacent equality\n * — non-consecutive entries with equal keys are NOT merged, preserving\n * stable-sort semantics).\n *\n * @param orderedEntries — DispatchEntry[] in transparent-sort order. Empty\n * array yields zero buckets (defensive empty-bucket suppression).\n * @param mode — current `TransparentSortConfig.mode`. Modes 0 (LAYER_Z)\n * and 1 (LAYER_Y) enable fold using the appropriate sort-axis coordinate\n * (posZ / posY respectively). Modes 2 and 3 produce singleton buckets\n * per entry (D-5 bypass).\n * @param renderables — parallel snapshot array indexed by\n * `DispatchEntry.renderableIndex`. The helper reads `transform.world`\n * to (a) extract the sort-axis coordinate for the bucket key (posZ\n * world[14] for mode 0, posY world[13] for mode 1), and (b) copy 16\n * floats per entry into the assembled transforms buffer. Out-of-range /\n * missing renderables defensively contribute a zero mat4 slot.\n * @returns Array of FoldBucket descriptors in input order.\n */\nexport function foldDispatchBuckets(\n orderedEntries: readonly DispatchEntry[],\n mode: TransparentSortConfig['mode'],\n renderables: readonly FoldRenderableLike[],\n): readonly FoldBucket[] {\n if (orderedEntries.length === 0) return [];\n\n // Bypass branch (D-5): modes 2 (LAYER_YZ) and 3 (DISTANCE) cannot fold\n // — their sort keys are composite foot-Y formulas or per-entity camera\n // distances, not reducible to a single world-mat4 coordinate read.\n // Each entry produces its own singleton bucket; the dispatch consumer\n // treats bucketSize=1 identically to per-entity drawIndexed (charter P3\n // silent fallback — no error fired).\n //\n // Mode 1 (LAYER_Y) falls through to the fold branch below and uses posY\n // (world[13]) as the sort-axis bucket key.\n if (mode !== TRANSPARENT_SORT_MODE_LAYER_Z && mode !== TRANSPARENT_SORT_MODE_LAYER_Y) {\n const out: FoldBucket[] = [];\n for (let i = 0; i < orderedEntries.length; i++) {\n const e = orderedEntries[i];\n if (e === undefined) continue;\n out.push(makeSingletonBucket(e, renderables, mode));\n }\n return out;\n }\n\n // Fold branch (mode 0 = LAYER_Z, mode 1 = LAYER_Y): linear scan, collect\n // runs with equal (layer, sortKey, materialHandle). sortKey is posZ for\n // mode 0, posY for mode 1 — see readSortKey().\n //\n // Transparent-pass-only gate (PR #502 fix + feat-20260625 R2 fix-up):\n // the only dispatch site that consumes `headBuckets` to emit one\n // instanced drawIndexed per bucket is the transparent-pass loop in\n // `render-system-record.ts` (~line 5500; routed via `splitLdrSprite`\n // filter on `material.transparent === true`). The geometry-pass loop\n // (~line 4660) iterates `validatedOrdered` and emits per-entity\n // drawIndexed unchanged; it does NOT branch on `headBuckets`. So when\n // a non-transparent entry (geometry-pass: unlit / standard-PBR / skin)\n // is folded into a multi-entry bucket, the mesh-SSBO upload loop\n // (~line 2710) still overwrites its mesh slot with identity (because\n // `headBuckets.has(i)` is true), but the geometry-pass then reads\n // identity and renders the 3D geometry at the origin — collapsing the\n // frame to black (hello-room CI regression).\n //\n // Concept-count fix: encode \"fold is transparent-sub-pass-only\" at the\n // head selection point — the gate is the single bucket-key invariant\n // that makes both dispatch sites correct without coupling identity-\n // overwrite logic to a separate check (avoiding the D-9 shared-exit\n // violation that selecting fix-location B would produce).\n //\n // Non-transparent entries (`transparent !== true`) always produce\n // singleton buckets (bucketSize=1), which `buildFoldDispatchPlan`\n // filters out (`if (bucket.bucketSize <= 1) continue`), so they never\n // enter `headBuckets` / `skipIndices` — the mesh-SSBO upload,\n // transparent-pass, and geometry-pass loops all see them as byte-\n // identical to the pre-fold per-entity path.\n //\n // feat-20260625 R2 fix-up: pre-feat the gate was `shadingModel ===\n // 'sprite'`; M3 / w15 narrowed the shadingModel union to\n // `'unlit' | undefined` (the `'sprite'` discriminator was the design\n // ablation target), so the gate now reads `material.transparent` —\n // the new SSOT for \"routes through the LDR split sub-pass\" mirrored\n // on `computeSplitLdrSprite` + the `splitLdrSprite` skip filter.\n const buckets: FoldBucket[] = [];\n let runStart = 0;\n while (runStart < orderedEntries.length) {\n const head = orderedEntries[runStart];\n if (head === undefined) {\n runStart += 1;\n continue;\n }\n // Transparent-pass-only gate (feat-20260625 R2 fix-up): non-transparent\n // heads emit a singleton bucket and advance the cursor by 1 — no run\n // extension. `RenderableSnapshot.material.transparent` is the SSOT\n // carrier (extract stage derives it from the first pass's\n // `renderState.blend !== undefined`, post-feat-20260626-collapse;\n // see `MaterialSnapshot.transparent`).\n const headTransparent = renderables[head.renderableIndex]?.material.transparent;\n if (headTransparent !== true) {\n buckets.push(makeSingletonBucket(head, renderables, mode));\n runStart += 1;\n continue;\n }\n const headSortKey = readSortKey(mode, head.renderableIndex, renderables);\n let runEnd = runStart + 1;\n while (runEnd < orderedEntries.length) {\n const cand = orderedEntries[runEnd];\n if (cand === undefined) break;\n if (cand.layer !== head.layer) break;\n if (cand.materialHandle !== head.materialHandle) break;\n // Defensive: cand transparent must also be true to join the run.\n // Same materialHandle implies same transparent flag in production\n // (material asset identity), but the check costs O(1) per cand and\n // makes the bucket invariant locally readable.\n const candTransparent = renderables[cand.renderableIndex]?.material.transparent;\n if (candTransparent !== true) break;\n const candSortKey = readSortKey(mode, cand.renderableIndex, renderables);\n if (candSortKey !== headSortKey) break;\n runEnd += 1;\n }\n\n const run = orderedEntries.slice(runStart, runEnd);\n const transforms = assembleTransforms(run, renderables);\n buckets.push({\n entries: run,\n bucketSize: run.length,\n transforms,\n materialHandle: head.materialHandle,\n layer: head.layer,\n sortKey: headSortKey,\n });\n runStart = runEnd;\n }\n return buckets;\n}\n\nfunction makeSingletonBucket(\n entry: DispatchEntry,\n renderables: readonly FoldRenderableLike[],\n mode: TransparentSortConfig['mode'],\n): FoldBucket {\n const transforms = new Float32Array(16);\n const w = renderables[entry.renderableIndex]?.transform.world;\n if (w !== undefined) transforms.set(w);\n const sortKey = readSortKey(mode, entry.renderableIndex, renderables);\n return {\n entries: [entry],\n bucketSize: 1,\n transforms,\n materialHandle: entry.materialHandle,\n layer: entry.layer,\n sortKey,\n };\n}\n\nfunction assembleTransforms(\n run: readonly DispatchEntry[],\n renderables: readonly FoldRenderableLike[],\n): Float32Array {\n const out = new Float32Array(run.length * 16);\n for (let i = 0; i < run.length; i++) {\n const e = run[i];\n if (e === undefined) continue;\n const w = renderables[e.renderableIndex]?.transform.world;\n if (w !== undefined) out.set(w, i * 16);\n }\n return out;\n}\n\nfunction readSortKey(\n mode: TransparentSortConfig['mode'],\n renderableIndex: number,\n renderables: readonly FoldRenderableLike[],\n): number {\n const w = renderables[renderableIndex]?.transform.world;\n if (w === undefined) return 0;\n // mode 0 (LAYER_Z): sort-axis is Z, column 3 row 2 = world[14].\n // mode 1 (LAYER_Y): sort-axis is Y, column 3 row 1 = world[13].\n return ((mode === TRANSPARENT_SORT_MODE_LAYER_Z ? w[14] : w[13]) ?? 0) as number;\n}\n\n/**\n * Per-validatedOrdered-index fold metadata consumed by the record-stage\n * dispatch loops. Built from {@link foldDispatchBuckets} output by\n * {@link buildFoldDispatchPlan}; see plan-strategy §3.2 sequence diagram.\n *\n * Field semantics (consumer contract, w4-record-swap):\n * - `headBuckets[i]` is non-null when validatedOrdered index `i` is the\n * **bucket head** of a non-singleton (bucketSize > 1) fold bucket. The\n * dispatch loop overrides @group(3) instances BG to a transient buffer\n * holding `bucket.transforms` and emits `drawIndexed(idxCount,\n * bucket.bucketSize)` instead of per-entity drawIndexed.\n * - `skipIndices.has(i)` is true when index `i` is a non-head member of\n * a non-singleton fold bucket; the dispatch loop emits `continue`.\n * - Singleton buckets (bucketSize === 1) leave both arrays empty for\n * that index — dispatch falls through to the existing per-entity path\n * byte-identically (mode-bypass / non-foldable head / fold-disabled).\n *\n * Note: the maps are keyed on `validatedOrderedIndex`, NOT\n * `renderableIndex`. The dispatch loops iterate `validatedOrdered` by\n * positional index `i`, and that index drives mesh SSBO slot offset\n * (`i * MESH_PER_ENTITY_STRIDE`), material UBO slot, and per-entity bind\n * group cache keys, all of which the swap must coordinate with.\n */\nexport interface FoldDispatchPlan {\n readonly headBuckets: ReadonlyMap<number, FoldBucket>;\n readonly skipIndices: ReadonlySet<number>;\n readonly foldedBucketCount: number;\n}\n\n/**\n * Build the per-validatedOrdered-index fold metadata from a\n * {@link foldDispatchBuckets} output.\n *\n * @param buckets — output of {@link foldDispatchBuckets}; ordered by\n * transparent-sort scan order.\n * @param renderableIndexToValidatedIndex — map from `DispatchEntry.renderableIndex`\n * to the validated-ordered index `i` (the loop counter the dispatch\n * loops use). Caller builds this once per frame from `validatedOrdered`.\n * @returns FoldDispatchPlan keyed by validated-ordered index.\n *\n * Empty / all-singleton input yields empty maps + `foldedBucketCount=0`,\n * which the dispatch loops treat as \"no fold this frame\" — byte-identical\n * to pre-feat behavior.\n */\nexport function buildFoldDispatchPlan(\n buckets: readonly FoldBucket[],\n renderableIndexToValidatedIndex: ReadonlyMap<number, number>,\n): FoldDispatchPlan {\n const headBuckets = new Map<number, FoldBucket>();\n const skipIndices = new Set<number>();\n let foldedBucketCount = 0;\n for (const bucket of buckets) {\n if (bucket.bucketSize <= 1) continue;\n const headEntry = bucket.entries[0];\n if (headEntry === undefined) continue;\n const headValidatedIdx = renderableIndexToValidatedIndex.get(headEntry.renderableIndex);\n if (headValidatedIdx === undefined) continue;\n headBuckets.set(headValidatedIdx, bucket);\n foldedBucketCount += 1;\n for (let i = 1; i < bucket.entries.length; i++) {\n const memberEntry = bucket.entries[i];\n if (memberEntry === undefined) continue;\n const memberValidatedIdx = renderableIndexToValidatedIndex.get(memberEntry.renderableIndex);\n if (memberValidatedIdx === undefined) continue;\n skipIndices.add(memberValidatedIdx);\n }\n }\n return { headBuckets, skipIndices, foldedBucketCount };\n}\n\n/**\n * WebGL2 uniform-fallback per-bucket instance-count ceiling\n * (feat-20260622-chunk-gpu-instancing-sprite-tilemap M2 / D-2 +\n * research N-1).\n *\n * 128 instances * 64 B/mat4 stride = 8192 B, comfortably below the WebGL2\n * minimum 16384 B UBO size, leaving headroom for the per-frame material\n * UBO slice. Locked at the type level via `RhiInstancingExceedsUniformCapDetail.limit`\n * (literal 128) — a future cap change would be a major evolution, not a\n * runtime knob.\n */\nexport const FOLD_UNIFORM_INSTANCE_CAP = 128;\n\n/**\n * Minimal `RhiCapabilities` shape consumed by the cap-fallback helper.\n *\n * The real `RhiDevice.caps` carries many feature flags; the helper only\n * reads `storageBuffer` (the WebGL2 / WebGPU split signal — true on\n * WebGPU + dawn / wgpu native paths, false on the WebGL2 uniform-only\n * fallback path). Mirrors the field name on the production `RhiCaps`\n * type so the dispatch site can pass `runtime.device.caps` straight in.\n */\nexport interface FoldCapsLike {\n readonly storageBuffer: boolean;\n}\n\n/**\n * Decision POD returned by {@link evaluateFoldBucketUniformCap}.\n *\n * Fields:\n * - `fallback` — `true` when the bucket must NOT fold and the dispatch\n * site must route it through the per-entity drawIndexed exit (the\n * same exit the mode-gate bypass uses, plan-strategy D-9 \"shared\n * fallback exit\"). `false` when the bucket can fold normally.\n * - `error` — the structured RhiError to fire alongside the fallback.\n * Always populated when `fallback === true`; always `undefined` when\n * `fallback === false` (charter proposition 4: explicit failure on\n * the failure path; silent success on the success path).\n *\n * Caller contract: when `fallback === true`, fire the error via the\n * runtime error registry AND draw the bucket's entries individually\n * (each as a 1-instance drawIndexed). Skipping the fallback while still\n * firing the error would leave the frame visually wrong (uniform buffer\n * write would clip at 128 entries).\n */\nexport interface FoldBucketCapDecision {\n readonly fallback: boolean;\n readonly error: RhiError | undefined;\n}\n\n/**\n * Decide whether a fold bucket fits the WebGL2 uniform-fallback per-bucket\n * instance-count ceiling, returning the structured RhiError + fallback\n * intent the dispatch site needs to act on\n * (feat-20260622-chunk-gpu-instancing-sprite-tilemap M2 / w11 +\n * plan-strategy D-2 + D-9 + AC-05).\n *\n * Decision matrix:\n *\n * | caps.storageBuffer | bucketSize | fallback | error |\n * |:--|:--|:--|:--|\n * | `true` | every | `false` | `undefined` (WebGPU has no per-binding instance cap inside the storage buffer's `maxStorageBufferBindingSize`; the byte-cap path emits `'limit-exceeded'` separately) |\n * | `false` | `<= 128` | `false` | `undefined` (fits inside the WebGL2 minimum 16384 B UBO with headroom) |\n * | `false` | `> 128` | `true` | `RhiError({ code: 'instancing-exceeds-uniform-cap', detail: { requested, limit: 128, scope } })` |\n *\n * Singleton buckets (`bucketSize === 1`) always pass — they are the\n * mode-gate bypass output and never need the cap check (the cap is\n * about *folded* bucket arity, not about per-entity per-frame work).\n *\n * @param bucket — the FoldBucket whose `bucketSize` is the sole input\n * (instance count = bucketSize); other fields are not consulted.\n * @param caps — the runtime's RHI capability flags\n * (`runtime.device.caps`); only `storageBuffer` is read.\n * @param scope — closed `'sprite' | 'tilemap-chunk'` discriminator the\n * dispatch site picks based on the call site (sprite-pass primary\n * sprite entry vs tilemap-chunk-derived entry). Surfaced verbatim on\n * the error's `.detail.scope` so AI users can branch their recovery\n * on which dispatch site overflowed.\n * @returns a {@link FoldBucketCapDecision} POD; never throws.\n */\nexport function evaluateFoldBucketUniformCap(\n bucket: FoldBucket,\n caps: FoldCapsLike,\n scope: 'sprite' | 'tilemap-chunk',\n): FoldBucketCapDecision {\n if (caps.storageBuffer) return { fallback: false, error: undefined };\n if (bucket.bucketSize <= FOLD_UNIFORM_INSTANCE_CAP) {\n return { fallback: false, error: undefined };\n }\n const error = new RhiError({\n code: 'instancing-exceeds-uniform-cap',\n expected: `bucket instance count <= ${FOLD_UNIFORM_INSTANCE_CAP} (uniform fallback cap)`,\n hint: `reduce the bucket size (smaller layer/material groupings), switch to a WebGPU-capable backend (storage buffers lift the cap), or accept the per-cell drawIndexed fallback for ${scope}`,\n detail: {\n requested: bucket.bucketSize,\n limit: FOLD_UNIFORM_INSTANCE_CAP,\n scope,\n },\n });\n return { fallback: true, error };\n}\n\n/**\n * Closed metric key for the AC-06 fold counter\n * (feat-20260622-chunk-gpu-instancing-sprite-tilemap M3 / D-3).\n *\n * Semantics — count of instanced `drawIndexed` calls the fold operator\n * emits this frame; one increment per non-singleton head bucket retained\n * after the M2 / w11 cap-fallback filter. NOT entity count, NOT pre-\n * filter bucket count — cap-overrun buckets that the dispatch site\n * routed through the per-entity fallback exit do not count.\n *\n * Naming follows the EngineMetrics dot-namespace convention\n * (`<feature>.<event>`); `render.instancing.*` covers both sprite and\n * tilemap-chunk dispatch sites without scope ambiguity (research F-5,\n * plan-strategy §8.2). The owning host evidence reads\n * `ownerMetrics.snapshot()['render.instancing.foldedDraws']`.\n */\nexport const FOLDED_DRAWS_METRIC_KEY = 'render.instancing.foldedDraws';\n\n/**\n * Minimal `EngineMetrics` shape consumed by {@link incrementFoldedDrawsMetric}.\n *\n * The real `EngineMetrics` carries `snapshot()` + `reset()` too; the\n * helper only writes, so the consumed surface narrows to a single\n * method. Lets the unit test inject a `vi.fn()` mock without faking the\n * read APIs.\n */\nexport interface FoldMetricsLike {\n increment(name: string): void;\n}\n\n/**\n * Bump the AC-06 `render.instancing.foldedDraws` counter once per fold-\n * eligible head bucket in `plan` (M3 / w13, plan-strategy D-3).\n *\n * Single counter-write site for the metric — the record-stage consumer\n * calls this once per `recordFrame` after the cap-fallback filter\n * (M2 / w11) so cap-overrun buckets do not contribute (their members\n * fall through to per-entity drawIndexed, which is not an instanced\n * draw). `plan.foldedBucketCount` is the SSOT for \"how many instanced\n * drawIndexed will this frame emit\"; passing the same plan to this\n * helper keeps the metric and the actual dispatch in lockstep.\n *\n * Mode-bypass plans (D-5: mode != 0 yields singleton-only buckets which\n * `buildFoldDispatchPlan` filters out) carry `foldedBucketCount === 0`\n * and produce no increments — per-entity drawIndexed is not folded so\n * the metric correctly stays at 0.\n *\n * @param plan — output of {@link buildFoldDispatchPlan} after possible\n * cap-fallback filtering by the record-stage consumer.\n * @param metrics — the owner-provided EngineMetrics counter; only\n * `increment(name)` is called. Empty `plan.foldedBucketCount === 0`\n * produces zero calls (no metric churn for fold-disabled frames).\n */\nexport function incrementFoldedDrawsMetric(plan: FoldDispatchPlan, metrics: FoldMetricsLike): void {\n for (let i = 0; i < plan.foldedBucketCount; i++) {\n metrics.increment(FOLDED_DRAWS_METRIC_KEY);\n }\n}\n","// @forgeax/engine-runtime — SSAO per-runtime persistent GPU buffers.\n//\n// feat-20260612-hdrp-ssao M1 / w4.\n//\n// Owner of 3 SSAO GPU resources, lazily allocated per RenderSystemRuntime,\n// following the getOrCreateHdrpBuffers WeakMap pattern (research F12):\n// (1) kernel UBO — 64 padded vec4 samples (1024 B), label hdrp-ssao-kernel\n// (2) noise texture — 4x4 rgba32float, label hdrp-ssao-noise, NEAREST/REPEAT\n// (3) uniform UBO — 3 mat4 + vec4 intensityPad (256 B aligned),\n// label hdrp-ssao-uniform\n//\n// plan-strategy D-1: uniform carries view + projection + inverseProjection.\n// plan-strategy D-C: intensity, radius, and bias are carried at offset 192\n// (the existing vec4 slot), so the lighting shader can mix(1.0, ssao*ao,\n// intensity) without a new UBO.\n// The kernel uses a uniform buffer on every backend. 1024 B is below the\n// WebGL2 minimum fragment UBO size, so SSAO does not need a storage-buffer\n// capability gate.\n\nimport type { Buffer, Sampler, Texture, TextureView } from '@forgeax/engine-rhi';\nimport { GPU_TEXTURE_USAGE_COPY_DST, GPU_TEXTURE_USAGE_TEXTURE_BINDING } from './gpu-texture-usage';\nimport { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from './gpu-usage';\nimport type { RenderSystemRuntime } from './record/render-context';\n\n// Deterministic host-side SSAO data is owned by the buffer allocator because\n// these values have no consumer outside the resources they initialize.\nexport const SSAO_KERNEL_SAMPLE_COUNT = 64;\nconst NOISE_SIZE = 16;\n\nfunction mulberry32(seed: number): () => number {\n let state = seed | 0;\n return () => {\n state = (state + 0x6d2b79f5) | 0;\n let t = Math.imul(state ^ (state >>> 15), 1 | state);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\nfunction lerp(a: number, b: number, t: number): number {\n return a + t * (b - a);\n}\n\nexport function generateSsaoKernel(seed: number = 0): readonly Float32Array[] {\n const rand = mulberry32(seed);\n const kernel: Float32Array[] = [];\n for (let i = 0; i < SSAO_KERNEL_SAMPLE_COUNT; i++) {\n let x = rand() * 2 - 1;\n let y = rand() * 2 - 1;\n let z = rand();\n const len = Math.sqrt(x * x + y * y + z * z);\n x /= len;\n y /= len;\n z /= len;\n const r = rand();\n x *= r;\n y *= r;\n z *= r;\n const scale = lerp(0.1, 1.0, (i / SSAO_KERNEL_SAMPLE_COUNT) ** 2);\n const sample = new Float32Array(3);\n sample[0] = x * scale;\n sample[1] = y * scale;\n sample[2] = z * scale;\n kernel.push(sample);\n }\n return kernel;\n}\n\nexport function generateSsaoNoise(seed: number = 0): Float32Array {\n const rand = mulberry32(seed);\n const noise = new Float32Array(NOISE_SIZE * 3);\n for (let i = 0; i < NOISE_SIZE; i++) {\n noise[i * 3 + 0] = rand() * 2 - 1;\n noise[i * 3 + 1] = rand() * 2 - 1;\n noise[i * 3 + 2] = 0;\n }\n return noise;\n}\n\n// Each vec3<f32> in a WGSL array is 16B (12B payload + 4B padding).\n// 64 samples * 16 B/sample = 1024 B.\nconst BYTES_PER_KERNEL_ELEMENT = 16;\n\n// SSAO uniform layout (plan-strategy §D-1 + §D-C, M7 round-2):\n// bytes [0..63] view mat4x4<f32>\n// bytes [64..127] projection mat4x4<f32>\n// bytes [128..191] inverseProjection mat4x4<f32>\n// bytes [192..207] intensityPad vec4<f32> // x = intensity, y = radius, z = bias, w = pad\n// bytes [208..255] padding // align to 256B WebGPU UBO offset\n//\n// The total is rounded to 256B so the same UBO can host an additional\n// shader-side scalar binding at the tail without re-allocation.\nconst UNIFORM_INTENSITY_OFFSET_BYTES = 192;\nconst UNIFORM_BYTES = 256;\nexport const SSAO_UNIFORM_INTENSITY_OFFSET = UNIFORM_INTENSITY_OFFSET_BYTES;\nexport const SSAO_UNIFORM_BYTES = UNIFORM_BYTES;\n\n// ── 1x1 white fallback texture (plan-strategy §D-B) ───────────────────────\n//\n// Single-PSO invariant: the HDRP unified BGL always declares a binding 7\n// texture_2d<f32>. When SSAO is disabled (or its resources are not yet\n// allocated), the bind group binds this 1x1 r8unorm texture filled with\n// 0xFF. r8unorm normalizes 255 -> 1.0, so the lighting shader reads\n// `ssaoFactor = 1.0`, and `mix(1.0, ssao*ao, intensity) = ao` collapses\n// back to the round-1 baseline (ambient = baked-AO only). No shader\n// recompile across enable/disable.\n\ninterface SsaoFallbackResources {\n readonly device: RenderSystemRuntime['device'];\n readonly texture: Texture;\n readonly view: TextureView;\n readonly sampler: Sampler;\n}\n\nconst fallbackCache = new WeakMap<RenderSystemRuntime, SsaoFallbackResources>();\n\n/**\n * Lazily allocate the 1x1 r8unorm white fallback texture + a sampler for\n * SSAO disabled / resource-missing path. Cached per RenderSystemRuntime so\n * subsequent calls reuse the same resources (charter P5 one-owner).\n *\n * Returns `null` if `device.createTexture` / `createTextureView` /\n * `createSampler` / `queue.writeTexture` fails; the caller (createBindGroup)\n * propagates the structured RhiError that landed on `runtime.errorRegistry`.\n */\nexport function getOrCreateSsaoFallbackTexture(\n runtime: RenderSystemRuntime,\n): SsaoFallbackResources | null {\n const cached = fallbackCache.get(runtime);\n if (cached !== undefined && cached.device === runtime.device) return cached;\n if (cached !== undefined) fallbackCache.delete(runtime);\n\n const device = runtime.device;\n const texRes = device.createTexture({\n label: 'hdrp-ssao-fallback-white',\n size: { width: 1, height: 1, depthOrArrayLayers: 1 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: 'r8unorm',\n usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST,\n textureBindingViewDimension: undefined,\n });\n if (!texRes.ok) {\n runtime.errorRegistry.fire(texRes.error);\n return null;\n }\n\n // r8unorm: a single byte 0xFF normalizes to 1.0 (white => AO = 1.0).\n const whitePixel = new Uint8Array([255]);\n const writeRes = device.queue.writeTexture(\n {\n texture: texRes.value,\n mipLevel: 0,\n origin: { x: 0, y: 0, z: 0 },\n },\n whitePixel,\n { offset: 0, bytesPerRow: 256, rowsPerImage: 1 },\n { width: 1, height: 1, depthOrArrayLayers: 1 },\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n return null;\n }\n\n const viewRes = device.createTextureView(texRes.value, {\n label: 'hdrp-ssao-fallback-white-view',\n format: 'r8unorm',\n dimension: '2d',\n aspect: 'all',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!viewRes.ok) {\n runtime.errorRegistry.fire(viewRes.error);\n return null;\n }\n\n const samplerRes = device.createSampler({\n label: 'hdrp-ssao-fallback-sampler',\n magFilter: 'linear',\n minFilter: 'linear',\n mipmapFilter: 'linear',\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n addressModeW: 'clamp-to-edge',\n });\n if (!samplerRes.ok) {\n runtime.errorRegistry.fire(samplerRes.error);\n return null;\n }\n\n const resources: SsaoFallbackResources = {\n device,\n texture: texRes.value,\n view: viewRes.value,\n sampler: samplerRes.value,\n };\n fallbackCache.set(runtime, resources);\n return resources;\n}\n\n/**\n * SSAO GPU resources owned by this module (plan-strategy D-1, D-4).\n *\n * Fields are readonly per charter P5: one resource, one owner.\n */\nexport interface SsaoBuffers {\n /** Device identity that owns every handle in this bundle. */\n readonly device: RenderSystemRuntime['device'];\n /** 64 padded vec4 uniform buffer for hemisphere samples. */\n readonly kernelBuffer: Buffer;\n readonly kernelBytes: number;\n /** 4x4 rgba32float noise texture for per-pixel TBN rotation. */\n readonly noiseTexture: Texture;\n /** SSAO uniform UBO: view (mat4) + projection (mat4) + inverseProjection (mat4). */\n readonly uniformBuffer: Buffer;\n readonly uniformBytes: number;\n}\n\nconst cache = new WeakMap<RenderSystemRuntime, SsaoBuffers>();\n\n/**\n * Lazily allocate the 3 SSAO GPU resources for `runtime`. Returns the\n * same `SsaoBuffers` object on subsequent calls (per-RenderSystem\n * stable identity, WeakMap).\n *\n * On `device.createBuffer` / `device.createTexture` failure, fires a\n * structured error on the runtime's error registry and returns `null`.\n *\n * @returns SsaoBuffers on success, null if an allocation fails.\n */\nexport function getOrCreateSsaoBuffers(runtime: RenderSystemRuntime): SsaoBuffers | null {\n const cached = cache.get(runtime);\n if (cached !== undefined && cached.device === runtime.device) return cached;\n if (cached !== undefined) cache.delete(runtime);\n\n const device = runtime.device;\n\n // (1) Kernel UBO — 64 padded vec4 samples (1024 B).\n const kernelSamples = generateSsaoKernel();\n const kernelData = new Float32Array(SSAO_KERNEL_SAMPLE_COUNT * 4); // 4 floats per padded vec3\n for (let i = 0; i < SSAO_KERNEL_SAMPLE_COUNT; i++) {\n const s = kernelSamples[i];\n if (s === undefined) continue;\n kernelData[i * 4 + 0] = s[0] ?? 0;\n kernelData[i * 4 + 1] = s[1] ?? 0;\n kernelData[i * 4 + 2] = s[2] ?? 0;\n // kernelData[i * 4 + 3] = 0 (padding for std140 vec3 alignment)\n }\n\n const kernelBufferRes = device.createBuffer({\n label: 'hdrp-ssao-kernel',\n size: SSAO_KERNEL_SAMPLE_COUNT * BYTES_PER_KERNEL_ELEMENT,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!kernelBufferRes.ok) {\n runtime.errorRegistry.fire(kernelBufferRes.error);\n return null;\n }\n\n // Upload kernel data to the buffer.\n const kernelWriteRes = device.queue.writeBuffer(kernelBufferRes.value, 0, kernelData);\n if (!kernelWriteRes.ok) {\n runtime.errorRegistry.fire(kernelWriteRes.error);\n return null;\n }\n\n // (2) Noise texture — 4x4 rgba32float, NEAREST/REPEAT.\n const noiseData = generateSsaoNoise();\n // Pad to rgba32float: 16 texels * 4 floats = 64 floats.\n const noiseRgba = new Float32Array(16 * 4);\n for (let i = 0; i < 16; i++) {\n noiseRgba[i * 4 + 0] = noiseData[i * 3 + 0] ?? 0;\n noiseRgba[i * 4 + 1] = noiseData[i * 3 + 1] ?? 0;\n noiseRgba[i * 4 + 2] = 0;\n noiseRgba[i * 4 + 3] = 1; // alpha = 1 for rgba32float\n }\n\n const noiseTexRes = device.createTexture({\n label: 'hdrp-ssao-noise',\n size: { width: 4, height: 4, depthOrArrayLayers: 1 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: 'rgba32float',\n usage: GPU_TEXTURE_USAGE_COPY_DST | GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n textureBindingViewDimension: undefined,\n });\n if (!noiseTexRes.ok) {\n runtime.errorRegistry.fire(noiseTexRes.error);\n return null;\n }\n\n // Direct CPU-to-GPU upload via writeTexture (no alignment requirement\n // unlike copyBufferToTexture; WebGPU spec §19.2). 4x4 rgba32float texture\n // = 16 texels * 4 floats * 4 bytes/float = 256 bytes.\n // The forgeax Texture brand wraps a raw GPUTexture; cast through unknown\n // follows the createRenderer.ts fallback-pixel pattern (line 4330).\n const noiseCopyRes = device.queue.writeTexture(\n {\n texture: noiseTexRes.value,\n mipLevel: 0,\n origin: { x: 0, y: 0, z: 0 },\n },\n noiseRgba,\n { offset: 0, bytesPerRow: 4 * 4 * 4, rowsPerImage: 4 },\n { width: 4, height: 4, depthOrArrayLayers: 1 },\n );\n if (!noiseCopyRes.ok) {\n runtime.errorRegistry.fire(noiseCopyRes.error);\n return null;\n }\n\n // (3) SSAO uniform UBO — 3 mat4 (192 B).\n const uniformBufRes = device.createBuffer({\n label: 'hdrp-ssao-uniform',\n size: UNIFORM_BYTES,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!uniformBufRes.ok) {\n runtime.errorRegistry.fire(uniformBufRes.error);\n return null;\n }\n\n const buffers: SsaoBuffers = {\n device,\n kernelBuffer: kernelBufferRes.value,\n kernelBytes: SSAO_KERNEL_SAMPLE_COUNT * BYTES_PER_KERNEL_ELEMENT,\n noiseTexture: noiseTexRes.value,\n uniformBuffer: uniformBufRes.value,\n uniformBytes: UNIFORM_BYTES,\n };\n\n cache.set(runtime, buffers);\n return buffers;\n}\n","// @forgeax/engine-runtime - HDRP per-runtime persistent GPU buffers.\n//\n// feat-20260608-cluster-lighting Round-2 fix-up [w18-fix-r2] (F-1 / F-2):\n//\n// The HDRP cluster-forward path needs four persistent GPU buffers (light_data\n// SSBO, cluster_grid SSBO, light_index_list SSBO, cluster_uniform UBO) on BGL\n// slots 3..6 (plan D-1). Round-1 declared them only as graph resources -- no\n// underlying RHI buffers existed, so the graph fail-fast'd on dangling-read\n// every frame and the binner output was discarded.\n//\n// This module owns the lazy, per-runtime allocation of those buffers via a\n// WeakMap keyed on RenderSystemRuntime. The HDRP buildGraph reaches in via\n// `getOrCreateHdrpBuffers(runtime)`; subsequent calls in the same frame return\n// the cached pair so `device.queue.writeBuffer` lands on the same handles as\n// the (eventual) bind-group layout consumer (charter P5: one resource, one\n// owner; AC-13: 4 RHI buffers actually exist on slot 3..6 layout).\n//\n// Storage usage flags come from the render package's dependency-free buffer\n// usage owner; this module stays decoupled from renderer bootstrap.\n//\n// Sizes:\n// - light_data : 256 x 80 B = 20 480 B\n// - cluster_grid : maxGridCells x 8 B = 64 x 64 x 64 x 8 B = 2 097 152 B max\n// (plan D-grid: x,y,z each in [1..64]; maxCells=262144;\n// stride 2 u32 = 8B; we allocate at the install-time\n// grid passed via DEFAULT_CLUSTER_GRID 16x9x24=3456 cells).\n// - light_index_list : 65536 u32 = 262 144 B\n// - cluster_uniform : = 32 B (2 vec4 std140)\n//\n// AC-14: cluster_uniform is allocated once with the install-time grid; runtime\n// grid changes do NOT trigger PSO rebuild because grid lives in the UBO not in\n// shader specialization. (Shader-side draw is M-future; this AC is satisfied\n// by the buffer being a UBO with field-level updates.)\n\nimport {\n type BindGroup,\n type BindGroupLayout,\n type BindGroupLayoutDescriptor,\n type Buffer,\n RhiError,\n type Sampler,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport { GPU_SHADER_STAGE_COMPUTE } from './gpu-stage';\nimport {\n GPU_BUFFER_USAGE_COPY_DST,\n GPU_BUFFER_USAGE_STORAGE,\n GPU_BUFFER_USAGE_UNIFORM,\n} from './gpu-usage';\nimport { BYTES_PER_DIRECT_LIGHT_SLOT } from './light-buffer-layout';\nimport { createPbrSkinMeshBindGroupEntries } from './pbr-pipeline';\nimport {\n CLUSTER_GRID_STRIDE_U32,\n DEFAULT_CLUSTER_GRID,\n LIGHT_INDEX_LIST_CAPACITY,\n MAX_LIGHTS,\n} from './pipeline/standard-profile';\nimport { createHdrpBindGroupLayoutDescriptor } from './pipeline-spec';\nimport { MESH_PER_ENTITY_STRIDE } from './record/mesh-ssbo';\nimport type { RenderSystemRuntime } from './record/render-context';\nimport { getOrCreateSsaoFallbackTexture } from './ssao-buffers';\n\nexport { getOrCreateSsaoFallbackTexture } from './ssao-buffers';\n\n/** Bind-group layout used only by the WebGPU cluster membership producer. */\nexport function createHdrpClusterMembershipBindGroupLayoutDescriptor(): BindGroupLayoutDescriptor {\n return {\n label: 'hdrp-cluster-membership-bgl',\n entries: [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_COMPUTE,\n buffer: { type: 'read-only-storage', hasDynamicOffset: false },\n },\n {\n binding: 1,\n visibility: GPU_SHADER_STAGE_COMPUTE,\n buffer: { type: 'storage', hasDynamicOffset: false },\n },\n {\n binding: 2,\n visibility: GPU_SHADER_STAGE_COMPUTE,\n buffer: { type: 'uniform', hasDynamicOffset: false },\n },\n {\n binding: 3,\n visibility: GPU_SHADER_STAGE_COMPUTE,\n buffer: { type: 'read-only-storage', hasDynamicOffset: false },\n },\n ],\n };\n}\n\n/**\n * The persistent HDRP GPU buffers (plan D-1, BGL slot 3..6) plus the unified\n * BGL layout for group(2) (plan D-6, feat-20260609-hdrp-cluster-fragment-ggx M3).\n *\n * AC-11: light_data stride = `BYTES_PER_DIRECT_LIGHT_SLOT` = 80 (double-sided\n * lock with WGSL hdrp-cluster-forward.wgsl DirectLightSlot).\n * AC-13: 4 distinct RHI Buffer handles, ready for slot-3..6 BGL binding.\n * AC-14: clusterUniform is a uniform buffer (not storage); runtime grid change\n * is a writeBuffer field update, not a PSO rebuild.\n * AC-06: unifiedBindGroupLayout is the 7-entry group(2) BGL (mesh SSBO +\n * cluster 4 buffer).\n */\nexport interface HdrpBuffers {\n /** Device identity that owns every handle in this bundle. */\n readonly device: RenderSystemRuntime['device'];\n /** light_data -- the full 256 x 80 B DirectLightSlot budget. */\n readonly lightDataBuffer: Buffer;\n readonly lightDataBytes: number;\n /** cluster_grid SSBO -- gridX*gridY*gridZ * 2 u32, BGL slot 4. */\n readonly clusterGridBuffer: Buffer;\n readonly clusterGridBytes: number;\n /** light_index_list SSBO -- 65536 u32 = 256 KiB, BGL slot 5. */\n readonly lightIndexListBuffer: Buffer;\n readonly lightIndexListBytes: number;\n /** cluster_uniform UBO -- 32 B (2 vec4 std140), BGL slot 6. */\n readonly clusterUniformBuffer: Buffer;\n readonly clusterUniformBytes: number;\n /** CPU-produced light AABBs consumed by the optional WebGPU membership pass. */\n readonly lightBoundsBuffer: Buffer;\n readonly lightBoundsBytes: number;\n /** The grid the buffers were sized for; cluster_grid is sized by gridX*gridY*gridZ. */\n readonly grid: { readonly x: number; readonly y: number; readonly z: number };\n /** Unified BGL layout for group(2). */\n readonly unifiedBindGroupLayout: BindGroupLayout;\n}\n\nconst cache = new WeakMap<RenderSystemRuntime, HdrpBuffers>();\n\n/**\n * Lazily allocate the 4 persistent HDRP buffers for `runtime`. Returns the same\n * `HdrpBuffers` object on subsequent calls (per-RenderSystem stable identity).\n *\n * On `device.createBuffer` failure, fires a structured RhiError on the runtime's\n * error registry and returns `null`; HDRP buildGraph treats null as a hard\n * pipeline disable (charter P3 explicit failure).\n *\n * `grid` defaults to `DEFAULT_CLUSTER_GRID` when undefined (matches the M5\n * record-stage default). A smaller grid reuses the existing capacity. When a\n * later install requests a larger grid, this owner allocates a complete new\n * bundle, publishes it atomically, and retires the previous bundle after the\n * device queue fence so graph and bind-group caches never observe a partially\n * replaced resource set.\n */\nexport function getOrCreateHdrpBuffers(\n runtime: RenderSystemRuntime,\n grid: { x: number; y: number; z: number } = DEFAULT_CLUSTER_GRID,\n): HdrpBuffers | null {\n // Cluster has one code-level transport. Capability failure is handled by\n // Standard transport admission; this owner never creates a second UBO ABI.\n if (runtime.device.caps?.storageBuffer !== true) return null;\n // Contract tests and reduced host adapters may advertise storage buffers\n // without implementing the resource-creation surface. Treat that as a\n // capability miss rather than dereferencing an absent method; callers\n // already route `null` through the structured cluster-transport fallback.\n const deviceSurface = runtime.device as unknown as {\n readonly createBuffer?: unknown;\n readonly createBindGroupLayout?: unknown;\n readonly destroyBuffer?: unknown;\n };\n if (\n typeof deviceSurface.createBuffer !== 'function' ||\n typeof deviceSurface.createBindGroupLayout !== 'function' ||\n typeof deviceSurface.destroyBuffer !== 'function'\n ) {\n return null;\n }\n const cached = cache.get(runtime);\n if (cached !== undefined && cached.device === runtime.device) {\n const requestedCells = grid.x * grid.y * grid.z;\n const cachedCells = cached.grid.x * cached.grid.y * cached.grid.z;\n if (requestedCells <= cachedCells) return cached;\n }\n const device = runtime.device;\n const clusterUniformBytes = 32;\n const lightDataBytes = MAX_LIGHTS * BYTES_PER_DIRECT_LIGHT_SLOT;\n const clusterCells = grid.x * grid.y * grid.z;\n const clusterGridBytes = clusterCells * CLUSTER_GRID_STRIDE_U32 * 4;\n const lightIndexListBytes = LIGHT_INDEX_LIST_CAPACITY * 4;\n const lightBoundsBytes = MAX_LIGHTS * 6 * 4;\n const created: Buffer[] = [];\n const releaseCreated = (): void => {\n for (const buffer of created) {\n const result = device.destroyBuffer(buffer);\n if (!result.ok) runtime.errorRegistry.fire(result.error);\n }\n created.length = 0;\n };\n const failAllocation = (error: RhiError): null => {\n runtime.errorRegistry.fire(error);\n releaseCreated();\n return null;\n };\n\n const lightData = device.createBuffer({\n label: 'hdrp-light-data',\n size: lightDataBytes,\n usage: GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!lightData.ok) {\n return failAllocation(lightData.error);\n }\n created.push(lightData.value);\n const clusterGrid = device.createBuffer({\n label: 'hdrp-cluster-grid',\n size: clusterGridBytes,\n usage: GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!clusterGrid.ok) {\n return failAllocation(clusterGrid.error);\n }\n created.push(clusterGrid.value);\n const lightIndexList = device.createBuffer({\n label: 'hdrp-light-index-list',\n size: lightIndexListBytes,\n usage: GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!lightIndexList.ok) {\n return failAllocation(lightIndexList.error);\n }\n created.push(lightIndexList.value);\n const clusterUniform = device.createBuffer({\n label: 'hdrp-cluster-uniform',\n size: clusterUniformBytes,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!clusterUniform.ok) {\n return failAllocation(clusterUniform.error);\n }\n created.push(clusterUniform.value);\n const lightBounds = device.createBuffer({\n label: 'hdrp-light-bounds',\n size: lightBoundsBytes,\n usage: GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!lightBounds.ok) {\n return failAllocation(lightBounds.error);\n }\n created.push(lightBounds.value);\n\n // Create the unified 7-entry BGL layout for group(2)\n // (plan D-6, feat-20260609-hdrp-cluster-fragment-ggx M3).\n // The HDRP BGL descriptor is owned by pipeline-spec and shared with the\n // pipeline dispatcher and its byte-identical tests.\n const unifiedBglRes = device.createBindGroupLayout(createHdrpBindGroupLayoutDescriptor());\n if (!unifiedBglRes.ok) {\n return failAllocation(unifiedBglRes.error);\n }\n const buffers: HdrpBuffers = {\n device,\n lightDataBuffer: lightData.value,\n lightDataBytes,\n clusterGridBuffer: clusterGrid.value,\n clusterGridBytes,\n lightIndexListBuffer: lightIndexList.value,\n lightIndexListBytes,\n clusterUniformBuffer: clusterUniform.value,\n clusterUniformBytes,\n lightBoundsBuffer: lightBounds.value,\n lightBoundsBytes,\n grid: { x: grid.x, y: grid.y, z: grid.z },\n unifiedBindGroupLayout: unifiedBglRes.value,\n };\n cache.set(runtime, buffers);\n if (cached !== undefined) {\n retireHdrpBuffers(runtime, cached);\n }\n return buffers;\n}\n\n/**\n * Drop the cached bundle before a device recovery or renderer disposal. The\n * bundle carries the old device identity, so retirement fences that device's\n * queue instead of consulting the replacement runtime device.\n */\nexport function resetHdrpBuffers(runtime: RenderSystemRuntime): void {\n const cached = cache.get(runtime);\n if (cached === undefined) return;\n cache.delete(runtime);\n retireHdrpBuffers(runtime, cached);\n}\n\nfunction retireHdrpBuffers(runtime: RenderSystemRuntime, buffers: HdrpBuffers): void {\n const device = buffers.device;\n const destroy = (): void => {\n for (const buffer of [\n buffers.lightDataBuffer,\n buffers.clusterGridBuffer,\n buffers.lightIndexListBuffer,\n buffers.clusterUniformBuffer,\n buffers.lightBoundsBuffer,\n ]) {\n const result = device.destroyBuffer(buffer);\n if (!result.ok) runtime.errorRegistry.fire(result.error);\n }\n };\n const queue = device.queue as {\n readonly onSubmittedWorkDone?: () => Promise<undefined>;\n };\n if (typeof queue.onSubmittedWorkDone === 'function') {\n queue.onSubmittedWorkDone().then(destroy, destroy);\n } else {\n // Minimal null/test devices may not expose queue fences; they also have no\n // submitted work that can retain the old bundle, so release synchronously.\n destroy();\n }\n}\n\n/**\n * Build the 8-float cluster_uniform std140 payload.\n *\n * [0] gridX u32 (cast in shader)\n * [1] gridY u32\n * [2] gridZ u32\n * [3] lightCount u32 (vec4 alignment; capped by MAX_LIGHTS)\n * [4] near f32\n * [5] far f32\n * [6] logFarOverNear f32\n * [7] ssaoIntensity f32 (scope-amend-webgl2-ubo: folded from removed\n * dedicated @binding(9) UBO; lighting shader\n * reads `cluster_uniform.near_far_log.w`)\n *\n * Matches `__tests__/hdrp-bgl-slots.test.ts CLUSTER_UNIFORM_LAYOUT`.\n *\n * Note: u32 values written into a Float32Array view are bit-pattern correct\n * because writeBuffer copies raw bytes; the WGSL `var<uniform>` declares the\n * field as u32 / f32 per its position so the device reinterprets correctly.\n * Use a Uint32Array view for the integer slots to keep the bit pattern intact.\n */\nexport function packClusterUniform(\n grid: { x: number; y: number; z: number },\n near: number,\n far: number,\n ssaoIntensity: number = 0,\n lightCount: number = 0,\n): ArrayBuffer {\n const buf = new ArrayBuffer(32);\n const u32 = new Uint32Array(buf);\n const f32 = new Float32Array(buf);\n u32[0] = grid.x >>> 0;\n u32[1] = grid.y >>> 0;\n u32[2] = grid.z >>> 0;\n u32[3] = Math.min(Math.max(lightCount, 0), MAX_LIGHTS) >>> 0;\n f32[4] = near;\n f32[5] = far;\n // logFarOverNear: log(far/near) used by the shader for log-z slice mapping.\n // Guard against near=0 / far<=near (returns 0; downstream uses fallback).\n f32[6] = near > 0 && far > near ? Math.log(far / near) : 0;\n // f32[7] = SSAO intensity (default 0 = disabled-equivalent: mix(1.0, x, 0) = 1).\n f32[7] = ssaoIntensity;\n return buf;\n}\n\n/**\n * Consumers pass the same mesh storage buffer + stride that URP uses, so the\n * dynamic offset (`i * MESH_PER_ENTITY_STRIDE`) at `setBindGroup(2, ...)`\n * stays valid across both pipelines.\n */\n/**\n * Build the unified group(2) BindGroup for HDRP — binding 0 = mesh SSBO\n * (dynamic offset, same buffer URP binds), bindings 3..6 = the cluster\n * buffers from `getOrCreateHdrpBuffers`.\n *\n * feat-20260609-hdrp-cluster-fragment-ggx M4 / w19. Called per-frame from the\n * recordFrame HDRP block after binner+writeBuffer; the resulting BindGroup\n * lands on `passCtx.hdrpClusterBindGroup` and recordMainPass binds it at\n * group(2) when the prepared Standard topology selects clustered lighting.\n *\n * Returns `null` on `device.createBindGroup` failure (a structured RhiError\n * is fired on `runtime.errorRegistry`); recordMainPass gracefully falls back\n * to the URP mesh bindGroup when null.\n *\n * Plan D-1 / D-4: the mesh SSBO buffer + stride mirror the URP path, so the\n * single dynamic offset issued at `setBindGroup(2, ...)` covers binding 0 of\n * the unified BGL just as it covers binding 0 of the URP mesh BGL.\n */\n/**\n * SSAO bind-group input (plan-strategy §D-B, M7;\n * scope-amend-webgl2-ubo: dedicated @binding(9) intensity UBO removed).\n *\n * The HDRP unified BGL always declares 7 entries (cluster 5 + ssao 2); the\n * caller supplies one of two shapes depending on `config.ssao?.enabled`:\n *\n * { enabled: true, ssaoBlurredView }\n * -> binding 7 = real ssaoBlurred view\n * -> binding 8 = real ssao sampler (lazy-allocated alongside fallback)\n *\n * { enabled: false }\n * -> binding 7 = 1x1 white fallback texture (AO = 1.0)\n * -> binding 8 = fallback sampler\n *\n * Intensity flows via `cluster_uniform.near_far_log.w` (binding 6); the host\n * writes intensity=0 when SSAO is disabled so the lighting blend\n * `mix(1.0, ssao*ao, 0) = 1.0` collapses to the round-1 baseline. The\n * \"always-7-entries\" invariant lets every PBR PSO use the same pipeline\n * layout regardless of SSAO state — toggling the runtime config never\n * triggers shader recompile (charter P4 one consistent abstraction).\n *\n * `ssaoBuffers` is no longer carried in the enabled variant: the SSAO\n * compute-side UBO continues to live on the SSAO compute pipeline's own\n * group(0) BGL, decoupled from the lighting-stage group(2).\n */\nexport type SsaoBindOptions =\n | {\n readonly enabled: true;\n readonly ssaoBlurredView: TextureView;\n }\n | { readonly enabled: false };\n\nexport function createHdrpUnifiedBindGroup(\n runtime: RenderSystemRuntime,\n hdrpBuffers: HdrpBuffers,\n meshStorageBuffer: Buffer,\n ssaoOptions: SsaoBindOptions = { enabled: false },\n): BindGroup | null {\n const fallback = getOrCreateSsaoFallbackTexture(runtime);\n if (fallback === null) return null;\n\n const ssaoTexView: TextureView = ssaoOptions.enabled\n ? ssaoOptions.ssaoBlurredView\n : fallback.view;\n const ssaoSampler: Sampler = fallback.sampler;\n\n const result = runtime.device.createBindGroup({\n label: 'hdrp-unified-bg-group2',\n layout: hdrpBuffers.unifiedBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: meshStorageBuffer,\n offset: 0,\n size: MESH_PER_ENTITY_STRIDE,\n },\n },\n },\n {\n binding: 3,\n resource: {\n kind: 'buffer',\n value: { buffer: hdrpBuffers.lightDataBuffer },\n },\n },\n {\n binding: 4,\n resource: {\n kind: 'buffer',\n value: { buffer: hdrpBuffers.clusterGridBuffer },\n },\n },\n {\n binding: 5,\n resource: {\n kind: 'buffer',\n value: { buffer: hdrpBuffers.lightIndexListBuffer },\n },\n },\n {\n binding: 6,\n resource: {\n kind: 'buffer',\n value: { buffer: hdrpBuffers.clusterUniformBuffer },\n },\n },\n {\n binding: 7,\n resource: { kind: 'textureView', value: ssaoTexView },\n },\n {\n binding: 8,\n resource: { kind: 'sampler', value: ssaoSampler },\n },\n ],\n });\n if (!result.ok) {\n runtime.errorRegistry.fire(result.error);\n return null;\n }\n return result.value;\n}\n\n/** Build the clustered skin group(2) bind group with one shared palette window. */\nexport function createHdrpSkinUnifiedBindGroup(\n runtime: RenderSystemRuntime,\n hdrpBuffers: HdrpBuffers,\n layout: BindGroupLayout,\n meshStorageBuffer: Buffer,\n paletteBuffer: Buffer,\n paletteBindingWindowBytes: number,\n ssaoOptions: SsaoBindOptions = { enabled: false },\n): BindGroup | null {\n const fallback = getOrCreateSsaoFallbackTexture(runtime);\n if (fallback === null) return null;\n const meshSize = MESH_PER_ENTITY_STRIDE;\n const result = runtime.device.createBindGroup({\n label: 'hdrp-skin-unified-bg-group2',\n layout,\n entries: [\n ...createPbrSkinMeshBindGroupEntries(\n meshStorageBuffer,\n meshSize,\n paletteBuffer,\n paletteBindingWindowBytes,\n ),\n { binding: 3, resource: { kind: 'buffer', value: { buffer: hdrpBuffers.lightDataBuffer } } },\n {\n binding: 4,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.clusterGridBuffer } },\n },\n {\n binding: 5,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.lightIndexListBuffer } },\n },\n {\n binding: 6,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.clusterUniformBuffer } },\n },\n {\n binding: 7,\n resource: {\n kind: 'textureView',\n value: ssaoOptions.enabled ? ssaoOptions.ssaoBlurredView : fallback.view,\n },\n },\n { binding: 8, resource: { kind: 'sampler', value: fallback.sampler } },\n ],\n });\n if (!result.ok) {\n runtime.errorRegistry.fire(result.error);\n return null;\n }\n return result.value;\n}\n\n/**\n * Build the compute-only bind group for ordered cluster membership output.\n * Its group is intentionally separate from the fragment group: the same\n * light-index buffer is read-only in the fragment pipeline but read-write in\n * the producer pipeline, which WebGPU represents with different binding\n * types.\n */\nexport function createHdrpClusterMembershipBindGroup(\n runtime: RenderSystemRuntime,\n hdrpBuffers: HdrpBuffers,\n layout: BindGroupLayout,\n): BindGroup | null {\n const result = runtime.device.createBindGroup({\n label: 'hdrp-cluster-membership-bg',\n layout,\n entries: [\n {\n binding: 0,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.clusterGridBuffer } },\n },\n {\n binding: 1,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.lightIndexListBuffer } },\n },\n {\n binding: 2,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.clusterUniformBuffer } },\n },\n {\n binding: 3,\n resource: { kind: 'buffer', value: { buffer: hdrpBuffers.lightBoundsBuffer } },\n },\n ],\n });\n if (!result.ok) {\n runtime.errorRegistry.fire(result.error);\n return null;\n }\n return result.value;\n}\n\n/** Sentinel error class re-export for tests asserting the error path. */\nexport { RhiError as HdrpBufferAllocError };\n","// @forgeax/engine-runtime — CPU cluster-forward binner (M3 pure functions)\n// feat-20260608-cluster-lighting.\n//\n// Transplants Bevy's clustered_forward CPU math skeleton (research Finding 1)\n// from WGSL to pure TypeScript. Four internal pure functions ported from\n// Bevy cluster.wgsl lines 75-200:\n// cluster_space_object_aabb — sphere -> view-space NDC AABB\n// ndc_position_to_cluster — NDC coords -> cluster index (XY+Z)\n// calculate_sphere_cluster_bounds — AABB -> cluster-cell range\n// view_z_to_z_slice — log-z inverse mapping (idTech6 formula)\n//\n// Public surface:\n// bin(lights, view, proj, grid, near, far, clusterGrid, lightIndexList, capacity)\n// -> Result<writtenLightIndexCount, ClusterBinError>\n//\n// deriveCullingRadius(range, intensity, threshold) — D-8 +Infinity fallback\n//\n// Constraints:\n// D-3: pure function + Result<number, ClusterBinError> + out param + no throw\n// D-8: spot uses sphere proxy (radius=range)\n// D-binner: CPU main thread, no GPU compute / worker\n// OOS-4: cone-AABB tight culling deferred\n// AGENTS.md conventions: structured errors, never throw for expected failures\n//\n// Capacity: max 65536 light index list entries (hard cap, AC-24).\n// Grid: {x,y,z} each in [1, 64] integers (validated at install time).\n\nimport { type Mat4, type Vec3, vec3 } from '@forgeax/engine-math';\nimport { err, ok, type Result } from '@forgeax/engine-rhi';\nimport type { RectAreaWorldFrame } from './render-system-extract';\n\n// ── types ──────────────────────────────────────────────────────────────────\n\nexport type ClusterBinErrorCode = 'index-overflow';\n\nexport interface ClusterBinError {\n readonly code: ClusterBinErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly detail: IndexOverflowDetail;\n}\n\nexport interface IndexOverflowDetail {\n readonly actual: number;\n readonly capacity: number;\n}\n\n/**\n * View-space NDC axis-aligned bounding box.\n * `min` and `max` are NDC coordinates clamped to [-1, 1] for XY;\n * Z may extend to projection-space depth values.\n */\nexport interface ClusterAabb {\n readonly min: Vec3;\n readonly max: Vec3;\n}\n\n/** Unsigned integer 3D cluster cell coordinate. */\nexport interface Uvec3 {\n readonly x: number;\n readonly y: number;\n readonly z: number;\n}\n\n/** Cluster cell range in the unsigned grid. */\nexport interface ClusterBounds {\n readonly min: Uvec3;\n readonly max: Uvec3;\n}\n\ntype MutableClusterBounds = {\n min: { x: number; y: number; z: number };\n max: { x: number; y: number; z: number };\n};\n\n/**\n * Reusable typed scratch for cluster-major output. The binner must emit one\n * contiguous light-index run per cluster, so counts and cursors replace the\n * per-frame `number[][]` staging lists without changing output order.\n */\nexport interface ClusterBinScratch {\n clusterCounts: Uint32Array;\n clusterCursors: Uint32Array;\n lightBounds: Int32Array;\n clusterDeltas: Int32Array;\n aabbOutput: ClusterAabb;\n boundsOutput: MutableClusterBounds;\n}\n\n/**\n * Selects the membership materialization owner after bounds and occupancy are\n * derived. The default keeps the existing CPU list writer; the WebGPU\n * producer uses the same CPU-owned scratch and leaves the ordered list to a\n * later compute pass.\n */\nexport interface ClusterBinOptions {\n readonly writeMembership?: boolean;\n}\n\nexport type ClusterBinProfilePhase =\n | 'light-bounds-and-occupancy'\n | 'light-bounds-and-occupancy/light-aabb'\n | 'light-bounds-and-occupancy/cluster-occupancy'\n | 'cluster-reserve'\n | 'light-index-write'\n | 'light-index-write/bounds-read'\n | 'light-index-write/cluster-write';\n\nexport type ClusterBinProfileRunner = <T>(phase: ClusterBinProfilePhase, action: () => T) => T;\n\nfunction runClusterBinProfilePhase<T>(\n runner: ClusterBinProfileRunner | undefined,\n phase: ClusterBinProfilePhase,\n action: () => T,\n): T {\n return runner === undefined ? action() : runner(phase, action);\n}\n\nexport function createClusterBinScratch(): ClusterBinScratch {\n return {\n clusterCounts: new Uint32Array(0),\n clusterCursors: new Uint32Array(0),\n lightBounds: new Int32Array(0),\n clusterDeltas: new Int32Array(0),\n aabbOutput: {\n min: vec3.create(0, 0, 0),\n max: vec3.create(0, 0, 0),\n },\n boundsOutput: {\n min: { x: 0, y: 0, z: 0 },\n max: { x: 0, y: 0, z: 0 },\n },\n };\n}\n\nfunction ensureScratchCapacity(\n scratch: ClusterBinScratch,\n clusterCount: number,\n lightCount: number,\n gridX: number,\n gridY: number,\n gridZ: number,\n): void {\n if (scratch.clusterCounts.length < clusterCount) {\n scratch.clusterCounts = new Uint32Array(clusterCount);\n scratch.clusterCursors = new Uint32Array(clusterCount);\n }\n if (scratch.lightBounds.length < lightCount * 6) {\n scratch.lightBounds = new Int32Array(lightCount * 6);\n }\n const differenceVolumeSize = (gridX + 1) * (gridY + 1) * (gridZ + 1);\n if (scratch.clusterDeltas.length < differenceVolumeSize) {\n scratch.clusterDeltas = new Int32Array(differenceVolumeSize);\n }\n}\n\n// ── deriveCullingRadius ────────────────────────────────────────────────────\n\n/**\n * Compute a culling radius for a punctual light.\n *\n * If `range` is finite, returns it verbatim (D-8 sphere proxy).\n * If `range === +Infinity`, derives a finite radius from the distance at which\n * the light's perceptible contribution drops below `threshold`.\n *\n * Formula: `sqrt(intensity / threshold)` gives the distance at which attenuation\n * = threshold (assuming E=1/r^2 falloff for point lights).\n * Cap to a conservative 1000 units to prevent overly large bounds.\n */\nexport function deriveCullingRadius(range: number, intensity: number, threshold = 0.001): number {\n if (Number.isFinite(range)) {\n return Math.max(0, range);\n }\n const derived = Math.sqrt(intensity / threshold);\n return Math.min(derived, 1000);\n}\n\n/** Conservative bounding-sphere radius for a finite Rect and its light range. */\nexport function rectAreaClusterRadius(frame: RectAreaWorldFrame, range: number): number {\n return Math.max(0, range) + Math.hypot(frame.halfWidth, frame.halfHeight);\n}\n\n/** Test the finite Rect's closest-point distance against a strict range window. */\nexport function rectAreaIsInRange(\n frame: RectAreaWorldFrame,\n point: ArrayLike<number>,\n range: number,\n): boolean {\n const toPoint = vec3.create(\n (point[0] ?? 0) - (frame.center[0] ?? 0),\n (point[1] ?? 0) - (frame.center[1] ?? 0),\n (point[2] ?? 0) - (frame.center[2] ?? 0),\n );\n const localX = Math.min(\n frame.halfWidth,\n Math.max(-frame.halfWidth, vec3.dot(toPoint, frame.axisX)),\n );\n const localY = Math.min(\n frame.halfHeight,\n Math.max(-frame.halfHeight, vec3.dot(toPoint, frame.axisY)),\n );\n const dx = (toPoint[0] ?? 0) - (frame.axisX[0] ?? 0) * localX - (frame.axisY[0] ?? 0) * localY;\n const dy = (toPoint[1] ?? 0) - (frame.axisX[1] ?? 0) * localX - (frame.axisY[1] ?? 0) * localY;\n const dz = (toPoint[2] ?? 0) - (frame.axisX[2] ?? 0) * localX - (frame.axisY[2] ?? 0) * localY;\n return dx * dx + dy * dy + dz * dz < range * range;\n}\n\n// ── view_z_to_z_slice ──────────────────────────────────────────────────────\n\n/**\n * Map view-space z (negative, camera-forward) to a cluster Z slice index.\n *\n * Implements the idTech6 inverse log-z formula (research §2):\n * slice = floor(log(-view_z / near) / log(far / near) * gridZ)\n *\n * Clamped to [0, gridZ - 1].\n */\nexport function viewZToZSlice(viewZ: number, gridZ: number, near: number, far: number): number {\n if (viewZ >= -near) {\n return 0;\n }\n const logFarOverNear = Math.log(far / near);\n const slice = Math.floor((Math.log(-viewZ / near) / logFarOverNear) * gridZ);\n if (slice < 0) return 0;\n if (slice >= gridZ) return gridZ - 1;\n return slice;\n}\n\n// ── cluster_space_object_aabb ───────────────────────────────────────────────\n\n/**\n * Compute view-space NDC AABB for a sphere (light culling proxy).\n *\n * Ported from Bevy `cluster_space_object_aabb` (cluster.wgsl lines 75-140).\n *\n * Steps:\n * 1. Transform sphere center to view space via view matrix.\n * 2. Expand by radius to get view-AABB corners.\n * 3. Project 4 key corners to NDC.\n * 4. Clamp to [-1, 1] for XY ; Z is kept as projected depth.\n */\nexport function clusterSpaceObjectAabb(\n center: Vec3,\n radius: number,\n view: Mat4,\n proj: Mat4,\n output?: ClusterAabb,\n): ClusterAabb {\n const result =\n output ??\n ({\n min: vec3.create(0, 0, 0),\n max: vec3.create(0, 0, 0),\n } satisfies ClusterAabb);\n const cx = center[0] ?? 0;\n const cy = center[1] ?? 0;\n const cz = center[2] ?? 0;\n\n const v00 = view[0] ?? 0;\n const v01 = view[1] ?? 0;\n const v02 = view[2] ?? 0;\n const v10 = view[4] ?? 0;\n const v11 = view[5] ?? 0;\n const v12 = view[6] ?? 0;\n const v20 = view[8] ?? 0;\n const v21 = view[9] ?? 0;\n const v22 = view[10] ?? 0;\n const v30 = view[12] ?? 0;\n const v31 = view[13] ?? 0;\n const v32 = view[14] ?? 0;\n\n const vx = v00 * cx + v10 * cy + v20 * cz + v30;\n const vy = v01 * cx + v11 * cy + v21 * cz + v31;\n const vz = v02 * cx + v12 * cy + v22 * cz + v32;\n\n const viewScaleX = Math.hypot(v00, v01, v02);\n const viewScaleY = Math.hypot(v10, v11, v12);\n const viewScaleZ = Math.hypot(v20, v21, v22);\n\n const rx = radius * viewScaleX;\n const ry = radius * viewScaleY;\n const rz = radius * viewScaleZ;\n\n const vMinX = vx - rx;\n const vMaxX = vx + rx;\n const vMinY = vy - ry;\n const vMaxY = vy + ry;\n // View-space camera looks down -Z, so view_z < 0 in front of camera. The\n // sphere's view-space z-extent is [vMinZ, vMaxZ] with vMinZ <= vMaxZ in raw\n // sign-order; vMinZ is the FARTHEST (most negative) edge, vMaxZ is the\n // NEAREST edge (could be positive if the sphere crosses the near plane).\n //\n // M4.5-followup: previously we did `minViewZ = max(vMinZ, -1e-5)` which\n // collapses the FAR edge of every visible light to view_z ~= 0, which the\n // log-z slice mapping then bins as slice 0. Result: every light only ever\n // wrote into slice 0/0/0 .. {gx-1}/{gy-1}/0 -- floor pixels at view_z=-3..-9\n // (slice 13..17) found 0 lights and rendered black. The clamp must guard\n // the NEAR edge (vMaxZ) instead so projectToNdc never receives a positive\n // or zero view_z, while letting the far edge flow through to its real\n // log-z slice.\n const vMinZ = vz - rz;\n const vMaxZ = vz + rz;\n\n const minViewZ = vMinZ;\n const maxViewZ = Math.min(vMaxZ, -1e-5);\n\n // If even the near edge of the sphere is behind the camera, the light\n // contributes nothing. Caller (calculateSphereClusterBounds) returns\n // min > max which the bin loop treats as cull.\n if (minViewZ > maxViewZ) {\n result.min[0] = 1;\n result.min[1] = 1;\n result.min[2] = -1e-5;\n result.max[0] = -1;\n result.max[1] = -1;\n result.max[2] = -1e-5;\n return result;\n }\n\n let ndcMinX = Infinity;\n let ndcMaxX = -Infinity;\n let ndcMinY = Infinity;\n let ndcMaxY = -Infinity;\n\n const p00 = proj[0] ?? 0;\n const p10 = proj[4] ?? 0;\n const p20 = proj[8] ?? 0;\n const p30 = proj[12] ?? 0;\n const p01 = proj[1] ?? 0;\n const p11 = proj[5] ?? 0;\n const p21 = proj[9] ?? 0;\n const p31 = proj[13] ?? 0;\n const p23 = proj[11] ?? 0;\n\n // In the engine's perspective matrices clip.w depends only on view-space z.\n // The XY extrema of each z face are therefore the interval of one linear\n // form, avoiding eight corner projections and their temporary tuples.\n const perspectiveWOnlyZ =\n Math.abs(proj[3] ?? 0) < 1e-8 &&\n Math.abs(proj[7] ?? 0) < 1e-8 &&\n Math.abs(proj[15] ?? 0) < 1e-8 &&\n Math.abs(p23) >= 1e-5;\n\n if (perspectiveWOnlyZ) {\n const xExtent = Math.abs(p00) * rx + Math.abs(p10) * ry;\n const yExtent = Math.abs(p01) * rx + Math.abs(p11) * ry;\n for (let face = 0; face < 2; face++) {\n const zTest = face === 0 ? minViewZ : maxViewZ;\n if (zTest > 0) continue;\n const invW = 1 / (p23 * zTest);\n const xCenter = p20 * zTest + p30;\n const yCenter = p21 * zTest + p31;\n const x0 = (xCenter - xExtent) * invW;\n const x1 = (xCenter + xExtent) * invW;\n const y0 = (yCenter - yExtent) * invW;\n const y1 = (yCenter + yExtent) * invW;\n ndcMinX = Math.min(ndcMinX, x0, x1);\n ndcMaxX = Math.max(ndcMaxX, x0, x1);\n ndcMinY = Math.min(ndcMinY, y0, y1);\n ndcMaxY = Math.max(ndcMaxY, y0, y1);\n }\n } else {\n const corners: Array<[number, number]> = [\n [vMinX, vMinY],\n [vMinX, vMaxY],\n [vMaxX, vMinY],\n [vMaxX, vMaxY],\n ];\n\n for (const zTest of [minViewZ, maxViewZ]) {\n if (zTest <= 0) {\n for (const corner of corners) {\n const sx = corner[0];\n const sy = corner[1];\n const ndc = projectToNdc(sx, sy, zTest, proj);\n ndcMinX = Math.min(ndcMinX, ndc[0]);\n ndcMaxX = Math.max(ndcMaxX, ndc[0]);\n ndcMinY = Math.min(ndcMinY, ndc[1]);\n ndcMaxY = Math.max(ndcMaxY, ndc[1]);\n }\n }\n }\n }\n\n ndcMinX = Math.max(ndcMinX, -1);\n ndcMinY = Math.max(ndcMinY, -1);\n ndcMaxX = Math.min(ndcMaxX, 1);\n ndcMaxY = Math.min(ndcMaxY, 1);\n\n // M4.5-followup: aabb.min/max[2] now carries VIEW-SPACE z (negative), not\n // projected-NDC z. calculateSphereClusterBounds + ndcPositionToCluster +\n // viewZToZSlice all want view_z to do the log-z slice mapping; passing the\n // projected NDC z (>= 0) collapsed every light to slice 0 so cube/floor\n // fragments outside that slice received zero light.\n result.min[0] = ndcMinX;\n result.min[1] = ndcMinY;\n result.min[2] = minViewZ;\n result.max[0] = ndcMaxX;\n result.max[1] = ndcMaxY;\n result.max[2] = maxViewZ;\n return result;\n}\n\n/**\n * Project a view-space point to NDC via the perspective projection matrix.\n * Returns [ndc_x, ndc_y, ndc_z].\n */\nfunction projectToNdc(vx: number, vy: number, vz: number, proj: Mat4): [number, number, number] {\n const p00 = proj[0] ?? 0;\n const p10 = proj[4] ?? 0;\n const p20 = proj[8] ?? 0;\n const p30 = proj[12] ?? 0;\n const p01 = proj[1] ?? 0;\n const p11 = proj[5] ?? 0;\n const p21 = proj[9] ?? 0;\n const p31 = proj[13] ?? 0;\n const p02 = proj[2] ?? 0;\n const p12 = proj[6] ?? 0;\n const p22 = proj[10] ?? 0;\n const p32 = proj[14] ?? 0;\n const p03 = proj[3] ?? 0;\n const p13 = proj[7] ?? 0;\n const p23 = proj[11] ?? 0;\n const p33 = proj[15] ?? 0;\n\n const cx = p00 * vx + p10 * vy + p20 * vz + p30;\n const cy = p01 * vx + p11 * vy + p21 * vz + p31;\n const cz = p02 * vx + p12 * vy + p22 * vz + p32;\n const cw = p03 * vx + p13 * vy + p23 * vz + p33;\n\n if (Math.abs(cw) < 1e-10) {\n return [vx < 0 ? -1 : 1, vy < 0 ? -1 : 1, cz];\n }\n\n const invW = 1 / cw;\n return [cx * invW, cy * invW, cz * invW];\n}\n\n// ── ndc_position_to_cluster ─────────────────────────────────────────────────\n\n/**\n * Map an NDC point to its cluster cell index (XY + Z).\n *\n * XY: floor((ndc.xy * 0.5 + 0.5) * gridXy) clamped to [0, gridXy - 1].\n * Z: delegated to view_z_to_z_slice with the given view-space z.\n */\nexport function ndcPositionToCluster(\n ndc: Vec3,\n viewZ: number,\n gridX: number,\n gridY: number,\n gridZ: number,\n near: number,\n far: number,\n): Uvec3 {\n const ndcX = ndc[0] ?? 0;\n const ndcY = ndc[1] ?? 0;\n\n let cx = Math.floor((ndcX * 0.5 + 0.5) * gridX);\n let cy = Math.floor((ndcY * 0.5 + 0.5) * gridY);\n\n if (cx < 0) cx = 0;\n if (cx >= gridX) cx = gridX - 1;\n if (cy < 0) cy = 0;\n if (cy >= gridY) cy = gridY - 1;\n\n const cz = viewZToZSlice(viewZ, gridZ, near, far);\n\n return { x: cx, y: cy, z: cz };\n}\n\n// ── calculate_sphere_cluster_bounds ─────────────────────────────────────────\n\n/**\n * Convert an NDC AABB to a range of cluster cell indices.\n *\n * Computes cluster indices for AABB min and max, then clamps and\n * orders the result so `min <= max` in each axis.\n *\n * If the sphere is entirely behind the camera, returns min > max\n * in at least one axis (cull signal).\n */\nexport function calculateSphereClusterBounds(\n aabb: ClusterAabb,\n gridX: number,\n gridY: number,\n gridZ: number,\n near: number,\n far: number,\n output?: MutableClusterBounds,\n): ClusterBounds {\n const result =\n output ??\n ({\n min: { x: 0, y: 0, z: 0 },\n max: { x: 0, y: 0, z: 0 },\n } satisfies MutableClusterBounds);\n const minZ = aabb.min[2] ?? 0;\n const maxZ = aabb.max[2] ?? 0;\n\n const idxMin = ndcPositionToCluster(aabb.min, minZ, gridX, gridY, gridZ, near, far);\n const idxMax = ndcPositionToCluster(aabb.max, maxZ, gridX, gridY, gridZ, near, far);\n\n result.min.x = Math.min(idxMin.x, idxMax.x);\n result.min.y = Math.min(idxMin.y, idxMax.y);\n result.min.z = Math.min(idxMin.z, idxMax.z);\n result.max.x = Math.max(idxMin.x, idxMax.x);\n result.max.y = Math.max(idxMin.y, idxMax.y);\n result.max.z = Math.max(idxMin.z, idxMax.z);\n return result;\n}\n\n// ── bin ─────────────────────────────────────────────────────────────────────\n\n/**\n * Main entry point: assign punctual lights to cluster cells.\n *\n * Light-major loop: for each light, compute its sphere-AABB and iterate the\n * intersecting cluster cells, appending the light index to the light_index_list\n * and updating cluster_grid offsets.\n *\n * @param lights — array of { position: Vec3, range: number }\n * @param view — view matrix (column-major 16 floats)\n * @param proj — projection matrix (column-major 16 floats)\n * @param grid — cluster grid dimensions { x, y, z }\n * @param near — near plane distance\n * @param far — far plane distance\n * @param clusterGrid — caller-owned Uint32Array, length = grid.x * grid.y * grid.z * 2.\n * Format: [offset, count] pairs. offset = start index in lightIndexList; count = number of lights.\n * @param lightIndexList — caller-owned Uint32Array for light index storage.\n * @param capacity — max entries in lightIndexList (hard cap, typically 65536).\n * @param scratch — optional per-render-system typed scratch reused across frames.\n *\n * @returns `ok(written light-index entry count)` on success; `err(ClusterBinError)` with code\n * 'index-overflow' on overflow. The count lets the upload owner avoid copying unused capacity.\n */\nexport function bin(\n lights: ReadonlyArray<{ readonly position: Vec3; readonly range: number }>,\n view: Mat4,\n proj: Mat4,\n grid: { readonly x: number; readonly y: number; readonly z: number },\n near: number,\n far: number,\n clusterGrid: Uint32Array,\n lightIndexList: Uint32Array,\n capacity: number,\n scratch?: ClusterBinScratch,\n profile?: ClusterBinProfileRunner,\n options: ClusterBinOptions = {},\n): Result<number, ClusterBinError> {\n const gridX = grid.x;\n const gridY = grid.y;\n const gridZ = grid.z;\n const clusterCount = gridX * gridY * gridZ;\n const binScratch = scratch ?? createClusterBinScratch();\n\n ensureScratchCapacity(binScratch, clusterCount, lights.length, gridX, gridY, gridZ);\n const { clusterCounts, clusterCursors, lightBounds, clusterDeltas } = binScratch;\n\n clusterGrid.fill(0, 0, clusterCount * 2);\n clusterCounts.fill(0, 0, clusterCount);\n\n let attemptedTotal = 0;\n\n runClusterBinProfilePhase(profile, 'light-bounds-and-occupancy', () => {\n runClusterBinProfilePhase(profile, 'light-bounds-and-occupancy/light-aabb', () => {\n for (let lightIdx = 0; lightIdx < lights.length; lightIdx++) {\n const boundsOffset = lightIdx * 6;\n lightBounds[boundsOffset] = -1;\n const light = lights[lightIdx];\n if (!light) continue;\n const radius = deriveCullingRadius(light.range, 1);\n\n if (radius <= 0) {\n continue;\n }\n\n const aabb = clusterSpaceObjectAabb(\n light.position,\n radius,\n view,\n proj,\n binScratch.aabbOutput,\n );\n\n const bounds = calculateSphereClusterBounds(\n aabb,\n gridX,\n gridY,\n gridZ,\n near,\n far,\n binScratch.boundsOutput,\n );\n if (\n bounds.min.x > bounds.max.x ||\n bounds.min.y > bounds.max.y ||\n bounds.min.z > bounds.max.z\n ) {\n continue;\n }\n\n lightBounds[boundsOffset] = bounds.min.x;\n lightBounds[boundsOffset + 1] = bounds.min.y;\n lightBounds[boundsOffset + 2] = bounds.min.z;\n lightBounds[boundsOffset + 3] = bounds.max.x;\n lightBounds[boundsOffset + 4] = bounds.max.y;\n lightBounds[boundsOffset + 5] = bounds.max.z;\n }\n });\n\n runClusterBinProfilePhase(profile, 'light-bounds-and-occupancy/cluster-occupancy', () => {\n const diffX = gridX + 1;\n const diffY = gridY + 1;\n const diffRow = diffX * diffY;\n clusterDeltas.fill(0, 0, diffRow * (gridZ + 1));\n\n const addDifference = (x: number, y: number, z: number, delta: number): void => {\n const index = z * diffRow + y * diffX + x;\n clusterDeltas[index] = (clusterDeltas[index] ?? 0) + delta;\n };\n\n for (let lightIdx = 0; lightIdx < lights.length; lightIdx++) {\n const boundsOffset = lightIdx * 6;\n if ((lightBounds[boundsOffset] ?? -1) < 0) continue;\n const minX = lightBounds[boundsOffset] ?? 0;\n const minY = lightBounds[boundsOffset + 1] ?? 0;\n const minZ = lightBounds[boundsOffset + 2] ?? 0;\n const maxX = lightBounds[boundsOffset + 3] ?? -1;\n const maxY = lightBounds[boundsOffset + 4] ?? -1;\n const maxZ = lightBounds[boundsOffset + 5] ?? -1;\n const endX = maxX + 1;\n const endY = maxY + 1;\n const endZ = maxZ + 1;\n addDifference(minX, minY, minZ, 1);\n addDifference(endX, minY, minZ, -1);\n addDifference(minX, endY, minZ, -1);\n addDifference(minX, minY, endZ, -1);\n addDifference(endX, endY, minZ, 1);\n addDifference(endX, minY, endZ, 1);\n addDifference(minX, endY, endZ, 1);\n addDifference(endX, endY, endZ, -1);\n }\n for (let cz = 0; cz < gridZ; cz++) {\n for (let cy = 0; cy < gridY; cy++) {\n for (let cx = 0; cx < gridX; cx++) {\n const diffIdx = cz * diffRow + cy * diffX + cx;\n let count = clusterDeltas[diffIdx] ?? 0;\n if (cx > 0) count += clusterDeltas[diffIdx - 1] ?? 0;\n if (cy > 0) count += clusterDeltas[diffIdx - diffX] ?? 0;\n if (cz > 0) count += clusterDeltas[diffIdx - diffRow] ?? 0;\n if (cx > 0 && cy > 0) count -= clusterDeltas[diffIdx - diffX - 1] ?? 0;\n if (cx > 0 && cz > 0) count -= clusterDeltas[diffIdx - diffRow - 1] ?? 0;\n if (cy > 0 && cz > 0) count -= clusterDeltas[diffIdx - diffRow - diffX] ?? 0;\n if (cx > 0 && cy > 0 && cz > 0) {\n count += clusterDeltas[diffIdx - diffRow - diffX - 1] ?? 0;\n }\n clusterDeltas[diffIdx] = count;\n const clusterIdx = cz * gridY * gridX + cy * gridX + cx;\n clusterCounts[clusterIdx] = count;\n attemptedTotal += count;\n }\n }\n }\n });\n });\n\n if (attemptedTotal > capacity) {\n return err({\n code: 'index-overflow',\n expected: `writeCount <= ${capacity}`,\n hint: `light index list overflow: needed ${attemptedTotal} entries, capacity ${capacity}; reduce lights, shrink grid, or shrink ranges (overrun = ${attemptedTotal - capacity})`,\n detail: { actual: attemptedTotal, capacity },\n });\n }\n\n // Reserve one contiguous output run per cluster. The second light-major pass\n // below preserves each cluster's original light ordering without allocating\n // one JavaScript array per cluster.\n const writeCount = runClusterBinProfilePhase(profile, 'cluster-reserve', () => {\n let reserved = 0;\n for (let ci = 0; ci < clusterCount; ci++) {\n const base = ci * 2;\n clusterGrid[base] = reserved;\n clusterGrid[base + 1] = clusterCounts[ci] ?? 0;\n clusterCursors[ci] = reserved;\n reserved += clusterCounts[ci] ?? 0;\n }\n return reserved;\n });\n\n if (options.writeMembership !== false) {\n runClusterBinProfilePhase(profile, 'light-index-write', () => {\n for (let lightIdx = 0; lightIdx < lights.length; lightIdx++) {\n const boundsOffset = lightIdx * 6;\n let valid = false;\n let minX = 0;\n let minY = 0;\n let minZ = 0;\n let maxX = -1;\n let maxY = -1;\n let maxZ = -1;\n runClusterBinProfilePhase(profile, 'light-index-write/bounds-read', () => {\n if ((lightBounds[boundsOffset] ?? -1) < 0) return;\n valid = true;\n minX = lightBounds[boundsOffset] ?? 0;\n minY = lightBounds[boundsOffset + 1] ?? 0;\n minZ = lightBounds[boundsOffset + 2] ?? 0;\n maxX = lightBounds[boundsOffset + 3] ?? -1;\n maxY = lightBounds[boundsOffset + 4] ?? -1;\n maxZ = lightBounds[boundsOffset + 5] ?? -1;\n });\n if (!valid) continue;\n runClusterBinProfilePhase(profile, 'light-index-write/cluster-write', () => {\n for (let cz = minZ; cz <= maxZ; cz++) {\n for (let cy = minY; cy <= maxY; cy++) {\n for (let cx = minX; cx <= maxX; cx++) {\n const clusterIdx = cz * gridY * gridX + cy * gridX + cx;\n const cursor = clusterCursors[clusterIdx] ?? 0;\n lightIndexList[cursor] = lightIdx;\n clusterCursors[clusterIdx] = cursor + 1;\n }\n }\n }\n });\n }\n });\n }\n\n return ok(writeCount);\n}\n","import type { ClusterBinError } from '../../cluster-binner';\nimport { StandardClusterIndexOverflowError } from '../../errors/render';\n\nexport function fromClusterBinError(error: ClusterBinError): StandardClusterIndexOverflowError {\n return new StandardClusterIndexOverflowError(error.detail.actual, error.detail.capacity);\n}\n","import { err, ok, type Result } from '@forgeax/engine-types';\nimport { bin, type ClusterBinScratch, createClusterBinScratch } from '../../cluster-binner';\nimport type { RenderError } from '../../errors/render';\nimport { fromClusterBinError } from './errors';\nimport type { StandardClusterLayout } from './layout';\nimport type { StandardLightFrame } from './light-frame';\n\nexport interface StandardClusterMembership {\n readonly clusterGrid: Uint32Array;\n readonly lightIndexList: Uint32Array;\n readonly lightBounds: Int32Array;\n readonly membershipEntryCount: number;\n readonly scratch: ClusterBinScratch;\n}\n\nexport function deriveStandardMembership(\n frame: StandardLightFrame,\n layout: StandardClusterLayout,\n scratch = createClusterBinScratch(),\n): Result<StandardClusterMembership, RenderError> {\n const clusterGrid = new Uint32Array(layout.clusterGridU32Length);\n const lightIndexList = new Uint32Array(layout.lightIndexListCapacity);\n const result = bin(\n frame.local,\n frame.view,\n frame.projection,\n layout.grid,\n frame.near,\n frame.far,\n clusterGrid,\n lightIndexList,\n layout.lightIndexListCapacity,\n scratch,\n );\n if (!result.ok) return err(fromClusterBinError(result.error));\n return ok({\n clusterGrid,\n lightIndexList,\n lightBounds: scratch.lightBounds.slice(0, frame.local.length * 6),\n membershipEntryCount: result.value,\n scratch,\n });\n}\n","import { err, ok, type Result } from '@forgeax/engine-types';\nimport { type RenderError, StandardLightBudgetExceededError } from '../../errors/render';\nimport { MAX_LIGHTS } from '../standard-profile';\nimport { createStandardClusterLayout, type StandardClusterLayout } from './layout';\nimport type { StandardLightFrame } from './light-frame';\nimport { deriveStandardMembership, type StandardClusterMembership } from './membership';\n\nexport type { StandardLightFrame } from './light-frame';\n\nexport interface PreparedStandardLighting extends StandardClusterMembership {\n readonly directional: StandardLightFrame['directional'];\n readonly local: StandardLightFrame['local'];\n readonly layout: StandardClusterLayout;\n readonly membershipLightCount: number;\n readonly renderPath: NonNullable<StandardLightFrame['renderPath']>;\n readonly maxLights: StandardLightFrame['lightCount'];\n}\n\nexport function prepareStandardLighting(\n frame: StandardLightFrame,\n): Result<PreparedStandardLighting, RenderError> {\n if (frame.local.length > frame.lightCount || frame.local.length > MAX_LIGHTS) {\n return err(new StandardLightBudgetExceededError(frame.local.length, frame.lightCount));\n }\n const layout = createStandardClusterLayout(frame.grid);\n const membership = deriveStandardMembership(frame, layout);\n if (!membership.ok) return membership;\n return ok({\n ...membership.value,\n directional: frame.directional,\n local: frame.local,\n layout,\n membershipLightCount: frame.local.length,\n renderPath: frame.renderPath,\n maxLights: frame.lightCount,\n });\n}\n","import { err, ok, type Result } from '@forgeax/engine-types';\nimport { type RenderError, StandardClusterTransportUnavailableError } from '../../errors/render';\nimport { BYTES_PER_DIRECT_LIGHT_SLOT } from '../../light-buffer-layout';\nimport type { PreparedStandardLighting } from './prepare';\n\nexport interface StandardClusterCapabilities {\n readonly compute: boolean;\n readonly storageBuffer: boolean;\n /**\n * The graph producer is ready to encode the selected compute lane. The\n * renderer supplies this from the actual pipeline + bind-group layout; it is\n * required so capability admission cannot forge a GPU producer from\n * `compute` alone.\n */\n readonly membershipPipelineReady: boolean;\n}\n\n/** Only transports with storage-backed membership representation exist. */\nexport type StandardClusterTransportKind = 'compute-storage' | 'cpu-storage';\nexport type StandardClusterMembershipProducer = 'cpu' | 'gpu';\n\nexport interface StandardClusterTransport {\n readonly kind: StandardClusterTransportKind;\n readonly producer: StandardClusterMembershipProducer;\n readonly layout: PreparedStandardLighting['layout'];\n readonly requestedLightCount: number;\n readonly admittedLightCount: number;\n readonly membershipEntryCount: number;\n readonly occupiedClusterCount: number;\n readonly clusterGridBytes: number;\n readonly lightIndexListBytes: number;\n readonly lightDataBytes: number;\n readonly lightBoundsBytes: number;\n}\n\nfunction occupiedClusterCount(prepared: PreparedStandardLighting): number {\n let occupied = 0;\n for (let index = 1; index < prepared.clusterGrid.length; index += 2) {\n if ((prepared.clusterGrid[index] ?? 0) > 0) occupied += 1;\n }\n return occupied;\n}\n\n/**\n * Select a transport from one prepared frame. Capability facts choose only a\n * producer/storage pair; all counts and byte sizes come from that frame.\n */\nexport function selectStandardClusterTransport(\n capabilities: StandardClusterCapabilities,\n prepared: PreparedStandardLighting,\n): Result<StandardClusterTransport, RenderError> {\n const requested = prepared.local.length;\n if (!capabilities.storageBuffer) {\n return err(\n new StandardClusterTransportUnavailableError(\n requested,\n 'enable a proven storage-buffer Cluster transport; compute without storage is not a membership path',\n ),\n );\n }\n\n const producer: StandardClusterMembershipProducer =\n capabilities.compute && capabilities.membershipPipelineReady ? 'gpu' : 'cpu';\n const kind: StandardClusterTransportKind = producer === 'gpu' ? 'compute-storage' : 'cpu-storage';\n return ok({\n kind,\n producer,\n layout: prepared.layout,\n requestedLightCount: requested,\n admittedLightCount: requested,\n membershipEntryCount: prepared.membershipEntryCount,\n occupiedClusterCount: occupiedClusterCount(prepared),\n clusterGridBytes: prepared.layout.clusterGridU32Length * Uint32Array.BYTES_PER_ELEMENT,\n lightIndexListBytes: prepared.membershipEntryCount * Uint32Array.BYTES_PER_ELEMENT,\n lightDataBytes: requested * BYTES_PER_DIRECT_LIGHT_SLOT,\n lightBoundsBytes: prepared.lightBounds.byteLength,\n });\n}\n","// @forgeax/engine-runtime - fullscreen post-process error model\n// (feat-20260604-resource-owning-render-graph-and-fullscreen-postpr M2 / w12;\n// feat-20260609-learn-render-4-5-framebuffers-demo-offscreen-rt-an M1 / T-2\n// added 'fullscreen-input-not-found').\n//\n// Closed 7-member PostProcessErrorCode union + PostProcessError discriminated-union class.\n// - 'post-process-already-registered' (programmer error) -> fullscreen effect registration THROWS a\n// PostProcessError, mirroring ShaderCatalog.installMaterialArtifact's Map.has -> throw\n// fail-fast (research Finding M2-4). A second register under the same id is a coding\n// mistake that must surface immediately.\n// - 'post-process-not-found' (runtime path) -> the typed fullscreen plan returns Result.err with\n// this code when the supplied id resolves to no registered post-process (stale / wrong\n// id). AI users branch on `err.code === 'post-process-not-found'` by property access.\n// - 'fullscreen-input-not-found' (runtime path, feat-20260609 M1 / D-2) -> the\n// dispatchFullscreenPass generic branch THROWS this when reads[0] references a\n// graph resource key that the per-pass resolve context cannot resolve (typo /\n// an unregistered colorTarget / mis-ordered color-target declaration vs the typed fullscreen pass).\n// - 'ssao-radius-non-positive' (runtime path, feat-20260612-hdrp-ssao M2 / w10) ->\n// SSAO radius parameter <= 0; fires when config.ssao.radius value is non-positive.\n// - 'ssao-bias-negative' (runtime path, feat-20260612-hdrp-ssao M2 / w10) ->\n// SSAO bias parameter < 0; fires when config.ssao.bias value is negative.\n//\n// D-1: a NEW independent union rather than folding into RuntimeErrorCode /\n// RuntimeErrorCode's members are render / skin / shadow domain; a separate union\n// keeps the post-process error surface cohesive and additively evolvable.\n//\n// Also per D-4: the fullscreen effect channel is parallel to installMaterialArtifact;\n// material shader errors carry 4-BGL / 12-float-vertex / depth / triangle-list semantics,\n// while post-process errors carry 0-vertex-buffer / no-depth / input-texture-BGL semantics.\n// Mixing the two error spaces would confuse AI users who branch on code for diagnostics.\n//\n// PostProcessError is exposed as a discriminated union (variant per code, AppError pattern)\n// so `if (err.code === 'X')` simultaneously narrows `err.detail` to the per-code payload.\n//\n// Related: requirements M2 AC-08 + AC-19; plan-strategy D-4 / D-9; charter P3 / P4;\n// feat-20260609 M1 plan-decisions D-2 (L-1 lock to scheme B - new closed-set member).\n\n/**\n * Closed union of fullscreen post-process error codes.\n *\n * Exactly 7 members; AI users perform exhaustive `switch (err.code)` without a default\n * and TS guards completeness (AC-08).\n *\n * | code | channel | trigger |\n * |:--|:--|:--|\n * | `'post-process-already-registered'` | throw | a second fullscreen effect registration under an already-registered `id` |\n * | `'post-process-not-found'` | throw / `Result.err` | a typed fullscreen plan whose `shader` id resolves to no registered post-process |\n * | `'fullscreen-input-not-found'` | throw | a typed fullscreen plan whose `reads` key is not a graph-declared color target, or a depth key missing TEXTURE_BINDING (D-4) |\n * | `'ssao-radius-non-positive'` | throw | SSAO `radius <= 0` |\n * | `'ssao-bias-negative'` | throw | SSAO `bias < 0` |\n * | `'params-size-mismatch'` | throw | a fullscreen effect declaration with `params.byteSize < 16` or `defaultValue.length !== byteSize` (feat-20260621 M-A4 / D-4) |\n * | `'params-update-size-mismatch'` | throw | per-frame data-driven write where `PostProcessParams.data` byteLength !== registered `params.byteSize` (feat-20260621 M-A4 / D-4) |\n */\nexport type PostProcessErrorCode = keyof typeof POST_PROCESS_POLICY;\n\n/**\n * Detail for `'post-process-already-registered'`: the post-process id that was already taken.\n * AI consumers read `.detail.id` by property access (charter P4), no message parsing.\n */\nexport interface PostProcessPreviouslyRegisteredDetail {\n readonly id: string;\n}\n\n/**\n * Detail for `'post-process-not-found'`: the post-process id that resolved to no\n * registered entry. Read via `.detail.id` after the code guard.\n */\nexport interface PostProcessNotFoundDetail {\n readonly id: string;\n}\n\n/**\n * Detail for `'fullscreen-input-not-found'`: the graph resource key that the\n * per-pass resolve context could not resolve, plus the pass name that referenced\n * it. Both fields are read via property access after `if (err.code === 'fullscreen-input-not-found')`\n * (charter P4); the AI user immediately knows WHICH key to declare and WHICH\n * pass needs wiring.\n */\nexport interface FullscreenInputNotFoundDetail {\n /** The reads[0] key that resolved to undefined (e.g. 'offscreenColor' / 'hdrColor'). */\n readonly readsKey: string;\n /** The name assigned to the typed fullscreen pass (e.g. 'pp' / 'post'). */\n readonly passName: string;\n}\n\n/**\n * Detail for `'ssao-radius-non-positive'`: the SSAO radius parameter was zero or negative.\n * AI consumers read `.detail.paramName` / `.detail.value` by property access (charter P4).\n */\nexport interface SsaoRadiusNonPositiveDetail {\n readonly paramName: string;\n readonly value: number;\n}\n\n/**\n * Detail for `'ssao-bias-negative'`: the SSAO bias parameter was negative.\n * AI consumers read `.detail.paramName` / `.detail.value` by property access.\n */\nexport interface SsaoBiasNegativeDetail {\n readonly paramName: string;\n readonly value: number;\n}\n\n/**\n * Detail for `'params-size-mismatch'`: the register call's byteSize / defaultValue.length\n * is invalid. Carries `byteSize` (the declared size) and `actualLength` (defaultValue.length).\n * AI consumers read `.detail.byteSize` / `.detail.actualLength` after the code guard.\n */\nexport interface PostProcessParamsSizeMismatchDetail {\n readonly byteSize: number;\n readonly actualLength: number;\n}\n\n/**\n * Detail for `'params-update-size-mismatch'`: the per-frame data-driven write\n * (PostProcessParams.data) had a byteLength that did not equal the registered\n * `params.byteSize`. Carries `byteSize` (registered) + `actualLength` (the\n * supplied data byteLength). AI consumers read `.detail.byteSize` /\n * `.detail.actualLength` after the code guard.\n *\n * NOTE (feat-20260621 M-A2): this code is wired here so dispatchFullscreenPass\n * can fail-fast on a mismatched per-frame write; the full error-model\n * formalization (expected/hint refinement, JSDoc member count, public\n * PostProcessError union variant) is finished in M-A4.\n */\nexport interface PostProcessParamsUpdateSizeMismatchDetail {\n readonly byteSize: number;\n readonly actualLength: number;\n}\n\n/**\n * Conditional resolver from `PostProcessErrorCode` to its detail payload type. Used by the\n * constructor signature so `new PostProcessError({ code: 'X', detail })` narrows the\n * `detail` parameter to the variant payload at compile time.\n */\nexport type PostProcessErrorDetailFor<C extends PostProcessErrorCode> =\n C extends 'post-process-already-registered'\n ? PostProcessPreviouslyRegisteredDetail\n : C extends 'post-process-not-found'\n ? PostProcessNotFoundDetail\n : C extends 'fullscreen-input-not-found'\n ? FullscreenInputNotFoundDetail\n : C extends 'ssao-radius-non-positive'\n ? SsaoRadiusNonPositiveDetail\n : C extends 'ssao-bias-negative'\n ? SsaoBiasNegativeDetail\n : C extends 'params-size-mismatch'\n ? PostProcessParamsSizeMismatchDetail\n : C extends 'params-update-size-mismatch'\n ? PostProcessParamsUpdateSizeMismatchDetail\n : never;\n\n/**\n * Tagged union of `.detail` payloads. The variants are unique by structural fields\n * (`{ id }` for the two id-by-string variants vs `{ readsKey, passName }` for the\n * graph-resource-miss variant); the code discriminator narrows the intent across\n * the two id-shaped variants.\n */\nexport type PostProcessErrorDetail = PostProcessErrorDetailFor<PostProcessErrorCode>;\n\nconst POST_PROCESS_POLICY = {\n 'post-process-already-registered': {\n expected: 'each post-process id is registered at most once',\n hint: (detail) =>\n `post-process id '${(detail as PostProcessPreviouslyRegisteredDetail).id}' is already ` +\n 'registered; same-id re-register is forbidden. Pick a distinct id ' +\n '(engine builtins use the forgeax:: prefix; user passes use <package>::<id>).',\n },\n 'post-process-not-found': {\n expected: 'typed fullscreen plan references a registered post-process id',\n hint: (detail) =>\n `no post-process is registered for id '${(detail as PostProcessNotFoundDetail).id}'. ` +\n `Register '${(detail as PostProcessNotFoundDetail).id}' with the feature host ({source, reads?}), ` +\n 'then reference it from a typed fullscreen RenderFeaturePlan.',\n },\n 'fullscreen-input-not-found': {\n expected: 'reads key must be a graph-declared colorTarget with TEXTURE_BINDING',\n hint: (detail) => {\n const d = detail as FullscreenInputNotFoundDetail;\n return (\n `fullscreen pass '${d.passName}' references reads key '${d.readsKey}' but that key is not ` +\n `declared as a graph color target, or the target is not sampleable as a texture. ` +\n `First declare graph color target '${d.readsKey}' with its format and size ` +\n `(or check spelling) before the typed fullscreen pass '${d.passName}' reads it. ` +\n `If '${d.readsKey}' is a depth target, ensure it has TEXTURE_BINDING usage (0x04) ` +\n `and is declared via graph.addColorTarget. Consider switching pipeline if your pipeline does not expose a sampleable depth target.`\n );\n },\n },\n 'ssao-radius-non-positive': {\n expected: 'SSAO radius must be > 0',\n hint: (detail) => {\n const d = detail as SsaoRadiusNonPositiveDetail;\n return (\n `SSAO parameter '${d.paramName}' is ${d.value}, must be greater than 0. ` +\n `Set config.ssao.${d.paramName} to a positive value (default 0.5) or disable SSAO with config.ssao.enabled = false.`\n );\n },\n },\n 'ssao-bias-negative': {\n expected: 'SSAO bias must be >= 0',\n hint: (detail) => {\n const d = detail as SsaoBiasNegativeDetail;\n return (\n `SSAO parameter '${d.paramName}' is ${d.value}, must be >= 0. ` +\n `Set config.ssao.${d.paramName} to a non-negative value (default 0.025) or disable SSAO.`\n );\n },\n },\n 'params-size-mismatch': {\n expected: 'params.byteSize >= 16 and defaultValue.length === byteSize',\n hint: (detail) => {\n const d = detail as PostProcessParamsSizeMismatchDetail;\n return (\n `params.byteSize is ${d.byteSize} but defaultValue.length is ${d.actualLength}. ` +\n 'The UBO byteSize must be >= 16 B and defaultValue.length must equal byteSize. ' +\n 'Pass a defaultValue Uint8Array whose .length matches byteSize exactly.'\n );\n },\n },\n 'params-update-size-mismatch': {\n expected: 'PostProcessParams.data byteLength === registered params.byteSize',\n hint: (detail) => {\n const d = detail as PostProcessParamsUpdateSizeMismatchDetail;\n return (\n `PostProcessParams.data byteLength is ${d.actualLength} but the registered ` +\n `params.byteSize is ${d.byteSize}. The per-frame data-driven write must match ` +\n 'the registered byteSize exactly; check the PostProcessParams.data you assign each frame.'\n );\n },\n },\n} satisfies Record<\n string,\n {\n readonly expected: string;\n readonly hint: (detail: unknown) => string;\n }\n>;\n\nclass PostProcessErrorClass<C extends PostProcessErrorCode> extends Error {\n readonly code: C;\n readonly expected: string;\n readonly hint: string;\n readonly detail: PostProcessErrorDetailFor<C>;\n\n constructor(args: { code: C; detail: PostProcessErrorDetailFor<C> }) {\n const policy = POST_PROCESS_POLICY[args.code];\n const hint = policy.hint(args.detail);\n super(`post-process: ${args.code} (${hint})`);\n this.name = 'PostProcessError';\n this.code = args.code;\n this.expected = policy.expected;\n this.hint = hint;\n this.detail = args.detail;\n }\n}\n\n/**\n * Variant intersection: a `PostProcessErrorClass` instance whose `code` literal narrows to\n * `C` and whose `detail` narrows to `PostProcessErrorDetailFor<C>`, so `if (err.code === 'X')`\n * simultaneously narrows `err.detail` (charter P3 + P4 discriminated union).\n */\ntype PostProcessErrorVariant<C extends PostProcessErrorCode> = PostProcessErrorClass<C> & {\n readonly code: C;\n readonly detail: PostProcessErrorDetailFor<C>;\n};\n\ninterface PostProcessErrorConstructor {\n new <C extends PostProcessErrorCode>(args: {\n code: C;\n detail: PostProcessErrorDetailFor<C>;\n }): PostProcessErrorVariant<C>;\n readonly prototype: PostProcessErrorClass<PostProcessErrorCode>;\n}\n\n/**\n * Public PostProcessError type - mapped from the authoritative code union.\n *\n * ```ts\n * function recover(err: PostProcessError): string {\n * switch (err.code) {\n * case 'post-process-already-registered': return `id taken: ${err.detail.id}`;\n * case 'post-process-not-found': return `bad id: ${err.detail.id}`;\n * case 'fullscreen-input-not-found': return `bad reads key: ${err.detail.readsKey} on pass ${err.detail.passName}`;\n * }\n * }\n * ```\n */\nexport type PostProcessError = {\n [C in PostProcessErrorCode]: PostProcessErrorVariant<C>;\n}[PostProcessErrorCode];\n\n/**\n * PostProcessError constructor - `new PostProcessError({ code, detail })`.\n *\n * The generic `C` is inferred from the literal `code` argument, which narrows `detail` to\n * the per-code payload (`PostProcessErrorDetailFor<C>`) and narrows the return type to the\n * corresponding `PostProcessErrorVariant<C>` so the call site walks the discriminated union\n * without manual cast (AppError pattern; TS class declarations cannot directly express\n * `<C> ... PostProcessErrorVariant<C>` polymorphism, hence the typed-cast affordance).\n */\nexport const PostProcessError: PostProcessErrorConstructor = PostProcessErrorClass;\n","// @forgeax/engine-render - SSAO parameter authority.\n\nimport { err, ok, type Result } from '@forgeax/engine-types';\nimport { PostProcessError } from './post-process-errors';\n\nexport const SSAO_DEFAULT_RADIUS = 0.5;\nexport const SSAO_DEFAULT_BIAS = 0.025;\nexport const SSAO_DEFAULT_INTENSITY = 1.0;\n\nexport interface SsaoParameterConfig {\n readonly radius?: number | undefined;\n readonly bias?: number | undefined;\n readonly intensity?: number | undefined;\n}\n\nexport interface ResolvedSsaoParameters {\n readonly radius: number;\n readonly bias: number;\n readonly intensity: number;\n}\n\n/**\n * Apply the public defaults without deciding whether the values are valid.\n * The record stage uses this only after the graph build has validated the\n * active HDRP configuration, or for the disabled/default fallback payload.\n */\nexport function getSsaoParameters(config: SsaoParameterConfig | undefined): ResolvedSsaoParameters {\n return {\n radius: config?.radius ?? SSAO_DEFAULT_RADIUS,\n bias: config?.bias ?? SSAO_DEFAULT_BIAS,\n intensity: config?.intensity ?? SSAO_DEFAULT_INTENSITY,\n };\n}\n\n/**\n * Resolve and validate the SSAO configuration used by both graph routes.\n * Invalid values remain structured PostProcessErrors instead of becoming\n * NaNs or silently falling back to shader literals.\n */\nexport function resolveSsaoParameters(\n config: SsaoParameterConfig | undefined,\n): Result<ResolvedSsaoParameters, PostProcessError> {\n const resolved = getSsaoParameters(config);\n if (resolved.radius <= 0) {\n return err(\n new PostProcessError({\n code: 'ssao-radius-non-positive',\n detail: { paramName: 'radius', value: resolved.radius },\n }),\n );\n }\n if (resolved.bias < 0) {\n return err(\n new PostProcessError({\n code: 'ssao-bias-negative',\n detail: { paramName: 'bias', value: resolved.bias },\n }),\n );\n }\n return ok(resolved);\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: helpers.\n// Extracted from render-system-record.ts (feat-20260704 M3/w17, pure move).\n\nimport { resolveAssetHandle } from '@forgeax/engine-assets-runtime';\nimport type { World } from '@forgeax/engine-ecs';\nimport { type Mat4, mat4 } from '@forgeax/engine-math';\nimport type { EquirectAsset } from '@forgeax/engine-types';\nimport { toShared } from '@forgeax/engine-types';\nimport { EquirectProjectionFailedError } from '../errors/render';\nimport { isStandardPbrMaterialShader } from '../pbr-pipeline';\nimport type { CameraSnapshot } from '../render-contract';\nimport type { MaterialSnapshot, SkyboxSnapshot, SkylightSnapshot } from '../render-system-extract';\nimport type { RenderFrameState } from './frame-snapshot';\nimport type { RenderSystemInternals } from './render-context';\n\n/** Convert pass-owned shader definitions into the manifest's canonical variant key. */\nexport function variantSetFromDefines(\n defines: Readonly<Record<string, string>> | undefined,\n): string | undefined {\n if (defines === undefined) return undefined;\n const entries = Object.entries(defines);\n if (entries.length === 0) return undefined;\n return entries\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([name, value]) => `${name}=${value}`)\n .join('+');\n}\n\n/**\n * Select the equirect source for the shared lazy projection.\n *\n * Skylight uses handle 0 as a real \"solid-color ambient\" sentinel, so nullish\n * coalescing cannot distinguish \"no equirect\" from a valid snapshot. Prefer a\n * non-zero Skylight handle and fall back to SkyboxBackground otherwise.\n */\nexport function selectLazyEquirectHandle(\n skylight: Pick<SkylightSnapshot, 'equirectHandle'> | undefined,\n skybox: Pick<SkyboxSnapshot, 'equirectHandle'> | undefined,\n): number {\n const skylightHandle = skylight?.equirectHandle ?? 0;\n return skylightHandle !== 0 ? skylightHandle : (skybox?.equirectHandle ?? 0);\n}\n\n/**\n * feat-20260608-multi-light-warn-once M3: warn-once latch for directional\n * N>1 overrun. Fires console.warn at most once per RenderSystem lifetime.\n * Extracted as a pure helper so the warn-once logic is directly testable\n * without a full recordFrame argument list (AC-05 (c)).\n */\nexport function warnMultiLightDirectional(\n frameState: Pick<RenderFrameState, 'warnedMultiLightDirectional'>,\n directionalCount: number,\n envOverride?: { env?: { NODE_ENV?: string } },\n): void {\n if (!frameState.warnedMultiLightDirectional && directionalCount > 1) {\n frameState.warnedMultiLightDirectional = true;\n const env =\n envOverride ?? (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\n if (env?.env?.NODE_ENV !== 'production') {\n console.warn(\n '[forgeax] render-system-multi-light directional: at most 1 entity (got N=' +\n directionalCount +\n '). First entity used; rest dropped.',\n {\n code: 'render-system-multi-light',\n expected: 'at most 1 directional',\n detail: { type: 'directional', got: directionalCount },\n },\n );\n }\n }\n}\n\n/**\n * feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M3 / w19:\n * once-warn for >1 Skylight entity (first archetype hit wins). Fires at most\n * once per RenderSystem lifetime and names the WINNING entity handle so the\n * scene author can tell which Skylight is used and that the rest are ignored\n * (F-8: warn carries conflicting entity info; charter P3 explicit failure with\n * a warn-once signal floor, no per-frame flooding).\n */\nexport function warnMultiSkylight(\n frameState: Pick<RenderFrameState, 'warnedMultiSkylight'>,\n skylightCount: number,\n winningEntityHandle: number,\n): void {\n if (!frameState.warnedMultiSkylight && skylightCount > 1) {\n frameState.warnedMultiSkylight = true;\n console.warn(\n `[forgeax] Skylight: ${skylightCount} Skylight entities found; using entity ` +\n `${winningEntityHandle} (first by archetype order) for IBL ambient. The other ` +\n `${skylightCount - 1} Skylight ${skylightCount - 1 === 1 ? 'entity is' : 'entities are'} ignored. ` +\n `Keep a single Skylight per scene, or reorder so the intended one is first.`,\n );\n }\n}\n\n/**\n * feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M3 / w19:\n * once-warn for >1 SkyboxBackground entity (mirrors warnMultiSkylight). Names\n * the winning entity handle; fires once per RenderSystem lifetime.\n */\nexport function warnMultiSkybox(\n frameState: Pick<RenderFrameState, 'warnedMultiSkybox'>,\n skyboxCount: number,\n winningEntityHandle: number,\n): void {\n if (!frameState.warnedMultiSkybox && skyboxCount > 1) {\n frameState.warnedMultiSkybox = true;\n console.warn(\n `[forgeax] SkyboxBackground: ${skyboxCount} SkyboxBackground entities found; using ` +\n `entity ${winningEntityHandle} (first by archetype order). The other ` +\n `${skyboxCount - 1} ${skyboxCount - 1 === 1 ? 'entity is' : 'entities are'} ignored. ` +\n `Keep a single SkyboxBackground per scene.`,\n );\n }\n}\n\n/**\n * feat-20260630-equirect-kind-internalized-ibl-declarative-skyligh M3 / w18:\n * lazy equirect-to-cubemap projection trigger. Driven once per frame from\n * `recordFrame` for the active equirect handle (Skylight's, or the\n * SkyboxBackground's when no Skylight cubemap is present -- both reuse one\n * handle). Implements the plan-strategy D-4 state machine:\n *\n * undefined (no entry) -> resolve POD + fire-and-forget projection; the\n * store selects rgba8 output on WebGL2\n * (the store writes status:'pending'\n * synchronously, so this launches once)\n * pending -> in flight; bind white fallback (no fire)\n * ready -> bound by recordMainPass's IBL cache check\n * failed -> fire EquirectProjectionFailedError ONCE\n * per handle (R-2/AC-09 no retry)\n * Fire-and-forget: `_uploadCubemapFromEquirect` is invoked WITHOUT await so the\n * record stay synchronous; the store mutates its own status map and (on\n * success) the per-device IblPipelineCache, which recordMainPass reads on a\n * later frame. The structured error from a fire-and-forget failure is reported\n * via the explicit `status === 'failed'` arm here (read on the next frame), not\n * by awaiting the promise (which would block record).\n */\nexport function driveLazyEquirectProjection(\n internals: RenderSystemInternals,\n world: World,\n frameState: Pick<RenderFrameState, 'firedEquirectProjectionFailedHandles'>,\n equirectHandle: number,\n): void {\n const store = internals.gpuStore;\n const handle = toShared<'EquirectAsset'>(equirectHandle);\n const status = store.getCubemapStatus(handle);\n\n if (status === 'failed') {\n // Fire the structured error exactly once per failed source (the store\n // records failed permanently and never retries; R-2 / AC-09).\n if (!frameState.firedEquirectProjectionFailedHandles.has(equirectHandle)) {\n frameState.firedEquirectProjectionFailedHandles.add(equirectHandle);\n internals.errorRegistry.fire(new EquirectProjectionFailedError(equirectHandle));\n }\n return;\n }\n\n // 'pending' and 'ready' are both handled downstream (white fallback while\n // pending; real IBL once ready). Only the first sight ('undefined') launches.\n if (status !== undefined) return;\n\n // First sight: resolve the equirect POD and fire-and-forget the projection.\n const podRes = resolveAssetHandle<EquirectAsset>(world, handle);\n if (!podRes.ok || podRes.value.kind !== 'equirect') {\n // The handle does not resolve to a live equirect POD (stale / wrong kind).\n // Launch nothing; the store stays empty and the white fallback holds. The\n // skybox / IBL degradation paths surface the missing resource per their own\n // gates -- this trigger only drives a valid equirect source.\n return;\n }\n // Fire-and-forget: do NOT await. The store writes status:'pending'\n // synchronously (before its first await), so a re-entry next frame\n // short-circuits and this launches exactly once.\n void store._uploadCubemapFromEquirect(world, handle, podRes.value);\n}\n\n/**\n * Returns true when a MaterialSnapshot uses a builtin standard/PBR shader\n * that will render black with zero lights.\n *\n * The default mid-grey fallback (materialShaderId === undefined) is excluded\n * — it routes through defaultMaterialSnapshot and never triggers the\n * zero-light warning. Custom shaders are also excluded: their lighting\n * contract is authored by the shader and cannot be inferred from this\n * generic diagnostic.\n *\n * @internal — exported so AC-02 zero-light-warning test can anchor to\n * the production implementation rather than a test-local copy.\n */\nexport function isLitMaterialSnapshot(material: MaterialSnapshot): boolean {\n return isStandardPbrMaterialShader(material.materialShaderId);\n}\n\nexport function computeViewMatrix(camera: CameraSnapshot): Mat4 {\n // feat-20260601 D-3: view = invert(camera world mat4). The camera's resolved\n // world mat4 (propagateTransforms output) is read straight off the snapshot;\n // no recompose from decomposed TRS.\n const cameraFromWorld = mat4.create();\n mat4.invert(cameraFromWorld, camera.world);\n return cameraFromWorld;\n}\n\nexport function computeProjectionMatrix(camera: CameraSnapshot): Mat4 {\n // feat-20260613 M6 / w20: branch on projection variant. The view UBO\n // record path needs the right matrix shape so the main pass renders\n // correctly under both perspective and orthographic cameras (mirrors\n // the CSM extract fix in render-system-extract.ts).\n const proj = mat4.create();\n if (camera.projection === 'orthographic') {\n mat4.orthographic(\n proj,\n camera.orthoLeft,\n camera.orthoRight,\n camera.orthoBottom,\n camera.orthoTop,\n camera.near,\n camera.far,\n );\n } else {\n mat4.perspective(proj, camera.fov, camera.aspect, camera.near, camera.far);\n }\n return proj;\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: view-ubo.\n// feat-20260704 M3/w18: the View UBO + CSM/spot-shadow matrix pack assembly\n// extracted verbatim from `recordFrame` (frame.ts). Builds the 240-float View\n// UBO payload (worldViewProj, directional light, camera pos, per-cascade\n// lightViewProj matrices, split planes, shadow bias, folded spot lightViewProj\n// lanes) and flushes it in one queue.writeBuffer round-trip. Kept as a\n// standalone function so recordFrame stays an orchestration skeleton (D-2).\n\nimport { mat4 } from '@forgeax/engine-math';\nimport type { Buffer, RhiQueue } from '@forgeax/engine-rhi';\nimport type { DirectionalShadowQuality } from '../components/directional-shadow-filter';\nimport type { PointsLinesStyle } from '../points-lines/snapshot';\nimport type { CameraSnapshot } from '../render-contract';\nimport type {\n DirectionalLightSnapshot,\n ExtractedLights,\n SpotLightSnapshot,\n} from '../render-system-extract';\nimport { SHADOW_ATLAS_DEFAULT_LAYERS } from '../shadow-atlas';\nimport type { TemporalView as LegacyTemporalView } from '../temporal/temporal-view';\nimport type { TemporalView } from '../temporal/view';\nimport { computeProjectionMatrix, computeViewMatrix } from './helpers';\n\nexport const VIEW_UNIFORM_BYTES = 960;\nexport const POINTS_LINES_VIEW_BYTES = 160;\nexport const POINTS_LINES_VIEW_SLOT_STRIDE = 256;\nexport const POINTS_LINES_VIEW_SLOT_COUNT = 1024;\nexport const POINTS_LINES_VIEW_BUFFER_SIZE =\n POINTS_LINES_VIEW_SLOT_STRIDE * POINTS_LINES_VIEW_SLOT_COUNT;\nexport const VIEW_UNIFORM_SLOT_STRIDE = 1024;\nexport const POINT_SHADOW_VIEW_SLOT_COUNT = 24;\nexport const CUBE_CAPTURE_VIEW_SLOT_BASE = 1 + POINT_SHADOW_VIEW_SLOT_COUNT;\nexport const REFLECTION_PROBE_VIEW_SLOT_BASE = CUBE_CAPTURE_VIEW_SLOT_BASE + 6;\nexport const REFLECTION_PROBE_VIEW_SLOT_COUNT = 16;\nexport const VIEW_UNIFORM_BUFFER_SIZE =\n VIEW_UNIFORM_SLOT_STRIDE * (REFLECTION_PROBE_VIEW_SLOT_BASE + REFLECTION_PROBE_VIEW_SLOT_COUNT);\n\nexport function pointShadowViewOffset(layer: number, face: number): number {\n return VIEW_UNIFORM_SLOT_STRIDE * (1 + layer * 6 + face);\n}\n\n/** Project the accepted Directional quality union into the frozen View ABI. */\nfunction directionalShadowFilterCarrier(\n quality: DirectionalShadowQuality | undefined,\n): readonly [number, number, number, number] {\n if (quality === undefined) return [0, 0, 0, 0];\n if (quality.kind === 'pcss') {\n return [\n quality.preset === 'medium' ? 4 : 5,\n quality.angularRadiusRadians,\n quality.maxPenumbraTexels,\n 0,\n ];\n }\n switch (quality.kernel) {\n case 1:\n return [1, 0, 0, 0];\n case 3:\n return [2, 0, 0, 0];\n case 5:\n return [3, 0, 0, 0];\n }\n}\n\nexport function writePointsLinesViewUbo(\n queue: RhiQueue,\n buffer: Buffer,\n camera: CameraSnapshot,\n width: number,\n height: number,\n model?: ArrayLike<number>,\n style?: PointsLinesStyle,\n byteOffset = 0,\n): void {\n const projection = computeProjectionMatrix(camera);\n const view = computeViewMatrix(camera);\n const worldViewProj = mat4.create();\n mat4.multiply(worldViewProj, projection, view);\n const payload = new Float32Array(40);\n payload.set(worldViewProj);\n if (model === undefined) {\n payload[16] = 1;\n payload[21] = 1;\n payload[26] = 1;\n payload[31] = 1;\n } else {\n for (let index = 0; index < 16; index += 1) {\n payload[16 + index] = model[index] ?? 0;\n }\n }\n payload[32] = width;\n payload[33] = height;\n if (style?.kind === 'points') {\n payload[36] = style.sizePx;\n payload[38] = style.shape === 'circle' ? 1 : 0;\n } else if (style?.kind === 'lines') {\n payload[36] = style.widthPx;\n payload[37] = 1;\n } else {\n payload[36] = 1;\n }\n const uploaded = queue.writeBuffer(buffer, byteOffset, payload);\n if (!uploaded.ok) throw uploaded.error;\n}\n\n/**\n * feat-20260704 M3/w18: assemble + upload the per-frame View UBO payload.\n *\n * feat-20260518 M3 / w14 (AC-07 / AC-09): builds the full view UBO payload.\n * Single queue.writeBuffer covers the whole payload (one round-trip per frame,\n * charter P5 consistent abstraction). Outgoing-direction convention\n * (DirectionalLight @semantics outgoing): the host uploads light.direction\n * verbatim; the shader negates it internally via\n * `let l = normalize(-view.lightDir)` to get the L vector for BRDF (single\n * SSOT, no double-negation).\n *\n * feat-20260520-directional-light-shadow-mapping M1b / w7 + feat-20260613-csm\n * M4 / w16+w25: viewPayload is 240 floats. Layout matches common.wgsl View\n * struct byte-for-byte:\n * [ 0..15] worldViewProj, [16..18] lightDir, [20..22] lightColor,\n * [24..26] cameraPos, [28..43] lightViewProj0 (was lightSpaceMatrix),\n * [44..59] inverseViewProj, [60..75] lightViewProj1,\n * [76..91] lightViewProj2, [92..107] lightViewProj3,\n * [108..123] splitPlanes (vec4 lanes: split/world texel/depth span/reserved),\n * [124] cascadeCount, [125] cascadeBlend,\n * [126] depthBias, [127] normalBias,\n * [128..131] directionalShadowFilter (profile/radius/max penumbra/reserved),\n * [132..195] spotLightViewProj array<mat4x4<f32>, 4> (feat-20260625 w25:\n * folded from standalone binding 9 to fix WebGL2 fragment uniform-buffer\n * overflow; lane N = spot with shadowAtlasTile === N, 16 f32 / lane,\n * 16 B-aligned at byte 528 = float 132).\n *\n * @internal\n */\nexport function writeViewUbo(\n queue: RhiQueue,\n viewUniformBuffer: Buffer,\n camera: CameraSnapshot,\n light: DirectionalLightSnapshot,\n lights: ExtractedLights,\n spotShadowSnapshots: readonly SpotLightSnapshot[],\n temporalOrOffset?: TemporalView | LegacyTemporalView | number,\n projectorSpotIndex?: number,\n): void {\n const byteOffset = typeof temporalOrOffset === 'number' ? temporalOrOffset : 0;\n const resolvedTemporal = typeof temporalOrOffset === 'number' ? undefined : temporalOrOffset;\n // Compose worldViewProj once per frame (view * proj).\n const projMatrix = computeProjectionMatrix(camera);\n const viewMatrix = computeViewMatrix(camera);\n const unjitteredViewProjection = mat4.create();\n mat4.multiply(unjitteredViewProjection, projMatrix, viewMatrix);\n const jitteredProjection = mat4.create();\n if (resolvedTemporal?.currentJitterUv !== undefined) {\n const jitter = mat4.identity(mat4.create());\n jitter[12] = resolvedTemporal.currentJitterUv[0] * 2;\n jitter[13] = resolvedTemporal.currentJitterUv[1] * -2;\n mat4.multiply(jitteredProjection, jitter, projMatrix);\n } else {\n for (let i = 0; i < 16; i += 1) jitteredProjection[i] = projMatrix[i] ?? 0;\n }\n const mainProjection = mat4.create();\n mat4.multiply(mainProjection, jitteredProjection, viewMatrix);\n\n const VIEW_PAYLOAD_FLOATS = 240;\n const viewPayload = new Float32Array(VIEW_PAYLOAD_FLOATS);\n for (let i = 0; i < 16; i++) viewPayload[i] = mainProjection[i] ?? 0;\n viewPayload[16] = (light.direction[0] ?? 0) * light.intensity;\n viewPayload[17] = (light.direction[1] ?? -1) * light.intensity;\n viewPayload[18] = (light.direction[2] ?? 0) * light.intensity;\n viewPayload[20] = light.color[0] ?? 0;\n viewPayload[21] = light.color[1] ?? 0;\n viewPayload[22] = light.color[2] ?? 0;\n viewPayload[24] = camera.position[0] ?? 0;\n viewPayload[25] = camera.position[1] ?? 0;\n viewPayload[26] = camera.position[2] ?? 0;\n // lightViewProj[0] at [28..43] (replaces lightSpaceMatrix).\n if (lights.lightViewProj !== undefined && lights.lightViewProj[0] !== undefined) {\n for (let i = 0; i < 16; i++) viewPayload[28 + i] = lights.lightViewProj[0][i] ?? 0;\n }\n // inverseViewProj at [44..59] — unchanged position.\n // Host pre-computes mat4.invert so the skybox fragment shader avoids\n // per-pixel matrix inversion (charter P4 consistent abstraction).\n const inverseViewProj = mat4.create();\n mat4.invert(inverseViewProj, mainProjection);\n for (let i = 0; i < 16; i++) viewPayload[44 + i] = inverseViewProj[i] ?? 0;\n // lightViewProj[1..3] at [60..107].\n if (lights.lightViewProj !== undefined) {\n for (let c = 1; c <= 3; c++) {\n const base = 60 + (c - 1) * 16;\n const lvp = lights.lightViewProj[c];\n if (lvp !== undefined) {\n for (let i = 0; i < 16; i++) viewPayload[base + i] = lvp[i] ?? 0;\n }\n }\n }\n\n // Temporal ABI tail: current and last-successful unjittered projections\n // stay separate from the jittered main projection and never advance on a\n // failed submission. The fixed 240-float payload already reserves these\n // 36 slots at byte offsets 784..920.\n const previous = resolvedTemporal?.previousUnjitteredViewProjection;\n for (let i = 0; i < 16; i += 1) {\n viewPayload[196 + i] = unjitteredViewProjection[i] ?? 0;\n // No previous successful frame exists on first frame/reset. Keep this\n // lane zeroed instead of copying current state into a history slot.\n viewPayload[212 + i] = previous?.[i] ?? 0;\n }\n viewPayload[228] = camera.near;\n viewPayload[229] = camera.far;\n viewPayload[230] = camera.projection === 'orthographic' ? 1 : 0;\n const previousCameraPosition =\n resolvedTemporal !== undefined && 'previousCameraPosition' in resolvedTemporal\n ? resolvedTemporal.previousCameraPosition\n : undefined;\n if (previousCameraPosition !== undefined) {\n viewPayload[232] = previousCameraPosition[0] ?? 0;\n viewPayload[233] = previousCameraPosition[1] ?? 0;\n viewPayload[234] = previousCameraPosition[2] ?? 0;\n viewPayload[235] = 1;\n }\n // splitPlanes at [108..123] (four vec4 lanes: split/world texel/depth span/reserved).\n if (lights.splitPlanes !== undefined) {\n for (let s = 0; s < 4; s++) {\n for (let lane = 0; lane < 4; lane++) {\n viewPayload[108 + s * 4 + lane] = lights.splitPlanes[s * 4 + lane] ?? 0;\n }\n }\n }\n // cascadeCount / cascadeBlend at [124..125].\n viewPayload[124] = lights.cascadeCount ?? 0;\n viewPayload[125] = lights.cascadeBlend ?? 0;\n // M1 directional shadow carrier: bias remains at [126]/[127], while the\n // accepted quality union occupies the existing four-float tail [128..131].\n // Point and Spot pcfKernelSize stay in their own snapshot paths and never\n // enter this Directional View projection.\n viewPayload[126] = lights.depthBias ?? 0.005;\n viewPayload[127] = lights.normalBias ?? 0.05;\n const filterCarrier = directionalShadowFilterCarrier(lights.directionalShadowQuality);\n viewPayload[128] = filterCarrier[0] ?? 0;\n viewPayload[129] = filterCarrier[1] ?? 0;\n viewPayload[130] = filterCarrier[2] ?? 0;\n viewPayload[131] = filterCarrier[3] ?? 0;\n\n // feat-20260625-spot-light-shadow-mapping w25 (scope-amend webkit-fallback):\n // spotLightViewProj array<mat4x4<f32>, 4> at floats [132..195] (byte 528,\n // 16 B-aligned after directionalShadowFilter). Lane N = the spot with\n // `shadowAtlasTile === N` (cap = 4); the perspective matrix was already\n // computed by the extract stage (SpotLightSnapshot.lightViewProj) — record\n // never recomputes it (Derive). The accepted projector is identified by its\n // spot index, not by a negative shadow tile: a projector-only spot publishes\n // its matrix in lane 0 so the shader never samples a zero matrix. Shadowed\n // projector spots keep their shadow tile lane and carry the projector bit in\n // the DirectLightSlot identity word.\n // Folded from the former standalone binding 9 UBO to keep the WebGL2\n // fallback fragment uniform-buffer count <= 11 (GLES 3.0).\n {\n const SPOT_LVP_BASE_FLOAT = 132;\n const SPOT_LVP_LANE_COUNT = 4;\n const SPOT_LVP_FLOATS_PER_LANE = 16;\n const spotSnaps = spotShadowSnapshots;\n for (let i = 0; i < spotSnaps.length; i++) {\n const ss = spotSnaps[i];\n if (ss === undefined) continue;\n const tile = ss.shadowAtlasTile;\n const lvp = ss.lightViewProj;\n if (lvp === undefined) continue;\n const lane =\n tile >= 0 && tile < SPOT_LVP_LANE_COUNT ? tile : i === projectorSpotIndex ? 0 : -1;\n if (lane < 0) continue;\n const base = SPOT_LVP_BASE_FLOAT + lane * SPOT_LVP_FLOATS_PER_LANE;\n for (let f = 0; f < SPOT_LVP_FLOATS_PER_LANE; f++) {\n viewPayload[base + f] = lvp[f] ?? 0;\n }\n }\n }\n\n const viewUploadResult = queue.writeBuffer(viewUniformBuffer, byteOffset, viewPayload);\n if (!viewUploadResult.ok) throw viewUploadResult.error;\n\n for (const snapshot of lights.pointShadow ?? []) {\n if (snapshot.shadowAtlasLayer < 0 || snapshot.shadowAtlasLayer >= SHADOW_ATLAS_DEFAULT_LAYERS)\n continue;\n for (let face = 0; face < 6; face += 1) {\n const facePayload = viewPayload.slice();\n const matrix = snapshot.shadowMatrices.subarray(face * 16, (face + 1) * 16);\n facePayload.set(matrix, 28);\n const uploaded = queue.writeBuffer(\n viewUniformBuffer,\n pointShadowViewOffset(snapshot.shadowAtlasLayer, face),\n facePayload,\n );\n if (!uploaded.ok) throw uploaded.error;\n }\n }\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: per-frame lighting.\n// feat-20260704 M5/w31: further-split from frame.ts (AC-05 <=1500 lines/file).\n// Pure leaf helpers invoked once each from recordFrame; behavior verbatim.\n\nimport { mat4, vec3 } from '@forgeax/engine-math';\nimport {\n type BindGroup,\n type BindGroupEntry,\n type BindGroupLayout,\n type RhiDevice,\n RhiError,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport { err, ok, type Result, toShared } from '@forgeax/engine-types';\nimport {\n PointShadowAtlasBoundsViolationError,\n PointShadowAtlasUninitializedError,\n type RenderError,\n RendererOperationError,\n StandardClusterTransportUnavailableError,\n} from '../errors/render';\nimport {\n createHdrpClusterMembershipBindGroup,\n createHdrpUnifiedBindGroup,\n getOrCreateHdrpBuffers,\n packClusterUniform,\n} from '../hdrp-buffers';\nimport { DIRECT_LIGHT_SLOT_FLOAT_COUNT, packDirectLightSlot } from '../light-buffer-layout';\nimport {\n type PreparedStandardLighting,\n prepareStandardLighting,\n} from '../pipeline/standard-lighting/prepare';\nimport type { StandardTopologyInputValue } from '../pipeline/standard-lighting/topology';\nimport {\n type StandardClusterTransport,\n selectStandardClusterTransport,\n} from '../pipeline/standard-lighting/transport';\nimport { DEFAULT_CLUSTER_GRID, DEFAULT_STANDARD_PROFILE } from '../pipeline/standard-profile';\nimport {\n COOKIE_MATRIX_BYTES,\n COOKIE_SLICE_SIZE,\n IES_SLICE_HEIGHT,\n IES_SLICE_WIDTH,\n} from '../prepare/extended-lighting/resources';\nimport type { ReflectionProbeTable } from '../reflection/gpu-table';\nimport type { ReflectionProbeSelectionResult } from '../reflection/projection';\nimport type { CameraSnapshot, RenderHdrpClusterPhase } from '../render-contract';\nimport type {\n DirectionalLightSnapshot,\n ExtractedLights,\n RenderableSnapshot,\n SkyboxSnapshot,\n SkylightSnapshot,\n} from '../render-system-extract';\nimport {\n SHADOW_ATLAS_DEFAULT_FACE_SIZE,\n SHADOW_ATLAS_DEFAULT_LAYERS,\n ShadowAtlas,\n} from '../shadow-atlas';\nimport { getOrCreateSsaoBuffers } from '../ssao-buffers';\nimport { getSsaoParameters } from '../ssao-config';\n// extendedLighting keeps Spot modifier factors on the existing light record\n// path; no additional render pass or submit owner is introduced.\nimport type { BindGroupCounts, RenderFrameState } from './frame-snapshot';\nimport {\n computeProjectionMatrix,\n computeViewMatrix,\n isLitMaterialSnapshot,\n warnMultiLightDirectional,\n} from './helpers';\nimport { getOrCreateFromChain, MESH_SSBO_BYTES, MESH_UBO_FULL_ARRAY_BYTES } from './mesh-ssbo';\nimport type { PipelineState, RecordProfileRunner, RenderSystemInternals } from './render-context';\nimport { POINTS_LINES_VIEW_BYTES, VIEW_UNIFORM_BYTES } from './view-ubo';\n\nexport interface StandardReflectionProbeBinding {\n readonly probeIndex: number | undefined;\n readonly useSkylight: boolean;\n}\n\nexport function resolveReflectionProbeBinding(\n selection: ReflectionProbeSelectionResult,\n table?: ReflectionProbeTable,\n): StandardReflectionProbeBinding {\n if (selection.kind !== 'probe') return { probeIndex: undefined, useSkylight: true };\n const primitiveKey = `${selection.worldId}:${selection.entityKey}`;\n const tableIndex = table?.cpuIndexByPrimitive(primitiveKey);\n return { probeIndex: tableIndex ?? selection.entityKey, useSkylight: false };\n}\n\nexport function projectDeviceOwnedBindGroup<T>(\n state:\n | {\n readonly device: RhiDevice;\n readonly layout: BindGroupLayout;\n readonly bindGroup: T;\n }\n | null\n | undefined,\n device: RhiDevice,\n layout: BindGroupLayout | null,\n): T | null {\n return state !== null && state !== undefined && state.device === device && state.layout === layout\n ? state.bindGroup\n : null;\n}\n\nfunction runHdrpClusterProfilePhase<T>(\n runner: RecordProfileRunner | undefined,\n phase: RenderHdrpClusterPhase,\n action: () => T,\n): T {\n return runner === undefined ? action() : runner(phase, action);\n}\n\nfunction mapClusterUploadFailure(\n resource: string,\n error: {\n readonly code: string;\n readonly expected: string;\n readonly hint: string;\n readonly detail?: unknown;\n },\n): RendererOperationError<'device-operation-failed'> {\n return new RendererOperationError('device-operation-failed', {\n operation: 'draw',\n cause: {\n code: error.code,\n expected: `queue.writeBuffer succeeds for Standard Cluster ${resource}`,\n hint: `repair the device write for Standard Cluster ${resource} and retry the frame`,\n detail: error,\n },\n });\n}\n\n/**\n * feat-20260704 M3/w18: per-frame bind-group cache resolution, extracted\n * verbatim from `recordFrame`. Walks the handle-identity WeakMap caches\n * (feat-20260531 M2 + feat-20260622 M3) to resolve or lazily create the view\n * (@group 0), mesh (@group 2), and — when HDRP is active — HDRP-unified cluster\n * bind groups. Returns all three (null when `hasValidated` is false, the Case E\n * clear-pass-only path). No new mutable state: `bindGroupCounts` accounting +\n * cache maps are threaded through explicitly.\n *\n * @internal\n */\nexport function buildPerFrameBindGroups(\n internals: RenderSystemInternals,\n frameState: RenderFrameState,\n pipelineState: PipelineState,\n hasValidated: boolean,\n bindGroupCounts: BindGroupCounts,\n graphTargets?: {\n readonly directionalShadow?: TextureView | undefined;\n readonly spotShadow?: TextureView | undefined;\n readonly projector?: TextureView | undefined;\n readonly projectorSampler?: import('@forgeax/engine-rhi').Sampler | undefined;\n },\n includeView = true,\n standardLighting?: StandardTopologyInputValue,\n): {\n viewBindGroup: BindGroup | null;\n meshBindGroup: BindGroup | null;\n hdrpClusterBindGroup: BindGroup | null;\n hdrpClusterMembershipBindGroup: BindGroup | null;\n} {\n // View main (#1) chain = b0(viewUniformBuffer), b3(graph shadowDepth view or\n // shadowFallbackTextureView), b4(shadowSampler), b5(atlas view), b6\n // (shadowParams); variant 'view-main'. Local lights are never mirrored in\n // the view group: Standard consumes the one Cluster group(2) payload.\n // Mesh (#2) chain = inner b0 buffer (meshStorageBuffer.buffer); variant 'mesh'.\n let viewBindGroup: BindGroup | null = null;\n let meshBindGroup: BindGroup | null = null;\n // Standard clustered group(2) bind group. Non-null when the prepared\n // topology selects the cluster transport and its persistent allocation\n // succeeds; consumed by recordMainPass at `setBindGroup(2, ...)`.\n let hdrpClusterBindGroup: BindGroup | null = null;\n // The prepared Standard topology is the per-frame authority for whether\n // group(2) carries Cluster storage. A missing declaration is the prewarm /\n // non-Standard path and must not allocate or bind the Cluster bundle based\n // on the install-time pipeline identity alone.\n const clusteredLighting = standardLighting?.kind === 'clustered';\n const membershipLayout = pipelineState.hdrpClusterMembershipBindGroupLayout;\n const membership = frameState.hdrpClusterMembership;\n const expectedHdrpBuffers =\n hasValidated && clusteredLighting\n ? getOrCreateHdrpBuffers(internals, frameState.installedPipelineConfig?.clusterGrid)\n : null;\n const currentMembership =\n expectedHdrpBuffers !== null &&\n membership?.clusterGridBuffer === expectedHdrpBuffers.clusterGridBuffer\n ? projectDeviceOwnedBindGroup(membership, internals.device, membershipLayout)\n : null;\n if (membership !== null && currentMembership === null) {\n frameState.hdrpClusterMembership = null;\n }\n const hdrpClusterMembershipBindGroup: BindGroup | null = clusteredLighting\n ? currentMembership\n : null;\n if (hasValidated) {\n // Shadow atlas view comes from the typed graph target.\n // Graph owns the texture lifecycle; record-stage reads the resolved\n // view each frame (D-2 SSOT). When the graph has not allocated the\n // target (castShadow:false or shadowMapSize=0),\n // `getColorTargetView` returns undefined and we fall through to the\n // 1x1 fallback view that keeps the BGL satisfied.\n if (includeView) {\n const shadowSampler = pipelineState.perPassResources.shadowSampler;\n if (shadowSampler === null) {\n return {\n viewBindGroup: null,\n meshBindGroup: null,\n hdrpClusterBindGroup: null,\n hdrpClusterMembershipBindGroup,\n };\n }\n const graphShadowView = graphTargets?.directionalShadow;\n const b3View =\n graphShadowView !== undefined ? graphShadowView : pipelineState.shadowFallbackTextureView;\n // feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1: bind the real\n // ShadowAtlas cube_array view when point shadows are active in this\n // frame; otherwise the 1x1x6 fallback (cleared to 1.0 = fully lit).\n const pointShadowAtlas = frameState.pointShadowAtlas;\n const atlasViewMaybe = pointShadowAtlas?.isAllocated()\n ? pointShadowAtlas.getAtlasView()\n : null;\n const b5View =\n atlasViewMaybe !== null ? atlasViewMaybe : pipelineState.shadowAtlasFallbackTextureView;\n // feat-20260625-spot-light-shadow-mapping M2 / w21 (D-1 fragment side +\n // D-5): bind the real `spotShadowDepth` 2D atlas view (graph-owned) when\n // spot shadows run this frame; otherwise the 1x1 depth fallback cleared to\n // 1.0 (fully lit) — same `texture_depth_2d` shape as binding 3, so it\n // satisfies the BGL without a dedicated spot fallback allocation. binding\n // 9 always binds the real spotLightViewProj UBO (zeroed lanes are safe via\n // the shadowAtlasTile >= 0 shader gate).\n const graphSpotShadowView = graphTargets?.spotShadow;\n const b8View =\n graphSpotShadowView !== undefined\n ? graphSpotShadowView\n : pipelineState.shadowFallbackTextureView;\n const extendedLighting = pipelineState.extendedLightingAvailable ?? true;\n const iesProfileTextureView = pipelineState.iesProfileTextureView;\n const cookieTextureView = pipelineState.cookieTextureView;\n const cookieMatrixBuffer = pipelineState.cookieMatrixBuffer;\n const ltcLambertTextureView = pipelineState.ltcLambertTextureView;\n const ltcGgxTextureView = pipelineState.ltcGgxTextureView;\n const extendedLightingResources =\n extendedLighting &&\n iesProfileTextureView !== undefined &&\n cookieTextureView !== undefined &&\n cookieMatrixBuffer !== undefined &&\n ltcLambertTextureView !== undefined &&\n ltcGgxTextureView !== undefined\n ? {\n sampler: pipelineState.defaultSampler,\n iesProfileTextureView,\n cookieTextureView,\n ltcLambertTextureView,\n ltcGgxTextureView,\n cookieMatrixBuffer,\n }\n : undefined;\n if (extendedLighting && extendedLightingResources === undefined) {\n return {\n viewBindGroup: null,\n meshBindGroup: null,\n hdrpClusterBindGroup: null,\n hdrpClusterMembershipBindGroup,\n };\n }\n const extendedLightingViews =\n extendedLightingResources !== undefined\n ? [\n extendedLightingResources.sampler,\n extendedLightingResources.iesProfileTextureView,\n extendedLightingResources.cookieTextureView,\n extendedLightingResources.ltcLambertTextureView,\n extendedLightingResources.ltcGgxTextureView,\n extendedLightingResources.cookieMatrixBuffer,\n ]\n : [];\n const projectorAvailable = pipelineState.projectorAvailable !== false;\n const b11View = graphTargets?.projector ?? pipelineState.defaultWhiteTextureView;\n const b12Sampler = graphTargets?.projectorSampler ?? pipelineState.defaultSampler;\n viewBindGroup = getOrCreateFromChain(\n frameState.viewBindGroupCache,\n [\n pipelineState.viewUniformBuffer,\n b3View,\n shadowSampler,\n b5View,\n pipelineState.shadowParamsBuffer,\n b8View,\n ...extendedLightingViews,\n ...(extendedLightingResources === undefined && projectorAvailable\n ? [b11View, b12Sampler]\n : []),\n pipelineState.pointsLinesViewBuffer ?? pipelineState.viewUniformBuffer,\n ],\n 'view-main',\n () => {\n const entries: BindGroupEntry[] = [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.viewUniformBuffer, size: VIEW_UNIFORM_BYTES },\n },\n },\n {\n binding: 3,\n resource: {\n kind: 'textureView',\n value: b3View,\n },\n },\n {\n binding: 4,\n resource: {\n kind: 'sampler',\n value: shadowSampler,\n },\n },\n // feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1:\n // cube_array shadow atlas view (real ShadowAtlas when point\n // shadows are active; else 1x1x6 fallback).\n {\n binding: 5,\n resource: {\n kind: 'textureView',\n value: b5View,\n },\n },\n // feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1:\n // shadowParams UBO (`array<vec4<f32>, 4>` = 64 B). Lane N\n // stores `(near, far, 1/(far-near), 0)` for the point light\n // with shadowAtlasLayer === N. Updated per frame from\n // `pointShadowSnapshots` below.\n {\n binding: 6,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.shadowParamsBuffer },\n },\n },\n // feat-20260613-csm-cascaded-shadow-maps M5 / w28 (rebased to\n // binding 7 on 2026-06-13 to make room for point-shadow 5/6):\n // forward shaders declare binding 7 in common.wgsl (shared\n // view BGL) but never reference it; only shadow_caster.wgsl\n // reads it. Host writes a stable singleton buffer so every\n // forward bind group entry stays populated.\n {\n binding: 7,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.shadowCasterCascadeBuffer },\n },\n },\n // feat-20260625-spot-light-shadow-mapping M3 / w21 (D-5):\n // spot shadow 2D atlas (real spotShadowDepth view when spot\n // shadows run this frame, else the 1x1 depth fallback). Always-on.\n {\n binding: 8,\n resource: {\n kind: 'textureView',\n value: b8View,\n },\n },\n {\n binding: 10,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.pointsLinesViewBuffer ?? pipelineState.viewUniformBuffer,\n size: POINTS_LINES_VIEW_BYTES,\n },\n },\n },\n ...(extendedLightingResources === undefined && projectorAvailable\n ? [\n { binding: 11, resource: { kind: 'textureView' as const, value: b11View } },\n { binding: 12, resource: { kind: 'sampler' as const, value: b12Sampler } },\n ]\n : []),\n ...(extendedLightingResources !== undefined\n ? [\n {\n binding: 9,\n resource: {\n kind: 'sampler' as const,\n value: extendedLightingResources.sampler,\n },\n },\n {\n binding: 11,\n resource: {\n kind: 'textureView' as const,\n value: extendedLightingResources.iesProfileTextureView,\n },\n },\n {\n binding: 12,\n resource: {\n kind: 'textureView' as const,\n value: extendedLightingResources.cookieTextureView,\n },\n },\n {\n binding: 13,\n resource: {\n kind: 'textureView' as const,\n value: extendedLightingResources.ltcLambertTextureView,\n },\n },\n {\n binding: 14,\n resource: {\n kind: 'textureView' as const,\n value: extendedLightingResources.ltcGgxTextureView,\n },\n },\n {\n binding: 15,\n resource: {\n kind: 'buffer' as const,\n value: {\n buffer: extendedLightingResources.cookieMatrixBuffer,\n size: COOKIE_MATRIX_BYTES,\n },\n },\n },\n ]\n : []),\n // feat-20260625-spot-light-shadow-mapping w25: the per-spot\n // fragment-read lightViewProj matrices fold into the View UBO\n // (binding 0, `view.spotLightViewProj`) — no standalone binding 9\n // (WebGL2 fragment uniform-buffer budget). binding 10 is the\n // dedicated vertex-only Points/Lines viewport UBO.\n ];\n const viewBindGroupResult = internals.device.createBindGroup({\n label: 'pbr-view-bg',\n layout: pipelineState.viewBindGroupLayout,\n entries,\n });\n if (!viewBindGroupResult.ok) throw viewBindGroupResult.error;\n return viewBindGroupResult.value;\n },\n bindGroupCounts,\n );\n }\n\n // M3 / w10 (D-3 hard constraint): use the inner `.buffer` as the\n // WeakMap chain key so the cache tracks the underlying GPU buffer\n // identity. The wrapper object's identity is stable across grow\n // events; using the wrapper would defeat AC-07 cache invalidation.\n meshBindGroup = getOrCreateFromChain(\n frameState.meshBindGroupCache,\n [pipelineState.meshStorageBuffer.buffer],\n 'mesh',\n () => {\n // bug-20260610: WebGL2 fallback path needs the binding to cover the\n // whole `array<Mesh, 128>` uniform buffer (14336 B) instead of a\n // single dynamic-offset slot (112 B). `caps.storageBuffer === false`\n // is the same proxy createRenderer uses to pick the uniform variant.\n const meshBindSize = internals.device.caps.storageBuffer\n ? MESH_SSBO_BYTES\n : MESH_UBO_FULL_ARRAY_BYTES;\n const meshBindGroupResult = internals.device.createBindGroup({\n label: 'pbr-mesh-bg',\n layout: pipelineState.meshBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.meshStorageBuffer.buffer,\n offset: 0,\n size: meshBindSize,\n },\n },\n },\n ],\n });\n if (!meshBindGroupResult.ok) throw meshBindGroupResult.error;\n return meshBindGroupResult.value;\n },\n bindGroupCounts,\n );\n\n // feat-20260609-hdrp-cluster-fragment-ggx M4 / w19: when HDRP is active,\n // build the unified group(2) BindGroup that carries the mesh SSBO at\n // binding 0 + the 4 cluster buffers at bindings 3..6. The bindGroup\n // shares the mesh SSBO with URP's `meshBindGroup` (same `meshStorageBuffer.buffer`\n // + same per-entity stride), so the dynamic offset issued at\n // `setBindGroup(2, ...)` covers binding 0 of either layout. Cached\n // alongside `meshBindGroupCache` keyed on the mesh SSBO + cluster\n // buffer identities; cache invalidates on a buffer-grow event the same\n // way the mesh path does (handle id rotation).\n if (clusteredLighting) {\n const hdrpBuffers = expectedHdrpBuffers;\n if (hdrpBuffers !== null) {\n // D-3: buffer dimension uses the inner `.buffer` (same constraint\n // as the mesh path) so a grow event rotates the chain key.\n hdrpClusterBindGroup = getOrCreateFromChain(\n frameState.meshBindGroupCache,\n [\n pipelineState.meshStorageBuffer.buffer,\n hdrpBuffers.lightDataBuffer,\n hdrpBuffers.clusterGridBuffer,\n hdrpBuffers.lightIndexListBuffer,\n hdrpBuffers.clusterUniformBuffer,\n ],\n 'hdrp-unified',\n () => {\n const bg = createHdrpUnifiedBindGroup(\n internals,\n hdrpBuffers,\n pipelineState.meshStorageBuffer.buffer,\n );\n if (bg === null) {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'HDRP unified BindGroup creation succeeds when HDRP is active',\n hint: 'inspect prior errorRegistry events for createBindGroup failure detail',\n });\n }\n return bg;\n },\n bindGroupCounts,\n );\n }\n }\n }\n return { viewBindGroup, meshBindGroup, hdrpClusterBindGroup, hdrpClusterMembershipBindGroup };\n}\n\n/**\n * feat-20260704 M3/w18: per-frame lighting preparation, extracted verbatim from\n * `recordFrame`. (1) pin the point + spot shadow snapshot lists onto frameState\n * for the shadow caster\n * pass closures + lazy-allocate the point-shadow cube_array atlas on first\n * non-empty frame (AC-09 zero-shadow zero-alloc). (3) derive the directional\n * fallback and the unified local-light corpus used by Standard Cluster.\n *\n * @internal\n */\nexport function prepareFrameLighting(\n internals: RenderSystemInternals,\n frameState: RenderFrameState,\n lights: ExtractedLights,\n camera: CameraSnapshot,\n pipelineState?: Pick<\n PipelineState,\n 'hdrpClusterMembershipPipeline' | 'hdrpClusterMembershipBindGroupLayout'\n >,\n): Result<\n {\n light: DirectionalLightSnapshot;\n pointLights: ExtractedLights['point'];\n spotLights: ExtractedLights['spot'];\n rectLights: ExtractedLights['rect'];\n totalLightCount: number;\n standard: StandardTopologyInputValue;\n },\n RenderError\n> {\n if (lights.directionalCount > 1) {\n warnMultiLightDirectional(frameState, lights.directionalCount);\n }\n // feat-20260621-merge-directionallightshadow-into-directionallight M3 / m3-t2:\n // the AC-04/AC-22 \"shadow disabled by missing component\" once-warn is gone.\n // After merging DirectionalLightShadow into DirectionalLight there is no\n // orphan-shadow / missing-companion configuration to warn about -- castShadow\n // defaults true on the single component, so the warn condition can never\n // arise. The error class + RuntimeErrorCode member have been removed in M4 (m4-t2).\n\n // feat-20260612-point-light-shadows-urp-hdrp M3 / T-M3-2 (plan-strategy §D-1):\n // project lights.pointShadow onto frameState so the URP point shadow caster\n // pass can read the snapshot list during graph execute. Lazy-allocate the\n // cube_array atlas on first non-empty frame; zero-shadow scenes never\n // touch the GPU here (AC-09). The snapshot list is stable for the\n // duration of recordFrame; its count is part of the typed topology key.\n frameState.pointShadowSnapshots = lights.pointShadow;\n // feat-20260625-spot-light-shadow-mapping M2 / w9 (D-2): pin the spot\n // snapshots for the spotShadowDepth caster pass closure. The spot atlas is\n // a graph-owned typed target, not a runtime ShadowAtlas, so graph compilation\n // owns the depth texture lifetime.\n frameState.spotShadowSnapshots = lights.spot;\n if (lights.pointShadow.length > 0) {\n if (frameState.pointShadowAtlas === null) {\n const firstSnap = lights.pointShadow[0];\n const faceSize = firstSnap?.mapSize ?? SHADOW_ATLAS_DEFAULT_FACE_SIZE;\n frameState.pointShadowAtlas = new ShadowAtlas(internals.device, {\n faceSize,\n layers: SHADOW_ATLAS_DEFAULT_LAYERS,\n });\n }\n try {\n frameState.pointShadowAtlas.ensure();\n } catch (e) {\n if (\n e instanceof PointShadowAtlasUninitializedError ||\n e instanceof PointShadowAtlasBoundsViolationError\n ) {\n internals.errorRegistry.fire(e);\n } else {\n throw e;\n }\n }\n }\n\n // ExtractedLights three-arm consumption (R-10 preparation; M2 / w16):\n //\n // - lights.directional : feeds the View UBO at slot [16..23]\n // (lightDir + lightColor; existing path).\n // - lights.point/spot/rect[] : packed into the one unified Standard\n // Cluster payload below. No per-kind light\n // transport exists at the renderer boundary.\n //\n // Each variant carries the discriminant `kind` so the record-time packing\n // call sites can run exhaustive switch (charter P2 + AC-03).\n const directionalLight: DirectionalLightSnapshot | undefined = lights.directional;\n const pointLights = lights.point;\n const spotLights = lights.spot;\n const rectLights = lights.rect;\n\n // Case C: 0 DirectionalLight = legitimate scene; the View UBO falls\n // back to a zero-intensity directional payload so the shader's\n // `view.lightDir * view.lightColor` term contributes nothing\n // (physically-correct black under standard, untouched under unlit).\n const light: DirectionalLightSnapshot = directionalLight ?? {\n kind: 'directional' as const,\n direction: vec3.create(0, -1, 0),\n color: vec3.create(0, 0, 0),\n intensity: 0,\n };\n\n const totalLightCount =\n (directionalLight !== undefined ? 1 : 0) +\n pointLights.length +\n spotLights.length +\n rectLights.length;\n\n const clusterGrid = frameState.installedPipelineConfig?.clusterGrid ?? DEFAULT_CLUSTER_GRID;\n const local = [\n ...pointLights.map((source) => ({\n kind: 'point' as const,\n shadowed: source.shadowAtlasLayer !== undefined && source.shadowAtlasLayer >= 0,\n position: source.position,\n range:\n Number.isFinite(source.invRangeSquared) && source.invRangeSquared > 0\n ? Math.sqrt(1 / source.invRangeSquared)\n : 1000,\n source,\n })),\n ...spotLights.map((source) => ({\n kind: 'spot' as const,\n shadowed:\n source.castShadow && source.shadowAtlasTile >= 0 && source.lightViewProj !== undefined,\n position: source.position,\n range:\n Number.isFinite(source.invRangeSquared) && source.invRangeSquared > 0\n ? Math.sqrt(1 / source.invRangeSquared)\n : 1000,\n source,\n })),\n ...rectLights.map((source) => ({\n kind: 'rect-area' as const,\n shadowed: false,\n position: source.position,\n range:\n (Number.isFinite(source.invRangeSquared) && source.invRangeSquared > 0\n ? Math.sqrt(1 / source.invRangeSquared)\n : 1000) + Math.hypot(source.halfWidth, source.halfHeight),\n source,\n })),\n ];\n const prepared = prepareStandardLighting({\n directional: directionalLight,\n local,\n view: computeViewMatrix(camera),\n projection: computeProjectionMatrix(camera),\n near: camera.near,\n far: camera.far,\n grid: clusterGrid,\n lightCount: internals.standardProfile?.lightCount ?? DEFAULT_STANDARD_PROFILE.lightCount,\n renderPath: internals.standardProfile?.renderPath ?? DEFAULT_STANDARD_PROFILE.renderPath,\n });\n if (!prepared.ok) return prepared;\n // Storage-capable Standard frames keep the same Cluster ABI even when the\n // local-light corpus is empty. Directional-only scenes still need the\n // unified mesh group(2) contract so their PBR draws do not select a second\n // local-light layout; the existing transport emits a zero-light payload and\n // the graph remains structurally identical. The no-storage backend has no\n // storage-backed local-light representation, so a directional-only frame\n // remains the sole no-local transport case.\n if (prepared.value.local.length === 0 && !internals.device.caps.storageBuffer) {\n return ok({\n light,\n pointLights,\n spotLights,\n rectLights,\n totalLightCount,\n standard: { kind: 'no-local-lights', prepared: prepared.value },\n });\n }\n const transport = selectStandardClusterTransport(\n {\n compute: internals.device.caps.compute,\n storageBuffer: internals.device.caps.storageBuffer,\n membershipPipelineReady:\n pipelineState !== undefined &&\n pipelineState.hdrpClusterMembershipPipeline !== null &&\n pipelineState.hdrpClusterMembershipBindGroupLayout !== null,\n },\n prepared.value,\n );\n if (!transport.ok) return transport;\n\n return ok({\n light,\n pointLights,\n spotLights,\n rectLights,\n totalLightCount,\n standard: { kind: 'clustered', prepared: prepared.value, transport: transport.value },\n });\n}\n\nfunction modifierDigest(data: Uint8Array): number {\n let hash = 2166136261;\n for (let index = 0; index < data.length; index += 1) {\n hash ^= data[index] ?? 0;\n hash = Math.imul(hash, 16777619);\n }\n return hash >>> 0;\n}\n\n/** Upload authored Spot modifier payloads into the renderer-owned array lane. */\nexport function writeSpotModifierTextures(\n internals: RenderSystemInternals,\n pipelineState: PipelineState,\n spots: readonly ExtractedLights['spot'][number][],\n): void {\n const iesTexture = pipelineState.iesProfileTexture;\n const cookieTexture = pipelineState.cookieTexture;\n const cookieMatrixBuffer = pipelineState.cookieMatrixBuffer;\n if (iesTexture === undefined && cookieTexture === undefined && cookieMatrixBuffer === undefined)\n return;\n let state = pipelineState.spotModifierUploadState;\n if (state === undefined) {\n state = { ies: new Map(), cookie: new Map(), cookieMatrix: new Map() };\n pipelineState.spotModifierUploadState = state;\n } else if (state.cookieMatrix === undefined) {\n state = { ...state, cookieMatrix: new Map() };\n pipelineState.spotModifierUploadState = state;\n }\n for (const spot of spots) {\n if (spot.iesProfileSlice !== undefined && spot.iesProfileData !== undefined && iesTexture) {\n if (spot.iesProfileData.byteLength === IES_SLICE_WIDTH * IES_SLICE_HEIGHT * 2) {\n const digest = modifierDigest(spot.iesProfileData);\n if (state.ies.get(spot.iesProfileSlice) !== digest) {\n const result = internals.device.queue.writeTexture(\n { texture: iesTexture, mipLevel: 0, origin: { x: 0, y: 0, z: spot.iesProfileSlice } },\n spot.iesProfileData,\n { offset: 0, bytesPerRow: IES_SLICE_WIDTH * 2, rowsPerImage: IES_SLICE_HEIGHT },\n { width: IES_SLICE_WIDTH, height: IES_SLICE_HEIGHT, depthOrArrayLayers: 1 },\n );\n if (!result.ok) throw result.error;\n state.ies.set(spot.iesProfileSlice, digest);\n }\n }\n }\n // Authored Cookie and the SpotLight projector share the same\n // fixed 256x256 array transport on the extended topology. Their shader\n // projection remains distinct: Cookie uses cookieMatrices, projector\n // uses View.spotLightViewProj. Upload both identities when a frame carries\n // both fields, while the direct-light metadata selects the one in use.\n for (const modifier of [\n {\n slice: spot.cookieSlice,\n data: spot.cookieData,\n matrix: spot.cookieMatrix,\n },\n {\n slice: spot.projectorSlice,\n data: spot.projectorData,\n matrix: spot.projectorMatrix,\n },\n ]) {\n if (modifier.slice !== undefined && modifier.data !== undefined && cookieTexture) {\n if (modifier.data.byteLength === COOKIE_SLICE_SIZE * COOKIE_SLICE_SIZE * 4) {\n const digest = modifierDigest(modifier.data);\n if (state.cookie.get(modifier.slice) !== digest) {\n const result = internals.device.queue.writeTexture(\n { texture: cookieTexture, mipLevel: 0, origin: { x: 0, y: 0, z: modifier.slice } },\n modifier.data,\n { offset: 0, bytesPerRow: COOKIE_SLICE_SIZE * 4, rowsPerImage: COOKIE_SLICE_SIZE },\n { width: COOKIE_SLICE_SIZE, height: COOKIE_SLICE_SIZE, depthOrArrayLayers: 1 },\n );\n if (!result.ok) throw result.error;\n state.cookie.set(modifier.slice, digest);\n }\n }\n }\n if (modifier.slice !== undefined && modifier.matrix !== undefined && cookieMatrixBuffer) {\n const matrixBytes = new Uint8Array(\n modifier.matrix.buffer,\n modifier.matrix.byteOffset,\n modifier.matrix.byteLength,\n );\n const digest = modifierDigest(matrixBytes);\n if (state.cookieMatrix.get(modifier.slice) !== digest) {\n const result = internals.device.queue.writeBuffer(\n cookieMatrixBuffer,\n modifier.slice * 16 * Float32Array.BYTES_PER_ELEMENT,\n modifier.matrix,\n );\n if (!result.ok) throw result.error;\n state.cookieMatrix.set(modifier.slice, digest);\n }\n }\n }\n }\n}\n\n/**\n * feat-20260704 M3/w18: write the point-shadow params UBO (bound at viewBg\n * binding 6), extracted verbatim from `recordFrame`.\n *\n * feat-20260612-point-light-shadows-urp-hdrp Round-2 F-1: 4 lanes x vec4<f32>;\n * lane[shadowAtlasLayer] = (near, far, 1/(far-near), 0). Lanes for non-shadow\n * slots stay zero (the WGSL sample path is gated by PointLight.shadowAtlasLayer\n * >= 0). Always writes the full 64 B so stale non-zero lanes from a previous\n * frame's allocation cannot poison the current frame.\n *\n * @internal\n */\nexport function writeShadowParamsBuffer(\n internals: RenderSystemInternals,\n frameState: RenderFrameState,\n pipelineState: PipelineState,\n): void {\n const SHADOW_PARAMS_LANE_COUNT = 4;\n const SHADOW_PARAMS_FLOATS_PER_LANE = 4;\n const shadowParamsArr = new Float32Array(\n SHADOW_PARAMS_LANE_COUNT * SHADOW_PARAMS_FLOATS_PER_LANE,\n );\n for (let i = 0; i < frameState.pointShadowSnapshots.length; i++) {\n const ps = frameState.pointShadowSnapshots[i];\n if (ps === undefined) continue;\n const layer = ps.shadowAtlasLayer;\n if (layer < 0 || layer >= SHADOW_PARAMS_LANE_COUNT) continue;\n const base = layer * SHADOW_PARAMS_FLOATS_PER_LANE;\n const near = ps.nearPlane;\n const far = ps.farPlane;\n const invSpan = far > near ? 1 / (far - near) : 0;\n shadowParamsArr[base] = near;\n shadowParamsArr[base + 1] = far;\n shadowParamsArr[base + 2] = invSpan;\n shadowParamsArr[base + 3] = 0;\n }\n const shadowParamsWriteRes = internals.device.queue.writeBuffer(\n pipelineState.shadowParamsBuffer,\n 0,\n shadowParamsArr,\n );\n if (!shadowParamsWriteRes.ok) {\n internals.errorRegistry.fire(shadowParamsWriteRes.error);\n }\n}\n\n/**\n * feat-20260704 M3/w18: zero-light standard-material once-warn, extracted\n * verbatim from `recordFrame`.\n *\n * feat-20260520-skylight-ibl-cubemap M4 / t27 (AC-10): fires once per\n * RenderSystem lifetime when the 0-light three-condition conjunction holds — no\n * Skylight, 0 direct light (totalLightCount === 0), AND at least one builtin\n * standard/PBR material (which renders black with no light). Custom shaders\n * own their lighting contract and cannot be classified by this generic\n * diagnostic. Suppressed under NODE_ENV=production.\n *\n * @internal\n */\nexport function warnZeroLightStandard(\n frameState: RenderFrameState,\n renderables: readonly RenderableSnapshot[],\n skylight: SkylightSnapshot | undefined,\n totalLightCount: number,\n): void {\n const hasStandardMaterial = renderables.some((r) => isLitMaterialSnapshot(r.material));\n if (\n skylight === undefined &&\n totalLightCount === 0 &&\n hasStandardMaterial &&\n !frameState.warnedZeroLightStandard\n ) {\n frameState.warnedZeroLightStandard = true;\n const env = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\n if (env?.env?.NODE_ENV !== 'production') {\n console.warn(\n '[forgeax] standard material renders black with 0 lights of every type (no Skylight, and directional + point + spot all empty); spawn at least one light (Skylight, DirectionalLight, PointLight, or SpotLight) or switch material to an unlit shader (Materials.unlit(...)). See AGENTS.md section Breaking changes 2026-05-19.',\n );\n }\n }\n}\n\n/**\n * Write the one prepared Standard Cluster payload into the persistent buffers.\n * Membership has already been derived by `prepareFrameLighting`; this function\n * only packs/uploads that immutable result and never re-runs the binner.\n *\n * @internal\n */\nexport function writeHdrpClusterAndSsaoBuffers(\n internals: RenderSystemInternals,\n frameState: RenderFrameState,\n camera: CameraSnapshot,\n prepared: PreparedStandardLighting,\n transport: StandardClusterTransport,\n profilePhase?: RecordProfileRunner,\n gpuMembershipPipelineReady = false,\n membershipBindGroupLayout: BindGroupLayout | null = null,\n projectorLightSlotIndex?: number,\n pipelineState?: PipelineState,\n): Result<void, RenderError> {\n const configuredClusterGrid = prepared.layout.grid;\n const gpuMembership = transport.producer === 'gpu';\n if (gpuMembership && (!gpuMembershipPipelineReady || membershipBindGroupLayout === null)) {\n return err(\n new StandardClusterTransportUnavailableError(\n prepared.local.length,\n 'the selected GPU Cluster producer requires a ready membership pipeline and bind-group layout',\n ),\n );\n }\n const hdrpBuffers = getOrCreateHdrpBuffers(internals, configuredClusterGrid);\n if (hdrpBuffers === null) {\n return err(\n new StandardClusterTransportUnavailableError(\n prepared.local.length,\n 'the selected Standard Cluster transport could not allocate its persistent buffers',\n ),\n );\n }\n const existingMembership = projectDeviceOwnedBindGroup(\n frameState.hdrpClusterMembership,\n internals.device,\n membershipBindGroupLayout,\n );\n const membershipMatchesBuffers =\n existingMembership !== null &&\n frameState.hdrpClusterMembership?.clusterGridBuffer === hdrpBuffers.clusterGridBuffer;\n if (!membershipMatchesBuffers) frameState.hdrpClusterMembership = null;\n if (\n gpuMembership &&\n membershipBindGroupLayout !== null &&\n frameState.hdrpClusterMembership === null\n ) {\n const bindGroup = createHdrpClusterMembershipBindGroup(\n internals,\n hdrpBuffers,\n membershipBindGroupLayout,\n );\n if (bindGroup === null) {\n return err(\n new StandardClusterTransportUnavailableError(\n prepared.local.length,\n 'the selected GPU Cluster producer could not create its membership bind group',\n ),\n );\n }\n frameState.hdrpClusterMembership = {\n device: internals.device,\n layout: membershipBindGroupLayout,\n bindGroup,\n clusterGridBuffer: hdrpBuffers.clusterGridBuffer,\n };\n }\n\n if (pipelineState !== undefined) {\n const preparedSpots: ExtractedLights['spot'][number][] = [];\n for (const local of prepared.local) {\n if (local.source?.kind === 'spot') preparedSpots.push(local.source);\n }\n writeSpotModifierTextures(internals, pipelineState, preparedSpots);\n }\n\n const gridX = prepared.layout.grid.x;\n const gridY = prepared.layout.grid.y;\n const gridZ = prepared.layout.grid.z;\n const clusterGridBuf = prepared.clusterGrid;\n const lightIndexListBuf = prepared.lightIndexList;\n const lightIndexCount = prepared.membershipEntryCount;\n\n // Falsify injection point retained for the real prepared payload. It edits\n // only this frame's projection and never creates a second membership owner.\n const envFalsify = (globalThis as { process?: { env?: Record<string, string | undefined> } })\n .process?.env;\n if (envFalsify?.FORGEAX_HDRP_FALSIFY_CLUSTER_GRID_ZERO) clusterGridBuf.fill(0);\n\n const hdrpPayload = runHdrpClusterProfilePhase(\n profilePhase,\n 'record/scene-state/hdrp-cluster/payload-packing',\n () => {\n const lightDataPayload = new Float32Array(\n prepared.layout.lightDataSlotCount * DIRECT_LIGHT_SLOT_FLOAT_COUNT,\n );\n let slotIdx = 0;\n for (const local of prepared.local) {\n const source = local.source;\n if (source === undefined) return null;\n const projectorSelected =\n projectorLightSlotIndex === undefined ? undefined : projectorLightSlotIndex === slotIdx;\n const packed = packDirectLightSlot(source, projectorSelected);\n lightDataPayload.set(packed, slotIdx * DIRECT_LIGHT_SLOT_FLOAT_COUNT);\n slotIdx += 1;\n }\n\n // scope-amend-webgl2-ubo: SSAO intensity is folded into the\n // cluster_uniform .w lane (formerly pad), removing the dedicated\n // @binding(9) UBO that pushed fragment-stage UBO count past\n // WebGL2's max_uniform_buffers_per_shader_stage=11. Disabled-SSAO\n // path writes 0 so `mix(1.0, ssao*ao, 0.0) = 1.0` in the lighting\n // shader (no PSO recompile across enable/disable).\n const clusterSsaoConfig = frameState.installedPipelineConfig?.ssao;\n const clusterSsaoIntensity =\n clusterSsaoConfig !== undefined && clusterSsaoConfig.enabled === true\n ? (clusterSsaoConfig.intensity ?? 1.0)\n : 0;\n const clusterUniformPayload = packClusterUniform(\n { x: gridX, y: gridY, z: gridZ },\n camera.near,\n camera.far,\n clusterSsaoIntensity,\n transport.admittedLightCount,\n );\n\n return {\n hdrpBuffers,\n lightDataUploadPayload: lightDataPayload.subarray(\n 0,\n slotIdx * DIRECT_LIGHT_SLOT_FLOAT_COUNT,\n ),\n clusterUniformPayload: new Uint8Array(clusterUniformPayload),\n };\n },\n );\n\n if (hdrpPayload === null) {\n return err(\n new StandardClusterTransportUnavailableError(\n prepared.local.length,\n 'the prepared Standard Cluster payload could not be materialized',\n ),\n );\n }\n\n const bufferUpload = runHdrpClusterProfilePhase(\n profilePhase,\n 'record/scene-state/hdrp-cluster/buffer-upload',\n (): Result<void, RenderError> => {\n const { hdrpBuffers, lightDataUploadPayload, clusterUniformPayload } = hdrpPayload;\n const lightDataUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.lightDataBuffer,\n 0,\n lightDataUploadPayload,\n );\n if (!lightDataUpload.ok)\n return err(mapClusterUploadFailure('light-data', lightDataUpload.error));\n\n if (gpuMembership) {\n const lightBoundsUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.lightBoundsBuffer,\n 0,\n prepared.lightBounds,\n );\n if (!lightBoundsUpload.ok)\n return err(mapClusterUploadFailure('light-bounds', lightBoundsUpload.error));\n }\n const clusterGridUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.clusterGridBuffer,\n 0,\n clusterGridBuf.subarray(0, gridX * gridY * gridZ * 2),\n );\n if (!clusterGridUpload.ok)\n return err(mapClusterUploadFailure('cluster-grid', clusterGridUpload.error));\n\n if (!gpuMembership && lightIndexCount > 0) {\n const lightIndexListUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.lightIndexListBuffer,\n 0,\n lightIndexListBuf.subarray(0, lightIndexCount),\n );\n if (!lightIndexListUpload.ok) {\n return err(mapClusterUploadFailure('light-index-list', lightIndexListUpload.error));\n }\n }\n\n const clusterUniformUpload = internals.device.queue.writeBuffer(\n hdrpBuffers.clusterUniformBuffer,\n 0,\n clusterUniformPayload,\n );\n if (!clusterUniformUpload.ok) {\n return err(mapClusterUploadFailure('cluster-uniform', clusterUniformUpload.error));\n }\n return ok(undefined);\n },\n );\n if (!bufferUpload.ok) return bufferUpload;\n\n // ── feat-20260612-hdrp-ssao M1 / w6 + M7 / w33 ───────────────\n // Per-frame SSAO uniform write (plan-strategy D-1 + D-C):\n // view + projection + inverseProjection at offsets 0/64/128 +\n // intensityPad (vec4 — x=intensity, y=radius, z=bias) at offset 192;\n // total 256 B (matches host SSAO_UNIFORM_BYTES + WGSL struct).\n // Single writeBuffer covers all four fields so one queue entry\n // updates the entire UBO.\n // Separate from View UBO (592 B invariant); does not affect\n // material PSO bytecode.\n //\n // Writes when HDRP is active; config.ssao?.enabled guard comes in\n // M4 / w19 after the config.ssao type narrowing is added.\n const ssaoUpload = runHdrpClusterProfilePhase(\n profilePhase,\n 'record/scene-state/hdrp-cluster/buffer-upload',\n (): Result<void, RenderError> => {\n const ssaoBufs = getOrCreateSsaoBuffers(internals);\n if (ssaoBufs === null) return ok(undefined);\n const sProj = computeProjectionMatrix(camera);\n const sView = computeViewMatrix(camera);\n // inverseProjection = inverse(projection): NDC -> view-space.\n const invProjOnly = mat4.create();\n mat4.invert(invProjOnly, sProj);\n\n // Float32Array of 64 (256 B): 3 mat4 (48) + intensityPad vec4 (4)\n // + 12 trailing padding floats. We only fill the declared region.\n const ssaoUniformPayload = new Float32Array(64);\n ssaoUniformPayload.set(sView, 0);\n ssaoUniformPayload.set(sProj, 16);\n ssaoUniformPayload.set(invProjOnly, 32);\n // intensityPad carries the same resolved values as the graph SSAO\n // calc pass; this early write keeps the shared UBO valid before the\n // typed fullscreen pass executes.\n const ssaoConfig = frameState.installedPipelineConfig?.ssao;\n const parameters = getSsaoParameters(\n ssaoConfig !== undefined && ssaoConfig.enabled === true ? ssaoConfig : undefined,\n );\n ssaoUniformPayload[48] = parameters.intensity;\n ssaoUniformPayload[49] = parameters.radius;\n ssaoUniformPayload[50] = parameters.bias;\n\n const ssaoUniformRes = internals.device.queue.writeBuffer(\n ssaoBufs.uniformBuffer,\n 0,\n ssaoUniformPayload,\n );\n if (!ssaoUniformRes.ok)\n return err(mapClusterUploadFailure('ssao-uniform', ssaoUniformRes.error));\n return ok(undefined);\n },\n );\n if (!ssaoUpload.ok) return ssaoUpload;\n return ok(undefined);\n}\n\n/**\n * feat-20260704 M3/w18: resolve `tonemapActive` + `skyboxActive` for this\n * frame, extracted verbatim from `recordFrame`.\n *\n * feat-20260519-tonemap-reinhard-mvp: tonemap is active when the camera carries\n * `tonemap !== 'none'` (routes geometry into the HDR offscreen target + a\n * fullscreen tonemap pass). feat-20260531-skybox-env-background M2 / w9: skybox\n * is active only when a SkyboxBackground entity is present AND tonemap is active\n * (hdrColor is only allocated on the tonemap path). M3 / w20: once-warn when\n * tonemap is 'none' but a skybox exists (config issue, not resource-timing —\n * no structured error). M3 / w18: skybox degrades to clear-colour for a frame\n * while its cubemap view is not yet resident (lazy equirect projection pending\n * / failed; the lazy trigger owns the fire-once-on-failed error).\n *\n * @internal\n */\nexport function resolveSkyboxActive(\n internals: RenderSystemInternals,\n frameState: RenderFrameState,\n camera: CameraSnapshot,\n skybox: SkyboxSnapshot | undefined,\n): { tonemapActive: boolean; skyboxActive: boolean } {\n const tonemapActive = camera.tonemap !== 'none';\n let skyboxActive = skybox !== undefined && tonemapActive;\n // feat-20260531-skybox-env-background M3 / w20: once-warn when camera\n // tonemap is 'none' but a SkyboxBackground entity exists. The skybox\n // pass requires the HDR render target allocated by the tonemap path;\n // without it the skybox is skipped for this frame. This is a config\n // issue, not a resource-timing issue -- don't fire a structured error\n // (plan-strategy D-2 NOTE, charter P3 non-silent).\n if (skybox !== undefined && !tonemapActive && !frameState.warnedSkyboxTonemapNone) {\n frameState.warnedSkyboxTonemapNone = true;\n console.warn(\n '[forgeax] SkyboxBackground: skybox requires tonemap active (camera.tonemap !== \"none\") to write HDR target. The skybox pass will be skipped for this frame.',\n );\n }\n // feat-20260531-skybox-env-background M3 / w18: degradation when cubemap\n // GPU view is not ready. getCubemapGpuView returns undefined if the\n // equirect-to-cube upload has not completed yet.\n if (skybox !== undefined && tonemapActive) {\n const cubemapView = internals.gpuStore.getCubemapGpuView(\n toShared<'EquirectAsset'>(skybox.equirectHandle),\n );\n if (cubemapView === undefined) {\n // The skybox reuses the Skylight's equirect handle; the cubemap\n // projection is driven lazily by the single trigger in `driveLazy\n // EquirectProjection` above (it owns the fire-and-forget launch AND the\n // fire-once-on-failed structured error). While the projection is\n // pending or has failed the cube view is not resident, so the skybox\n // pass degrades to the clear-colour background for this frame\n // (charter P3: it activates once the shared projection flips to\n // 'ready'). No error is fired here -- 'pending' is a normal transition\n // (firing per frame would flood the channel), and 'failed' is reported\n // once by the lazy trigger. (feat-20260630 M3 / w18.)\n skyboxActive = false;\n }\n }\n return { tonemapActive, skyboxActive };\n}\n","// IblPipelineCache.ts -- DeviceScope-generation cache for IBL precompute.\n//\n// Plan-strategy D-1/D-7: cache for 4 GPU passes (equirect->cube /\n// irradiance / prefilter / BRDF LUT). M2 provides the cache skeleton;\n// M3 (t18/t20) wires real shader math from ibl.wgsl.\n//\n// The cache is keyed by the renderer-owned DeviceScope generation. Raw device\n// handles are inputs to pipeline creation, never cache or lifecycle owners.\n//\n// Public surface (M3):\n// - getOrCreateIblCache(scope): get or initialize the generation cache\n// - iblCacheSize(): introspection hook\n// - hasIblCache(scope): introspection hook\n// - setIblWgslSource(source): set the ibl.wgsl WGSL source string\n// - createIblShaderModules(device, factory): create shader modules from ibl.wgsl\n// - createIblPipelines(scope, device, factory, modules): create 4 render pipelines\n// - runIblPrecompute(opts): execute 4 GPU precompute passes (M3 t20)\n//\n// M3 t20: pipeline slots are filled with real render pipelines loaded from\n// ibl.wgsl, replacing the M2 stub undefined slots. The 4 GPU passes are\n// executed in the standard order (equirect->cube -> irradiance -> prefilter\n// -> BRDF LUT), with counters set post-execution per AC-04/05/06.\n\n// ─── RHI-owned handles ───────────────────────────────────────────────────────\n\nimport {\n type BindGroup,\n type BindGroupLayout,\n type Buffer,\n type CommandBuffer,\n err,\n ok,\n type RenderPipeline,\n type Result,\n type RhiCommandEncoder,\n type RhiDevice,\n type RhiError,\n type RhiRenderPassEncoder,\n type Sampler,\n type ShaderModule,\n type Texture,\n type TextureFormat,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport type { DeviceScope } from '../device/device-scope';\nimport { createIblKernelCache, type IblKernelCache } from './kernel-cache';\n\nexport {\n createIblKernelCache,\n type IblKernelCache,\n resetIblKernelCaches,\n} from './kernel-cache';\n\nimport { GPU_SHADER_STAGE_FRAGMENT, GPU_SHADER_STAGE_VERTEX } from '../gpu-stage';\nimport {\n GPU_TEXTURE_USAGE_COPY_DST,\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING,\n} from '../gpu-texture-usage';\n\n/**\n * Shader module factory (async, injected via configureGpuDevice).\n * Mirrors `MipmapShaderModuleFactory` from mipmap-generator.\n */\n/**\n * IBL is assembled by the renderer's device owner, so it consumes the full\n * opaque RHI device rather than a structurally-compatible raw/shim split.\n * Keeping the owner as RhiDevice makes the backend boundary explicit: raw\n * GPU handles can only exist inside an RHI implementation or a test readback.\n */\nexport type IblRhiOwner = RhiDevice;\n\nexport type IblShaderModuleFactory = (\n device: IblRhiOwner,\n desc: { code: string; label?: string },\n) => Promise<Result<ShaderModule, RhiError>>;\n\nexport interface IblPipelineSet {\n readonly equirectToCubePipeline: RenderPipeline;\n readonly irradiancePipeline: RenderPipeline;\n readonly prefilterPipeline: RenderPipeline;\n readonly brdfLutPipeline: RenderPipeline;\n}\n\nexport interface IblPipelineError {\n readonly code: 'ibl-pipeline-create-failed' | 'ibl-shader-module-missing';\n readonly expected: string;\n readonly hint: string;\n readonly detail: { readonly stage: string; readonly rhiCode?: RhiError['code'] };\n}\n\n/**\n * Per-DeviceScope-generation IBL pipeline cache instance.\n *\n * M3.5 (round-2 t52): the 4 pipeline slots are mutable so createIblPipelines\n * can fill them after construction. The 4 textures + their views are also\n * cached here so runIblPrecompute targets are stable across calls\n * (idempotent).\n */\nexport interface IblPipelineCache {\n /** Reusable generation-scoped kernel state; per-probe outputs stay elsewhere. */\n readonly probeKernel: IblKernelCache;\n /** Color format shared by all precompute outputs for this device. */\n outputFormat?: TextureFormat;\n /** Equirectangular-to-cubemap pipeline. */\n equirectToCubePipeline?: RenderPipeline;\n /** Diffuse irradiance convolution pipeline. */\n irradiancePipeline?: RenderPipeline;\n /** Specular prefilter pipeline. */\n prefilterPipeline?: RenderPipeline;\n /** BRDF integration LUT pipeline. */\n brdfLutPipeline?: RenderPipeline;\n\n /** Face uniforms BGL (shared across equirect/irradiance/prefilter, D-9). */\n faceUniformsBgl?: BindGroupLayout;\n /** group(1) BGL for the equirect-to-cube pass (texture_2d + sampler). */\n equirectGroup1Bgl?: BindGroupLayout;\n /** group(1) BGL for irradiance + prefilter (texture_cube + sampler). */\n cubeGroup1Bgl?: BindGroupLayout;\n /** group(0) BGL for prefilter (face + prefilter uniforms). */\n prefilterGroup0Bgl?: BindGroupLayout;\n\n /** Irradiance cubemap texture (32x32; outputFormat, cube). */\n irradianceTexture?: Texture;\n /** Irradiance cubemap view (dimension:cube). */\n irradianceView?: TextureView;\n /** Per-face 2D views for irradiance (render-attachment use). */\n irradianceFaceViews?: ReadonlyArray<TextureView>;\n /** Specular prefilter cubemap (128x128, 5 mip levels). */\n prefilterTexture?: Texture;\n /** Prefilter cubemap view (dimension:cube, all mips). */\n prefilterView?: TextureView;\n /** Per-face 2D views per mip for prefilter (5 mips x 6 faces). */\n prefilterFaceViewsByMip?: ReadonlyArray<ReadonlyArray<TextureView>>;\n /** BRDF LUT (256x256; outputFormat). */\n brdfLutTexture?: Texture;\n /** BRDF LUT view. */\n brdfLutView?: TextureView;\n\n /** Counter: times irradiance pass has executed. AC-04: == 1 after first cook. */\n irradianceBakeCount: number;\n /** Counter: times prefilter pass has executed. AC-05: == 1 after first cook. */\n prefilterBakeCount: number;\n /** Counter: times BRDF LUT pass has executed. AC-06: == 1 after first cook. */\n brdfLutBakeCount: number;\n}\n\n/**\n * Cache ownership follows the renderer's DeviceScope generation. A cache is\n * never recovered by looking up an opaque device handle, so every pipeline and\n * side texture is born under the same lifecycle owner as the rest of the\n * renderer resources.\n */\nconst scopeCaches: WeakMap<DeviceScope, IblPipelineCache> = new WeakMap();\n\n/**\n * Get or create the current-generation IBL pipeline cache.\n */\nexport function getOrCreateIblCache(scope: DeviceScope): IblPipelineCache {\n const existing = scopeCaches.get(scope);\n if (existing !== undefined) return existing;\n\n const cache: IblPipelineCache = {\n probeKernel: createIblKernelCache(scope.generation),\n irradianceBakeCount: 0,\n prefilterBakeCount: 0,\n brdfLutBakeCount: 0,\n };\n scopeCaches.set(scope, cache);\n return cache;\n}\n\n/**\n * Check whether a DeviceScope generation has an active cache entry.\n */\nexport function hasIblCache(scope: DeviceScope): boolean {\n return scopeCaches.has(scope);\n}\n\n// ─── M3.5 composed ibl-* shader source registry ─────────────────────────────\n//\n// 4 composed WGSL strings -- one per render pipeline. Each string is the\n// output of @forgeax/engine-naga composeShader after merging ibl_shared +\n// the per-pass module. Built by ShaderCatalog / vite-plugin-shader at\n// build-time so the runtime cache never reaches into engine-naga\n// (AGENTS.md grep gate forbids).\n\nexport interface IblComposedShaders {\n /** ibl-equirect-to-cube composed (cubemap_vs + equirectToCube_fs). */\n readonly equirectToCube: string;\n /** ibl-irradiance composed (cubemap_vs + irradianceConvolve_fs). */\n readonly irradiance: string;\n /** ibl-prefilter composed (cubemap_vs + prefilterEnv_fs). */\n readonly prefilter: string;\n /** ibl-brdf-lut composed (fullscreen_vs + brdfLutBake_fs). */\n readonly brdfLut: string;\n}\n\nlet iblComposedShadersCache: IblComposedShaders | undefined;\n\n/**\n * Inject the composed ibl-* shader sources used by createIblPipelines.\n * Called once by the engine bootstrap (createRenderer step \"shader-load\")\n * with the 4 composed entries from ShaderCatalog.\n */\nexport function setIblComposedShaders(sources: IblComposedShaders): void {\n iblComposedShadersCache = sources;\n}\n\n// ─── Standard cube vertices for cubemap face rendering ───────────────────────\n// 36 vertices (6 faces * 2 triangles * 3 vertices), vec3<f32> format.\n// Unit cube [-1, 1]^3 centered at origin.\nexport const CUBEMAP_FACE_VERTICES = new Float32Array([\n // +X face (+1, 0, 0)\n 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,\n // -X face (-1, 0, 0)\n -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,\n 1.0,\n // +Y face (0, +1, 0)\n -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,\n // -Y face (0, -1, 0)\n -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0,\n 1.0,\n // +Z face (0, 0, +1)\n -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0,\n // -Z face (0, 0, -1)\n 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0,\n -1.0,\n]);\n\n// 6 capture view-projection matrices (right-handed, from origin).\n// Projection Y is negated for WebGPU top-left framebuffer origin.\n// Target directions: +X, -X, +Y, -Y, +Z, -Z.\n// Up vectors: -Y for X/Z faces, +Z for +Y, -Z for -Y.\nexport const CAPTURE_VIEW_PROJS = buildCaptureViewProjs();\n\nfunction buildCaptureViewProjs(): Float32Array[] {\n const targets: [number, number, number][] = [\n [1, 0, 0],\n [-1, 0, 0],\n [0, 1, 0],\n [0, -1, 0],\n [0, 0, 1],\n [0, 0, -1],\n ];\n const ups: [number, number, number][] = [\n [0, -1, 0],\n [0, -1, 0],\n [0, 0, 1],\n [0, 0, -1],\n [0, -1, 0],\n [0, -1, 0],\n ];\n\n const proj = cubemapCaptureProjection(Math.PI / 2, 0.1, 10.0);\n\n return targets.map((_t, i) => {\n const t = _t;\n const u = ups[i] ?? [0, -1, 0];\n const view = lookAtMatrix([0, 0, 0], t, u);\n return mulMat4(proj, view);\n });\n}\n\nfunction cubemapCaptureProjection(fovy: number, near: number, far: number): Float32Array {\n const f = 1.0 / Math.tan(fovy / 2);\n const nf = 1.0 / (near - far);\n // biome-ignore format: manual column-major mat4\n return new Float32Array([\n f, 0, 0, 0,\n 0, -f, 0, 0,\n 0, 0, (far + near) * nf, -1,\n 0, 0, 2 * far * near * nf, 0,\n ]);\n}\n\nfunction lookAtMatrix(\n eye: readonly number[],\n target: readonly number[],\n up: readonly number[],\n): Float32Array {\n const [ex, ey0, ez] = [eye[0] ?? 0, eye[1] ?? 0, eye[2] ?? 0];\n const [tx, ty, tz] = [target[0] ?? 0, target[1] ?? 0, target[2] ?? 0];\n const [upx, upy, upz] = [up[0] ?? 0, up[1] ?? 0, up[2] ?? 0];\n let fx = ex - tx,\n fy = ey0 - ty,\n fz = ez - tz;\n const fLen = Math.sqrt(fx * fx + fy * fy + fz * fz);\n fx /= fLen;\n fy /= fLen;\n fz /= fLen;\n\n let rx = upy * fz - upz * fy;\n let ry = upz * fx - upx * fz;\n let rz = upx * fy - upy * fx;\n const rLen = Math.sqrt(rx * rx + ry * ry + rz * rz);\n rx /= rLen;\n ry /= rLen;\n rz /= rLen;\n\n const ux = fy * rz - fz * ry;\n const uy = fz * rx - fx * rz;\n const uz = fx * ry - fy * rx;\n\n return new Float32Array([\n rx,\n ux,\n fx,\n 0,\n ry,\n uy,\n fy,\n 0,\n rz,\n uz,\n fz,\n 0,\n -(rx * ex + ry * ey0 + rz * ez),\n -(ux * ex + uy * ey0 + uz * ez),\n -(fx * ex + fy * ey0 + fz * ez),\n 1,\n ]);\n}\n\n// Column-major matrix product `r = a * b` where each Float32Array stores\n// 4 contiguous column vectors of 4 floats (WGSL `mat4x4<f32>` uniform\n// layout). For column-major storage `flat[c*4 + row] = M[col=c, row]`, so:\n// (a * b)[col=c, row=r] = sum_k a[col=k, row=r] * b[col=c, row=k]\n// flat_out[c*4 + r] = sum_k a[k*4 + r] * b[c*4 + k]\n//\n// The prior row-major iteration silently transposed the result, producing\n// `b * a` in WGSL's view -- IBL equirect-to-cube vertices then projected\n// to clip with w=0 / w=-1, every face fell outside the [-1,1] frustum, no\n// fragments drew, and every downstream IBL texture (irradiance / prefilter)\n// inherited the clearValue=(0,0,0,1). Demo 3x3 sphere matrix rendered\n// pure black because `ambient = kD * 0 + specular * 0 = 0` and there are\n// no direct lights in the IBL demo scene.\nfunction mulMat4(a: Float32Array, b: Float32Array): Float32Array {\n const r = new Float32Array(16);\n for (let c = 0; c < 4; c++) {\n for (let row = 0; row < 4; row++) {\n let sum = 0;\n for (let k = 0; k < 4; k++) {\n sum += (a[k * 4 + row] ?? 0) * (b[c * 4 + k] ?? 0);\n }\n r[c * 4 + row] = sum;\n }\n }\n return r;\n}\n\n// ─── M3.5 t52: createIblPipelines (4 independent GPURenderPipelines) ─────────\n\n// IBL output texture sizes (plan D-10 SSOT, mirrored in ibl-brdf-lut.wgsl).\nexport const IRRADIANCE_SIZE = 32;\nexport const PREFILTER_SIZE = 128;\nexport const PREFILTER_MIP_LEVELS = 5;\nexport const BRDF_LUT_SIZE = 256;\n\n/**\n * Create 4 independent GPURenderPipelines + their shared / per-pass bind\n * group layouts. Pipeline slots are stored on the per-device cache and\n * survive across calls (D-1 startup-once cook).\n *\n * D-9: faceUniforms BGL (@group(0) for equirect/irradiance/prefilter) is\n * a single instance reused across 3 pipelines (binary-compatible).\n * group(1) is per-pipeline: texture_2d for equirect, texture_cube for\n * irradiance + prefilter, none for brdf-lut.\n */\nexport async function createIblPipelines(\n scope: DeviceScope,\n device: IblRhiOwner,\n factory: IblShaderModuleFactory,\n cubeOutputFormat: TextureFormat = 'rgba16float',\n): Promise<Result<IblPipelineSet, RhiError | IblPipelineError>> {\n const cache = getOrCreateIblCache(scope);\n if (\n cache.equirectToCubePipeline !== undefined &&\n cache.irradiancePipeline !== undefined &&\n cache.prefilterPipeline !== undefined &&\n cache.brdfLutPipeline !== undefined\n ) {\n return ok({\n equirectToCubePipeline: cache.equirectToCubePipeline,\n irradiancePipeline: cache.irradiancePipeline,\n prefilterPipeline: cache.prefilterPipeline,\n brdfLutPipeline: cache.brdfLutPipeline,\n });\n }\n // Keep the output format on the per-device cache so the four pipelines and\n // their lazily-created side textures cannot drift. WebGL2 may need the\n // renderable rgba8 fallback even when the source equirect remains float.\n const outputFormat = cubeOutputFormat;\n cache.outputFormat = outputFormat;\n\n const composed = iblComposedShadersCache;\n // Mock-device path: factory returns synthetic modules. Both production\n // (composed) and unit-test (placeholder code) paths converge here.\n const fallbackCode = '@vertex fn vs() -> @builtin(position) vec4<f32> { return vec4<f32>(0.0); }';\n const src = composed ?? {\n equirectToCube: fallbackCode,\n irradiance: fallbackCode,\n prefilter: fallbackCode,\n brdfLut: fallbackCode,\n };\n\n const modules = await Promise.all([\n factory(device, { code: src.equirectToCube, label: 'ibl-equirect-to-cube' }),\n factory(device, { code: src.irradiance, label: 'ibl-irradiance' }),\n factory(device, { code: src.prefilter, label: 'ibl-prefilter' }),\n factory(device, { code: src.brdfLut, label: 'ibl-brdf-lut' }),\n ]);\n for (const m of modules) {\n if (!m.ok) return err(m.error);\n }\n const shaderModules = modules.flatMap((module) => (module.ok ? [module.value] : []));\n if (shaderModules.length !== 4) {\n return err(iblPipelineError('shader-modules', 'ibl-shader-module-missing'));\n }\n const [mEq, mIr, mPr, mBr] = shaderModules;\n if (mEq === undefined || mIr === undefined || mPr === undefined || mBr === undefined) {\n return err(iblPipelineError('shader-modules', 'ibl-shader-module-missing'));\n }\n\n // D-9: faceUniforms BGL shared across 3 pipelines (equirect / irradiance /\n // prefilter). The prefilter additionally needs binding(1) for prefUniforms;\n // we keep a separate BGL for the prefilter group(0) to honour the WGSL\n // declaration in ibl-prefilter.wgsl.\n const faceBgl = device.createBindGroupLayout({\n label: 'ibl-face-uniforms-bgl',\n entries: [{ binding: 0, visibility: GPU_SHADER_STAGE_VERTEX, buffer: { type: 'uniform' } }],\n });\n if (!faceBgl.ok) return err(faceBgl.error);\n cache.faceUniformsBgl = faceBgl.value;\n\n const prefilterGroup0 = device.createBindGroupLayout({\n label: 'ibl-prefilter-group0-bgl',\n entries: [\n { binding: 0, visibility: GPU_SHADER_STAGE_VERTEX, buffer: { type: 'uniform' } },\n { binding: 1, visibility: GPU_SHADER_STAGE_FRAGMENT, buffer: { type: 'uniform' } },\n ],\n });\n if (!prefilterGroup0.ok) return err(prefilterGroup0.error);\n cache.prefilterGroup0Bgl = prefilterGroup0.value;\n\n const equirectGroup1 = device.createBindGroupLayout({\n label: 'ibl-equirect-group1-bgl',\n entries: [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n },\n {\n binding: 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n ],\n });\n if (!equirectGroup1.ok) return err(equirectGroup1.error);\n cache.equirectGroup1Bgl = equirectGroup1.value;\n\n const cubeGroup1 = device.createBindGroupLayout({\n label: 'ibl-cube-group1-bgl',\n entries: [\n {\n binding: 0,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: 'cube' },\n },\n {\n binding: 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n },\n ],\n });\n if (!cubeGroup1.ok) return err(cubeGroup1.error);\n cache.cubeGroup1Bgl = cubeGroup1.value;\n\n // Pipeline layouts.\n const equirectLayout = device.createPipelineLayout({\n label: 'ibl-equirect-pipeline-layout',\n bindGroupLayouts: [faceBgl.value, equirectGroup1.value],\n });\n if (!equirectLayout.ok) return err(equirectLayout.error);\n const irradianceLayout = device.createPipelineLayout({\n label: 'ibl-irradiance-pipeline-layout',\n bindGroupLayouts: [faceBgl.value, cubeGroup1.value],\n });\n if (!irradianceLayout.ok) return err(irradianceLayout.error);\n const prefilterLayout = device.createPipelineLayout({\n label: 'ibl-prefilter-pipeline-layout',\n bindGroupLayouts: [prefilterGroup0.value, cubeGroup1.value],\n });\n if (!prefilterLayout.ok) return err(prefilterLayout.error);\n const brdfLutLayout = device.createPipelineLayout({\n label: 'ibl-brdf-lut-pipeline-layout',\n bindGroupLayouts: [],\n });\n if (!brdfLutLayout.ok) return err(brdfLutLayout.error);\n\n const vertexLayout3F = {\n arrayStride: 12,\n attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x3' as const }],\n };\n\n const pipeEquirect = device.createRenderPipeline({\n label: 'ibl-equirect-to-cube-pipeline',\n layout: equirectLayout.value,\n vertex: { module: mEq, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },\n fragment: {\n module: mEq,\n entryPoint: 'equirectToCube_fs',\n targets: [{ format: cubeOutputFormat }],\n },\n primitive: { topology: 'triangle-list', cullMode: 'none' },\n });\n if (!pipeEquirect.ok) return err(pipeEquirect.error);\n cache.equirectToCubePipeline = pipeEquirect.value;\n\n const pipeIrradiance = device.createRenderPipeline({\n label: 'ibl-irradiance-pipeline',\n layout: irradianceLayout.value,\n vertex: { module: mIr, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },\n fragment: {\n module: mIr,\n entryPoint: 'irradianceConvolve_fs',\n targets: [{ format: cubeOutputFormat }],\n },\n primitive: { topology: 'triangle-list', cullMode: 'none' },\n });\n if (!pipeIrradiance.ok) return err(pipeIrradiance.error);\n cache.irradiancePipeline = pipeIrradiance.value;\n\n const pipePrefilter = device.createRenderPipeline({\n label: 'ibl-prefilter-pipeline',\n layout: prefilterLayout.value,\n vertex: { module: mPr, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },\n fragment: {\n module: mPr,\n entryPoint: 'prefilterEnv_fs',\n targets: [{ format: cubeOutputFormat }],\n },\n primitive: { topology: 'triangle-list', cullMode: 'none' },\n });\n if (!pipePrefilter.ok) return err(pipePrefilter.error);\n cache.prefilterPipeline = pipePrefilter.value;\n\n const pipeBrdfLut = device.createRenderPipeline({\n label: 'ibl-brdf-lut-pipeline',\n layout: brdfLutLayout.value,\n vertex: { module: mBr, entryPoint: 'fullscreen_vs', buffers: [] },\n fragment: {\n module: mBr,\n entryPoint: 'brdfLutBake_fs',\n targets: [{ format: cubeOutputFormat }],\n },\n primitive: { topology: 'triangle-list', cullMode: 'none' },\n });\n if (!pipeBrdfLut.ok) return err(pipeBrdfLut.error);\n cache.brdfLutPipeline = pipeBrdfLut.value;\n\n return ok({\n equirectToCubePipeline: pipeEquirect.value,\n irradiancePipeline: pipeIrradiance.value,\n prefilterPipeline: pipePrefilter.value,\n brdfLutPipeline: pipeBrdfLut.value,\n });\n}\n\nfunction iblPipelineError(\n stage: string,\n code: IblPipelineError['code'],\n cause?: RhiError,\n): IblPipelineError {\n return {\n code,\n expected: `${stage} completed through the RHI Result contract`,\n hint: `inspect the ${stage} RHI error before retrying IBL pipeline creation`,\n detail: { stage, ...(cause === undefined ? {} : { rhiCode: cause.code }) },\n };\n}\n\n// ─── M3.5 t53: runIblPrecompute (4-pass dispatch + queue.submit) ─────────────\n\n/**\n * Options consumed by runIblPrecompute. The caller (the internal\n * GpuResidencyCache equirect-to-cubemap projection) provides the equirect input\n * + cubemap target GPU resources; the face-uniform / prefilter-uniform buffers\n * come from the t55 helpers.\n */\nexport interface RunIblPrecomputeOptions {\n readonly scope: DeviceScope;\n readonly device: IblRhiOwner;\n readonly equirectGpuTex: Texture;\n readonly equirectView: TextureView;\n readonly cubeGpuTex: Texture;\n readonly cubeView: TextureView;\n readonly cubeFaceViews: ReadonlyArray<TextureView>;\n readonly faceUniformsBuffer: Buffer;\n readonly prefilterUniformsBuffer: Buffer;\n readonly cubeVertexBuffer: Buffer;\n}\n\nexport interface IblPrecomputeError {\n readonly code: 'ibl-precompute-not-dispatched';\n readonly expected: string;\n readonly hint: string;\n readonly detail?: { readonly stage: string; readonly rhiCode?: RhiError['code'] };\n}\n\n/**\n * Execute the 4 IBL precompute passes (equirect-to-cube / irradiance /\n * prefilter / brdf-lut) in a single CommandEncoder and submit.\n *\n * Counter invariant (AC-20, plan D-7 / N-3): the\n * `irradiance/prefilter/brdfLut BakeCount` counters are incremented\n * AFTER queue.submit returns. If submit throws or returns Result.err, the\n * counters stay at 0 -- this is the prime safety guard against the\n * round-1 \"counter += 1 as dispatch proxy\" anti-pattern.\n *\n * Returns Result.err with code='ibl-precompute-not-dispatched' when the\n * underlying device lacks queue.submit or one of the 4 pipelines was not\n * created (createIblPipelines must run first).\n */\nexport function runIblPrecompute(\n opts: RunIblPrecomputeOptions,\n): Result<{ submitted: boolean }, IblPrecomputeError> {\n const { device, scope } = opts;\n const cache = getOrCreateIblCache(scope);\n const outputFormat = cache.outputFormat ?? 'rgba16float';\n\n if (\n cache.equirectToCubePipeline === undefined ||\n cache.irradiancePipeline === undefined ||\n cache.prefilterPipeline === undefined ||\n cache.brdfLutPipeline === undefined\n ) {\n return err({\n code: 'ibl-precompute-not-dispatched',\n expected: '4 IBL pipelines created via createIblPipelines',\n hint: 'check IblPipelineCache.createIblPipelines was called before runIblPrecompute; counters must not increment before queue.submit',\n detail: { stage: 'pipeline-cache' },\n });\n }\n\n // Allocate side textures (irradiance / prefilter / brdf-lut) lazily.\n // M5-amend Bug 1: dawn readback (t51 + reference baker) copies the\n // side textures back to a buffer via copyTextureToBuffer, which\n // requires the TextureUsage::CopySrc bit on the source. Without it\n // Dawn fails-fast \"usage doesn't include CopySrc\".\n\n if (cache.irradianceTexture === undefined) {\n const textureResult = device.createTexture({\n label: 'ibl-irradiance-cube',\n size: { width: IRRADIANCE_SIZE, height: IRRADIANCE_SIZE, depthOrArrayLayers: 6 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: outputFormat,\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |\n GPU_TEXTURE_USAGE_COPY_DST |\n GPU_TEXTURE_USAGE_COPY_SRC,\n viewFormats: [],\n textureBindingViewDimension: undefined,\n });\n if (!textureResult.ok) return err(badAlloc('irradiance-texture', textureResult.error));\n cache.irradianceTexture = textureResult.value;\n const cubeViewResult = device.createTextureView(textureResult.value, {\n label: 'ibl-irradiance-cube-view',\n dimension: 'cube',\n arrayLayerCount: 6,\n });\n if (!cubeViewResult.ok) return err(badAlloc('irradiance-view', cubeViewResult.error));\n cache.irradianceView = cubeViewResult.value;\n const faceViews: TextureView[] = [];\n for (let f = 0; f < 6; f++) {\n const viewResult = device.createTextureView(textureResult.value, {\n label: `ibl-irradiance-face-${f}`,\n dimension: '2d',\n baseArrayLayer: f,\n arrayLayerCount: 1,\n });\n if (!viewResult.ok) return err(badAlloc('irradiance-face-view', viewResult.error));\n faceViews.push(viewResult.value);\n }\n cache.irradianceFaceViews = faceViews;\n }\n\n if (cache.prefilterTexture === undefined) {\n const textureResult = device.createTexture({\n label: 'ibl-prefilter-cube',\n size: { width: PREFILTER_SIZE, height: PREFILTER_SIZE, depthOrArrayLayers: 6 },\n mipLevelCount: PREFILTER_MIP_LEVELS,\n sampleCount: 1,\n dimension: '2d',\n format: outputFormat,\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |\n GPU_TEXTURE_USAGE_COPY_DST |\n GPU_TEXTURE_USAGE_COPY_SRC,\n viewFormats: [],\n textureBindingViewDimension: undefined,\n });\n if (!textureResult.ok) return err(badAlloc('prefilter-texture', textureResult.error));\n cache.prefilterTexture = textureResult.value;\n const cubeViewResult = device.createTextureView(textureResult.value, {\n label: 'ibl-prefilter-cube-view',\n dimension: 'cube',\n arrayLayerCount: 6,\n baseMipLevel: 0,\n mipLevelCount: PREFILTER_MIP_LEVELS,\n });\n if (!cubeViewResult.ok) return err(badAlloc('prefilter-view', cubeViewResult.error));\n cache.prefilterView = cubeViewResult.value;\n const mipViews: TextureView[][] = [];\n for (let m = 0; m < PREFILTER_MIP_LEVELS; m++) {\n const faces: TextureView[] = [];\n for (let f = 0; f < 6; f++) {\n const viewResult = device.createTextureView(textureResult.value, {\n label: `ibl-prefilter-mip${m}-face${f}`,\n dimension: '2d',\n baseMipLevel: m,\n mipLevelCount: 1,\n baseArrayLayer: f,\n arrayLayerCount: 1,\n });\n if (!viewResult.ok) return err(badAlloc('prefilter-face-view', viewResult.error));\n faces.push(viewResult.value);\n }\n mipViews.push(faces);\n }\n cache.prefilterFaceViewsByMip = mipViews;\n }\n\n if (cache.brdfLutTexture === undefined) {\n const textureResult = device.createTexture({\n label: 'ibl-brdf-lut',\n size: { width: BRDF_LUT_SIZE, height: BRDF_LUT_SIZE, depthOrArrayLayers: 1 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: outputFormat,\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |\n GPU_TEXTURE_USAGE_COPY_DST |\n GPU_TEXTURE_USAGE_COPY_SRC,\n viewFormats: [],\n textureBindingViewDimension: undefined,\n });\n if (!textureResult.ok) return err(badAlloc('brdf-lut-texture', textureResult.error));\n cache.brdfLutTexture = textureResult.value;\n const viewResult = device.createTextureView(textureResult.value, {\n label: 'ibl-brdf-lut-view',\n dimension: '2d',\n });\n if (!viewResult.ok) return err(badAlloc('brdf-lut-view', viewResult.error));\n cache.brdfLutView = viewResult.value;\n }\n\n // Shared sampler (filtering, linear-linear).\n // U=repeat because equirect wraps horizontally (atan2 seam at ±π);\n // V=clamp because equirect poles are clamped vertically.\n const samplerResult = device.createSampler({\n label: 'ibl-precompute-sampler',\n magFilter: 'linear',\n minFilter: 'linear',\n mipmapFilter: 'linear',\n addressModeU: 'repeat',\n addressModeV: 'clamp-to-edge',\n addressModeW: 'clamp-to-edge',\n });\n if (!samplerResult.ok) return err(badAlloc('sampler', samplerResult.error));\n const sampler: Sampler = samplerResult.value;\n\n const encoderResult = device.createCommandEncoder({ label: 'ibl-precompute-encoder' });\n if (!encoderResult.ok) return err(badAlloc('encoder', encoderResult.error));\n const encoder: RhiCommandEncoder = encoderResult.value;\n\n const faceUniformsBgl = cache.faceUniformsBgl;\n const equirectGroup1Bgl = cache.equirectGroup1Bgl;\n const cubeGroup1Bgl = cache.cubeGroup1Bgl;\n const prefilterGroup0Bgl = cache.prefilterGroup0Bgl;\n const equirectPipeline = cache.equirectToCubePipeline;\n const irradiancePipeline = cache.irradiancePipeline;\n const prefilterPipeline = cache.prefilterPipeline;\n const brdfLutPipeline = cache.brdfLutPipeline;\n const irrFaceViews = cache.irradianceFaceViews;\n const prefMipViews = cache.prefilterFaceViewsByMip;\n const brdfLutView = cache.brdfLutView;\n if (\n faceUniformsBgl === undefined ||\n equirectGroup1Bgl === undefined ||\n cubeGroup1Bgl === undefined ||\n prefilterGroup0Bgl === undefined ||\n equirectPipeline === undefined ||\n irradiancePipeline === undefined ||\n prefilterPipeline === undefined ||\n brdfLutPipeline === undefined ||\n irrFaceViews === undefined ||\n prefMipViews === undefined ||\n brdfLutView === undefined\n ) {\n return err(badAlloc('ibl-cache-resources'));\n }\n\n // Bind group: equirect group(1).\n const equirectBgResult = device.createBindGroup({\n label: 'ibl-equirect-bg',\n layout: equirectGroup1Bgl,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: opts.equirectView } },\n { binding: 1, resource: { kind: 'sampler', value: sampler } },\n ],\n });\n if (!equirectBgResult.ok) return err(badAlloc('equirect-bg', equirectBgResult.error));\n const equirectBg: BindGroup = equirectBgResult.value;\n\n // Bind group: cube group(1) for irradiance + prefilter.\n const cubeBgResult = device.createBindGroup({\n label: 'ibl-cube-bg',\n layout: cubeGroup1Bgl,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: opts.cubeView } },\n { binding: 1, resource: { kind: 'sampler', value: sampler } },\n ],\n });\n if (!cubeBgResult.ok) return err(badAlloc('cube-bg', cubeBgResult.error));\n const cubeBg: BindGroup = cubeBgResult.value;\n\n // (a) equirect-to-cube: 6 face draws.\n const cubeFaceViews = opts.cubeFaceViews;\n for (let face = 0; face < 6; face++) {\n const cubeFaceView = cubeFaceViews[face];\n if (cubeFaceView === undefined) return err(badAlloc('cube-face-view'));\n const pass: RhiRenderPassEncoder = encoder.beginRenderPass({\n label: 'ibl-equirect-to-cube',\n colorAttachments: [\n {\n view: cubeFaceView,\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n loadOp: 'clear',\n storeOp: 'store',\n },\n ],\n });\n // Face uniform: dynamic offset = face * 256.\n const faceBgResult = device.createBindGroup({\n label: `ibl-face-bg-${face}`,\n layout: faceUniformsBgl,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: opts.faceUniformsBuffer,\n offset: face * 256,\n size: 64,\n },\n },\n },\n ],\n });\n if (!faceBgResult.ok) return err(badAlloc('face-bg', faceBgResult.error));\n pass.setPipeline(equirectPipeline);\n pass.setBindGroup(0, faceBgResult.value);\n pass.setBindGroup(1, equirectBg);\n pass.setVertexBuffer(0, opts.cubeVertexBuffer);\n pass.draw(6, 1, face * 6, 0);\n pass.end();\n }\n\n // (b) irradiance convolve: 6 face draws.\n for (let face = 0; face < 6; face++) {\n const irrFaceView = irrFaceViews[face];\n if (irrFaceView === undefined) return err(badAlloc('irradiance-face-view'));\n const pass: RhiRenderPassEncoder = encoder.beginRenderPass({\n label: 'ibl-irradiance',\n colorAttachments: [\n {\n view: irrFaceView,\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n loadOp: 'clear',\n storeOp: 'store',\n },\n ],\n });\n const faceBgResult = device.createBindGroup({\n label: `ibl-irr-face-bg-${face}`,\n layout: faceUniformsBgl,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: opts.faceUniformsBuffer,\n offset: face * 256,\n size: 64,\n },\n },\n },\n ],\n });\n if (!faceBgResult.ok) return err(badAlloc('irr-face-bg', faceBgResult.error));\n pass.setPipeline(irradiancePipeline);\n pass.setBindGroup(0, faceBgResult.value);\n pass.setBindGroup(1, cubeBg);\n pass.setVertexBuffer(0, opts.cubeVertexBuffer);\n pass.draw(6, 1, face * 6, 0);\n pass.end();\n }\n\n // (c) prefilter env: 5 mips x 6 faces = 30 sub-passes.\n for (let mip = 0; mip < PREFILTER_MIP_LEVELS; mip++) {\n const mipFaceViews = prefMipViews[mip];\n if (mipFaceViews === undefined) return err(badAlloc('prefilter-mip-views'));\n for (let face = 0; face < 6; face++) {\n const subIdx = mip * 6 + face;\n const mipFaceView = mipFaceViews[face];\n if (mipFaceView === undefined) return err(badAlloc('prefilter-face-view'));\n const pass: RhiRenderPassEncoder = encoder.beginRenderPass({\n label: 'ibl-prefilter',\n colorAttachments: [\n {\n view: mipFaceView,\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n loadOp: 'clear',\n storeOp: 'store',\n },\n ],\n });\n const bgResult = device.createBindGroup({\n label: `ibl-pref-bg-${subIdx}`,\n layout: prefilterGroup0Bgl,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: opts.faceUniformsBuffer,\n offset: face * 256,\n size: 64,\n },\n },\n },\n {\n binding: 1,\n resource: {\n kind: 'buffer',\n value: {\n buffer: opts.prefilterUniformsBuffer,\n offset: subIdx * 256,\n size: 16,\n },\n },\n },\n ],\n });\n if (!bgResult.ok) return err(badAlloc('pref-bg', bgResult.error));\n pass.setPipeline(prefilterPipeline);\n pass.setBindGroup(0, bgResult.value);\n pass.setBindGroup(1, cubeBg);\n pass.setVertexBuffer(0, opts.cubeVertexBuffer);\n pass.draw(6, 1, face * 6, 0);\n pass.end();\n }\n }\n\n // (d) brdf-lut: fullscreen triangle.\n {\n const pass: RhiRenderPassEncoder = encoder.beginRenderPass({\n label: 'ibl-brdf-lut',\n colorAttachments: [\n {\n view: brdfLutView,\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n loadOp: 'clear',\n storeOp: 'store',\n },\n ],\n });\n pass.setPipeline(brdfLutPipeline);\n pass.draw(3, 1, 0, 0);\n pass.end();\n }\n\n // Finish + submit. Counter increments are STRICTLY after submit; if\n // submit throws or fails, counters stay at 0 (AC-20 critical invariant).\n const finishRes = encoder.finish();\n if (!finishRes.ok) return err(badAlloc('finish', finishRes.error));\n const cmdBuffer: CommandBuffer = finishRes.value;\n const submitRes = device.queue.submit([cmdBuffer]);\n if (!submitRes.ok) return err(badAlloc('queue.submit', submitRes.error));\n\n // POST-SUBMIT counter increments (AC-20).\n cache.irradianceBakeCount += 1;\n cache.prefilterBakeCount += 1;\n cache.brdfLutBakeCount += 1;\n\n return ok({ submitted: true });\n}\n\n// Local helper -- structured error payload shared across allocation paths.\nfunction badAlloc(stage: string, cause?: RhiError): IblPrecomputeError {\n return {\n code: 'ibl-precompute-not-dispatched',\n expected: `${stage} allocated successfully`,\n hint: `check the RHI Result for ${stage}; counters must not increment before queue.submit`,\n ...(cause === undefined ? {} : { detail: { stage, rhiCode: cause.code } }),\n };\n}\n","import type { PointsLinesExpandedGeometry } from './expansion-cache';\nimport type { PointsLinesRetainedSnapshot } from './snapshot';\n\nexport const POINTS_LINES_MATERIAL_SHADER_ID = 'forgeax::points-lines';\n\nexport type PointsLinesLane = 'direct' | 'clustered' | 'cpu-webgl2';\nexport type PointsLinesBackend = 'webgpu' | 'wgpu-webgl2' | 'null';\n\nexport interface PointsLinesLaneContract {\n readonly lane: PointsLinesLane;\n readonly backend: PointsLinesBackend;\n readonly authoring: 'shared';\n readonly evidence: 'runtime' | 'structural-only';\n readonly material: {\n readonly source: 'MaterialAsset';\n readonly shaderId: typeof POINTS_LINES_MATERIAL_SHADER_ID;\n readonly shadingModel: 'unlit';\n readonly clusteredLighting: false;\n readonly lit: false;\n };\n readonly graph: {\n readonly additionalAttachments: 0;\n readonly additionalPasses: 0;\n };\n readonly shadowDrawCount: 0;\n readonly capabilities: {\n readonly compute: false;\n readonly storage: false;\n readonly indirect: false;\n };\n}\n\nexport interface PointsLinesRecordPlan {\n readonly lane: PointsLinesLane;\n readonly backend: PointsLinesBackend;\n readonly materialShaderId: typeof POINTS_LINES_MATERIAL_SHADER_ID;\n readonly component: 'Points' | 'Lines';\n readonly meshGeneration: number;\n readonly materialGeneration: number;\n readonly vertexCount: number;\n readonly indexCount: number;\n readonly drawCount: 0 | 1;\n readonly shadowDrawCount: 0;\n readonly conservativeMarginPx: number;\n readonly graph: PointsLinesLaneContract['graph'];\n}\n\n/**\n * Describes the shared lane boundary without selecting a backend in authoring.\n * Every lane uses CPU-uploaded triangle expansion; capability flags therefore\n * stay false, including on WebGPU, and the graph remains the existing pass.\n */\nexport function createPointsLinesLaneContract(\n lane: PointsLinesLane,\n backend: PointsLinesBackend,\n): PointsLinesLaneContract {\n return {\n lane,\n backend,\n authoring: 'shared',\n evidence: backend === 'null' ? 'structural-only' : 'runtime',\n material: {\n source: 'MaterialAsset',\n shaderId: POINTS_LINES_MATERIAL_SHADER_ID,\n shadingModel: 'unlit',\n clusteredLighting: false,\n lit: false,\n },\n graph: { additionalAttachments: 0, additionalPasses: 0 },\n shadowDrawCount: 0,\n capabilities: { compute: false, storage: false, indirect: false },\n };\n}\n\n/**\n * Turns one retained expansion into the bounded draw facts consumed by the\n * existing record pass. The shader expands one quad per point or segment,\n * so the limits are exactly four vertices and six indices per primitive.\n */\nexport function createPointsLinesRecordPlan(\n snapshot: PointsLinesRetainedSnapshot,\n geometry: PointsLinesExpandedGeometry,\n contract: PointsLinesLaneContract,\n): PointsLinesRecordPlan {\n const primitiveCount = geometry.pointCount + geometry.segmentCount;\n const visible = snapshot.visible && primitiveCount > 0;\n const conservativeMarginPx =\n snapshot.style?.kind === 'points'\n ? snapshot.style.sizePx * 0.5\n : (snapshot.style?.widthPx ?? 0) * 0.5;\n return {\n lane: contract.lane,\n backend: contract.backend,\n materialShaderId: POINTS_LINES_MATERIAL_SHADER_ID,\n component: geometry.component,\n meshGeneration: snapshot.meshGeneration,\n materialGeneration: snapshot.materialGeneration,\n vertexCount: primitiveCount * 4,\n indexCount: primitiveCount * 6,\n drawCount: visible ? 1 : 0,\n shadowDrawCount: 0,\n conservativeMarginPx,\n graph: contract.graph,\n };\n}\n\nexport interface PointsLinesLaneAdapter {\n readonly contract: PointsLinesLaneContract;\n createRecordPlan(\n snapshot: PointsLinesRetainedSnapshot,\n geometry: PointsLinesExpandedGeometry,\n ): PointsLinesRecordPlan;\n}\n\nexport function createPointsLinesLaneAdapter(\n lane: PointsLinesLane,\n backend: PointsLinesBackend,\n): PointsLinesLaneAdapter {\n const contract = createPointsLinesLaneContract(lane, backend);\n return {\n contract,\n createRecordPlan: (snapshot, geometry) =>\n createPointsLinesRecordPlan(snapshot, geometry, contract),\n };\n}\n","// @forgeax/engine-runtime / gpu-resource\n//\n// feat-20260612-rhi-destroy-renderer-dispose-gpu-lifecycle / M2 / w7 + w8.\n//\n// Runtime-side wrappers around RHI Buffer / Texture opaque handles that\n// expose an explicit `.destroy()` lifecycle and an `isDestroyed` flag.\n//\n// Design rationale (charter + plan-strategy + architecture-principles):\n//\n// - SSOT (architecture-principles §1): the lifecycle bookkeeping (the\n// \"is this handle destroyed yet?\" fact) lives once in the RHI shim\n// layer (rhi-webgpu device.ts: BUFFER_META_MAP / TEXTURE_META_MAP;\n// rhi-wgpu device.ts: same shape over the wgpu wasm boundary). The\n// runtime wrapper does NOT keep its own destroyed: Set; it forwards\n// to `device.destroyBuffer(handle)` / `device.destroyTexture(handle)`\n// and lets the RHI shim be the authority. The local `destroyed`\n// boolean is a derived view (architecture-principles §2 Derive,\n// Don't Duplicate) for the synchronous `isDestroyed` getter --\n// flipped on the success branch of the forward, never on the err\n// branch (so a second destroy preserves the prior `true`).\n//\n// - Concept compression (charter F1 / AGENTS.md design axiom): a\n// single union `type GpuResource = GpuBuffer | GpuTexture` covers\n// both buffer and texture lifecycles so AI-user-facing code that\n// just wants \"a GPU resource I need to dispose\" reaches one\n// symbol. Parallel classes (not a runtime-tagged generic\n// `GpuResource<'buffer' | 'texture'>`) so the shape mirrors the\n// RHI opaque-handle taxonomy verbatim and TS narrowing on\n// instanceof / `'data' in r` keeps each branch typed end-to-end\n// (plan-strategy D-2).\n//\n// - v1 single-owner immortal (requirements §Constraints 8): no refcount,\n// no shared ownership, no move semantics. The wrapper holds the\n// handle once; whoever constructed it disposes it. A future\n// refcount layer (if needed) wraps GpuResource externally without\n// re-entering this file.\n//\n// - Plain boolean isDestroyed (plan-strategy D-5): no typed-state\n// narrowing (i.e. no `Live<GpuBuffer>` / `Destroyed<GpuBuffer>`\n// compile-time partition). The check happens at runtime via the\n// getter; the RHI fail-fast on second destroy is the structural\n// guard. Keeps the public type surface flat (charter F1: one\n// symbol, not three states).\n//\n// - RHI stays spec-aligned and opaque-handle-only (requirements\n// §Constraints 3): GpuResource is a runtime concept; the RHI package\n// exports no wrapper class.\n//\n// Failure paths (forwarded verbatim from RhiDevice):\n// - second `.destroy()` on the same wrapper -> `Result.err({ code:\n// 'destroy-after-destroy', ... })` (RHI errors.ts §RhiErrorCode;\n// introduced in feat-20260612 M1 / w1).\n\nimport type { Buffer, Result, RhiDevice, RhiError, Texture } from '@forgeax/engine-rhi';\n\n/**\n * Runtime wrapper around an RHI `Buffer` opaque handle that exposes\n * an explicit `.destroy()` lifecycle.\n *\n * Holds the device by reference (no clone); the device's own lifetime\n * outlives the buffer. After `.destroy()` returns ok, `isDestroyed`\n * flips to true; a second `.destroy()` returns err code\n * `'destroy-after-destroy'` forwarded from `device.destroyBuffer(...)`.\n *\n * @example\n * import { GpuBuffer } from './gpu-resource';\n * const created = device.createBuffer({ size: 64, usage: GPUBufferUsage.STORAGE });\n * if (!created.ok) return;\n * const gpuBuf = new GpuBuffer(device, created.value);\n * // ... use gpuBuf.handle in RHI calls ...\n * const r = gpuBuf.destroy();\n * if (!r.ok) {\n * // r.error.code is one of the RhiErrorCode union members,\n * // typically 'destroy-after-destroy' on a stale handle.\n * }\n */\nexport class GpuBuffer {\n readonly device: RhiDevice;\n readonly handle: Buffer;\n // SSOT note: the canonical destroyed: boolean lives on the RHI shim's\n // BUFFER_META_MAP. This local flag is a derived view written only on\n // the success branch of `device.destroyBuffer(...)`; charter §F1.\n private destroyed = false;\n\n constructor(device: RhiDevice, handle: Buffer) {\n this.device = device;\n this.handle = handle;\n }\n\n get isDestroyed(): boolean {\n return this.destroyed;\n }\n\n /**\n * Destroy the underlying GPU buffer. Forwards to\n * `device.destroyBuffer(handle)`; on ok flips `isDestroyed` to true,\n * on err leaves the flag unchanged so a downstream second destroy\n * still surfaces the underlying RHI fail-fast.\n */\n destroy(): Result<void, RhiError> {\n const r = this.device.destroyBuffer(this.handle);\n if (r.ok) {\n this.destroyed = true;\n }\n return r;\n }\n}\n\n/**\n * Runtime wrapper around an RHI `Texture` opaque handle that exposes\n * an explicit `.destroy()` lifecycle. Mirrors `GpuBuffer` exactly --\n * the only difference is the underlying RHI surface\n * (`device.destroyTexture` instead of `device.destroyBuffer`) and the\n * handle brand. Same SSOT rationale: the destroyed bookkeeping lives\n * on the RHI shim's TEXTURE_META_MAP; the local flag is a derived view.\n *\n * @example\n * import { GpuTexture } from './gpu-resource';\n * const r = device.createTexture({ size: [w, h, 1], format: 'rgba8unorm', usage: ... });\n * if (!r.ok) return;\n * const gpuTex = new GpuTexture(device, r.value);\n * // ... use gpuTex.handle in RHI calls ...\n * gpuTex.destroy();\n */\nexport class GpuTexture {\n readonly device: RhiDevice;\n readonly handle: Texture;\n private destroyed = false;\n\n constructor(device: RhiDevice, handle: Texture) {\n this.device = device;\n this.handle = handle;\n }\n\n get isDestroyed(): boolean {\n return this.destroyed;\n }\n\n /**\n * Destroy the underlying GPU texture. Forwards to\n * `device.destroyTexture(handle)`; ok branch sets `isDestroyed=true`.\n */\n destroy(): Result<void, RhiError> {\n const r = this.device.destroyTexture(this.handle);\n if (r.ok) {\n this.destroyed = true;\n }\n return r;\n }\n}\n\n/**\n * Union of runtime-managed GPU resources requiring explicit\n * `.destroy()`. AI-user-facing code that needs to dispose \"a GPU\n * resource\" types its parameter as `GpuResource` and lets TS narrow\n * via `instanceof GpuBuffer / GpuTexture` if branch-specific access\n * is required. Charter F1 single-entry indexability.\n */\nexport type GpuResource = GpuBuffer | GpuTexture;\n","// skylight-bind-group.ts -- Skylight resources merged into @group(1) PBR\n// material BGL (binding 7..13) + fallback identity resource bundle. The\n// complete Standard material group appends transmission entries.\n//\n// Plan-strategy D-5 (round-4 REVISED): the round-2 stand-alone @group(4)\n// Skylight BindGroupLayout collided with WebGPU's default maxBindGroups=4\n// limit, blocking pbr-pl pipeline-layout creation in chrome-beta. Round-4\n// rewrites the contract: Skylight 7 entries are **appended** to the\n// existing PBR material BindGroupLayout at bindings 7..13; pipeline layout\n// stays at 4 slots `[view, material, mesh, instances]`; unlit pipeline is\n// untouched (it uses its own material BGL).\n//\n// Surface (M2 round-4 / t40 amend):\n// - mergeSkylightIntoMaterialBgl(materialBglEntries): given the existing\n// 7 PBR material BindGroupLayout entries (binding 0..6), returns the\n// merged 14-entry array with Skylight resources at binding 7..13\n// [irrTex, irrSampler, prefTex, prefSampler, brdfTex, brdfSampler,\n// uniform { intensity: f32 }]. The merge is a pure function -- caller\n// (createRenderer) is responsible for passing the result to\n// `device.createBindGroupLayout`.\n// - assembleMaterialWithSkylightEntries(materialEntries, skylightResources):\n// given the existing material BindGroupEntry values + a skylight\n// resource bundle (active or fallback), returns the merged material\n// array with the engine-owned transmission pair at the end, suitable for\n// `device.createBindGroup`. Charter P5 minimal\n// surface: this helper does NOT allocate samplers/textures itself.\n// - createSkylightFallback(device, queue): allocate a 1x1 white\n// irradiance/prefilter cube pair + a 1x1 BRDF approximation + intensity=0 uniform\n// buffer + a shared linear/clamp sampler. Returns the resource bundle\n// so createRenderer can wire it into PipelineState.skylightFallback;\n// no stand-alone bindGroup is created (that was the round-2 shape).\n//\n// All resources write into PipelineState.skylightFallback so the M4\n// recordFrame branch (Skylight present vs absent) selects active vs\n// fallback resources when assembling the PBR material BindGroup\n// (charter P4 consistent abstraction -- one BG layout, one assembly path).\n// The irradiance texture uses the canonical irradianceEOverPi payload semantic;\n// sampling applies the single E/pi normalization at the shader callsite.\n\nimport type {\n BindGroupEntry,\n Buffer,\n Result,\n RhiError,\n Sampler,\n SamplerDescriptor,\n Texture,\n TextureDescriptor,\n TextureView,\n TextureViewDescriptor,\n} from '@forgeax/engine-rhi';\nimport { GPU_SHADER_STAGE_FRAGMENT } from '../gpu-stage';\nimport {\n GPU_TEXTURE_USAGE_COPY_DST,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from '../gpu-texture-usage';\nimport { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from '../gpu-usage';\n\n// The rhi shim enforces bytesPerRow % 256 === 0 uniformly (see\n// fallback-white texture upload in createRenderer.ts). Pad each 1x1 face\n// upload to a 256-byte row stride.\nexport const FALLBACK_BYTES_PER_ROW = 256;\n\n// Local alias for the @webgpu/types BindGroupLayoutEntry shape. Used at\n// object-literal push sites below to dodge the AC-08 (j) `as GPU<Type>`\n// grep gate (charter proposition 5 red line for shim leaks); the underlying\n// type is identical to GPUBindGroupLayoutEntry, so byte-level behavior is\n// unchanged. engine-rhi does not yet re-export a BindGroupLayoutEntry alias\n// (the public surface is BindGroupLayoutDescriptor which Picks `entries`);\n// once it does this alias collapses into a direct import.\ntype BglEntry = GPUBindGroupLayoutEntry;\n\n// ─── Device shim shapes ──────────────────────────────────────────────────────\n//\n// We accept a structural subset of RhiDevice so unit tests can pass a\n// mocked device without standing up the full RHI surface. The createRenderer\n// production path passes a real RhiDevice; both satisfy the interface.\n\n/**\n * Minimal RhiDevice subset used by the skylight fallback helper.\n * Mirrors RhiDevice for the methods touched by this module (charter P4\n * narrowest surface -- avoids dragging the full RhiDevice in for tests).\n */\nexport interface SkylightDevice {\n createSampler(desc: SamplerDescriptor): Result<Sampler, RhiError>;\n createTexture(desc: TextureDescriptor): Result<Texture, RhiError>;\n createTextureView(tex: Texture, desc: TextureViewDescriptor): Result<TextureView, RhiError>;\n createBuffer(desc: {\n label?: string | undefined;\n size: number;\n usage: number;\n mappedAtCreation?: boolean | undefined;\n }): Result<Buffer, RhiError>;\n}\n\n/**\n * Minimal queue subset used for fallback resource upload (zero-pixel\n * texture seed + intensity=0 uniform seed).\n */\nexport interface SkylightQueue {\n writeTexture(\n destination: {\n texture: Texture;\n mipLevel?: number;\n origin?: { x: number; y: number; z: number };\n },\n data: ArrayBufferView,\n dataLayout: { offset: number; bytesPerRow: number; rowsPerImage: number },\n size: { width: number; height: number; depthOrArrayLayers: number },\n ): Result<void, RhiError> | unknown;\n writeBuffer(\n buffer: Buffer,\n bufferOffset: number,\n data: ArrayBufferView,\n ): Result<void, RhiError> | unknown;\n}\n\n// ─── Public types ───────────────────────────────────────────────────────────\n\n/**\n * Skylight bind group resources (cube + cube + 2D LUT + intensity uniform).\n * The active set comes from the IblPipelineCache precompute path; the\n * fallback set is the 1x1 zero identity bundle below.\n */\nexport interface SkylightBindGroupResources {\n readonly irradianceView: TextureView;\n readonly irradianceSampler: Sampler;\n readonly prefilterView: TextureView;\n readonly prefilterSampler: Sampler;\n readonly brdfLutView: TextureView;\n readonly brdfLutSampler: Sampler;\n readonly intensityBuffer: Buffer;\n}\n\n/**\n * Fallback resource bundle attached to `PipelineState.skylightFallback`.\n * The M4 round-4 recordFrame branch reads this bundle when\n * `skylightCount === 0` and feeds it through\n * `assembleMaterialWithSkylightEntries` so the PBR material BindGroup\n * binds the same 14-entry layout shape with zero data + intensity=0.\n *\n * No stand-alone `bindGroup` field: the round-2 stand-alone Skylight BG\n * is gone (D-5 round-4); the fallback resources flow into the PBR\n * material BG at binding 7..13.\n */\nexport interface SkylightFallback {\n readonly irradianceTexture: Texture;\n readonly irradianceView: TextureView;\n readonly prefilterTexture: Texture;\n readonly prefilterView: TextureView;\n readonly brdfLutTexture: Texture;\n readonly brdfLutView: TextureView;\n readonly sampler: Sampler;\n readonly intensityBuffer: Buffer;\n}\n\n// ─── Pure merger: BindGroupLayout entries (D-5 round-4) ─────────────────────\n\n/**\n * Append the 7 Skylight BindGroupLayout entries after the existing PBR\n * user-region entries. Pure function -- the\n * caller passes the result to `device.createBindGroupLayout`. Charter P4\n * consistent abstraction: one BGL holds material + Skylight together,\n * no second `@group(4)` allocated.\n *\n * Throws if the input is too short to contain the material UBO plus one\n * sampler/texture pair (defensive guard; mirrors charter P3 explicit failure).\n */\nexport function mergeSkylightIntoMaterialBgl(\n materialBglEntries: readonly GPUBindGroupLayoutEntry[],\n): GPUBindGroupLayoutEntry[] {\n if (materialBglEntries.length < 7) {\n throw new Error(\n `mergeSkylightIntoMaterialBgl: expected at least 7 material BGL entries (PBR layout), got ${materialBglEntries.length}`,\n );\n }\n const merged: GPUBindGroupLayoutEntry[] = [...materialBglEntries];\n const skylightBindingStart = materialBglEntries.length;\n // binding 7: irradianceMap (texture_cube)\n merged.push({\n binding: skylightBindingStart,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: 'cube' },\n } as BglEntry);\n // binding 8: irradianceSampler\n merged.push({\n binding: skylightBindingStart + 1,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n } as BglEntry);\n // binding 9: prefilterMap (texture_cube)\n merged.push({\n binding: skylightBindingStart + 2,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: 'cube' },\n } as BglEntry);\n // binding 10: prefilterSampler\n merged.push({\n binding: skylightBindingStart + 3,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n } as BglEntry);\n // binding 11: brdfLut (texture_2d)\n merged.push({\n binding: skylightBindingStart + 4,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n } as BglEntry);\n // binding 12: brdfLutSampler\n merged.push({\n binding: skylightBindingStart + 5,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n sampler: { type: 'filtering' },\n } as BglEntry);\n // binding 13: uniform { intensity: f32 }\n merged.push({\n binding: skylightBindingStart + 6,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n buffer: { type: 'uniform' },\n } as BglEntry);\n return merged;\n}\n\n// ─── Pure merger: BindGroupEntry values (assembly site) ─────────────────────\n\n/**\n * Append the 7 Skylight BindGroupEntry resources (binding 7..13) onto the\n * existing PBR material BindGroupEntry values (binding 0..6). The caller\n * passes the result to `device.createBindGroup` as part of the merged\n * material BG.\n *\n * The skylight argument may be the fallback identity bundle (rendered\n * with ambient=0) or the active IblPipelineCache output bundle. Same\n * call site, same layout shape -- charter P4 + F1 (AI users do not need\n * a `if (hasSkylight)` branch when writing demos).\n */\n/** Engine-owned material transmission injection resources. */\nexport interface TransmissionBindGroupResources {\n readonly sampler: Sampler;\n readonly backdropView?: TextureView | null;\n}\n\n// Lightmap (emissive + occlusion sampler/texture pair x 2) and transmission\n// injection starts are computed from the assembled list length on each push —\n// no hardcoded binding literals.\n\nexport function assembleMaterialWithSkylightEntries(\n materialEntries: readonly BindGroupEntry[],\n skylight: SkylightBindGroupResources,\n transmission?: TransmissionBindGroupResources | undefined,\n): BindGroupEntry[] {\n // IBL injection start = end of the user-region. The user-region IS\n // `materialEntries` (UBO binding 0 + N sampler/texture pairs), so its length\n // is the injection start — was a hardcoded 7, now per-shader (a 4-texture\n // parallax material's user-region is 9 entries, so IBL lands at 9). This\n // mirrors the BGL-side `appendInjection(userRegion, 'ibl')` (D-1 / D-8),\n // which likewise reads `bgl.length`.\n const iblStart = materialEntries.length;\n const result: BindGroupEntry[] = [\n ...materialEntries,\n {\n binding: iblStart,\n resource: { kind: 'textureView', value: skylight.irradianceView },\n },\n {\n binding: iblStart + 1,\n resource: { kind: 'sampler', value: skylight.irradianceSampler },\n },\n {\n binding: iblStart + 2,\n resource: { kind: 'textureView', value: skylight.prefilterView },\n },\n {\n binding: iblStart + 3,\n resource: { kind: 'sampler', value: skylight.prefilterSampler },\n },\n {\n binding: iblStart + 4,\n resource: { kind: 'textureView', value: skylight.brdfLutView },\n },\n {\n binding: iblStart + 5,\n resource: { kind: 'sampler', value: skylight.brdfLutSampler },\n },\n {\n binding: iblStart + 6,\n resource: { kind: 'buffer', value: { buffer: skylight.intensityBuffer } },\n },\n ];\n // Transmission injection is always present after IBL. Non-transmission\n // variants bind the existing Skylight resources as layout-only placeholders;\n // they are not a functional fallback and are never sampled by those shaders.\n const transmissionSampler = transmission?.sampler ?? skylight.irradianceSampler;\n const transmissionView = transmission?.backdropView ?? skylight.brdfLutView;\n const transmissionStart = result.length;\n result.push(\n {\n binding: transmissionStart,\n resource: { kind: 'sampler', value: transmissionSampler },\n },\n {\n binding: transmissionStart + 1,\n resource: { kind: 'textureView', value: transmissionView },\n },\n );\n return result;\n}\n\n// ─── Fallback constructor (createRenderer wires this into pipelineState) ────\n\n/**\n * Allocate the fallback Skylight resource bundle: 1x1 WHITE rgba16float\n * irradiance/prefilter texture_cube pair + 1x1 rg16float BRDF approximation\n * `[1, 0]` + a 16-byte uniform buffer + a single\n * linear / clamp-to-edge sampler reused across all three texture slots.\n *\n * Two regimes share this bundle (the per-frame Skylight uniform selects):\n * - No Skylight entity: render-system-record writes intensity=0, so\n * ambient = whiteIrradiance * kD * albedo * color * 0 == 0\n * -- physically black, no `if (hasSkylight)` shader branch (D-5 round-4).\n * - Skylight with NO cubemap (downstream integration #4): record writes the\n * user's intensity + color, so the WHITE irradiance gives an instant\n * solid-color ambient and a neutral white specular reflection with no\n * async precompute. The 1x1 BRDF approximation is intentionally roughness\n * independent; a real cubemap swaps in the prefiltered IBL views and LUT.\n *\n * No stand-alone BindGroupLayout / BindGroup is created here -- those\n * roles moved into the PBR material BGL factory (D-5 round-4). The\n * caller (createRenderer) feeds the resource handles below through\n * `assembleMaterialWithSkylightEntries` when composing the per-frame\n * material BindGroup.\n */\nexport function createSkylightFallback(\n device: SkylightDevice,\n queue: SkylightQueue,\n): SkylightFallback {\n // One sampler shared across the three texture slots. The PBR material\n // BindGroup still declares 3 separate sampler bindings (D-5 round-4\n // ordering at binding 8/10/12), so we pass the same handle three times\n // in assembleMaterialWithSkylightEntries; WebGPU spec permits sampler\n // reuse across BindGroupEntry slots.\n const samplerResult = device.createSampler({\n label: 'skylight-fallback-sampler',\n magFilter: 'linear',\n minFilter: 'linear',\n mipmapFilter: 'linear',\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n addressModeW: 'clamp-to-edge',\n });\n if (!samplerResult.ok) throw samplerResult.error;\n const sampler = samplerResult.value;\n\n // 1x1 all-zero rgba16float cube (irradiance fallback). depthOrArrayLayers=6\n // gives the texture cube semantics (D-5 fallback shape; testable via\n // createTexture descriptor capture in unit tests).\n const irradianceTexResult = device.createTexture({\n label: 'skylight-fallback-irradiance-cube',\n size: { width: 1, height: 1, depthOrArrayLayers: 6 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: 'rgba16float',\n usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST,\n viewFormats: [],\n textureBindingViewDimension: 'cube',\n });\n if (!irradianceTexResult.ok) throw irradianceTexResult.error;\n const irradianceTexture = irradianceTexResult.value;\n\n // 1x1 white rgba16float cube (prefilter fallback). A Skylight without an\n // equirect is still a white environment, so its specular input must not be\n // black just because the full prefilter bake is unavailable.\n const prefilterTexResult = device.createTexture({\n label: 'skylight-fallback-prefilter-cube',\n size: { width: 1, height: 1, depthOrArrayLayers: 6 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: 'rgba16float',\n usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST,\n viewFormats: [],\n textureBindingViewDimension: 'cube',\n });\n if (!prefilterTexResult.ok) throw prefilterTexResult.error;\n const prefilterTexture = prefilterTexResult.value;\n\n // 1x1 rg16float BRDF approximation (A=1, B=0). This keeps the split-sum\n // specular response non-zero for the white-environment fallback; a real IBL\n // bake replaces it with the roughness/NdotV-dependent LUT.\n const brdfLutTexResult = device.createTexture({\n label: 'skylight-fallback-brdf-lut',\n size: { width: 1, height: 1, depthOrArrayLayers: 1 },\n mipLevelCount: 1,\n sampleCount: 1,\n dimension: '2d',\n format: 'rg16float',\n usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST,\n viewFormats: [],\n textureBindingViewDimension: undefined,\n });\n if (!brdfLutTexResult.ok) throw brdfLutTexResult.error;\n const brdfLutTexture = brdfLutTexResult.value;\n\n // 1x1 rgba16float = 8 bytes per pixel; 1x1 rg16float = 4 bytes per pixel.\n // The shim requires bytesPerRow % 256 === 0, so we pad each row to 256 bytes\n // (matches the fallback-white pattern in createRenderer.ts). Destination\n // stays 1x1; only the row stride is padded.\n //\n // A Skylight with no cubemap represents a flat white environment. Both\n // irradiance and prefilter are therefore white (half-float 1.0 = 0x3c00),\n // while the BRDF fallback approximates `A=1, B=0`. Crucially this does NOT\n // light scenes that lack a Skylight: the per-frame Skylight uniform writes\n // intensity 0 when no Skylight entity exists (render-system-record).\n const whitePixel = new Uint8Array(FALLBACK_BYTES_PER_ROW);\n {\n const dv = new DataView(whitePixel.buffer);\n // RGBA half-float 1.0 = 0x3c00 (little-endian) at byte offsets 0,2,4,6.\n dv.setUint16(0, 0x3c00, true);\n dv.setUint16(2, 0x3c00, true);\n dv.setUint16(4, 0x3c00, true);\n dv.setUint16(6, 0x3c00, true);\n }\n const brdfApproxPixel = new Uint8Array(FALLBACK_BYTES_PER_ROW);\n new DataView(brdfApproxPixel.buffer).setUint16(0, 0x3c00, true);\n for (const face of [0, 1, 2, 3, 4, 5]) {\n queue.writeTexture(\n {\n texture: irradianceTexture,\n mipLevel: 0,\n origin: { x: 0, y: 0, z: face },\n },\n whitePixel,\n { offset: 0, bytesPerRow: FALLBACK_BYTES_PER_ROW, rowsPerImage: 1 },\n { width: 1, height: 1, depthOrArrayLayers: 1 },\n );\n queue.writeTexture(\n {\n texture: prefilterTexture,\n mipLevel: 0,\n origin: { x: 0, y: 0, z: face },\n },\n whitePixel,\n { offset: 0, bytesPerRow: FALLBACK_BYTES_PER_ROW, rowsPerImage: 1 },\n { width: 1, height: 1, depthOrArrayLayers: 1 },\n );\n }\n queue.writeTexture(\n {\n texture: brdfLutTexture,\n mipLevel: 0,\n origin: { x: 0, y: 0, z: 0 },\n },\n brdfApproxPixel,\n { offset: 0, bytesPerRow: FALLBACK_BYTES_PER_ROW, rowsPerImage: 1 },\n { width: 1, height: 1, depthOrArrayLayers: 1 },\n );\n\n // Cube views over the depthOrArrayLayers=6 textures so the @group(1)\n // @binding(7,9) texture_cube bindings can sample them.\n const irradianceViewResult = device.createTextureView(irradianceTexture, {\n label: 'skylight-fallback-irradiance-cube-view',\n dimension: 'cube',\n arrayLayerCount: 6,\n });\n if (!irradianceViewResult.ok) throw irradianceViewResult.error;\n const irradianceView = irradianceViewResult.value;\n\n const prefilterViewResult = device.createTextureView(prefilterTexture, {\n label: 'skylight-fallback-prefilter-cube-view',\n dimension: 'cube',\n arrayLayerCount: 6,\n });\n if (!prefilterViewResult.ok) throw prefilterViewResult.error;\n const prefilterView = prefilterViewResult.value;\n\n const brdfLutViewResult = device.createTextureView(brdfLutTexture, {\n label: 'skylight-fallback-brdf-lut-view',\n dimension: '2d',\n });\n if (!brdfLutViewResult.ok) throw brdfLutViewResult.error;\n const brdfLutView = brdfLutViewResult.value;\n\n // intensity=0 uniform. The WGSL struct is two vec4-aligned lanes:\n // [intensity, colorR, colorG, colorB] + [rotation quaternion].\n const intensityBufResult = device.createBuffer({\n label: 'skylight-fallback-intensity',\n size: 32,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n });\n if (!intensityBufResult.ok) throw intensityBufResult.error;\n const intensityBuffer = intensityBufResult.value;\n queue.writeBuffer(intensityBuffer, 0, new Float32Array([0, 0, 0, 0, 0, 0, 0, 1]));\n\n return {\n irradianceTexture,\n irradianceView,\n prefilterTexture,\n prefilterView,\n brdfLutTexture,\n brdfLutView,\n sampler,\n intensityBuffer,\n };\n}\n","// @forgeax/engine-runtime - RenderData projection layer\n// (feat-20260601-device/gpu-residency-extraction M2 / w5).\n//\n// The middle of the three GPU-asset layers: AssetRegistry catalogues CPU asset\n// POD; `deriveRenderData*` PROJECTS a POD into the GPU descriptor a resource\n// build needs; GpuResidencyCache owns device-side resource life/death. These\n// projections are PURE -- they know the asset `kind` but never touch a device\n// (AC-07). The store consumes the descriptor and does the createTexture /\n// createBuffer / writeX work.\n//\n// Coverage is exactly the three GPU-resource kinds (mesh / texture / equirect,\n// the latter projected to a cubemap). Asset kinds with no GPU residency are\n// never projected -- the\n// `ensureResident` miss switch dispatches per-kind with no default, so a fourth\n// GPU-resource kind would surface as a `tsc -b` exhaustiveness error at the\n// switch rather than a silent fallthrough (AC-06).\n\nimport {\n bytesPerRow as blockBytesPerRow,\n blockParamsForFormat,\n isCompressedFormat,\n} from '@forgeax/engine-codec';\nimport {\n deriveVertexLayoutProjection,\n type VertexLayoutProjection,\n} from '@forgeax/engine-geometry';\nimport { err, ok, type Result } from '@forgeax/engine-rhi';\nimport {\n ASSET_ERROR_HINTS,\n type AssetError,\n deriveTextureLayout,\n type MeshAsset,\n type Submesh,\n type TextureAsset,\n type TextureShape,\n} from '@forgeax/engine-types';\nimport {\n GPU_TEXTURE_USAGE_COPY_DST,\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from './gpu-texture-usage';\nimport {\n GPU_BUFFER_USAGE_COPY_DST,\n GPU_BUFFER_USAGE_INDEX,\n GPU_BUFFER_USAGE_VERTEX,\n} from './gpu-usage';\n\n// AssetError without importing AssetRegistry: build the 4-field surface\n// (.code / .expected / .hint) directly against the @forgeax/engine-types SSOT\n// (charter P5 producer / consumer split; mirrors the store's RuntimeAssetError).\nclass ProjectionAssetError extends Error implements AssetError {\n readonly code: AssetError['code'];\n readonly expected: string;\n readonly hint: string;\n constructor(fields: { code: AssetError['code']; expected: string; hint: string }) {\n super(`[AssetError ${fields.code}] expected: ${fields.expected}; hint: ${fields.hint}`);\n this.name = 'AssetError';\n this.code = fields.code;\n this.expected = fields.expected;\n this.hint = fields.hint;\n }\n}\n\nfunction projectionError(fields: {\n code: AssetError['code'];\n expected: string;\n hint: string;\n}): AssetError {\n return new ProjectionAssetError(fields);\n}\n\n/** Descriptor for a mesh's GPU vertex + index buffers (projected from POD). */\nexport interface MeshRenderData {\n readonly vertexByteLength: number;\n /** Geometry-owned immutable layout facts used by all GPU consumers. */\n readonly layoutProjection: VertexLayoutProjection;\n /** Index byte length padded up to a 4-byte multiple (writeBuffer alignment). */\n readonly indexByteLength: number;\n readonly indexCount: number;\n readonly indexFormat: 'uint16' | 'uint32';\n readonly vertexUsage: number;\n readonly indexUsage: number;\n /**\n * Submeshes from the source MeshAsset, projected verbatim to the GPU store\n * so the record stage can iterate per-submesh draw calls (feat-20260608 M4 / w16).\n * Mirrors MeshAsset.submeshes (readonly Submesh[]) 1:1.\n */\n readonly submeshes: readonly Submesh[];\n}\n\n/** Descriptor for a sampled texture's GPU resource (projected from POD). */\nexport interface TextureRenderData {\n /** Logical width retained for existing projection consumers. */\n readonly width: number;\n /** Logical height retained for existing projection consumers. */\n readonly height: number;\n /** Authored shape; the residency layer must preserve this view dimension. */\n readonly shape: TextureShape;\n /** Array layers for `2d-array`, depth slices for `3d`, otherwise one. */\n readonly depthOrArrayLayers: number;\n /** Authored content extent; TextureAsset remains the logical asset SSOT. */\n readonly logicalExtent: TextureExtent;\n /** GPU allocation extent, derived from format + logicalExtent. */\n readonly physicalExtent: TextureExtent;\n /** Maps logical UVs away from block padding. */\n readonly uvScale: readonly [number, number];\n readonly format: GPUTextureFormat;\n readonly mipLevelCount: number;\n readonly usage: number;\n /**\n * Row pitch for the BASE mip (level 0) the store passes to `writeTexture`.\n * Derived from the canonical texture layout, so format-specific uncompressed\n * widths (for example R8 density) and block-compressed widths stay aligned\n * with the upload contract. The per-mip layout for a multi-level compressed\n * upload comes from {@link deriveMipUploadLayout}.\n */\n readonly bytesPerRow: number;\n /** True iff `format` is a block-compressed format (drives the store's upload arm). */\n readonly compressed: boolean;\n}\n\nexport interface TextureExtent {\n readonly width: number;\n readonly height: number;\n}\n\n/**\n * The sole logical-content to physical-storage projection for a texture.\n * Block sizes come from codec's format table; no physical dimensions are\n * authored or serialized with TextureAsset.\n */\nexport function deriveTextureExtent(\n format: GPUTextureFormat,\n width: number,\n height: number,\n): {\n readonly logicalExtent: TextureExtent;\n readonly physicalExtent: TextureExtent;\n readonly uvScale: readonly [number, number];\n} {\n const params = blockParamsForFormat(format);\n const physicalWidth = params === null ? width : Math.ceil(width / params.blockW) * params.blockW;\n const physicalHeight =\n params === null ? height : Math.ceil(height / params.blockH) * params.blockH;\n return {\n logicalExtent: { width, height },\n physicalExtent: { width: physicalWidth, height: physicalHeight },\n uvScale: [width / physicalWidth, height / physicalHeight],\n };\n}\n\n/** One mip level's GPU-upload layout (feat-20260707 M5 / w35, AC-08). */\nexport interface MipUploadLevel {\n /** Mip level index (0 = base / largest). */\n readonly level: number;\n /** Logical pixel width of this level (`baseWidth >> level`, min 1). */\n readonly width: number;\n /** Logical pixel height of this level (`baseHeight >> level`, min 1). */\n readonly height: number;\n /** Block-aligned storage dimensions for this logical mip. */\n readonly physicalWidth: number;\n readonly physicalHeight: number;\n /** Logical `writeTexture` copy width; full-subresource copies may end mid-block. */\n readonly copyWidth: number;\n /** Logical `writeTexture` copy height; full-subresource copies may end mid-block. */\n readonly copyHeight: number;\n /** Bytes per compressed row: `ceil(width / blockW) * bytesPerBlock`. */\n readonly bytesPerRow: number;\n /** Block rows: `ceil(height / blockH)` (the writeTexture `rowsPerImage`). */\n readonly rowsPerImage: number;\n /** Byte offset of this level in the mip-major payload (sum of prior levels). */\n readonly byteOffset: number;\n /** Byte length of this level (`bytesPerRow * rowsPerImage`). */\n readonly byteLength: number;\n}\n\n/**\n * Derive the per-mip GPU-upload layout for a block-compressed texture\n * (feat-20260707 M5 / w35, AC-08). Each level pads the pixel width up to a full\n * block (`ceil(width / blockW) * bytesPerBlock`) and counts block rows\n * (`ceil(height / blockH)`); `byteOffset` accumulates the prior levels' byte\n * lengths (mip-major layout). The GPU samples only the valid texel region, so a\n * non-4-multiple size or a 1x1 / 2x2 mip tail pads up to a block without image\n * corruption (t5). Block math is sourced from the codec block table (SSOT --\n * Derive, Don't Duplicate); TextureAsset carries no block fields (F-6).\n *\n * `format` must be a block-compressed format; callers branch on the projection's\n * `compressed` flag first (the uncompressed path uses the linear `width * 4`\n * pitch). Level dimensions floor-halve per mip, clamped to a 1-pixel minimum.\n */\nexport function deriveMipUploadLayout(\n format: GPUTextureFormat,\n baseWidth: number,\n baseHeight: number,\n mipLevelCount: number,\n): readonly MipUploadLevel[] {\n const params = blockParamsForFormat(format);\n if (params === null) return [];\n const levels: MipUploadLevel[] = [];\n let byteOffset = 0;\n for (let level = 0; level < mipLevelCount; level++) {\n const width = Math.max(1, baseWidth >> level);\n const height = Math.max(1, baseHeight >> level);\n const blockCols = Math.ceil(width / params.blockW);\n const blockRows = Math.ceil(height / params.blockH);\n const rowBytes = blockCols * params.bytesPerBlock;\n const byteLength = rowBytes * blockRows;\n levels.push({\n level,\n width,\n height,\n physicalWidth: blockCols * params.blockW,\n physicalHeight: blockRows * params.blockH,\n copyWidth: blockCols * params.blockW,\n copyHeight: blockRows * params.blockH,\n bytesPerRow: rowBytes,\n rowsPerImage: blockRows,\n byteOffset,\n byteLength,\n });\n byteOffset += byteLength;\n }\n return levels;\n}\n\n/** Descriptor for a cubemap built from an equirect source (projected from POD). */\nexport interface CubeRenderData {\n /** Square cube face edge length (== source equirect height). */\n readonly cubeFaceSize: number;\n /** Filterable output format the IBL pipeline BGL expects. */\n readonly outputFormat: 'rgba16float';\n /** True when the source is rgba32float and the store must pack to rgba16float. */\n readonly needsHalfConversion: boolean;\n readonly cubeUsage: number;\n}\n\n/**\n * Project a `MeshAsset` POD into its GPU vertex / index buffer descriptor.\n * Pure: computes byte lengths, the 4-byte-aligned index size, index format,\n * and the buffer usage flags the store's `createBuffer` calls need.\n */\nexport function deriveRenderDataMesh(mesh: MeshAsset): Result<MeshRenderData, AssetError> {\n // Vertex-only meshes (no `indices`) take the non-indexed draw path. Their\n // index-side fields are zeroed; `indexFormat` keeps a `'uint16'` placeholder\n // (never consumed when no index buffer is built).\n const indices = mesh.indices;\n const indexBytesUnpadded = indices === undefined ? 0 : indices.byteLength;\n const indexByteLength = ((indexBytesUnpadded + 3) >> 2) << 2;\n const layoutProjection = deriveVertexLayoutProjection(mesh.attributes);\n return ok({\n vertexByteLength: mesh.vertices.byteLength,\n layoutProjection,\n indexByteLength,\n indexCount: indices === undefined ? 0 : indices.length,\n indexFormat: indices instanceof Uint32Array ? 'uint32' : 'uint16',\n vertexUsage: GPU_BUFFER_USAGE_VERTEX | GPU_BUFFER_USAGE_COPY_DST,\n indexUsage: GPU_BUFFER_USAGE_INDEX | GPU_BUFFER_USAGE_COPY_DST,\n submeshes: mesh.submeshes,\n });\n}\n\n/**\n * Project a `TextureAsset` POD into its GPU texture descriptor. Pure: derives\n * the mip-level count (when `mipmap`), the row pitch, and the usage flags, and\n * fails fast if the POD's `format` and `colorSpace` are internally\n * inconsistent (a `-srgb` format requires an `srgb` colorSpace and vice versa).\n */\nexport function deriveRenderDataTexture(tex: TextureAsset): Result<TextureRenderData, AssetError> {\n const width = tex.shape.extent.width;\n const height = tex.shape.extent.height;\n const isSrgbFormat = tex.format.endsWith('-srgb');\n const expectedColorSpace: 'srgb' | 'linear' = isSrgbFormat ? 'srgb' : 'linear';\n if (tex.colorSpace !== expectedColorSpace) {\n return err(\n projectionError({\n code: 'invalid-source-format',\n expected: \"format ends in '-srgb' iff colorSpace is 'srgb' (linear otherwise)\",\n hint: ASSET_ERROR_HINTS['invalid-source-format'],\n }),\n );\n }\n\n const compressed = isCompressedFormat(tex.format);\n const layout = deriveTextureLayout({ shape: tex.shape, format: tex.format, mips: tex.mips });\n if (!layout.ok) {\n return err(\n projectionError({\n code: 'invalid-source-format',\n expected: layout.error.expected,\n hint: layout.error.hint,\n }),\n );\n }\n // feat-20260707 M5 / w35 (AC-09, D-9): a block-compressed texture cannot have\n // its mips GPU-generated (F-7). An OFFLINE chain baked into `data`\n // (mipLevelCount > 1, e.g. a KTX2 level chain) is the normal compressed path\n // and passes; requesting RUNTIME mip generation (`mipmap:true` with no offline\n // chain) fails fast with a self-recovery hint (fail-fast at the projection\n // layer -- producer self-validate).\n if (compressed && tex.mips.kind === 'generate') {\n return err(\n projectionError({\n code: 'mipgen-unsupported-compressed-format',\n expected:\n 'a compressed texture requesting mipmap:true must carry an offline mip chain (mipLevelCount > 1)',\n hint: ASSET_ERROR_HINTS['mipgen-unsupported-compressed-format'],\n }),\n );\n }\n\n // Uncompressed: runtime mip-gen count from the pixel size. Compressed: the\n // level count is authored (offline chain) -- honour the POD's mipLevelCount,\n // never re-derive it from the size (a compressed chain may stop early).\n const mipLevelCount = layout.value.levels.length;\n\n const baseLevel = layout.value.levels[0];\n if (baseLevel === undefined) {\n return err(\n projectionError({\n code: 'invalid-source-format',\n expected: 'texture layout contains a base mip level',\n hint: ASSET_ERROR_HINTS['invalid-source-format'],\n }),\n );\n }\n if (!compressed && tex.data.byteLength < baseLevel.byteLength) {\n return err(\n projectionError({\n code: 'invalid-source-format',\n expected: 'uncompressed texture data contains at least one complete base mip',\n hint: ASSET_ERROR_HINTS['invalid-source-format'],\n }),\n );\n }\n\n // Compressed rows derive from block format. Uncompressed row pitch derives\n // from the format, not aggregate payload length: imported images may retain\n // trailing decoder bytes and offline mip chains contain more than the base mip.\n const bytesPerRow = compressed\n ? (blockBytesPerRow(tex.format, width) ?? baseLevel.bytesPerRow)\n : baseLevel.bytesPerRow;\n\n // Compressed formats are not renderable -- RENDER_ATTACHMENT would fail\n // createTexture validation, and the runtime mipmap blit (which needs it) never\n // runs on a compressed texture anyway (the mip gate above rules out runtime\n // mip-gen). Both paths keep COPY_SRC so a real consumer can validate the\n // uploaded texture through the standard GPU readback contract.\n const usage = compressed\n ? GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST | GPU_TEXTURE_USAGE_COPY_SRC\n : GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |\n GPU_TEXTURE_USAGE_COPY_DST |\n GPU_TEXTURE_USAGE_COPY_SRC;\n\n return ok({\n width,\n height,\n shape: tex.shape,\n depthOrArrayLayers:\n tex.shape.viewDimension === '2d'\n ? 1\n : tex.shape.viewDimension === '2d-array'\n ? tex.shape.extent.layers\n : tex.shape.extent.depth,\n ...deriveTextureExtent(tex.format, width, height),\n format: tex.format,\n mipLevelCount,\n usage,\n bytesPerRow,\n compressed,\n });\n}\n\n/**\n * Project an equirectangular HDR `TextureAsset` source into its cubemap\n * descriptor. Pure: validates the source is a linear HDR format, computes the\n * square cube face size (== source height), narrows the output to the filterable\n * `rgba16float` the IBL pipeline expects, and flags whether the store must pack\n * an rgba32float source down to rgba16float. The store keeps the resource build\n * (createTexture / cube + face views / IBL precompute) and the rgba32f->rgba16f\n * byte conversion.\n *\n * feat-20260707 M5 fix: the accepted-format whitelist is `rgba16float |\n * rgba32float` only -- a block-compressed HDR format (`bc6h-rgb-ufloat`) is NOT\n * accepted here. An equirect cube source drives equirect-to-cube / irradiance /\n * prefilter RENDER passes, and a BC6H texture is sample-only, never a color-\n * renderable render target (\"BC6HRGBUfloat is not color renderable\"). The\n * equirect is therefore always delivered uncompressed rgba16float; this\n * fail-fast whitelist is the projection-layer guard that rejects a non-\n * renderable cube source rather than letting it blow up at GPU createTexture.\n */\nexport function deriveRenderDataCubemap(source: TextureAsset): Result<CubeRenderData, AssetError> {\n const isAcceptedHdr = source.format === 'rgba16float' || source.format === 'rgba32float';\n if (!isAcceptedHdr || source.colorSpace !== 'linear') {\n return err(\n projectionError({\n code: 'invalid-source-format',\n expected: \"format 'rgba16float' or 'rgba32float' with colorSpace 'linear'\",\n hint: ASSET_ERROR_HINTS['invalid-source-format'],\n }),\n );\n }\n const sourceHeight = source.shape.viewDimension === '2d' ? source.shape.extent.height : 0;\n return ok({\n cubeFaceSize: sourceHeight,\n outputFormat: 'rgba16float',\n needsHalfConversion: source.format === 'rgba32float',\n cubeUsage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |\n GPU_TEXTURE_USAGE_COPY_DST |\n GPU_TEXTURE_USAGE_COPY_SRC,\n });\n}\n","import type { AssetRegistry, DynamicTextureStore } from '@forgeax/engine-assets-runtime';\nimport type { World } from '@forgeax/engine-ecs';\nimport type { VertexLayoutProjection } from '@forgeax/engine-geometry';\nimport type { Profiler } from '@forgeax/engine-profiler';\nimport type { CompiledRenderGraphInfo } from '@forgeax/engine-render-graph';\nimport type {\n BindGroup,\n BindGroupLayout,\n Buffer,\n ComputePipeline,\n PipelineLayout,\n Result,\n RhiCanvasContext,\n RhiCommandEncoder,\n RhiDevice,\n RenderPipeline as RhiRenderPipeline,\n Sampler,\n Texture,\n TextureFormat,\n TextureView,\n} from '@forgeax/engine-rhi';\nimport { err, ok, RhiError } from '@forgeax/engine-rhi';\nimport type { MaterialRuntimeArtifact, MaterialShaderArtifact } from '@forgeax/engine-shader';\nimport type {\n MaterialRenderState,\n ParamSchemaEntry,\n PassKind,\n PrimitiveTopology,\n VertexAttributeMap,\n} from '@forgeax/engine-types';\nimport type { MaterialRenderProjection } from '../assembly/material/assembly';\nimport type { DeviceScope } from '../device/device-scope';\nimport type { MeshGpuHandles } from '../device/gpu-residency';\nimport type { EngineMetrics } from '../engine-metrics';\nimport type { RenderFeatureHost } from '../features/host';\nimport type { RenderFeatureShaderModuleMode } from '../features/types';\nimport {\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from '../gpu-texture-usage';\nimport type { SkylightFallback } from '../ibl/skylight-bind-group';\nimport type { BloomInspection } from '../inspection-types';\nimport type { HealthListenerRegistry, RhiErrorListenerRegistry } from '../lifecycle';\nimport type { PipelineGroup2Contract } from '../pbr-pipeline';\nimport type { StandardTopologyInputValue } from '../pipeline/standard-lighting/topology';\nimport type { StandardProfile } from '../pipeline/standard-profile';\nimport type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';\nimport type { PointsLinesInspection } from '../points-lines/inspection';\nimport type { PointsLinesRecordPlan } from '../points-lines/record';\nimport type { ReflectionProbeTable } from '../reflection/gpu-table';\nimport type { ReflectionProbeSelectionResult } from '../reflection/projection';\nimport type { SsrAdmissionIdentity } from '../ssr/identity';\nimport type { GpuPassTimingReason } from './gpu-pass-timing/errors';\nimport type {\n GpuPassTimingCapture,\n GpuPassTimingFrameIdentity,\n GpuPassTimingSession,\n} from './gpu-pass-timing/session';\n\nexport interface PointsLinesRecordSubmission {\n readonly plan: PointsLinesRecordPlan;\n readonly vertexBuffer: Buffer;\n readonly indexBuffer: Buffer;\n readonly layoutProjection: VertexLayoutProjection;\n}\n\nexport interface ReflectionProbeRecordState {\n readonly table: ReflectionProbeTable;\n readonly selections: ReadonlyMap<string, ReflectionProbeSelectionResult>;\n readonly graph: import('./typed-frame-graph').ReflectionProbeGraphState;\n /** Detached committed fallback projections joined by main-pass renderable key. */\n readonly fallbackProjections?: ReadonlyMap<\n string,\n import('../inspection-types').ReflectionFallbackReceipt\n >;\n /** Demand is derived from this frame's renderable/source selection. */\n readonly fallbackDemand?: boolean;\n /** True when at least one selected row must prove a non-zero readback. */\n readonly fallbackHasNonNeutral?: boolean;\n readonly completeSubmission: (\n submitted: boolean,\n completed?: Promise<unknown>,\n fallbackOutput?: {\n readonly format: TextureFormat;\n readonly size: { readonly width: number; readonly height: number };\n readonly frameId: number;\n readonly graphGeneration: number;\n readonly textureIdentity: number;\n readonly readback?: Promise<{\n readonly linearHdr: readonly [number, number, number, number];\n readonly hash: string;\n readonly graphGeneration: number;\n readonly textureIdentity: number;\n }>;\n },\n fallbackRequested?: boolean,\n ) => Promise<void>;\n}\n\nexport interface MaterialShaderPipelineEntry {\n readonly pipeline: RhiRenderPipeline;\n readonly group2Contract: PipelineGroup2Contract;\n}\n\nimport type {\n RenderDebugOverlay,\n RenderPipelineContext,\n RenderRecordPhase,\n VolumetricFogShaderSources,\n} from '../render-contract';\nimport type {\n DispatchEntry,\n MaterialSnapshot,\n SkyboxSnapshot,\n SkylightSnapshot,\n} from '../render-system-extract';\nimport type { SkinPaletteAllocator } from '../systems/skin-palette-allocator';\nimport type { RenderTarget } from '../targets/contracts';\nimport type { RenderTargetPhysical } from '../targets/physical';\nimport type {\n BindGroupCounts,\n BloomFrameReceipts,\n DispatchCounts,\n MaterialBgAssemblyCacheEntry,\n RenderFrameState,\n ValidatedRenderable,\n} from './frame-snapshot';\nimport type { FoldDispatchPlan } from './mesh-ssbo';\n\nexport interface RenderSystemRuntime {\n readonly device: RhiDevice;\n /** Internal backend-fixture hook evaluated at the submit transaction edge. */\n readonly beforeSubmit?: ((device: RhiDevice) => RhiError | undefined) | undefined;\n readonly deviceScope: DeviceScope;\n readonly errorRegistry: RhiErrorListenerRegistry;\n readonly debugOverlay?: RenderDebugOverlay | undefined;\n readonly healthRegistry: HealthListenerRegistry;\n readonly getMaterialProjection?: (materialGuid: string) => MaterialRenderProjection | undefined;\n readonly getMaterialArtifact?: (specializationKey: string) => MaterialRuntimeArtifact | undefined;\n /** Producer-owned cooked Standard PBR artifact used by GPU-driven projection. */\n readonly getMaterialShaderArtifact?: (\n materialShaderId: string,\n ) => MaterialShaderArtifact | undefined;\n readonly getMaterialShaderPipeline?: (\n materialShaderId: string,\n isHdr: boolean,\n renderState?: MaterialRenderState,\n topology?: PrimitiveTopology,\n indexFormat?: 'uint16' | 'uint32',\n variantSet?: string,\n passKind?: PassKind,\n meshAttributes?: VertexAttributeMap,\n sampleCount?: number,\n colorFormatOverride?: GPUTextureFormat,\n shaderUvSetCount?: number,\n depthFormatOverride?: GPUTextureFormat | null,\n vertexLayout?: string,\n vertexLayoutProjection?: VertexLayoutProjection,\n shaderModuleMode?: RenderFeatureShaderModuleMode,\n layoutKindOverride?: 'pbr' | 'pbr-skin',\n additionalColorFormats?: readonly GPUTextureFormat[],\n ) => RhiRenderPipeline | null;\n readonly getMaterialShaderPipelineEntry?: (\n materialShaderId: string,\n isHdr: boolean,\n renderState?: MaterialRenderState,\n topology?: PrimitiveTopology,\n indexFormat?: 'uint16' | 'uint32',\n variantSet?: string,\n passKind?: PassKind,\n meshAttributes?: VertexAttributeMap,\n sampleCount?: number,\n colorFormatOverride?: GPUTextureFormat,\n shaderUvSetCount?: number,\n depthFormatOverride?: GPUTextureFormat | null,\n vertexLayout?: string,\n vertexLayoutProjection?: VertexLayoutProjection,\n shaderModuleMode?: RenderFeatureShaderModuleMode,\n layoutKindOverride?: 'pbr' | 'pbr-skin',\n additionalColorFormats?: readonly GPUTextureFormat[],\n ) => MaterialShaderPipelineEntry | null;\n readonly getMaterialShaderBindingContract?: (\n materialShaderId: string,\n ) => 'group-0' | 'group-0-resource' | 'view-only' | 'view-and-scene-depth' | 'render-material';\n readonly getParamSchema?: (materialShaderId: string) => readonly ParamSchemaEntry[] | undefined;\n readonly getMaterialBindGroupLayout?: (materialShaderId: string) => BindGroupLayout | undefined;\n readonly metrics: EngineMetrics;\n readonly lookupPostProcess?: (\n id: string,\n ) => import('../fullscreen-post-process-pass').PostProcessShaderEntry | undefined;\n readonly getPostProcessParamsBuffer?: (id: string) => Buffer | undefined;\n readonly getPostProcessPipeline?: (\n id: string,\n bgl: BindGroupLayout,\n colorFormat: GPUTextureFormat,\n entry?: import('../fullscreen-post-process-pass').PostProcessShaderEntry,\n ) => RhiRenderPipeline | null;\n readonly clearPostProcessPipelineCache?: (id: string) => void;\n readonly invalidateShaderModule?: (label: string) => void;\n readonly dynamicTextureStore?: DynamicTextureStore | undefined;\n /** Resolves a render-target source to the active generation-owned GPU view. */\n readonly resolveRenderTargetTextureSource?: (\n source: import('../targets/contracts').RenderTargetTextureSource,\n ) => import('../targets/material-source').RenderTargetMaterialSourceBinding | undefined;\n}\n\n/** Renderer-owned bridge from retained Points/Lines facts into main geometry. */\nexport interface PointsLinesRecordOwner {\n prepare(entry: ValidatedRenderable, clustered: boolean): PointsLinesRecordSubmission | undefined;\n beginFrame(): void;\n resetForDeviceLoss(): void;\n inspections(): readonly PointsLinesInspection[];\n}\n\nexport interface PerPassResources {\n depthTexture: Texture | null;\n depthTextureView: TextureView | null;\n depthTextureWidth: number;\n depthTextureHeight: number;\n configured: boolean;\n hdrColorTexture: Texture | null;\n hdrColorView: TextureView | null;\n hdrDepthTexture: Texture | null;\n hdrDepthView: TextureView | null;\n hdrTextureWidth: number;\n hdrTextureHeight: number;\n hdrDepthSampleCount: number;\n readonly fxaaPipeline: RhiRenderPipeline | null;\n readonly fxaaBindGroupLayout: BindGroupLayout | null;\n readonly fxaaSampler: Sampler | null;\n msaaColorTexture: Texture | null;\n msaaColorView: TextureView | null;\n msaaSpriteColorTexture: Texture | null;\n msaaSpriteColorView: TextureView | null;\n msaaDepthTexture: Texture | null;\n msaaDepthView: TextureView | null;\n msaaTextureWidth: number;\n msaaTextureHeight: number;\n hdrColorMsaaTexture: Texture | null;\n hdrColorMsaaView: TextureView | null;\n readonly skyboxPipeline: RhiRenderPipeline | null;\n readonly skyboxPipelineMsaa: RhiRenderPipeline | null;\n readonly skyboxBindGroupLayout: BindGroupLayout | null;\n readonly skyboxSampler: Sampler | null;\n readonly skyboxRotationBuffer: Buffer | null;\n bloomBrightPipeline: RhiRenderPipeline | null;\n bloomBlurHPipeline: RhiRenderPipeline | null;\n bloomBlurVPipeline: RhiRenderPipeline | null;\n bloomCompositePipeline: RhiRenderPipeline | null;\n bloomBrightBindGroupLayout: BindGroupLayout | null;\n bloomBlurBindGroupLayout: BindGroupLayout | null;\n bloomCompositeBindGroupLayout: BindGroupLayout | null;\n bloomSampler: Sampler | null;\n bloomBrightParamsBuffer: Buffer | null;\n bloomBlurHParamsBuffer: Buffer | null;\n bloomBlurVParamsBuffer: Buffer | null;\n bloomCompositeParamsBuffer: Buffer | null;\n ensureBloomResources?: () => void;\n getBloomResources?: () => BloomPersistentBundle | null;\n commitBloomResources?: () => void;\n commitBloomFrameReceipts?: (receipts: BloomFrameReceipts) => void;\n discardBloomResources?: () => void;\n retireBloomResources?: (completion: Promise<unknown>) => void;\n /** Drain candidate, active, and fence-retiring Bloom generations. */\n drainBloomResources?: () => void;\n inspectBloomResources?: (graph?: CompiledRenderGraphInfo) => BloomInspection;\n bloomBrightTexture: Texture | null;\n bloomBrightView: TextureView | null;\n bloomBrightWidth: number;\n bloomBrightHeight: number;\n bloomBlurHTexture: Texture | null;\n bloomBlurHView: TextureView | null;\n bloomBlurHWidth: number;\n bloomBlurHHeight: number;\n bloomBlurVTexture: Texture | null;\n bloomBlurVView: TextureView | null;\n bloomBlurVWidth: number;\n bloomBlurVHeight: number;\n ssaoCalcPipeline: RhiRenderPipeline | null;\n ssaoBlurPipeline: RhiRenderPipeline | null;\n ssaoBgl: BindGroupLayout | null;\n ssaoFilteringSampler: Sampler | null;\n ssaoDepthSampler: Sampler | null;\n ssaoFallbackRawView: TextureView | null;\n shadowTexture: Texture | null;\n shadowMapSize: number;\n shadowCascadeCount: number;\n shadowSampler: Sampler | null;\n shadowLightSpaceMatrix: Float32Array | null;\n shadowCsmLightViewProj: Float32Array | null;\n shadowCsmSelection: {\n readonly viewMatrix: Float32Array;\n readonly splitPlanes: Float32Array;\n } | null;\n}\n\n/** Renderer-private Bloom bundle selected for one record transaction. */\nexport interface BloomPersistentBundle {\n readonly scope: DeviceScope;\n readonly generation: number;\n readonly bloomBrightPipeline: RhiRenderPipeline | null;\n readonly bloomBlurHPipeline: RhiRenderPipeline | null;\n readonly bloomBlurVPipeline: RhiRenderPipeline | null;\n readonly bloomCompositePipeline: RhiRenderPipeline | null;\n readonly bloomBrightBindGroupLayout: BindGroupLayout | null;\n readonly bloomBlurBindGroupLayout: BindGroupLayout | null;\n readonly bloomCompositeBindGroupLayout: BindGroupLayout | null;\n readonly bloomSampler: Sampler | null;\n readonly bloomBrightParamsBuffer: Buffer | null;\n readonly bloomBlurHParamsBuffer: Buffer | null;\n readonly bloomBlurVParamsBuffer: Buffer | null;\n readonly bloomCompositeParamsBuffer: Buffer | null;\n}\n\nexport interface PipelineState {\n /** Device that owns every opaque handle in this pipeline state. */\n readonly device: RhiDevice;\n readonly meshes: ReadonlyMap<number, MeshGpuHandles>;\n readonly format: TextureFormat;\n readonly colorAttachmentFormat: TextureFormat;\n /** Surface route committed by configureSurface for inspection provenance. */\n readonly surfaceProfile?: 'dual-view' | 'raw-only';\n readonly viewBindGroupLayout: BindGroupLayout;\n /** Device capability gate for the optional SpotLight projector binding. */\n readonly projectorAvailable?: boolean;\n readonly materialBindGroupLayout: BindGroupLayout;\n readonly meshBindGroupLayout: BindGroupLayout;\n readonly viewUniformBuffer: Buffer;\n readonly pointsLinesViewBuffer?: Buffer;\n readonly shadowCasterCascadeBuffer: Buffer;\n readonly materialUniformBuffer: { readonly buffer: Buffer; readonly sizeInBytes: number };\n readonly meshStorageBuffer: { readonly buffer: Buffer; readonly sizeInBytes: number };\n readonly instancesBindGroupLayout: BindGroupLayout;\n /** Probe-enabled slot-3 layout; omitted from no-probe bind groups. */\n readonly probeInstancesBindGroupLayout?: BindGroupLayout;\n readonly identityInstanceBuffer: Buffer;\n readonly defaultSampler: Sampler;\n readonly nearestSampler: Sampler;\n readonly fallbackTextureView: TextureView;\n readonly unlitPipeline: RhiRenderPipeline | null;\n readonly standardPipeline: RhiRenderPipeline | null;\n readonly unlitPipelineMsaa: RhiRenderPipeline | null;\n readonly unlitPipelineHdrMsaa: RhiRenderPipeline | null;\n readonly pbrPipelineLayout: PipelineLayout | null;\n readonly pbrProbePipelineLayout?: PipelineLayout | null;\n readonly hdrpPbrPipelineLayout: PipelineLayout | null;\n readonly hdrpProbePbrPipelineLayout?: PipelineLayout | null;\n readonly hdrpClusterMembershipPipeline: ComputePipeline | null;\n readonly hdrpClusterMembershipBindGroupLayout: BindGroupLayout | null;\n readonly pbrSkinPipelineLayout: PipelineLayout | null;\n readonly pbrSkinProbePipelineLayout?: PipelineLayout | null;\n readonly pbrSkinMeshBindGroupLayout: BindGroupLayout | null;\n readonly hdrpSkinPipelineLayout: PipelineLayout | null;\n readonly hdrpSkinMeshBindGroupLayout: BindGroupLayout | null;\n readonly skinPaletteAllocator: SkinPaletteAllocator | null;\n readonly defaultWhiteTextureView: TextureView;\n readonly defaultNormalTextureView: TextureView;\n readonly unlitPipelineHdr: RhiRenderPipeline | null;\n readonly shadowFallbackTextureView: TextureView;\n readonly shadowAtlasFallbackTextureView: TextureView;\n readonly extendedLightingAvailable?: boolean;\n readonly iesProfileTexture?: Texture;\n readonly cookieTexture?: Texture;\n readonly cookieMatrixBuffer?: Buffer;\n spotModifierUploadState?: {\n readonly ies: Map<number, number>;\n readonly cookie: Map<number, number>;\n readonly cookieMatrix: Map<number, number>;\n };\n readonly iesProfileTextureView?: TextureView;\n readonly cookieTextureView?: TextureView;\n readonly ltcLambertTextureView?: TextureView;\n readonly ltcGgxTextureView?: TextureView;\n readonly shadowParamsBuffer: Buffer;\n readonly skylightFallback: SkylightFallback | null;\n readonly perPassResources: PerPassResources;\n}\n\nexport interface RenderSystemInternals extends RenderSystemRuntime {\n readonly canvas: HTMLCanvasElement | OffscreenCanvas;\n /** Build identity injected by the host's build-tool adapter. */\n readonly build?: string | undefined;\n /** Host identity binding for the renderer-owned SSR dependency seam. */\n readonly ssrIdentity?: SsrAdmissionIdentity | undefined;\n readonly standardProfile?: StandardProfile | undefined;\n readonly standardPipeline: RenderFrameState['activePipeline'];\n readonly featureHost?: RenderFeatureHost | undefined;\n readonly shaderModuleFactory?: PipelineBuilderShaderModuleFactory;\n readonly createShaderModule?: (\n device: import('@forgeax/engine-rhi').RhiDevice,\n descriptor: { readonly code: string; readonly label?: string },\n ) => Promise<\n Result<import('@forgeax/engine-rhi').ShaderModule, import('@forgeax/engine-rhi').RhiError>\n >;\n /** Optional handle-first factory for feature-owned generated shader programs. */\n readonly immediateShaderModuleFactory?: PipelineBuilderShaderModuleFactory;\n readonly profiler?: Profiler | undefined;\n readonly context: RhiCanvasContext | null;\n readonly getPipelineState: () => PipelineState | null;\n readonly assets: AssetRegistry;\n readonly gpuStore: import('../device/gpu-residency').GpuResidencyCache;\n readonly growMeshSsbo?:\n | ((neededSlots: number) =>\n | { readonly ok: true }\n | {\n readonly ok: false;\n readonly code: 'mesh-ssbo-ceiling-reached' | 'mesh-ssbo-capacity-exceeded';\n readonly degradedToSlotCount: number;\n })\n | undefined;\n readonly meshSsboState?: { readonly slotCount: number } | undefined;\n readonly buildPostProcessPipeline?:\n | ((\n entry: import('../fullscreen-post-process-pass').PostProcessShaderEntry,\n bgl: BindGroupLayout,\n colorFormat: GPUTextureFormat,\n label: string,\n ) => RhiRenderPipeline | null)\n | undefined;\n gpuPassTimingSession?: GpuPassTimingSession | undefined;\n gpuPassTimingCapture?: GpuPassTimingCapture | undefined;\n gpuPassTimingSubmittedWork?: Promise<void> | undefined;\n gpuPassTimingFrameIdentity?: GpuPassTimingFrameIdentity | undefined;\n gpuPassTimingBeginReason?: GpuPassTimingReason | undefined;\n readonly getRenderTargetPhysical?: (target: RenderTarget) => RenderTargetPhysical | undefined;\n readonly encodeRenderTargetReadbacks?: (\n encoder: RhiCommandEncoder,\n faces?: readonly number[],\n ) => void;\n /** Composed renderer utility sources installed atomically at build-ready. */\n volumetricFogShaders?: VolumetricFogShaderSources | undefined;\n}\n\nexport interface _StandardForwardSceneView {\n readonly assets: AssetRegistry;\n readonly store: import('../device/gpu-residency').GpuResidencyCache;\n readonly pipelineState: PipelineState;\n readonly bloomResources?: BloomPersistentBundle | null;\n readonly runtime: RenderSystemRuntime;\n readonly validated: readonly ValidatedRenderable[];\n readonly validatedOrdered: readonly ValidatedRenderable[];\n readonly viewBindGroup: BindGroup | null;\n /** Dynamic View-UBO slot used by auxiliary cube/probe face cameras. */\n readonly viewBindGroupDynamicOffset?: number;\n readonly meshBindGroup: BindGroup | null;\n readonly frameState: RenderFrameState;\n readonly dispatchCounts: DispatchCounts;\n readonly bindGroupCounts: BindGroupCounts;\n readonly skylight: SkylightSnapshot | undefined;\n readonly skylightCount: number;\n readonly skybox: SkyboxSnapshot | undefined;\n readonly profilePhase?: <T>(phase: RenderRecordPhase, action: () => T) => T;\n readonly directionalShadowCacheReuse: boolean;\n readonly world: World;\n readonly gpuDrivenEntityKeys: ReadonlySet<number>;\n /** Renderer-local world namespace paired with gpuDrivenEntityKeys. */\n readonly gpuDrivenWorldKeys?: readonly number[];\n readonly tonemapActive: boolean;\n readonly geometryColorView: TextureView | null;\n readonly geometryDepthView: TextureView | null;\n readonly geometryDepthKey: string | null;\n readonly skyboxActive: boolean;\n readonly splitLdrSprite: boolean;\n readonly ldrSpritePassView: TextureView | null;\n readonly transparentColorFormat?: GPUTextureFormat;\n /** Second Standard main-pass attachment used by the fallback producer. */\n readonly reflectionFallbackColorFormat?: GPUTextureFormat;\n readonly dispatch: readonly DispatchEntry[];\n readonly hdrpClusterBindGroup: BindGroup | null;\n readonly hdrpClusterMembershipBindGroup: BindGroup | null;\n /** Prepared Standard lighting declaration accepted by this graph frame. */\n readonly standardLighting?: StandardTopologyInputValue;\n readonly foldDispatchPlan: FoldDispatchPlan | null;\n readonly materialSlotIndices: readonly (readonly number[])[];\n readonly materialSlots: readonly MaterialSnapshot[];\n readonly materialSlotOwners: readonly number[];\n readonly materialSlotCount: number;\n readonly pointsLines: PointsLinesRecordOwner | undefined;\n readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;\n readonly reflectionProbes?: ReflectionProbeRecordState;\n materialUboPayloadCache?: {\n readonly materialSlots: readonly MaterialSnapshot[];\n readonly materialSlotCount: number;\n readonly payload: Uint8Array;\n };\n hdrpSsaoBlurredView?: TextureView;\n readonly occlusion?: import('../scene/visibility/occlusion-runtime').OcclusionFrameProjection;\n}\n\nexport type _InternalRenderPipelineContext = RenderPipelineContext & _StandardForwardSceneView;\n\nexport type RecordProfileRunner = <T>(phase: RenderRecordPhase, action: () => T) => T;\n\nexport const STANDARD_PBR_UBO_SIZE = 384;\nexport const MATERIAL_PER_ENTITY_STRIDE = 512;\n\nexport type SwapChainFormatPair = {\n readonly storage: GPUTextureFormat;\n readonly view: GPUTextureFormat;\n readonly fallbackReason?: 'preferred-canvas-format-missing';\n};\n\n/** Internal closed projection of the concrete surface route. */\nexport type SurfaceProfile =\n | {\n readonly kind: 'dual-view';\n readonly storageFormat: GPUTextureFormat;\n readonly viewFormat: GPUTextureFormat;\n readonly viewFormats: readonly [GPUTextureFormat];\n readonly hasDisplayEndpoint: true;\n }\n | {\n readonly kind: 'raw-only';\n readonly storageFormat: GPUTextureFormat;\n readonly viewFormat: GPUTextureFormat;\n readonly viewFormats: readonly [];\n readonly hasDisplayEndpoint: false;\n };\n\nexport interface SurfaceCapabilityFacts {\n /** Concrete wgpu downlevel `SURFACE_VIEW_FORMATS` flag. */\n readonly surfaceViewFormats: boolean;\n readonly rawAttachment: boolean;\n readonly floatRenderAttachment: boolean;\n}\n\nexport function resolveSurfaceProfile(\n storageFormat: GPUTextureFormat,\n viewFormat: GPUTextureFormat,\n facts: SurfaceCapabilityFacts,\n): Result<SurfaceProfile, RhiError> {\n if (facts.surfaceViewFormats) {\n return ok({\n kind: 'dual-view',\n storageFormat,\n viewFormat,\n viewFormats: [viewFormat],\n hasDisplayEndpoint: true,\n });\n }\n if (!facts.rawAttachment || !facts.floatRenderAttachment) {\n return err(\n new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'raw surface attachment and rgba16float render attachment capabilities',\n hint: 'surface profile cannot establish a raw-only linear output route',\n detail: {\n error: {\n code: 'surface-raw-endpoint-failed',\n message: 'raw-only surface capabilities are incomplete',\n },\n },\n }),\n );\n }\n return ok({\n kind: 'raw-only',\n storageFormat,\n viewFormat: storageFormat,\n viewFormats: [],\n hasDisplayEndpoint: false,\n });\n}\n\nexport type SurfaceBackendKind = 'webgpu' | 'wgpu-native' | 'wgpu-webgl2' | 'null';\n\nexport function resolveSurfaceFormatPair(\n _backendKind: SurfaceBackendKind,\n storage: GPUTextureFormat,\n view: GPUTextureFormat,\n): SwapChainFormatPair {\n return { storage, view };\n}\n\nfunction surfaceCapabilityFacts(\n device: RhiDevice,\n storageFormat: GPUTextureFormat,\n): SurfaceCapabilityFacts {\n const internal = device as unknown as { readonly surfaceViewFormats?: boolean };\n return {\n surfaceViewFormats: internal.surfaceViewFormats ?? device.caps?.backendKind !== 'wgpu-webgl2',\n rawAttachment: storageFormat === 'rgba8unorm' || storageFormat === 'bgra8unorm',\n floatRenderAttachment: device.caps?.rgba16floatRenderable ?? true,\n };\n}\n\nexport function configureSurface(\n context: RhiCanvasContext,\n device: RhiDevice,\n format: TextureFormat,\n colorAttachmentFormat: TextureFormat,\n): Result<void, RhiError> {\n const backendKind = device.caps?.backendKind ?? 'webgpu';\n const isWebGl2 = backendKind === 'wgpu-webgl2';\n const surfaceFormats = resolveSurfaceFormatPair(\n backendKind,\n format as GPUTextureFormat,\n colorAttachmentFormat as GPUTextureFormat,\n );\n const profile = resolveSurfaceProfile(\n surfaceFormats.storage,\n surfaceFormats.view,\n surfaceCapabilityFacts(device, surfaceFormats.storage),\n );\n if (!profile.ok) return profile;\n // WebGL2 surface pixels are proven by the compositor fixture, so it has no\n // surface consumer for optional TEXTURE_BINDING/COPY_SRC usage. The concrete\n // wgpu surface derives supported usages from SurfaceCapabilities and rejects\n // unsupported requests; this path requests only the guaranteed attachment\n // usage. Raw-only deliberately has no alternate view.\n const supportsTextureBinding =\n backendKind !== 'wgpu-webgl2' && (device.caps?.storageBuffer ?? true);\n const configured = context.configure({\n device,\n format: surfaceFormats.storage,\n alphaMode: isWebGl2 ? 'opaque' : 'premultiplied',\n usage:\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n (supportsTextureBinding ? GPU_TEXTURE_USAGE_TEXTURE_BINDING : 0) |\n (isWebGl2 ? 0 : GPU_TEXTURE_USAGE_COPY_SRC),\n viewFormats: [...profile.value.viewFormats],\n });\n if (!configured.ok) return configured;\n if (\n isWebGl2 &&\n (context.presentationProof === undefined ||\n !context.presentationProof.descriptor ||\n !context.presentationProof.acquisition ||\n !context.presentationProof.validation ||\n typeof context.presentationProof.surfaceIdentity !== 'string' ||\n context.presentationProof.surfaceIdentity.length === 0 ||\n context.presentationProof.requested === undefined ||\n context.presentationProof.validated === undefined ||\n JSON.stringify(context.presentationProof.requested) !==\n JSON.stringify(context.presentationProof.validated))\n ) {\n return err(\n new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'WebGL2 surface storage has descriptor, acquisition, and validation proof',\n hint: 'run the concrete presentation probe and retain the last-known-good graph when proof is absent',\n detail: {\n error: {\n code: 'surface-raw-endpoint-failed',\n message: 'surface storage raw endpoint proof is incomplete',\n },\n },\n }),\n );\n }\n return ok(undefined);\n}\n\nexport function selectSwapChainFormat(\n storageBufferCapable: boolean,\n surfaceViewFormats = true,\n): SwapChainFormatPair {\n if (!storageBufferCapable) {\n return {\n storage: 'rgba8unorm',\n view: surfaceViewFormats ? 'rgba8unorm-srgb' : 'rgba8unorm',\n };\n }\n const nav = (\n globalThis as { navigator?: { gpu?: { getPreferredCanvasFormat?: () => GPUTextureFormat } } }\n ).navigator;\n const gpu = nav?.gpu;\n const getPreferred = gpu?.getPreferredCanvasFormat;\n if (gpu !== undefined && typeof getPreferred === 'function') {\n const storage = getPreferred.call(gpu);\n const view =\n storage === 'rgba8unorm'\n ? 'rgba8unorm-srgb'\n : storage === 'bgra8unorm'\n ? 'bgra8unorm-srgb'\n : storage;\n return {\n storage,\n view: surfaceViewFormats ? view : storage,\n };\n }\n return {\n storage: 'rgba8unorm',\n view: surfaceViewFormats ? 'rgba8unorm-srgb' : 'rgba8unorm',\n fallbackReason: 'preferred-canvas-format-missing',\n };\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: main-pass-material.\n// Extracted from render-system-record.ts (feat-20260704 M3/w17, pure move).\n\nimport { resolveAssetHandle } from '@forgeax/engine-assets-runtime';\nimport type { EntityHandle, World } from '@forgeax/engine-ecs';\nimport {\n VIDEO_ELEMENT_PROVIDER_KEY,\n type VideoElementProvider,\n} from '@forgeax/engine-graphics-extras';\nimport {\n type BindGroup,\n type BindGroupEntry,\n type BindGroupLayout,\n type Buffer,\n type RenderPipeline,\n RhiError,\n type Sampler,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport {\n DEFAULT_MSDF_TEXT_PARAM_SCHEMA,\n DEFAULT_SPRITE_PARAM_SCHEMA,\n DEFAULT_STANDARD_PBR_PARAM_SCHEMA,\n DEFAULT_UNLIT_PARAM_SCHEMA,\n} from '@forgeax/engine-shader';\nimport type {\n Handle,\n ImageError,\n MaterialRenderState,\n ParamSchemaEntry,\n PrimitiveTopology,\n SamplerAsset,\n TextureAsset,\n} from '@forgeax/engine-types';\nimport { derive, handleSlot, resolveMaterialTextureCoordinates } from '@forgeax/engine-types';\nimport type { GpuResidencyCache } from '../device/gpu-residency';\nimport { VideoUploadUnsupportedError } from '../errors/render';\nimport {\n assembleMaterialWithSkylightEntries,\n type SkylightBindGroupResources,\n type TransmissionBindGroupResources,\n} from '../ibl/skylight-bind-group';\nimport type { PipelineGroup2Contract } from '../pbr-pipeline';\nimport { isStandardPbrMaterialShader } from '../pbr-pipeline';\nimport { deriveTextureExtent } from '../render-data';\nimport type { MaterialSnapshot } from '../render-system-extract';\nimport type { RenderTargetTextureSource } from '../targets/contracts';\nimport {\n type RenderTargetMaterialSourceBinding,\n resolveRenderTargetMaterialSource,\n} from '../targets/material-source';\nimport type { StandardReflectionProbeBinding } from './frame-lighting';\nimport type { BindGroupCounts, MaterialBgAssemblyCacheEntry } from './frame-snapshot';\nimport { extractEntryResourceHandle, getOrCreatePerEntity } from './mesh-ssbo';\nimport {\n type PipelineState,\n type RenderSystemRuntime,\n STANDARD_PBR_UBO_SIZE,\n} from './render-context';\n\n/**\n * Resolve the group(2) resource layout from the material shader contract.\n * Standard clustered PBR consumes the unified cluster bind group; every other\n * material consumes the ordinary mesh bind group. Missing ordinary resources\n * remain missing so the caller can skip the draw rather than violate layout\n * compatibility by binding a cluster group.\n */\nexport function selectMaterialGroup2(\n clusterGroup: BindGroup | null,\n meshGroup: BindGroup | null,\n group2Contract: PipelineGroup2Contract,\n): BindGroup | null {\n if (group2Contract === 'cluster') return clusterGroup;\n if (group2Contract === 'mesh') return meshGroup;\n return null;\n}\n\n// Param schemas are immutable runtime contracts: the shader registry installs\n// them once and material snapshots only retain the same array reference. Keep\n// the expensive pure derivation on that identity so the per-submesh record\n// path does not rebuild the same UBO/texture maps for every visible material\n// on every frame. A WeakMap keeps this optimization bounded by the lifetime of\n// the schema owner and adds no global strong-reference lifetime.\nconst DERIVED_PARAM_SCHEMA_CACHE = new WeakMap<\n readonly ParamSchemaEntry[],\n ReturnType<typeof derive>\n>();\n\nfunction derivedParamSchema(schema: readonly ParamSchemaEntry[]): ReturnType<typeof derive> {\n const cached = DERIVED_PARAM_SCHEMA_CACHE.get(schema);\n if (cached !== undefined) return cached;\n const derived = derive(schema);\n DERIVED_PARAM_SCHEMA_CACHE.set(schema, derived);\n return derived;\n}\n\n// feat-20260601-customizable-render-pipeline-seam M2 / w12: the former\n// `RecordPassContext` (26-field full surface, including the `internals` kitchen-sink and\n// the 0-consumed `skyboxCount` residual) is DELETED. The per-frame shared state injected\n// into the render-graph pass execute closures is now the clean `RenderPipelineContext`\n// (defined in `render-system.ts`): `internals` is gone (replaced by the named\n// `assets` / `store` / `pipelineState` / `runtime` surfaces) so a pipeline author cannot\n// reach the runtime kitchen-sink through the public ctx (AC-08). The graph is\n// `RenderGraph<RenderPipelineContext>` so `execute(ctx)` forwards the object to each\n// closure with no `as` assertion.\n//\n// Encoder ownership (RD-4): `ctx.encoder` is the SHARED frame encoder used by the main /\n// tonemap / FXAA passes (finished + submitted once at frame end); the shadow pass opens\n// its OWN encoder internally + submits independently (the runtime-side manual barrier for\n// the depth write -> sample hazard).\n\n// M1 / w7: ensureLazyTexture DELETED — GPU texture ownership moved to render-graph\n// via addColorTarget + compile(device). The graph allocates transient/persistent\n// render targets during the compile allocation phase; pass execute closures resolve\n// TextureViews through resolve(name). PerPassResources texture slots still hold\n// the last-used views for bindgroup-invalidation self-checks (D-3 physical texture\n// identity), but the graph owns the create/destroy lifecycle.\n\n/**\n * Keep line primitives visible when they share a depth plane with filled\n * geometry. The same topology policy is consumed by the CPU and GPU-driven\n * raster lanes so a mixed mesh does not change appearance when ownership\n * moves between them.\n */\nexport function geometryRenderStateForTopology(\n topology: PrimitiveTopology,\n renderState: MaterialRenderState | undefined,\n): MaterialRenderState | undefined {\n if (topology !== 'line-list' && topology !== 'line-strip') return renderState;\n return {\n ...renderState,\n depthWriteEnabled: false,\n depthCompare: 'less-equal',\n };\n}\n\n/**\n * feat-20260604-learn-render-4.10-anti-aliasing-msaa M2 / w9: pick the static\n * unlit geometry pipeline handle for a (tonemapActive x msaaActive)\n * combination. The four mode axes (LDR/HDR x single/MSAA) map to the 14 static\n * pipeline handles built in createRenderer (7 base + 7 count=4 variants). A\n * pipeline's `multisample.count` must match the colour-attachment sampleCount,\n * so the count=4 variant is required whenever the camera carries\n * `antialias === 'msaa'`. Returns null when the requested pipeline was not\n * built (empty-manifest path / MSAA variant build failure) -- the caller fires\n * a structured `shader-compile-failed` on the null-narrow.\n */\n// feat-20260615-pipeline-spec-ssot M6-T1: the standard-shading fallback\n// selector was deleted. The pre-M6 selector silently substituted the\n// boot-time URP `pipelineState.standardPipeline*` whenever the per-\n// MaterialShader cache returned null and HDRP was inactive -- masking\n// real PipelineSpecError build failures behind a layout-compatible-but-\n// wrong PSO. Charter P3 explicit-failure now governs: a missing cache\n// entry surfaces as null, and the per-submesh\n// `if (smPipelineHandle === null) continue` skip-draw (which already\n// covered the HDRP-active and skin-shader miss-skip paths) is the single\n// uniform recovery shape across URP / HDRP / skin.\n\nexport function selectGeometryPipeline(\n pipelineState: PipelineState,\n tonemapActive: boolean,\n msaaActive: boolean,\n): RenderPipeline | null {\n if (tonemapActive) {\n return msaaActive ? pipelineState.unlitPipelineHdrMsaa : pipelineState.unlitPipelineHdr;\n }\n return msaaActive ? pipelineState.unlitPipelineMsaa : pipelineState.unlitPipeline;\n}\n\n/**\n * feat-city-glb Bug 5 (per-submesh transparency): true when EVERY submesh\n * material of the entity is transparent (blend). Used by the geometry pass to\n * decide whether to skip the whole entity (fully transparent → deferred to the\n * blend sub-pass) vs. draw its opaque submeshes and skip only the transparent\n * ones per-submesh.\n *\n * Falls back to the entity-level `material.transparent` when `materials` is\n * absent (single-material entities / test fixtures), byte-identical to the\n * pre-fix whole-entity gate.\n *\n * @internal\n */\nexport function isEntityFullyTransparent(source: {\n readonly material: MaterialSnapshot;\n readonly materials?: readonly MaterialSnapshot[];\n}): boolean {\n const mats = source.materials;\n if (mats === undefined || mats.length === 0) return source.material.transparent === true;\n for (let j = 0; j < mats.length; j++) {\n if (mats[j]?.transparent !== true) return false;\n }\n return true;\n}\n\n/**\n * feat-city-glb Bug 5: true when the entity has at least one transparent AND at\n * least one opaque submesh — i.e. it must be drawn in BOTH the geometry pass\n * (opaque submeshes) and the blend sub-pass (transparent submeshes). A pure-\n * opaque or pure-transparent entity returns false (handled by the whole-entity\n * fast paths).\n *\n * @internal\n */\nexport function entityHasTransparentSubmesh(source: {\n readonly material: MaterialSnapshot;\n readonly materials?: readonly MaterialSnapshot[];\n}): boolean {\n const mats = source.materials;\n if (mats === undefined) return source.material.transparent === true;\n for (let j = 0; j < mats.length; j++) {\n if (mats[j]?.transparent === true) return true;\n }\n return false;\n}\n\n/**\n * feat-20260601-device/gpu-residency-extraction M1 / D-9: resolve a texture's\n * GPU view through the pull-model residency store. The three steps replace the\n * pre-extraction single-call accessor on the registry:\n * 1. fetch the TextureAsset POD off the registry (CPU; registry keeps PODs)\n * 2. synchronously `ensureResident(handle, pod)` (first access builds the\n * GPU texture + prewarmed mipmap blit; subsequent access is O(1))\n * 3. return the GPU view (or undefined on POD miss / ensureResident err)\n *\n * Returns `undefined` when the POD is absent (handle never registered) or the\n * upload fails (a structured error is fired). Callers then fall back to their\n * existing placeholder view, preserving the pre-extraction fallback semantics.\n */\nfunction isImageError(error: unknown): error is ImageError {\n if (typeof error !== 'object' || error === null) return false;\n const code = (error as { readonly code?: unknown }).code;\n return typeof code === 'string' && code.startsWith('image-');\n}\n\nexport function residentTextureView(\n world: World,\n store: GpuResidencyCache,\n runtime: RenderSystemRuntime,\n handle: Handle<'TextureAsset', 'shared'>,\n worldId: World | number = world,\n): TextureView | undefined {\n const podRes = resolveAssetHandle<TextureAsset>(world, handle);\n if (!podRes.ok) return undefined;\n const residentRes = store.ensureResident(handle, podRes.value, worldId);\n if (!residentRes.ok) {\n // Preserve the concrete asset-capability boundary on the renderer error\n // channel. In particular, WebGL2 texture-dimension refusal must not\n // collapse into the later debug-pink asset-not-registered fallback.\n if (residentRes.error instanceof RhiError || isImageError(residentRes.error)) {\n runtime.errorRegistry.fire(residentRes.error);\n }\n return undefined;\n }\n return store.getTextureGpuView(handle, worldId);\n}\n\nfunction residentSampler(\n world: World,\n store: GpuResidencyCache,\n runtime: RenderSystemRuntime,\n handle: Handle<'SamplerAsset', 'shared'>,\n worldId: World | number = world,\n): Sampler | undefined {\n const podRes = resolveAssetHandle<SamplerAsset>(world, handle);\n if (!podRes.ok) return undefined;\n const residentRes = store.ensureSamplerResident(handle, podRes.value, worldId);\n if (!residentRes.ok) {\n runtime.errorRegistry.fire(residentRes.error);\n return undefined;\n }\n return residentRes.value;\n}\n\n// feat-20260623-world-space-video-asset M4 / w16 (D-3): resolve the\n// current-frame GPU view for a video-sourced texture field through the\n// transient DynamicTextureStore, NOT the static `residentTextureView` /\n// `ensureResident` cache (video never enters that switch; AC-08).\n//\n// Per frame: ask the host-registered VideoElementProvider (World Resource,\n// D-1) for this entity's HTMLVideoElement, upload its current frame via\n// `store.uploadFrame` (copyExternalImageToTexture), and return the resulting\n// view. When the provider is absent / returns no element / the element has no\n// decodable dimensions yet, fall back to a previously-uploaded view and\n// finally to `undefined` (caller binds the default view this frame — charter\n// P3 graceful, no garbage sampling). A failed GPU upload fires the structured\n// RhiError on the engine channel and degrades to the default view.\n//\n// `highPerfAvailable` is the w17 capability probe; the high-perf\n// GPUExternalTexture branch is a reserved hook (OOS-5) — when it ever becomes\n// available the upload would route there. Today it is always false so the\n// general copyExternalImageToTexture path is the only one taken.\ntype DynamicTextureStore = import('@forgeax/engine-assets-runtime').DynamicTextureStore;\n\ntype VideoUploadFailureEpisodes = Map<number, Set<number>>;\n\n// The store is renderer-owned, so this keeps one failure episode per\n// renderer/entity/clip without creating a second video system or leaking\n// state across a replacement renderer.\nconst VIDEO_UPLOAD_FAILURE_EPISODES = new WeakMap<\n DynamicTextureStore,\n VideoUploadFailureEpisodes\n>();\n\nfunction markVideoUploadFailureEpisode(\n store: DynamicTextureStore,\n entityKey: number,\n clip: Handle<'VideoAsset', 'shared'>,\n): boolean {\n let clips = VIDEO_UPLOAD_FAILURE_EPISODES.get(store);\n if (clips === undefined) {\n clips = new Map();\n VIDEO_UPLOAD_FAILURE_EPISODES.set(store, clips);\n }\n let episodes = clips.get(entityKey);\n if (episodes === undefined) {\n episodes = new Set();\n clips.set(entityKey, episodes);\n }\n const clipId = handleSlot(clip);\n if (episodes.has(clipId)) return false;\n episodes.add(clipId);\n return true;\n}\n\nfunction clearVideoUploadFailureEpisode(\n store: DynamicTextureStore,\n entityKey: number,\n clip: Handle<'VideoAsset', 'shared'>,\n): void {\n const clips = VIDEO_UPLOAD_FAILURE_EPISODES.get(store);\n const episodes = clips?.get(entityKey);\n if (episodes === undefined) return;\n episodes.delete(handleSlot(clip));\n if (episodes.size === 0) clips?.delete(entityKey);\n if (clips?.size === 0) VIDEO_UPLOAD_FAILURE_EPISODES.delete(store);\n}\n\nexport function videoTextureView(\n world: World,\n store: DynamicTextureStore | undefined,\n runtime: RenderSystemRuntime,\n entityKey: number,\n clip: Handle<'VideoAsset', 'shared'>,\n highPerfAvailable: boolean,\n): TextureView | undefined {\n if (store === undefined) return undefined;\n const provider = world.hasResource(VIDEO_ELEMENT_PROVIDER_KEY)\n ? world.getResource<VideoElementProvider>(VIDEO_ELEMENT_PROVIDER_KEY)\n : undefined;\n const element = provider?.getElement(entityKey as EntityHandle, clip);\n // AC-10 double-miss: a VideoPlayer entity can reach NEITHER upload path this\n // frame — no host HTMLVideoElement (general copyExternalImageToTexture path)\n // AND no high-perf GPUExternalTexture path. This is the genuine \"this backend\n // exposes no usable video upload path\" case (no provider registered, or the\n // provider yields nothing while the high-perf reserved hook is unavailable —\n // OOS-5 keeps it always false today). Rather than silently binding the\n // default view, fire the structured VideoUploadUnsupportedError on the engine\n // error channel so an AI user can detect the dead path via `.code` / `.hint`\n // (charter P3; AC-10 signal lives on the REAL per-frame upload path, not an\n // orphan system). The default view is still bound this frame so the draw\n // does not crash (graceful degradation), but the failure is no longer silent.\n if (element === undefined && !highPerfAvailable) {\n if (markVideoUploadFailureEpisode(store, entityKey, clip)) {\n runtime.errorRegistry.fire(new VideoUploadUnsupportedError());\n }\n return store.getView(clip);\n }\n // D-2 / w17 high-perf reserved hook: a future GPUExternalTexture import path\n // would key off `highPerfAvailable` here. It is always false today\n // (importExternalTexture absent), so the general copyExternalImageToTexture\n // path below is the sole route end-to-end.\n if (element === undefined) {\n clearVideoUploadFailureEpisode(store, entityKey, clip);\n return store.getView(clip);\n }\n const width = element.videoWidth;\n const height = element.videoHeight;\n // Metadata dimensions can be non-zero before the decoder has produced a\n // current frame. WebGPU rejects copyExternalImageToTexture in that window\n // because the video element has no back resource yet; keep the previous\n // frame/default view until HAVE_CURRENT_DATA (2) is reached.\n if (width <= 0 || height <= 0 || element.readyState < 2) return store.getView(clip);\n const uploaded = store.uploadFrame(clip, element, width, height);\n if (uploaded === undefined) return store.getView(clip);\n if (!uploaded.ok) {\n runtime.errorRegistry.fire(uploaded.error);\n return store.getView(clip);\n }\n clearVideoUploadFailureEpisode(store, entityKey, clip);\n return uploaded.value;\n}\n\n// feat-20260621-learn-render-5-5-parallax M2 / w8 (D-3): the built-in\n// standard-PBR user-region texture field order, used when the shader is not\n// resolvable through getParamSchema (cross-worktree late-register). Mirrors\n// derive(default-standard-pbr).textureFieldNames.\nexport const BUILTIN_USER_REGION_TEXTURE_FIELDS: readonly string[] = [\n 'baseColorTexture',\n 'metallicRoughnessTexture',\n 'normalTexture',\n 'specularTintTexture',\n 'emissiveTexture',\n 'occlusionTexture',\n 'transmissionTexture',\n 'thicknessTexture',\n];\n\nconst LEGACY_MATERIAL_TEXTURE_SCALE_OFFSET = 80;\n// The Standard schema owns five transmission numeric fields between\n// normalScale and the engine-owned coordinate records. Keep this fallback\n// aligned with derive(DEFAULT_STANDARD_PBR_PARAM_SCHEMA): the first record is\n// at byte 128, not the pre-transmission byte 96.\nconst STANDARD_PBR_TEXTURE_SCALE_OFFSET = 128;\nconst MATERIAL_TEXTURE_SCALE_FIELDS = [\n 'baseColorTexture',\n 'metallicRoughnessTexture',\n 'normalTexture',\n 'specularTintTexture',\n 'emissiveTexture',\n 'occlusionTexture',\n 'transmissionTexture',\n 'thicknessTexture',\n] as const;\nconst LEGACY_MATERIAL_TEXTURE_SCALE_FIELDS = [\n 'baseColorTexture',\n 'metallicRoughnessTexture',\n 'normalTexture',\n 'emissiveTexture',\n 'occlusionTexture',\n] as const;\nconst STANDARD_PBR_TEXTURE_COORDINATE_OFFSET = 128;\nconst STANDARD_PBR_TEXTURE_COORDINATE_STRIDE = 8;\nconst DEFAULT_LEGACY_TEXTURE_SCALES = new Float32Array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);\nconst DEFAULT_STANDARD_TEXTURE_COORDINATES = new Float32Array([\n 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, 0, 0, 1, 1, 0,\n 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,\n]);\n\nexport interface StandardReflectionProbeMaterialProjection {\n readonly probeIndex: number | undefined;\n readonly fallbackToSkylight: boolean;\n}\n\n/** Keeps the fallback output as a same-pass, linear-HDR material projection. */\nexport function standardPbrFallbackDemand(\n projection: StandardReflectionProbeMaterialProjection,\n): boolean {\n return projection.probeIndex !== undefined || projection.fallbackToSkylight;\n}\n\n/** Projects the selected scene row into the Standard material lane. */\nexport function projectReflectionProbeMaterialBinding(\n binding: StandardReflectionProbeBinding,\n): StandardReflectionProbeMaterialProjection {\n return {\n probeIndex: binding.probeIndex,\n fallbackToSkylight: binding.useSkylight,\n };\n}\n\n/** Derives the logical-content UV scale for an uploaded material texture. */\nexport function materialTextureUvScale(\n texture: Pick<TextureAsset, 'shape' | 'format'> | undefined,\n): readonly [number, number] {\n if (texture === undefined) return [1, 1];\n return deriveTextureExtent(\n texture.format,\n texture.shape.extent.width,\n texture.shape.extent.height,\n ).uvScale;\n}\n\nfunction materialTextureForField(\n material: MaterialSnapshot,\n field: string,\n): Handle<'TextureAsset', 'shared'> | undefined {\n if (field === 'emissiveTexture') return material.emissiveTexture;\n if (field === 'occlusionTexture') return material.occlusionTexture;\n return material.textureHandles?.get(field);\n}\n\n/** Resolve a renderer-local target source without entering AssetRegistry. */\nexport function materialRenderTargetSourceForField(\n material: MaterialSnapshot,\n field: string,\n resolveSource?: RenderSystemRuntime['resolveRenderTargetTextureSource'],\n): RenderTargetMaterialSourceBinding | undefined {\n const source = material.textureSources?.get(field) as RenderTargetTextureSource | undefined;\n return source === undefined\n ? undefined\n : (resolveSource?.(source) ?? resolveRenderTargetMaterialSource(source));\n}\n\n/**\n * Appends the engine-owned scale for every built-in material texture binding.\n * Asset dimensions remain logical; this is the sole record-stage projection\n * from a bound texture asset to its shader sampling coordinates.\n */\ntype MaterialUboPayload = ArrayBuffer | Uint8Array | Float32Array;\n\nfunction materialUboFloatView(payload: MaterialUboPayload): Float32Array {\n if (payload instanceof Float32Array) return payload;\n return payload instanceof Uint8Array\n ? new Float32Array(payload.buffer, payload.byteOffset, payload.byteLength / 4)\n : new Float32Array(payload);\n}\n\nexport function applyMaterialTextureUvScales(\n payload: MaterialUboPayload,\n material: MaterialSnapshot,\n world: World,\n): void {\n const f32 = materialUboFloatView(payload);\n const coordinateSchema = materialCoordinateSchema(material);\n if (coordinateSchema !== undefined) {\n const coordinateRecords = derivedParamSchema(coordinateSchema).coordinateRecords;\n for (const record of coordinateRecords) {\n const field = record.parameter;\n const handle = materialTextureForField(material, field);\n const resolvedTexture =\n handle === undefined ? undefined : resolveAssetHandle<TextureAsset>(world, handle);\n const texture = resolvedTexture?.ok === true ? resolvedTexture.value : undefined;\n const [u, v] = materialTextureUvScale(texture);\n const coordinates = resolveMaterialTextureCoordinates(\n material.textureCoordinates?.get(field),\n );\n const offset = record.offset / 4;\n f32[offset] = coordinates.transform.offset[0];\n f32[offset + 1] = coordinates.transform.offset[1];\n f32[offset + 2] = coordinates.transform.scale[0];\n f32[offset + 3] = coordinates.transform.scale[1];\n f32[offset + 4] = coordinates.set;\n f32[offset + 5] = coordinates.transform.rotation;\n f32[offset + 6] = u;\n f32[offset + 7] = v;\n }\n return;\n }\n // Standard PBR has a schema-derived 128-byte authored region before the\n // engine-owned UV records. Sprite, sprite-lit, unlit, and text keep their\n // own legacy tail positions because their WGSL layouts differ.\n const textureScaleOffset = isStandardPbrMaterialShader(material.materialShaderId)\n ? STANDARD_PBR_TEXTURE_SCALE_OFFSET\n : LEGACY_MATERIAL_TEXTURE_SCALE_OFFSET;\n const isStandardPbr = textureScaleOffset === STANDARD_PBR_TEXTURE_SCALE_OFFSET;\n const hasTextureMetadata =\n material.textureCoordinates !== undefined ||\n material.textureHandles !== undefined ||\n material.videoTextureFields !== undefined ||\n material.baseColorTexture !== undefined ||\n material.metallicRoughnessTexture !== undefined ||\n material.normalTexture !== undefined ||\n material.emissiveTexture !== undefined ||\n material.occlusionTexture !== undefined;\n if (!hasTextureMetadata) {\n f32.set(\n isStandardPbr ? DEFAULT_STANDARD_TEXTURE_COORDINATES : DEFAULT_LEGACY_TEXTURE_SCALES,\n textureScaleOffset / 4,\n );\n return;\n }\n const fields = isStandardPbr\n ? MATERIAL_TEXTURE_SCALE_FIELDS\n : LEGACY_MATERIAL_TEXTURE_SCALE_FIELDS;\n for (let index = 0; index < fields.length; index++) {\n const field = fields[index];\n if (field === undefined) continue;\n const handle = materialTextureForField(material, field);\n const resolved =\n handle === undefined ? undefined : resolveAssetHandle<TextureAsset>(world, handle);\n const texture = resolved?.ok === true ? resolved.value : undefined;\n const [u, v] = materialTextureUvScale(texture);\n if (isStandardPbr) {\n const coordinates = material.textureCoordinates?.get(field);\n const transform = coordinates?.transform;\n const offset =\n STANDARD_PBR_TEXTURE_COORDINATE_OFFSET / 4 + index * STANDARD_PBR_TEXTURE_COORDINATE_STRIDE;\n f32[offset] = transform?.offset?.[0] ?? 0;\n f32[offset + 1] = transform?.offset?.[1] ?? 0;\n f32[offset + 2] = transform?.scale?.[0] ?? 1;\n f32[offset + 3] = transform?.scale?.[1] ?? 1;\n f32[offset + 4] = coordinates?.set ?? 0;\n f32[offset + 5] = transform?.rotation ?? 0;\n f32[offset + 6] = u;\n f32[offset + 7] = v;\n } else {\n const offset = textureScaleOffset / 4 + index * 2;\n f32[offset] = u;\n f32[offset + 1] = v;\n }\n }\n}\n\nfunction materialCoordinateSchema(\n material: MaterialSnapshot,\n): readonly ParamSchemaEntry[] | undefined {\n if (\n isStandardPbrMaterialShader(material.materialShaderId) &&\n material.paramSnapshot !== undefined\n ) {\n return DEFAULT_STANDARD_PBR_PARAM_SCHEMA;\n }\n if (material.materialParamSchema !== undefined && material.materialParamSchema.length > 0) {\n return material.materialParamSchema;\n }\n switch (material.materialShaderId) {\n case 'forgeax::default-unlit':\n return DEFAULT_UNLIT_PARAM_SCHEMA;\n case 'forgeax::sprite':\n case 'forgeax::sprite-lit':\n return DEFAULT_SPRITE_PARAM_SCHEMA;\n case 'forgeax::msdf-text':\n return DEFAULT_MSDF_TEXT_PARAM_SCHEMA;\n default:\n return undefined;\n }\n}\n\n/**\n * feat-20260621-learn-render-5-5-parallax M2 / w8 (D-3): ordered user-region\n * texture field names for a material's bind-group assembly, derived from the\n * shader's paramSchema via the `derive()` SSOT (insertion order = sampler/\n * texture pair order in derive().bglEntries). Falls back to the built-in\n * fields only when the schema is unavailable; an explicit empty schema means\n * the authored material has no user-region textures.\n */\nexport function userRegionTextureFieldOrder(\n schema: Parameters<typeof derive>[0] | undefined,\n): readonly string[] {\n if (schema === undefined) return BUILTIN_USER_REGION_TEXTURE_FIELDS;\n const fields = [...derivedParamSchema(schema).textureFieldNames];\n return fields;\n}\n\n/**\n * feat-20260621-learn-render-5-5-parallax M2 / w8: the fallback texture view\n * for a user-region field when no handle is provided (graceful, charter P3).\n * normalTexture decodes to a flat tangent normal; everything else (baseColor,\n * MR, height, ...) uses the 1x1 white default (height white -> zero displacement).\n */\nexport function defaultViewForUserRegionField(\n field: string,\n pipelineState: PipelineState,\n schema?: readonly ParamSchemaEntry[],\n): TextureView {\n const parameter = schema?.find((entry) => entry.name === field);\n if (parameter?.type === 'texture_cube') {\n // The renderer already owns a valid white cube for the Skylight fallback.\n // Use it until a receipt-promoted RenderTarget source becomes available;\n // binding a 2D view here would invalidate the custom cube material BGL.\n return pipelineState.skylightFallback?.prefilterView ?? pipelineState.defaultWhiteTextureView;\n }\n if (field === 'normalTexture') return pipelineState.defaultNormalTextureView;\n if (field === 'baseColorTexture') return pipelineState.fallbackTextureView;\n return pipelineState.defaultWhiteTextureView;\n}\n\n/**\n * feat-20260527-sprite-nineslice M4 / w17 (AC-16): once-per-renderable\n * detection of \"Transform.scale below the four 9-slice corner anchors\". Pure\n * helper extracted out of recordFrame so unit tests can drive it without a\n * GPU device — the recordFrame loop calls this with its `transformWorld` /\n * `slices` / `renderableIndex` / `seenIndices` / `metrics` arguments.\n *\n * The scale-vs-anchor formula mirrors plan-strategy §D-3 — the world x scale must\n * accommodate `|slices.x| + |slices.z|`, and `scaleY` must accommodate\n * `|slices.y| + |slices.w|`. Slices ≡ all zero is a no-op (legacy quad\n * path); a breach increments `nineslice.scale-too-small` exactly once per\n * `renderableIndex` per RenderSystem lifetime via the `seenIndices` Set\n * (the same warn-once anchor pattern used for missing-texture sprites).\n *\n * @param transformWorld The entity's resolved GlobalTransform.world mat4 (16 floats column-major).\n * @param slices The four anchor distances `[left, top, right, bottom]`\n * (sentinel `bottom < 0` for tile mode is consumed via abs()).\n * @param renderableIndex The entity index into the validated renderables list.\n * @param seenIndices The per-frame-state guard Set; entries are added on increment.\n * @param metrics The owner-provided EngineMetrics counter.\n * @internal — exported for unit-test access (w17).\n */\nexport function detectNineSliceScaleTooSmall(\n transformWorld: Float32Array,\n slices: readonly [number, number, number, number],\n renderableIndex: number,\n seenIndices: Set<number>,\n metrics: { increment(name: string): void },\n): void {\n const anyNonZero = slices[0] !== 0 || slices[1] !== 0 || slices[2] !== 0 || slices[3] !== 0;\n if (!anyNonZero) return;\n const sx = Math.hypot(transformWorld[0] ?? 1, transformWorld[1] ?? 0, transformWorld[2] ?? 0);\n const sy = Math.hypot(transformWorld[4] ?? 0, transformWorld[5] ?? 1, transformWorld[6] ?? 0);\n const horizontalAnchor = Math.abs(slices[0]) + Math.abs(slices[2]);\n const verticalAnchor = Math.abs(slices[1]) + Math.abs(slices[3]);\n if (sx < horizontalAnchor || sy < verticalAnchor) {\n if (!seenIndices.has(renderableIndex)) {\n seenIndices.add(renderableIndex);\n metrics.increment('nineslice.scale-too-small');\n }\n }\n}\n\n/**\n * Build the 384-byte Material UBO payload for a PBR / unlit material entry\n * (feat-20260527-sprite-nineslice M2 / w11; D-7 regression-net helper).\n *\n * Byte-for-byte equivalent to the legacy hard-coded PBR write path; each\n * deviation is caught by `render-system-record-pbr-ubo-stable.test.ts`.\n * The schema-driven paramSnapshot overlay (feat-20260523 M9-T05; AC-14)\n * positions vec4 / f32 slots onto std140 [slot0 vec4, slot1 f32 metallic,\n * slot1 f32 roughness] mirroring the engine-shipped default-standard-pbr\n * Material struct.\n */\nexport function buildPbrMaterialUboPayload(material: MaterialSnapshot): Uint8Array {\n const buf = new Uint8Array(STANDARD_PBR_UBO_SIZE);\n writePbrMaterialUboPayload(buf, material);\n return buf;\n}\n\n/**\n * Write the standard material payload into caller-owned storage.\n *\n * The allocating wrapper above remains the byte-stable test/helper surface,\n * while the frame recorder reuses one scratch slot for all materials. A\n * scene with thousands of submeshes otherwise allocates one 384-byte\n * Uint8Array per material per frame, creating avoidable GC pressure without\n * changing GPU-visible bytes.\n */\nexport function writePbrMaterialUboPayload(\n buf: Uint8Array | Float32Array,\n material: MaterialSnapshot,\n): void {\n if (buf.byteLength < STANDARD_PBR_UBO_SIZE) {\n throw new RangeError(\n `writePbrMaterialUboPayload: expected at least ${STANDARD_PBR_UBO_SIZE} bytes, got ${buf.byteLength}`,\n );\n }\n buf.fill(0);\n const f32 = materialUboFloatView(buf);\n // Layout (issue-1: channelMap split per D-8) -- byte-equivalent to the\n // post-split sidecar paramSchema for default-standard-pbr (12 numeric\n // entries packed std140 into one merged UBO at binding(0)).\n // f32[0..3] baseColor (offset 0, vec4)\n // f32[4] metallic (offset 16)\n // f32[5] roughness (offset 20)\n // f32[6] metallicChannel (offset 24) -- glTF 2.0 default = B = 2\n // f32[7] roughnessChannel (offset 28) -- glTF 2.0 default = G = 1\n // f32[8] aoChannel (offset 32) -- glTF 2.0 default = R = 0\n // f32[9] extraChannel (offset 36) -- reserved = 0\n // (offset 40..47 implicit pad: vec3 align=16)\n // f32[12..14] emissive (offset 48, vec3)\n // f32[15] emissiveIntensity (offset 60)\n // f32[16] occlusionStrength (offset 64)\n // f32[17] alphaCutoff (offset 68)\n // f32[18] clearcoat (offset 72)\n // f32[19] clearcoatRoughness (offset 76)\n // f32[20..22] specularTint (offset 80, vec3)\n // f32[23] normalScale (offset 92)\n // f32[24] transmission (offset 96)\n // f32[25] ior (offset 100)\n // f32[26] thickness (offset 104)\n // f32[28..30] attenuationColor (offset 112, vec3)\n // f32[31] attenuationDistance(offset 124)\n // f32[32..95] engine-owned texture coordinate records (offset 128)\n f32[0] = material.baseColor[0] ?? 0;\n f32[1] = material.baseColor[1] ?? 0;\n f32[2] = material.baseColor[2] ?? 0;\n f32[3] = 1;\n f32[4] = material.metallic;\n f32[5] = material.roughness;\n // channelMap default = (B, G, R, _) per AGENTS.md + glTF 2.0\n // KHR_materials_pbrSpecularGlossiness ARM packing -- now 4 independent\n // f32 selectors; fragment casts each to u32 at the pick site.\n f32[6] = 2; // metallicChannel <- B\n f32[7] = 1; // roughnessChannel <- G\n f32[8] = 0; // aoChannel <- R\n f32[9] = 0; // extraChannel <- reserved\n // emissive vec3 + emissiveIntensity (offset 48..63)\n const em = material.emissive;\n f32[12] = em?.[0] ?? 0;\n f32[13] = em?.[1] ?? 0;\n f32[14] = em?.[2] ?? 0;\n f32[15] = material.emissiveIntensity ?? 0;\n // occlusionStrength (offset 64)\n f32[16] = material.occlusionStrength ?? 1;\n // alphaCutoff (offset 68).\n const alphaCutoff = material.paramSnapshot?.alphaCutoff;\n f32[17] = typeof alphaCutoff === 'number' ? alphaCutoff : 0;\n f32[18] = material.clearcoat ?? 0;\n f32[19] = material.clearcoatRoughness ?? 0.5;\n const specularTint = material.specularTint;\n f32[20] = specularTint?.[0] ?? 1;\n f32[21] = specularTint?.[1] ?? 1;\n f32[22] = specularTint?.[2] ?? 1;\n const snapshotNumber = (name: string, fallback: number): number => {\n const value = material.paramSnapshot?.[name];\n return typeof value === 'number' ? value : fallback;\n };\n const snapshotVec3 = (\n name: string,\n fallback: readonly [number, number, number],\n ): readonly [number, number, number] => {\n const value = material.paramSnapshot?.[name];\n return Array.isArray(value)\n ? [value[0] ?? fallback[0], value[1] ?? fallback[1], value[2] ?? fallback[2]]\n : fallback;\n };\n f32[23] = material.normalScale ?? snapshotNumber('normalScale', 1);\n f32[24] = snapshotNumber('transmission', 0);\n f32[25] = snapshotNumber('ior', 1.5);\n f32[26] = snapshotNumber('thickness', 0);\n const attenuationColor = snapshotVec3('attenuationColor', [1, 1, 1]);\n f32[28] = attenuationColor[0];\n f32[29] = attenuationColor[1];\n f32[30] = attenuationColor[2];\n f32[31] = snapshotNumber('attenuationDistance', 0);\n // Schema-driven paramSnapshot overlay (feat-20260523 M9-T05, AC-14):\n // for user-shaders with a paramSnapshot, project the first vec4/color\n // entry onto slot 0 and the first two f32 entries onto slot 1's first\n // two floats. The default-standard-pbr path lands on the same offsets\n // via the explicit fields above, so the overlay is a no-op for the\n // engine's stock PBR shader (charter P4 + R-H regression fence).\n const paramSnap = material.paramSnapshot;\n if (paramSnap !== undefined) {\n const f32Snap = (name: string): number | undefined => {\n const v = paramSnap[name];\n return typeof v === 'number' ? v : undefined;\n };\n const colorSnap = (name: string): readonly number[] | undefined => {\n const v = paramSnap[name];\n return Array.isArray(v) && v.every((x) => typeof x === 'number')\n ? (v as readonly number[])\n : undefined;\n };\n // Walk schema in declared order, fill positional UBO slots.\n const materialShaderId = material.materialShaderId;\n // Note: schema lookup is the caller's job (it owns the runtime ref);\n // when the helper has no access to runtime, paramSnap is consumed\n // positionally without a schema walk. The inline caller (recordFrame)\n // still performs the schema-driven walk and writes the overlay before\n // queueing this payload, so this helper is only the byte-stable\n // baseline. To preserve byte-for-byte equivalence in the helper-only\n // unit-test path, the overlay pass is skipped when the helper is\n // called without an external schema reference.\n void materialShaderId;\n void f32Snap;\n void colorSnap;\n }\n}\n\n/**\n * Generic std140 UBO writer driven by `derive(paramSchema).uboLayout.entries`\n * (feat-20260625-refactor-sprite-as-transparent-mesh M1 / w3, plan-strategy\n * section 2 D-2).\n *\n * For each numeric entry in the schema, looks up the matching value in\n * `paramSnapshot` and writes it at the std140 offset `derive` computed.\n * Vec / color entries pull from `paramSnapshot[name]` as a `readonly number[]`\n * (writes `min(size/4, value.length)` floats, padding with 0 if shorter for\n * the field's declared width); scalar entries pull a single number.\n *\n * Behaviour:\n * - schema or snapshot `undefined` -> no writes (caller may keep payload\n * baseline).\n * - missing snapshot field -> that field's bytes are left untouched\n * (overlay semantics; same shape the legacy inline overlay had).\n * - field type the writer cannot interpret (texture / sampler / storage_\n * buffer / value-type mismatch) -> skipped silently; `derive` strips\n * non-numeric entries from `uboLayout.entries` so the loop only iterates\n * numeric fields.\n *\n * The writer reads `paramSnapshot` only -- it does NOT call\n * `runtime.assets.get<MaterialAsset>` or cast `firstMaterial`. Gate R-H\n * (plan-strategy section 5.6) bans those paths through\n * `scripts/forgeax/check-render-record-no-material-asset-get.mjs`.\n *\n * standard-pbr remains byte-identical to `buildPbrMaterialUboPayload`: the\n * engine's stock PBR material ships `paramSnapshot: undefined`, so this\n * writer is a no-op on that path; the explicit field writes in the helper\n * above cover every byte. User shaders (sprite-shaped 4 x vec4 or another\n * paramSchema) get their fields written at the offsets declared by derive.\n *\n * @internal export-for-test (consumed inside `recordFrame` + render-system-\n * record.test.ts; not part of the package's public surface).\n */\nexport function applyParamSnapshotToUbo(\n payload: MaterialUboPayload,\n paramSchema: readonly ParamSchemaEntry[] | undefined,\n paramSnapshot:\n | Readonly<Record<string, number | readonly number[] | string | undefined>>\n | undefined,\n): void {\n if (paramSchema === undefined) return;\n if (paramSnapshot === undefined) return;\n const f32 = materialUboFloatView(payload);\n const effectiveSchema =\n Object.hasOwn(paramSnapshot, 'transmission') &&\n Object.hasOwn(paramSnapshot, 'ior') &&\n Object.hasOwn(paramSnapshot, 'thickness')\n ? DEFAULT_STANDARD_PBR_PARAM_SCHEMA\n : paramSchema;\n const { uboLayout } = derivedParamSchema(effectiveSchema);\n for (const entry of uboLayout.entries) {\n const value = paramSnapshot[entry.name];\n if (value === undefined) continue;\n const f32Offset = entry.offset / 4;\n const f32Width = entry.size / 4;\n if (typeof value === 'number') {\n // Scalar f32 / i32 / u32 -- single-slot write. (i32 / u32 still arrive\n // as a JS number; the GPU side reads the four bytes as the declared\n // type, so an f32 write is the correct bit pattern when the caller\n // already produced an integer value.)\n if (f32Width >= 1) f32[f32Offset] = value;\n continue;\n }\n if (Array.isArray(value)) {\n const arr = value as readonly number[];\n const writeCount = Math.min(arr.length, f32Width);\n for (let i = 0; i < writeCount; i++) {\n const v = arr[i];\n if (typeof v === 'number') f32[f32Offset + i] = v;\n }\n }\n // string values (texture GUIDs) belong to texture bindings, not the\n // UBO; derive's uboLayout.entries already strips non-numeric schema\n // entries, so we will not see a uboLayout entry whose snapshot value\n // is a string under normal flow. Skip defensively if we do.\n }\n}\n\n/**\n * feat-20260704 M3/w19: shared per-submesh material bind-group assembly, hoisted\n * from the `buildPerSubmeshMaterialBg` closure inside recordMainPass so both the\n * geometry pass and the LDR blend sub-pass (extracted to separate functions)\n * call the identical layout.\n *\n * feat-city-glb Bug 5 (per-submesh transparency): a transparent PBR submesh\n * binds the identical metallic/roughness/normal/emissive/occlusion +\n * Skylight layout the geometry pass uses (the sub-pass previously bound a\n * sprite-only BG, which cannot render a PBR decal). The per-frame closure state\n * (runtime / pipelineState / world / store / skylightResources / the shared\n * material BG cache + counters) is threaded through `deps`; the caller passes\n * the per-submesh material snapshot + entityKey (video texture routing) and sets\n * the dynamic UBO offset itself.\n *\n * @internal\n */\nexport interface PerSubmeshMaterialBgDeps {\n readonly runtime: RenderSystemRuntime;\n readonly pipelineState: PipelineState;\n readonly world: World;\n readonly store: GpuResidencyCache;\n readonly materialSlice: number;\n readonly videoHighPerfAvailable: boolean;\n readonly skylightResources: SkylightBindGroupResources;\n readonly resolveRenderTargetTextureSource?: RenderSystemRuntime['resolveRenderTargetTextureSource'];\n readonly resolveReflectionProbeResources?: (\n materialWorld: World,\n entityKey: number,\n ) => SkylightBindGroupResources | undefined;\n readonly materialBgShared: Map<string, WeakMap<object, unknown>>;\n /** Cross-frame final BG reuse keyed by the stable source material handle. */\n readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;\n /** Active transmission backdrop; undefined/null means layout placeholder. */\n readonly transmissionBackdropView?: TextureView | null;\n readonly bindGroupCounts: BindGroupCounts;\n}\n\n/** @internal Exported only so buffer-generation invalidation stays regression-tested. */\nexport function isMaterialBgAssemblyCacheHit(\n cached: MaterialBgAssemblyCacheEntry | undefined,\n material: MaterialSnapshot,\n materialBgl: BindGroupLayout,\n materialBuffer: Buffer,\n skylightResources: SkylightBindGroupResources,\n materialResourceEpoch: number,\n transmissionBackdropView?: TextureView | null,\n): cached is MaterialBgAssemblyCacheEntry {\n if (transmissionBackdropView != null) return false;\n return (\n cached?.material === material &&\n cached.materialResourceEpoch === materialResourceEpoch &&\n cached.materialBgl === materialBgl &&\n cached.materialBuffer === materialBuffer &&\n cached.skylightResources.irradianceView === skylightResources.irradianceView &&\n cached.skylightResources.irradianceSampler === skylightResources.irradianceSampler &&\n cached.skylightResources.prefilterView === skylightResources.prefilterView &&\n cached.skylightResources.prefilterSampler === skylightResources.prefilterSampler &&\n cached.skylightResources.brdfLutView === skylightResources.brdfLutView &&\n cached.skylightResources.brdfLutSampler === skylightResources.brdfLutSampler &&\n cached.skylightResources.intensityBuffer === skylightResources.intensityBuffer\n );\n}\n\nexport function buildPerSubmeshMaterialBg(\n deps: PerSubmeshMaterialBgDeps,\n submeshMaterial: MaterialSnapshot,\n entityKey: number,\n materialWorld: World = deps.world,\n): BindGroup {\n const {\n runtime,\n pipelineState,\n store,\n materialSlice,\n videoHighPerfAvailable,\n skylightResources,\n resolveRenderTargetTextureSource,\n resolveReflectionProbeResources,\n materialBgShared,\n materialBgAssemblyCache,\n transmissionBackdropView,\n bindGroupCounts,\n } = deps;\n const effectiveSkylightResources =\n resolveReflectionProbeResources?.(materialWorld, entityKey) ?? skylightResources;\n const smMaterialHandle = submeshMaterial.materialHandle;\n const materialCacheKey =\n smMaterialHandle === undefined ? undefined : `${materialWorld.identity}:${smMaterialHandle}`;\n const smHasVideoFields = (submeshMaterial.videoTextureFields?.size ?? 0) > 0;\n const smShaderId = submeshMaterial.materialShaderId;\n const smPerShaderBgl =\n smShaderId !== undefined ? runtime.getMaterialBindGroupLayout?.(smShaderId) : undefined;\n const smMaterialBgl = smPerShaderBgl ?? pipelineState.materialBindGroupLayout;\n const hasActiveTransmissionBackdrop = transmissionBackdropView != null;\n if (smMaterialHandle !== undefined && !smHasVideoFields && !hasActiveTransmissionBackdrop) {\n const cached =\n materialCacheKey === undefined ? undefined : materialBgAssemblyCache.get(materialCacheKey);\n if (\n isMaterialBgAssemblyCacheHit(\n cached,\n submeshMaterial,\n smMaterialBgl,\n pipelineState.materialUniformBuffer.buffer,\n effectiveSkylightResources,\n store.materialResourceEpoch,\n transmissionBackdropView,\n )\n ) {\n return cached.bindGroup;\n }\n }\n const smSchema =\n submeshMaterial.materialParamSchema ??\n (smShaderId !== undefined ? runtime.getParamSchema?.(smShaderId) : undefined);\n // The shipped PBR shaders always own the eight texture pairs declared by the\n // standard shader artifact. The runtime PBR BGL exposes those pairs directly;\n // emissive and occlusion are not duplicated in an engine injection region.\n // Keep the record projection on the shader-owned layout so IBL starts at\n // binding 17 rather than colliding with transmissionSampler.\n const smUserRegionFields =\n smPerShaderBgl === undefined || isStandardPbrMaterialShader(smShaderId)\n ? BUILTIN_USER_REGION_TEXTURE_FIELDS\n : userRegionTextureFieldOrder(smSchema);\n let materialResourcesResident = true;\n const smSamplerForField = (field: string | undefined): Sampler => {\n const handle = field === undefined ? undefined : submeshMaterial.samplerHandles?.get(field);\n if (handle === undefined) return pipelineState.defaultSampler;\n const sampler = residentSampler(materialWorld, store, runtime, handle);\n if (sampler === undefined) materialResourcesResident = false;\n return sampler ?? pipelineState.defaultSampler;\n };\n const smBaseEntries: BindGroupEntry[] = [\n {\n binding: 0,\n resource: {\n kind: 'buffer' as const,\n value: {\n buffer: pipelineState.materialUniformBuffer.buffer,\n offset: 0,\n size: materialSlice,\n },\n },\n },\n ];\n const smBglPairCount = smUserRegionFields.length;\n for (let fi = 0; fi < smBglPairCount; fi++) {\n const field = smUserRegionFields[fi];\n const samplerBinding = 1 + fi * 2;\n const textureBinding = samplerBinding + 1;\n let smView: TextureView =\n field !== undefined\n ? defaultViewForUserRegionField(field, pipelineState, smSchema)\n : pipelineState.defaultWhiteTextureView;\n const smVideoClip =\n field !== undefined ? submeshMaterial.videoTextureFields?.get(field) : undefined;\n const smTargetSource =\n field === undefined\n ? undefined\n : materialRenderTargetSourceForField(\n submeshMaterial,\n field,\n resolveRenderTargetTextureSource,\n );\n if (smTargetSource !== undefined) {\n // The Renderer host resolves the generation-checked physical view. A\n // candidate is never exposed here; until its matching FrameReceipt\n // completes, the material remains on the neutral fallback.\n if (smTargetSource.textureView !== undefined) smView = smTargetSource.textureView;\n else materialResourcesResident = false;\n } else if (smVideoClip !== undefined) {\n const view = videoTextureView(\n materialWorld,\n runtime.dynamicTextureStore,\n runtime,\n entityKey,\n smVideoClip,\n videoHighPerfAvailable,\n );\n if (view !== undefined) smView = view;\n } else {\n const smHandle =\n field === 'emissiveTexture'\n ? submeshMaterial.emissiveTexture\n : field === 'occlusionTexture'\n ? submeshMaterial.occlusionTexture\n : field !== undefined\n ? submeshMaterial.textureHandles?.get(field)\n : undefined;\n if (smHandle !== undefined) {\n const view = residentTextureView(materialWorld, store, runtime, smHandle);\n if (view !== undefined) smView = view;\n else materialResourcesResident = false;\n }\n }\n smBaseEntries.push(\n {\n binding: samplerBinding,\n resource: { kind: 'sampler' as const, value: smSamplerForField(field) },\n },\n {\n binding: textureBinding,\n resource: { kind: 'textureView' as const, value: smView },\n },\n );\n }\n // The backdrop is a full mip-chain view owned by the pipeline. Reuse the\n // pipeline's existing filtering/clamp sampler for screen-space sampling;\n // the material default sampler intentionally keeps repeat addressing for\n // authored UV textures and is not a backdrop sampler.\n const transmissionSampler =\n transmissionBackdropView != null\n ? effectiveSkylightResources.prefilterSampler\n : pipelineState.defaultSampler;\n const smMergedEntries = assembleMaterialWithSkylightEntries(\n smBaseEntries,\n effectiveSkylightResources,\n {\n sampler: transmissionSampler,\n ...(transmissionBackdropView === undefined ? {} : { backdropView: transmissionBackdropView }),\n } satisfies TransmissionBindGroupResources,\n );\n const createBindGroup = (): BindGroup => {\n const result = runtime.device.createBindGroup({\n label: 'pbr-material-skylight-bg',\n layout: smMaterialBgl,\n entries: smMergedEntries,\n });\n if (!result.ok) throw result.error;\n return result.value;\n };\n const smBindGroup = hasActiveTransmissionBackdrop\n ? createBindGroup()\n : getOrCreatePerEntity(\n materialBgShared,\n smShaderId ?? '',\n smMergedEntries.map((e) => extractEntryResourceHandle(e)),\n 'material-shared',\n createBindGroup,\n bindGroupCounts,\n );\n if (\n smMaterialHandle !== undefined &&\n !smHasVideoFields &&\n materialResourcesResident &&\n !hasActiveTransmissionBackdrop\n ) {\n if (materialCacheKey !== undefined) {\n materialBgAssemblyCache.set(materialCacheKey, {\n material: submeshMaterial,\n materialResourceEpoch: store.materialResourceEpoch,\n materialBgl: smMaterialBgl,\n materialBuffer: pipelineState.materialUniformBuffer.buffer,\n skylightResources: effectiveSkylightResources,\n bindGroup: smBindGroup,\n });\n }\n }\n return smBindGroup;\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: main-pass geometry draws.\n// feat-20260704 M5/w31: further-split from main-pass.ts (AC-05 <=1500 lines/file).\n// recordGeometryDraws + resolveGeometryInstanceBuffer, moved verbatim.\n\nimport type { World } from '@forgeax/engine-ecs';\nimport {\n type BindGroup,\n type Buffer,\n type RenderPipeline,\n RhiError,\n type RhiRenderPassEncoder,\n} from '@forgeax/engine-rhi';\nimport type { PassKind, PrimitiveTopology } from '@forgeax/engine-types';\nimport { GpuBuffer } from '../gpu-resource';\nimport {\n GPU_BUFFER_USAGE_COPY_DST,\n GPU_BUFFER_USAGE_STORAGE,\n GPU_BUFFER_USAGE_UNIFORM,\n} from '../gpu-usage';\nimport { createHdrpSkinUnifiedBindGroup, getOrCreateHdrpBuffers } from '../hdrp-buffers';\nimport type { InstanceBufferCacheEntry } from '../instance-buffer-cache';\nimport { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';\nimport {\n createPbrSkinMeshBindGroupEntries,\n isStandardPbrMaterialShader,\n pbrSkinMeshDynamicOffsets,\n SKIN_MATERIAL_SHADER_ID,\n} from '../pbr-pipeline';\nimport {\n renderStateHash,\n standardStorageVariantSet,\n standardTopologyVariantSet,\n variantSetFromVertexLayoutProjection,\n} from '../pipeline-spec';\nimport type { PointsLinesRecordPlan } from '../points-lines/record';\nimport { POINTS_LINES_MATERIAL_SHADER_ID } from '../points-lines/record';\nimport type { RenderRecordPhase } from '../render-contract';\nimport type { MaterialSnapshot } from '../render-system-extract';\nimport {\n PROBE_BLEND_RECORD_BYTE_SIZE,\n PROBE_BLEND_RECORD_STRIDE,\n probeBlendRecordOffset,\n} from '../scene/probe-blend-record';\nimport { worldEntityKey } from './frame-snapshot';\nimport {\n geometryRenderStateForTopology,\n isEntityFullyTransparent,\n selectGeometryPipeline,\n selectMaterialGroup2,\n} from './main-pass-material';\nimport {\n getOrCreateFromChain,\n INSTANCE_UBO_FULL_ARRAY_BYTES,\n MAX_UNIFORM_INSTANCES,\n MESH_PER_ENTITY_STRIDE,\n MESH_SSBO_BYTES,\n MESH_UBO_FULL_ARRAY_BYTES,\n packInstanceStorageBuffer,\n} from './mesh-ssbo';\nimport type { _InternalRenderPipelineContext, MaterialShaderPipelineEntry } from './render-context';\nimport { MATERIAL_PER_ENTITY_STRIDE } from './render-context';\nimport { POINTS_LINES_VIEW_SLOT_STRIDE, writePointsLinesViewUbo } from './view-ubo';\n\ntype GeometryInstanceDraw = {\n readonly instanceBuffer: Buffer;\n readonly instanceBindGroup: BindGroup;\n /** -1 means the no-probe layout and therefore no dynamic offset. */\n readonly probeOffset: number;\n readonly instanceCount: number;\n};\n\ntype GeometryBindingState = {\n pipeline: RenderPipeline | null;\n instancesBuffer: Buffer | null;\n probeOffset: number;\n};\n\ntype MaterialPipelineLookup = {\n readonly materialShaderId: string;\n readonly isHdrTarget: boolean;\n readonly renderStateKey: string;\n readonly topology: PrimitiveTopology;\n readonly indexFormat: 'uint16' | 'uint32';\n readonly variantSet: string | undefined;\n readonly passKind: PassKind;\n readonly layoutProjection: import('@forgeax/engine-geometry').VertexLayoutProjection;\n readonly sampleCount: number;\n readonly colorFormatOverride: GPUTextureFormat | undefined;\n readonly additionalColorFormats: readonly GPUTextureFormat[] | undefined;\n readonly handle: MaterialShaderPipelineEntry | null;\n};\n\ntype GeometryRecordProfileSegment = 'material-bind-groups' | 'pipeline-selection' | 'draw-submit';\n\ntype GeometryRenderState = ReturnType<typeof geometryRenderStateForTopology>;\n\n/**\n * Resolve the depth contract for a geometry pass without changing the base\n * material state. Temporal scene-data shares the main pass depth attachment:\n * it is read-only and accepts the equal depth produced by the unjittered\n * temporal projection, while still rejecting fragments behind the visible\n * surface.\n */\nexport function geometryRenderStateForPass(\n base: GeometryRenderState,\n passKind: PassKind,\n): GeometryRenderState {\n if (passKind !== 'temporal') return base;\n return {\n ...base,\n depthWriteEnabled: false,\n depthCompare: 'less-equal' as const,\n };\n}\n\nfunction geometryRecordPhase(\n passKind: PassKind,\n segment: GeometryRecordProfileSegment,\n): RenderRecordPhase {\n const pass = passKind === 'deferred' ? 'g-buffer' : 'forward';\n return `record/graph-execute/${pass}/${segment}` as RenderRecordPhase;\n}\n\nfunction profileGeometrySegment<T>(\n c: _InternalRenderPipelineContext,\n passKind: PassKind,\n segment: GeometryRecordProfileSegment,\n action: () => T,\n): T {\n const profilePhase = c.profilePhase;\n return profilePhase === undefined\n ? action()\n : profilePhase(geometryRecordPhase(passKind, segment), action);\n}\n\nfunction submitSubmeshDraws(\n pass: RhiRenderPassEncoder,\n state: GeometryBindingState,\n pipeline: RenderPipeline,\n instanceDraws: readonly GeometryInstanceDraw[],\n indexed: boolean,\n indexCount: number,\n vertexCount: number,\n indexOffset: number,\n): void {\n if (state.pipeline !== pipeline) {\n pass.setPipeline(pipeline);\n state.pipeline = pipeline;\n }\n for (const instanceDraw of instanceDraws) {\n if (\n instanceDraw.instanceBuffer !== state.instancesBuffer ||\n instanceDraw.probeOffset !== state.probeOffset\n ) {\n if (instanceDraw.probeOffset < 0) {\n pass.setBindGroup(3, instanceDraw.instanceBindGroup);\n } else {\n pass.setBindGroup(3, instanceDraw.instanceBindGroup, [instanceDraw.probeOffset]);\n }\n state.instancesBuffer = instanceDraw.instanceBuffer;\n state.probeOffset = instanceDraw.probeOffset;\n }\n if (indexed) {\n pass.drawIndexed(indexCount, instanceDraw.instanceCount, indexOffset, 0, 0);\n } else {\n pass.draw(vertexCount, instanceDraw.instanceCount, 0, 0);\n }\n }\n}\n\n/**\n * Issues a prepared Points/Lines draw into the already-open geometry pass.\n * Pass lifetime, attachments, bind groups, and submission remain owned by the\n * existing main-pass interpreter.\n */\nexport function recordPointsLinesDraw(\n pass: RhiRenderPassEncoder,\n plan: PointsLinesRecordPlan,\n): void {\n if (plan.drawCount === 0) return;\n if (plan.indexCount > 0) {\n pass.drawIndexed(plan.indexCount, 1, 0, 0, 0);\n return;\n }\n pass.draw(plan.vertexCount, 1, 0, 0);\n}\n\n/**\n * feat-20260704 M3/w19: per-entity geometry (main colour) draw loop, extracted\n * verbatim from recordMainPass. Walks `c.validatedOrdered`, selects the\n * per-entity / per-submesh PBR / unlit / skin pipeline, uploads the per-submesh\n * material UBO slices, binds view / material / mesh / instances bind groups, and\n * issues the per-submesh draws into the already-begun geometry `pass`. Fully-\n * transparent entities are skipped here (drawn in the LDR blend sub-pass);\n * mixed meshes draw their opaque submeshes here and skip transparent submeshes.\n * The pass-selector match set, per-entity material-slot start table, MSAA sample\n * count, Standard group(2) bind group, fallback mesh group(2) bind group, and\n * the shared per-submesh material BG builder are threaded in explicitly.\n *\n * @internal\n */\nexport function recordGeometryDraws(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n matchedMaterials: ReadonlyMap<number, ReadonlySet<number>> | null,\n materialSlotIndices: readonly (readonly number[])[],\n sampleCount: number,\n meshGroup2: BindGroup | null,\n meshBindGroup: BindGroup | null,\n resolveMaterialBindGroup: (\n materialSlot: number,\n submeshMaterial: MaterialSnapshot,\n entityKey: number,\n materialWorld: World,\n ) => BindGroup,\n passKind: PassKind = 'forward',\n): void {\n const {\n runtime,\n pipelineState,\n frameState,\n bindGroupCounts,\n dispatchCounts,\n tonemapActive,\n msaaActive,\n validatedOrdered,\n splitLdrSprite,\n viewBindGroup,\n viewBindGroupDynamicOffset = 0,\n } = c;\n const colorFormatOverride = c.transparentColorFormat as GPUTextureFormat | undefined;\n // The prepared Standard topology is the frame authority. A bind-group\n // identity is only a resource result; using it to infer the shader lane\n // would silently fall back to URP when the clustered resource is missing.\n const clusteredLighting = c.standardLighting?.kind === 'clustered';\n // A no-tone frame may still render into the graph-owned rgba16float target\n // (the linear-LDR route). Shader variants must follow the attachment's\n // numeric domain rather than the camera's tone-map switch, otherwise the\n // LDR/OETF fragment entry point is encoded once here and again by the\n // output transform.\n const isHdrTarget = tonemapActive || colorFormatOverride === 'rgba16float';\n let lastVertexBuffer: GpuBuffer | null = null;\n let lastIndexBuffer: GpuBuffer | null = null;\n const bindingState: GeometryBindingState = {\n pipeline: null,\n instancesBuffer: null,\n probeOffset: -1,\n };\n const identityInstanceBuffer = pipelineState.identityInstanceBuffer;\n const identityInstanceDraws: readonly GeometryInstanceDraw[] = [\n {\n instanceBuffer: identityInstanceBuffer,\n instanceBindGroup: resolveGeometryInstancesBindGroup(c, identityInstanceBuffer, undefined),\n probeOffset: -1,\n instanceCount: 1,\n },\n ];\n const profilePhase = c.profilePhase;\n const materialGroup1DynamicOffsets = new Uint32Array(1);\n const meshGroup2DynamicOffsets = [0];\n let lastStencilReference: number | null = null;\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (D-7):\n // sprite PSO selection no longer maintains a dedicated tag — the\n // generic materialShaderId path covers sprite via the same per-\n // MaterialShader pipeline cache PBR / unlit use. The 4-placeholder\n // BG bindings (D-1 candidate b) still apply via the generic per-\n // submesh BG construction below; sprite's `forgeax::sprite` shader\n // module ships through the same cache key formula.\n // Pipeline identity does not include material parameters or the material\n // asset handle. Keying this cache by material handle therefore misses for\n // every distinct asset even when all assets use the same PSO. The nested\n // table keeps lookup O(1) by shader and immutable render-state identity; the\n // renderer's authoritative cache still owns lifetime/invalidation, while\n // this frame-local table removes the hot call/lookup overhead.\n const materialPipelineLookupCache = new Map<string, Map<string, MaterialPipelineLookup[]>>();\n const recordOcclusionCandidate = (draw: () => void): void => {\n draw();\n };\n const resolveMaterialPipeline = (\n materialShaderId: string,\n renderState: MaterialSnapshot['renderState'],\n topology: PrimitiveTopology,\n indexFormat: 'uint16' | 'uint32',\n variantSet: string | undefined,\n colorFormat: GPUTextureFormat | undefined,\n layoutProjection: import('@forgeax/engine-geometry').VertexLayoutProjection,\n ): MaterialShaderPipelineEntry | null => {\n // The fallback MRT is an extension of the built-in Standard PBR output\n // contract only. The render pass may carry a second attachment whenever\n // another renderable needs S_fallback, but shaders such as unlit, sprite,\n // and the skin PBR variant still expose only @location(0). Passing that\n // attachment into their PSO would make WebGPU reject the pipeline before\n // the first draw (\"Color target has no corresponding fragment stage\n // output\"). Keep the graph attachment shared while deriving pipeline\n // targets from the shader's actual output contract.\n const reflectionFallbackFormats =\n materialShaderId === 'forgeax::default-standard-pbr' &&\n c.reflectionFallbackColorFormat !== undefined\n ? [c.reflectionFallbackColorFormat]\n : undefined;\n const renderStateKey = renderStateHash(renderState);\n const shaderLookupCache = materialPipelineLookupCache.get(materialShaderId);\n const cachedLookups = shaderLookupCache?.get(renderStateKey);\n if (cachedLookups !== undefined) {\n for (const cached of cachedLookups) {\n if (\n cached.isHdrTarget === isHdrTarget &&\n cached.renderStateKey === renderStateKey &&\n cached.topology === topology &&\n cached.indexFormat === indexFormat &&\n cached.variantSet === variantSet &&\n cached.passKind === passKind &&\n cached.layoutProjection.digest === layoutProjection.digest &&\n cached.sampleCount === sampleCount &&\n cached.colorFormatOverride === colorFormat &&\n cached.additionalColorFormats?.join(',') === reflectionFallbackFormats?.join(',')\n ) {\n return cached.handle;\n }\n }\n }\n const resolvedVariantSetResult =\n variantSet === undefined &&\n (materialShaderId === 'forgeax::sprite' || materialShaderId === 'forgeax::sprite-lit')\n ? ({ ok: true, value: undefined } as const)\n : variantSetFromVertexLayoutProjection(layoutProjection, variantSet);\n if (!resolvedVariantSetResult.ok) {\n runtime.errorRegistry.fire(resolvedVariantSetResult.error);\n return null;\n }\n const resolvedVariantSet = resolvedVariantSetResult.value;\n const fallbackVariantSet =\n materialShaderId !== 'forgeax::default-standard-pbr'\n ? resolvedVariantSet\n : c.reflectionFallbackColorFormat !== undefined && resolvedVariantSet === ''\n ? ''\n : `${resolvedVariantSet === undefined || resolvedVariantSet === '' ? '' : `${resolvedVariantSet}+`}REFLECTION_FALLBACK_AVAILABLE=${c.reflectionFallbackColorFormat !== undefined}`;\n const resolvePipeline = () =>\n runtime.getMaterialShaderPipelineEntry?.(\n materialShaderId,\n isHdrTarget,\n renderState,\n topology,\n indexFormat,\n fallbackVariantSet,\n passKind,\n undefined,\n sampleCount,\n colorFormat,\n undefined,\n undefined,\n undefined,\n layoutProjection,\n undefined,\n undefined,\n reflectionFallbackFormats,\n ) ?? null;\n const handle =\n profilePhase === undefined\n ? resolvePipeline()\n : profileGeometrySegment(c, passKind, 'pipeline-selection', resolvePipeline);\n // A null handle is a transient async-build signal (`rhi-not-available`),\n // not a stable pipeline result. Do not memoize it in this frame's lookup:\n // caching the first pending lookup would turn a one-frame shader warm-up\n // into a permanent skip for every later frame in a tight smoke loop. The\n // owning runtime cache remains the SSOT; retrying here is bounded by the\n // existing per-frame draw path and preserves the explicit skip-draw\n // recovery while the pipeline becomes ready.\n if (handle !== null) {\n const nextLookup: MaterialPipelineLookup = {\n materialShaderId,\n isHdrTarget,\n renderStateKey,\n topology,\n indexFormat,\n variantSet,\n passKind,\n layoutProjection,\n sampleCount,\n colorFormatOverride: colorFormat,\n additionalColorFormats: reflectionFallbackFormats,\n handle,\n };\n if (shaderLookupCache === undefined) {\n materialPipelineLookupCache.set(\n materialShaderId,\n new Map([[renderStateKey, [nextLookup]]]),\n );\n } else if (cachedLookups === undefined) {\n shaderLookupCache.set(renderStateKey, [nextLookup]);\n } else {\n cachedLookups.push(nextLookup);\n }\n }\n return handle;\n };\n\n for (let i = 0; i < validatedOrdered.length; i++) {\n const entry = validatedOrdered[i];\n if (entry === undefined) continue;\n\n // Points/Lines share the Standard geometry pass. Their retained source\n // is prepared once by the renderer owner, while this loop remains the\n // sole pass/draw submission owner and preserves the authored topology.\n const pointsLinesSubmission = c.pointsLines?.prepare(entry, clusteredLighting);\n if (entry.source.pointsLines !== undefined && pointsLinesSubmission?.plan.drawCount !== 1)\n continue;\n\n if (\n passKind === 'forward' &&\n c.gpuDrivenEntityKeys.has(\n worldEntityKey(\n c.gpuDrivenWorldKeys?.[entry.source.worldId] ?? entry.source.worldId,\n entry.source.entityKey,\n ),\n )\n ) {\n continue;\n }\n\n // feat-20260609 M2: skip entities that don't match the pass selector.\n if (matchedMaterials !== null && !matchedMaterials.has(entry.renderableIndex)) continue;\n\n // D-2 generalised feat-20260625 M2 / w7: transparent entities are\n // dispatched in the separate sub-pass (bgra8unorm unorm view,\n // loadOp=load) so they must NOT be drawn here in the geometry pass\n // (bgra8unorm-srgb sRGB view, loadOp=clear). In the HDR path\n // (tonemapActive=true) or when there are no transparent entries,\n // splitLdrSprite=false and this guard is a no-op. Post-w13 the\n // legacy shadingModel arm is gone; transparent is the single SSOT\n // mirrored on `computeSplitLdrSprite`.\n //\n // feat-city-glb Bug 5 (per-submesh transparency): only skip the WHOLE\n // entity here when EVERY submesh is transparent (the sprite / fully-\n // transparent-mesh fast path, byte-identical to the pre-fix behavior for\n // single-material entities). A mixed mesh (opaque road submesh + BLEND\n // decal submesh) is NOT skipped at the entity level; its opaque submeshes\n // draw here and the per-submesh loop below skips the transparent ones\n // (they are drawn in the blend sub-pass instead).\n if (splitLdrSprite && isEntityFullyTransparent(entry.source)) continue;\n\n const pipelineTag: 'unlit' = 'unlit';\n\n // w10: setStencilReference per draw when the dispatch entry carries\n // a stencil reference value (plan-strategy D-3: draw-call dynamic\n // state after setPipeline). Defaults to 0 when no reference is set\n // (WebGPU stencil reference default, semantically a no-op).\n const stencilReference = entry.stencilReference ?? 0;\n if (stencilReference !== lastStencilReference) {\n pass.setStencilReference(stencilReference);\n lastStencilReference = stencilReference;\n }\n\n if (pointsLinesSubmission !== undefined && entry.source.pointsLines !== undefined) {\n const pointsLinesMaterial: MaterialSnapshot = {\n ...entry.source.material,\n materialShaderId: POINTS_LINES_MATERIAL_SHADER_ID,\n materialParamSchema:\n runtime.getParamSchema?.(POINTS_LINES_MATERIAL_SHADER_ID) ??\n entry.source.material.materialParamSchema,\n };\n const materialSlot = materialSlotIndices[i]?.[0] ?? 0;\n const pointsLinesBindGroup = resolveMaterialBindGroup(\n materialSlot,\n pointsLinesMaterial,\n entry.source.entityKey,\n entry.world ?? c.world,\n );\n const pointsLinesPipelineEntry = resolveMaterialPipeline(\n POINTS_LINES_MATERIAL_SHADER_ID,\n {\n ...pointsLinesMaterial.renderState,\n cullMode: 'none',\n },\n 'triangle-list',\n 'uint32',\n undefined,\n colorFormatOverride,\n pointsLinesSubmission.layoutProjection,\n );\n if (pointsLinesPipelineEntry === null) continue;\n const pointsLinesPipeline = pointsLinesPipelineEntry.pipeline;\n if (pipelineState.pointsLinesViewBuffer === undefined) continue;\n writePointsLinesViewUbo(\n runtime.device.queue,\n pipelineState.pointsLinesViewBuffer,\n c.camera,\n c.targetW,\n c.targetH,\n entry.source.transform.world,\n entry.source.pointsLines.style,\n i * POINTS_LINES_VIEW_SLOT_STRIDE,\n );\n pass.setBindGroup(\n 0,\n viewBindGroup as BindGroup,\n new Uint32Array([0, i * POINTS_LINES_VIEW_SLOT_STRIDE]),\n 0,\n 2,\n );\n pass.setPipeline(pointsLinesPipeline);\n pass.setVertexBuffer(0, pointsLinesSubmission.vertexBuffer);\n pass.setIndexBuffer(pointsLinesSubmission.indexBuffer, 'uint32');\n materialGroup1DynamicOffsets[0] = materialSlot * MATERIAL_PER_ENTITY_STRIDE;\n pass.setBindGroup(1, pointsLinesBindGroup, materialGroup1DynamicOffsets, 0, 1);\n const pointsLinesMeshGroup = meshBindGroup ?? meshGroup2;\n if (pointsLinesMeshGroup === null) continue;\n pass.setBindGroup(2, pointsLinesMeshGroup, meshGroup2DynamicOffsets);\n const pointsLinesInstancesBg =\n identityInstanceDraws[0]?.instanceBindGroup ??\n resolveGeometryInstancesBindGroup(c, identityInstanceBuffer, undefined);\n pass.setBindGroup(3, pointsLinesInstancesBg);\n recordOcclusionCandidate(() => recordPointsLinesDraw(pass, pointsLinesSubmission.plan));\n pass.setBindGroup(0, viewBindGroup as BindGroup, [viewBindGroupDynamicOffset, 0]);\n continue;\n }\n\n if (entry.mesh.vertexBuffer !== lastVertexBuffer) {\n pass.setVertexBuffer(0, entry.mesh.vertexBuffer.handle);\n lastVertexBuffer = entry.mesh.vertexBuffer;\n }\n // feat-20260604 M4 / w11: vertex-only meshes (indexed === false) carry no\n // index buffer; skip setIndexBuffer entirely and dispatch via pass.draw\n // below. Indexed meshes keep the existing setIndexBuffer path unchanged.\n if (entry.mesh.indexed && entry.mesh.indexBuffer !== lastIndexBuffer) {\n if (entry.mesh.indexBuffer !== null) {\n pass.setIndexBuffer(entry.mesh.indexBuffer.handle, entry.mesh.indexFormat);\n lastIndexBuffer = entry.mesh.indexBuffer;\n }\n }\n\n // Dispatch counter bump — sprite folds into the same 2-bucket\n // surface for now (`pipelineDispatchCounts.{unlit, standard}`\n // mirror the original 2-pipeline scope; sprite-bucket counters\n // can land in a follow-up if AI users need them separately).\n // sprite entries do not bump either counter — the bench (M-4)\n // can read sprite render counts via the transparent bucket\n // length instead.\n if (pipelineTag === 'unlit') dispatchCounts.unlit += 1;\n\n const instanceDraws = resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws, false);\n if (instanceDraws === null) continue;\n\n // feat-20260611 R2 / M8 / w28 (IS-14): skin entries need a 3-binding\n // group(2) BG matching `pbr-skin-pl` (binding 0 mesh-array UBO +\n // binding 1 current palette UBO + binding 2 previous palette UBO).\n // Building this here -- not in the\n // `meshBindGroup` factory above -- because the binding-shape\n // (1-entry vs 3-entry) is per-entry, not per-frame. URP / HDRP\n // entries keep using `meshGroup2` (1-entry mesh-array or HDRP\n // unified). The skin-variant cache key includes both buffer\n // identities so a future allocator-driven palette buffer rotation\n // invalidates the BG without manual eviction.\n //\n // PSO-availability gate: only swap to the skin BG when (a) the\n // skin pipeline layout itself was built (charter P3 fail-stop on\n // BGL-build failure), AND (b) the skin PSO cache returns a non-null\n // pipeline for this entry. Without (b), the per-submesh selector\n // below falls back to URP `standardPipeline` (`pbr-pl` layout,\n // 1-entry mesh-array BGL); binding the 3-entry skin BG against\n // that pipeline reproduces the exact `pbr-mesh-array-bgl ... does\n // not match layout pbr-skin-mesh-array-bgl` device error R1\n // captured. Mirrors the uniform null skip-draw pattern (M6-T1).\n let group2BindGroup: BindGroup = meshGroup2 as BindGroup;\n // feat-20260612-skin-palette-per-frame-upload M3 / m3-2: dyn-offset\n // tuple follows the skin group2 offset contract. Defaults to the\n // length-1 non-skin shape; the skin branch below re-computes with the\n // per-entity `entry.source.skin.byteOffset` cursor.\n meshGroup2DynamicOffsets[0] = i * MESH_PER_ENTITY_STRIDE;\n let group2DynamicOffsets: readonly number[] = meshGroup2DynamicOffsets;\n const isSkinEntry = entry.source.skin !== undefined;\n const probeBlendRecordAvailable =\n runtime.device.caps.storageBuffer && entry.source.probeBlendRecord !== undefined;\n // feat-20260612-skin-palette-per-frame-upload M1 / m1-3 + M6: the\n // record stage reads the GPU buffer reference through\n // `entry.source.skin.buffer` (per-slice carrier set at extract time\n // by allocateSlice). On the storage path every slice carries the\n // same shared buffer pointer, so the BG cache key collapses to one\n // entry per frame (miss=1 + hit=N-1). On the uniform fallback path\n // each slice carries its own per-entity 16320 B UBO, so the BG\n // cache key naturally splits per entity (one BG per buffer pointer)\n // -- there is no shared-buffer assumption to break under\n // 16 KiB UBO cap. Charter P3 explicit failure preserved: skin\n // entries skip when the pipeline layout is missing OR the slice\n // failed to allocate (no buffer field). dynOffset[1] = byteOffset\n // is 0 on the uniform path (entry already covers the full buffer)\n // and walks 0, 1536, 3072, ... on the storage path.\n const skinAllocator = pipelineState.skinPaletteAllocator;\n const skinSlice = entry.source.skin;\n const clusteredSkin = clusteredLighting;\n const skinMeshBindGroupLayout = clusteredSkin\n ? pipelineState.hdrpSkinMeshBindGroupLayout\n : pipelineState.pbrSkinMeshBindGroupLayout;\n const hdrpSkinBuffers =\n isSkinEntry && clusteredSkin\n ? getOrCreateHdrpBuffers(runtime, frameState.installedPipelineConfig?.clusterGrid)\n : null;\n const skinResources =\n isSkinEntry &&\n skinMeshBindGroupLayout !== null &&\n skinAllocator !== null &&\n skinSlice !== undefined &&\n (!clusteredSkin || hdrpSkinBuffers !== null)\n ? {\n meshArrayBgl: skinMeshBindGroupLayout,\n paletteBuffer: skinSlice.buffer,\n paletteBindingWindowBytes: skinAllocator.bindingWindowBytes,\n hdrpBuffers: hdrpSkinBuffers,\n }\n : null;\n // Probe the skin PSO cache up front so we can decide whether to swap\n // to the skin BG. The same probe + selector is repeated in\n // the per-submesh loop below (the loop's variantSet derivation is\n // identical -- skin shader registers a single all-true variant so\n // the canonical empty-key rule applies on HDRP and the URP key is\n // the explicit expanded form, mirroring the standard PBR path).\n const skinVariantSetResult = variantSetFromVertexLayoutProjection(\n entry.mesh.layoutProjection,\n standardTopologyVariantSet(\n c.standardLighting,\n runtime.device.caps.storageBuffer,\n entry.mesh.layoutProjection.attributes.some((attribute) => attribute.key === 'color'),\n probeBlendRecordAvailable,\n ),\n );\n if (!skinVariantSetResult.ok) runtime.errorRegistry.fire(skinVariantSetResult.error);\n const skinVariantSet = skinVariantSetResult.ok ? skinVariantSetResult.value : undefined;\n const skinPsoProbe =\n skinResources !== null && skinVariantSetResult.ok\n ? (runtime.getMaterialShaderPipeline?.(\n SKIN_MATERIAL_SHADER_ID,\n isHdrTarget,\n entry.source.material.renderState,\n entry.mesh.submeshes[0]?.topology ?? 'triangle-list',\n entry.mesh.indexFormat,\n skinVariantSet,\n passKind,\n undefined, // meshAttributes — skin probe uses first submesh, derive from entry\n sampleCount,\n colorFormatOverride,\n undefined,\n undefined,\n undefined,\n entry.mesh.layoutProjection,\n undefined,\n undefined,\n undefined,\n ) ?? null)\n : null;\n if (skinResources !== null && skinPsoProbe !== null) {\n const meshBindSize = runtime.device.caps.storageBuffer\n ? MESH_SSBO_BYTES\n : MESH_UBO_FULL_ARRAY_BYTES;\n // m3-2 / D-8: skin BG cache miss / hit instrumentation. The chain\n // walk no longer exposes a string key to `.has()`, so we derive\n // hit/miss from the w7 `bindGroupCounts.createBindGroup` accounting:\n // snapshot the counter, run `getOrCreateFromChain`, and compare. A\n // delta of 1 means the factory ran (miss); 0 means a chain hit. This\n // publishes the per-frame counter the m3-1 acceptanceCheck reads\n // (miss=1 + hit=N-1 across N skin entries sharing one allocator\n // buffer + mesh SSBO). Field is optional + opt-in (read via\n // structural cast so prod paths that omit the counter pay nothing).\n const skinStats = (pipelineState as { _skinBgCacheStats?: { miss: number; hit: number } })\n ._skinBgCacheStats;\n const skinMissesBefore = bindGroupCounts.createBindGroup;\n const skinBindGroup: BindGroup = getOrCreateFromChain(\n frameState.meshBindGroupCache,\n [\n pipelineState.meshStorageBuffer.buffer,\n skinResources.paletteBuffer,\n ...(skinResources.hdrpBuffers === null\n ? []\n : [\n skinResources.hdrpBuffers.lightDataBuffer,\n skinResources.hdrpBuffers.clusterGridBuffer,\n skinResources.hdrpBuffers.lightIndexListBuffer,\n skinResources.hdrpBuffers.clusterUniformBuffer,\n ]),\n ],\n 'pbr-skin-mesh',\n () => {\n if (skinResources.hdrpBuffers !== null) {\n const result = createHdrpSkinUnifiedBindGroup(\n runtime,\n skinResources.hdrpBuffers,\n skinResources.meshArrayBgl,\n pipelineState.meshStorageBuffer.buffer,\n skinResources.paletteBuffer,\n skinResources.paletteBindingWindowBytes,\n );\n if (result === null) {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'HDRP clustered skin BindGroup creation succeeds',\n hint: 'inspect prior errorRegistry events for createBindGroup failure detail',\n });\n }\n return result;\n }\n const result = runtime.device.createBindGroup({\n label: 'pbr-skin-mesh-bg',\n layout: skinResources.meshArrayBgl,\n entries: createPbrSkinMeshBindGroupEntries(\n pipelineState.meshStorageBuffer.buffer,\n meshBindSize,\n skinResources.paletteBuffer,\n skinResources.paletteBindingWindowBytes,\n ),\n });\n if (!result.ok) throw result.error;\n return result.value;\n },\n bindGroupCounts,\n );\n if (skinStats !== undefined) {\n if (bindGroupCounts.createBindGroup > skinMissesBefore) skinStats.miss += 1;\n else skinStats.hit += 1;\n }\n group2BindGroup = skinBindGroup;\n // m3-2: dyn-offset tuple uses the per-entity palette cursor M2 m2-6\n // wrote at the extract stage.\n // Replaces the prior PR #353 hard-coded `0` second slot -- every\n // skin entry now points the palette window at its own slice while\n // sharing the worst-case BG entry size above.\n group2DynamicOffsets = pbrSkinMeshDynamicOffsets(\n i * MESH_PER_ENTITY_STRIDE,\n entry.source.skin?.byteOffset ?? 0,\n );\n } else if (isSkinEntry) {\n // Skin entry but skin PSO not ready (cache miss / async build pending,\n // or skin pipeline layout failed at boot). Skip the draw rather than\n // fall back to URP `pbr-pl` against the 6-attribute skin VBO -- that\n // path produced the layer-3 / layer-4 device errors R1 captured. Once\n // the async PSO compile resolves the cache hits and the next frame\n // routes the skin BG + skin pipeline together. Mirrors the uniform\n // null skip-draw shape (M6-T1, charter P3 explicit failure).\n continue;\n }\n // feat-20260520-2d-sprite-layer-mvp M-3 / w25 (@fallback sprite\n // bucket): sprite entries get a per-entity material BindGroup so\n // each sprite carries its own texture binding at @group(1) @binding(2).\n // Bindings 3..6 (metallicRoughness sampler/texture + normal\n // sampler/texture) bind `pipelineState.defaultSampler` +\n // `pipelineState.defaultWhiteTextureView` placeholders (D-1\n // candidate b — zero new GPU resource; the 1x1 white view was\n // already provisioned for unlit / standard fallback so the sprite\n // path adds 4 binding references, no new resource code).\n //\n // Missing-texture fallback (AC-18 path 4 + R7 isolation): when the\n // sprite texture has no GPU view, the binding uses\n // `defaultWhiteTextureView` as the fallback texture and the\n // material UBO upload above wrote debug-pink colorTint so the\n // sprite is visually distinct. The warn-once + RhiError surface\n // fires inside the upload loop. R7 isolation: this does NOT change\n // the existing unlit / standard bucket missing-texture handling —\n // those keep their silent-white fallback (a future\n // `feat-future-pbr-missing-texture-fallback-explicit` will retrofit).\n // bug-20260610 layer 7d: BG is per-submesh — each iteration of\n // the submesh draw loop below builds (or cache-hits) a BG with\n // matsForRebind[smIdx]'s 5 textureViews (baseColor / MR / normal /\n // emissive / occlusion). Cache key is 14-handle-id only (entityKey\n // dropped) so identical-material submeshes / entities dedup\n // globally. Sprite path is unchanged (single spriteBg, sprite\n // per-submesh OOS-1). The non-sprite branch leaves perSubmeshBg\n // declared but null; the submesh loop reassigns it per iteration\n // and the source-grep gate in skylight-fallback-path.test.ts /\n // systems.unit.test.ts continues to match\n // `setBindGroup\\s*\\(\\s*1\\s*,\\s*perSubmeshBg\\b` on the in-loop call.\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w13 (D-1\n // candidate b): the sprite-specific BG construction is gone — sprite\n // materials reuse the same per-submesh BG path PBR / unlit use. The\n // 7-entry BGL is byte-for-byte shared (binding 0 = Material UBO,\n // 1 = baseColorSampler, 2 = baseColorTexture, 3-6 = filler samplers /\n // textureViews). Sprite's \"no metallic/normal/emissive/occlusion\n // texture\" simply falls through to `defaultWhite` / `defaultNormal`\n // — the same placeholders the unlit path already used. The generic\n // branch below builds the per-submesh BG.\n let perSubmeshBg: BindGroup | null = null;\n // feat-20260608 M4 / w16: per-submesh pipeline selection + draw loop.\n // Each submesh carries its own topology, so pipeline selection is per-submesh.\n // Vertex/index buffers and bind groups are set once (shared across all submeshes).\n // feat-20260608 M5 amend / w16-a: the material UBO bind (group=1)\n // ALSO moves into the loop -- the j-th submesh sees the j-th\n // material slot via dynamic offset (entitySlotStart + j) * 256.\n const matsForRebind = entry.source.materials;\n for (let smIdx = 0; smIdx < entry.mesh.submeshes.length; smIdx++) {\n const sm = entry.mesh.submeshes[smIdx];\n if (sm === undefined) continue;\n const matSlotIdx = sm.materialSlot;\n const submeshMaterial = matsForRebind[matSlotIdx] ?? entry.source.material;\n if (matchedMaterials !== null) {\n const materialHandles = matchedMaterials.get(entry.renderableIndex);\n const materialHandle = submeshMaterial.materialHandle ?? 0;\n if (materialHandles === undefined || !materialHandles.has(materialHandle)) continue;\n }\n // feat-city-glb Bug 5 (per-submesh transparency): in the LDR split, a\n // transparent submesh is drawn in the blend sub-pass (non-sRGB view),\n // NOT here in the sRGB geometry pass. Skip it. Opaque submeshes of the\n // same (mixed) mesh still draw here. Single-material / fully-opaque\n // meshes are unaffected (their submesh materials are not transparent).\n if (splitLdrSprite && submeshMaterial.transparent === true) {\n continue;\n }\n // bug-20260610 layer 7d: per-submesh BG construction. Texture\n // views resolve from `matsForRebind[smIdx]` so the j-th submesh\n // sees its own materials[j] textures (baseColor / MR / normal /\n // emissive / occlusion). Pick slot j when materials.length covers\n // smIdx; otherwise fall back to slot 0 (count-mismatch already\n // filtered by extract; this guard handles the materials.length=1\n // single-material path mapped over multi-submesh meshes safely).\n // This BG drops entityKey: identical-texture-set submeshes\n // (whether on the same entity or different ones) share one BG via\n // the shaderId-outer `materialBgShared` cache. The 14 handle\n // objects form the WeakMap chain and fully discriminate the\n // binding state since sampler/textureView/buffer handle identities\n // are stable across frames.\n //\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w13:\n // sprite materials now use the same per-submesh BG construction\n // (the sprite-specific BG branch above is deleted; sprite per-\n // submesh single-slot is still enforced via materialSlotIndices\n // and the sprite-shaped paramSnapshot fills the PBR-shaped BGL\n // bindings via fallback textures for the 4 unused slots).\n // feat-city-glb Bug 5: per-submesh material BG assembly extracted to\n // the shared `buildPerSubmeshMaterialBg` closure (also called by the\n // LDR blend sub-pass). Resolves the shader's user-region textures\n // (baseColor/MR/normal + a custom Nth texture), emissive/occlusion\n // injection, and Skylight merge; deduped cross-entity via the\n // shaderId-outer `materialBgShared` cache.\n const materialSlot = materialSlotIndices[i]?.[matSlotIdx] ?? materialSlotIndices[i]?.[0] ?? 0;\n perSubmeshBg =\n profilePhase === undefined\n ? resolveMaterialBindGroup(\n materialSlot,\n submeshMaterial,\n entry.source.entityKey,\n entry.world ?? c.world,\n )\n : profileGeometrySegment(c, passKind, 'material-bind-groups', () =>\n resolveMaterialBindGroup(\n materialSlot,\n submeshMaterial,\n entry.source.entityKey,\n entry.world ?? c.world,\n ),\n );\n materialGroup1DynamicOffsets[0] = materialSlot * MATERIAL_PER_ENTITY_STRIDE;\n pass.setBindGroup(1, perSubmeshBg, materialGroup1DynamicOffsets, 0, 1);\n const smTopology = sm.topology;\n const smMaterialShaderId =\n entry.source.skin !== undefined\n ? SKIN_MATERIAL_SHADER_ID\n : submeshMaterial.materialShaderId;\n const probeBlendAvailable =\n probeBlendRecordAvailable && isStandardPbrMaterialShader(smMaterialShaderId);\n const isSpriteShader =\n smMaterialShaderId === 'forgeax::sprite' || smMaterialShaderId === 'forgeax::sprite-lit';\n // Preserve the dedicated sprite-pass state when the linear-LDR graph\n // routes a sprite through this generic geometry path. Negative scale\n // flips winding, so back-face culling would erase the quad.\n const basePipelineRenderState = isSpriteShader\n ? {\n ...submeshMaterial.renderState,\n depthWriteEnabled: false,\n depthCompare: 'less-equal' as const,\n cullMode: 'none' as const,\n blend: submeshMaterial.renderState?.blend ?? SPRITE_PREMULTIPLIED_ALPHA_BLEND,\n }\n : geometryRenderStateForTopology(smTopology, submeshMaterial.renderState);\n const pipelineRenderState = geometryRenderStateForPass(basePipelineRenderState, passKind);\n let smPipelineHandle: typeof pipelineState.unlitPipeline;\n let materialGroup2Contract: 'mesh' | 'skin' | 'cluster' | 'skin-cluster' | undefined;\n let materialPipelineEntry: MaterialShaderPipelineEntry | null = null;\n if (smMaterialShaderId === undefined || smMaterialShaderId === 'forgeax::default-unlit') {\n const unlitShaderId = smMaterialShaderId ?? 'forgeax::default-unlit';\n const unlitProjectionVariantResult = variantSetFromVertexLayoutProjection(\n entry.mesh.layoutProjection,\n undefined,\n );\n if (!unlitProjectionVariantResult.ok) {\n runtime.errorRegistry.fire(unlitProjectionVariantResult.error);\n continue;\n }\n const unlitHasColor = unlitProjectionVariantResult.value === 'VERTEX_COLOR_AVAILABLE=true';\n const unlitVariantSet = standardStorageVariantSet(\n runtime.device.caps.storageBuffer,\n unlitHasColor,\n );\n const unlitRsp = resolveMaterialPipeline(\n unlitShaderId,\n pipelineRenderState,\n smTopology,\n entry.mesh.indexFormat,\n unlitVariantSet,\n colorFormatOverride,\n entry.mesh.layoutProjection,\n );\n materialPipelineEntry = unlitRsp;\n smPipelineHandle =\n unlitRsp?.pipeline ??\n (colorFormatOverride === undefined\n ? selectGeometryPipeline(pipelineState, isHdrTarget, msaaActive)\n : null);\n } else if (smMaterialShaderId !== undefined) {\n // feat-20260609 M4.5 / w38 (D-11): the variantSet handed to\n // getMaterialShaderPipeline MUST mirror the boot-time\n // `definesKey` rule at createRenderer.ts:2483-2485 (sortedEntries\n // .every(v=>v===true) ? '' : 'A=v+...'). manifest variant.definesKey\n // is `''` for the all-true variant, so HDRP (both axes true) must\n // pass the canonical empty key to hit that variant via\n // findVariantByKey. Passing the expanded form would produce a\n // miss and silently fall back to the registered default WGSL,\n // creating a layout/binding mismatch under HDRP.\n //\n // URP path passes the explicit expanded form because the URP\n // variant's manifest definesKey IS that exact non-empty string\n // (CLUSTER_FORWARD_AVAILABLE=false+STORAGE_BUFFER_AVAILABLE=true)\n // -- the canonical-empty rule only applies to the all-true case.\n const hasVertexColor = entry.mesh.layoutProjection.attributes.some(\n (attribute) => attribute.key === 'color',\n );\n // The all-true HDRP variant uses the canonical empty key only when\n // every variant axis is true. A plain mesh adds the geometry-owned\n // VERTEX_COLOR_AVAILABLE=false axis, so retain the two capability\n // axes explicitly or the selector would silently choose the URP\n // group(2) layout for an HDRP cluster bind group.\n const capabilityVariantSet = standardTopologyVariantSet(\n c.standardLighting,\n runtime.device.caps.storageBuffer,\n hasVertexColor,\n probeBlendAvailable,\n );\n // Sprite's base request must retain the boot-selected artifact. Only\n // SpriteInstances uses the explicit empty key for the\n // PER_INSTANCE_REGION=true variant; synthesizing the generic PBR\n // capability axes for a base sprite would invent a lazy module label\n // that has no boot seed and skip the first HDR draw.\n const variantSet = isSpriteShader\n ? smMaterialShaderId === 'forgeax::sprite' && entry.source.spriteInstances !== undefined\n ? ''\n : undefined\n : entry.variantSet === undefined\n ? capabilityVariantSet\n : capabilityVariantSet === ''\n ? entry.variantSet\n : `${capabilityVariantSet}+${entry.variantSet}`;\n const cachedPipeline = resolveMaterialPipeline(\n smMaterialShaderId,\n pipelineRenderState,\n smTopology,\n entry.mesh.indexFormat,\n variantSet,\n colorFormatOverride,\n entry.mesh.layoutProjection,\n );\n // feat-20260615-pipeline-spec-ssot M6-T1: cache miss resolves to\n // null uniformly across URP / HDRP / skin shaders. Charter P3\n // explicit failure: the pre-M6 URP-path silent fallback to the\n // boot-time `pipelineState.standardPipeline*` (M4.5-followup w43)\n // masked real PipelineSpecError build failures behind a\n // layout-compatible-but-wrong PSO. The per-submesh\n // `if (smPipelineHandle === null) continue` skip-draw (which\n // already covered HDRP-active and skin miss paths) is now the\n // single uniform recovery shape -- one frame of skip-draw on\n // first-touch, then the cached PSO flows in once the async\n // build resolves. The pre-loop skin-PSO probe still skips the\n // entire entry on first-submesh probe miss; this site only\n // fires on per-submesh topology variance miss.\n materialPipelineEntry = cachedPipeline;\n smPipelineHandle = cachedPipeline?.pipeline ?? null;\n } else {\n smPipelineHandle = selectGeometryPipeline(pipelineState, isHdrTarget, msaaActive);\n }\n\n if (smPipelineHandle === null) {\n continue;\n }\n // The probe record is an ABI extension of the built-in Standard PBR\n // shaders only. RenderScene may retain a record on every projected\n // renderable, but unlit/custom shaders still use the one-binding\n // instances BGL and must never receive the probe bind group. Resolve\n // this per submesh so mixed-material meshes cannot cross the layouts.\n const instanceDraws = resolveGeometryInstanceBuffer(\n c,\n entry,\n identityInstanceDraws,\n probeBlendAvailable,\n );\n if (instanceDraws === null) continue;\n // Standard clustered PBR variants declare the unified cluster/SSAO\n // group(2) layout. Unlit and other URP-layout materials must bind the\n // ordinary mesh group instead; choosing one group for the whole pass\n // makes Dawn reject an otherwise valid unlit pipeline and invalidates\n // the command buffer before it reaches the surface.\n if (!isSkinEntry) {\n materialGroup2Contract = materialPipelineEntry?.group2Contract;\n if (materialGroup2Contract === undefined) continue;\n const selectedGroup = selectMaterialGroup2(\n meshGroup2,\n meshBindGroup,\n materialGroup2Contract,\n );\n if (selectedGroup === null) continue;\n group2BindGroup = selectedGroup;\n }\n pass.setBindGroup(2, group2BindGroup, group2DynamicOffsets);\n\n if (profilePhase === undefined) {\n recordOcclusionCandidate(() =>\n submitSubmeshDraws(\n pass,\n bindingState,\n smPipelineHandle,\n instanceDraws,\n entry.mesh.indexed,\n sm.indexCount,\n sm.vertexCount,\n sm.indexOffset,\n ),\n );\n } else {\n profileGeometrySegment(c, passKind, 'draw-submit', () =>\n recordOcclusionCandidate(() =>\n submitSubmeshDraws(\n pass,\n bindingState,\n smPipelineHandle,\n instanceDraws,\n entry.mesh.indexed,\n sm.indexCount,\n sm.vertexCount,\n sm.indexOffset,\n ),\n ),\n );\n }\n }\n }\n}\n\n/**\n * Resolve the per-entity @group(3) instance buffers for the geometry pass.\n *\n * @internal\n */\nfunction resolveGeometryInstanceBuffer(\n c: _InternalRenderPipelineContext,\n entry: _InternalRenderPipelineContext['validatedOrdered'][number],\n identityInstanceDraws: readonly GeometryInstanceDraw[],\n useProbeBlend: boolean,\n): readonly GeometryInstanceDraw[] | null {\n const { runtime, pipelineState, frameState } = c;\n const inst = entry.source.instances;\n const probeBinding =\n !useProbeBlend ||\n !runtime.device.caps.storageBuffer ||\n entry.source.probeBlendRecord === undefined\n ? undefined\n : resolveProbeBlendBuffer(\n c,\n entry.source.probeBlendRecord,\n worldEntityKey(entry.source.worldId, entry.source.entityKey),\n );\n if (inst === undefined) {\n const identity = identityInstanceDraws[0];\n if (identity === undefined) return null;\n return [\n {\n ...identity,\n instanceBindGroup: resolveGeometryInstancesBindGroup(\n c,\n pipelineState.identityInstanceBuffer,\n probeBinding?.buffer,\n ),\n probeOffset: probeBinding?.offset ?? -1,\n },\n ];\n }\n // A present, empty Instances array means zero draws. Do not fall back to\n // the shared identity buffer, which would silently render one instance.\n if (inst.instanceCount === 0) return [];\n let instanceBuffer: Buffer = pipelineState.identityInstanceBuffer;\n let instanceCount = 1;\n {\n // feat-20260526-pbr-uniform-fallback-no-storage-buffer M3 / w13:\n // caps.storageBuffer===false -> uniform fallback with 128-instance\n // cap (128 * 64B = 8192B < WebGL2 min 16384B UBO limit).\n // caps.storageBuffer===true -> existing storage buffer path unchanged.\n const uniformFallback = runtime.device.caps.storageBuffer === false;\n let instanceBufferUsage = GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;\n\n if (uniformFallback && inst.instanceCount > MAX_UNIFORM_INSTANCES) {\n const draws: GeometryInstanceDraw[] = [];\n for (let start = 0; start < inst.instanceCount; start += MAX_UNIFORM_INSTANCES) {\n const count = Math.min(MAX_UNIFORM_INSTANCES, inst.instanceCount - start);\n const chunk = inst.transforms.subarray(start * 16, (start + count) * 16);\n const bufRes = runtime.device.createBuffer({\n size: INSTANCE_UBO_FULL_ARRAY_BYTES,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n return null;\n }\n const buffer = new GpuBuffer(runtime.device, bufRes.value);\n frameState.transientInstanceBuffers.push({\n buffer,\n uploadedArchVersion: inst.archVersion,\n uploadedByteLength: chunk.byteLength,\n });\n const writeRes = runtime.device.queue.writeBuffer(buffer.handle, 0, chunk);\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n return null;\n }\n draws.push({\n instanceBuffer: buffer.handle,\n instanceBindGroup: resolveGeometryInstancesBindGroup(\n c,\n buffer.handle,\n probeBinding?.buffer,\n ),\n probeOffset: probeBinding?.offset ?? -1,\n instanceCount: count,\n });\n }\n return draws;\n }\n if (uniformFallback) {\n instanceBufferUsage = GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST;\n }\n\n {\n // Cap-gate (LimitExceededDetail single emit point — feat-20260514\n // M3 / w15 anchor): `requestedBytes <= maxStorageBufferBindingSize`.\n const instancePayload = uniformFallback\n ? inst.transforms\n : packInstanceStorageBuffer(inst.transforms);\n const requestedBytes = instancePayload.byteLength;\n const cap = runtime.device.limits.maxStorageBufferBindingSize;\n if (!uniformFallback && typeof cap === 'number' && cap > 0 && requestedBytes > cap) {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'limit-exceeded',\n expected: `requestedBytes (${requestedBytes}) <= maxStorageBufferBindingSize (${cap})`,\n hint: 'reduce instance count to fit within device.limits.maxStorageBufferBindingSize, or split transforms across multiple Instances entries',\n detail: {\n maxStorageBufferBindingSize: cap,\n requestedBytes,\n },\n }),\n );\n return null;\n } else {\n // Look up the cached GPU buffer or create a fresh one when the\n // archetype version bumped or the byte length changed.\n const cached = frameState.instanceBuffers.get(\n worldEntityKey(entry.source.worldId, inst.cacheKey),\n );\n let active: InstanceBufferCacheEntry | null = null;\n if (\n cached !== undefined &&\n cached.uploadedArchVersion === inst.archVersion &&\n cached.uploadedByteLength === requestedBytes\n ) {\n active = cached;\n } else if (requestedBytes > 0) {\n const bufRes = runtime.device.createBuffer({\n size: uniformFallback ? INSTANCE_UBO_FULL_ARRAY_BYTES : requestedBytes,\n usage: instanceBufferUsage,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n } else {\n // feat-20260619 M4 / F12: destroy the old cached buffer\n // before replacing it with the new one (D-6).\n if (cached !== undefined && !cached.buffer.isDestroyed) {\n const r = cached.buffer.destroy();\n if (!r.ok) runtime.errorRegistry.fire(r.error);\n }\n const newBuffer = new GpuBuffer(runtime.device, bufRes.value);\n active = {\n buffer: newBuffer,\n uploadedArchVersion: inst.archVersion,\n uploadedByteLength: requestedBytes,\n };\n frameState.instanceBuffers.set(\n worldEntityKey(entry.source.worldId, inst.cacheKey),\n active,\n );\n }\n }\n if (active !== null) {\n const writeRes = runtime.device.queue.writeBuffer(\n active.buffer.handle,\n 0,\n instancePayload,\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n } else {\n instanceBuffer = active.buffer.handle;\n instanceCount = Math.max(1, inst.instanceCount);\n }\n }\n }\n // The cache write above is keyed by worldEntityKey(worldId, cacheKey)\n // so separate worlds cannot alias their instance buffers.\n }\n }\n return [\n {\n instanceBuffer,\n instanceBindGroup: resolveGeometryInstancesBindGroup(c, instanceBuffer, probeBinding?.buffer),\n probeOffset: probeBinding?.offset ?? -1,\n instanceCount,\n },\n ];\n}\n\nexport function resolveProbeBlendBuffer(\n c: _InternalRenderPipelineContext,\n record: import('../scene/probe-blend-record').ProbeBlendRecord | undefined,\n entityKey?: number,\n): { readonly buffer: Buffer; readonly offset: number } {\n const { runtime, frameState } = c;\n const usage = runtime.device.caps.storageBuffer\n ? GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST\n : GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST;\n if (record === undefined) throw new Error('probe blend record is required for probe allocation');\n if (entityKey === undefined) throw new Error('probe blend record requires an entity key');\n const offset = probeBlendRecordOffset(record.objectKey);\n const requiredCapacity = record.objectKey + 2;\n let buffer = frameState.probeBlendRecordBuffer;\n if (buffer === undefined || frameState.probeBlendRecordBufferCapacity < requiredCapacity) {\n const created = runtime.device.createBuffer({\n label: 'probe-blend-records',\n size: requiredCapacity * PROBE_BLEND_RECORD_STRIDE,\n usage,\n mappedAtCreation: false,\n });\n if (!created.ok) throw created.error;\n buffer = new GpuBuffer(runtime.device, created.value);\n frameState.probeBlendRecordBuffer = buffer;\n frameState.probeBlendRecordBufferCapacity = requiredCapacity;\n // The cache is tied to the previous backing allocation. A new buffer has\n // no valid record contents, so every later object must upload its full\n // 160B payload even when generation/bytes match the old allocation.\n frameState.probeBlendBuffers.clear();\n }\n const cached = frameState.probeBlendBuffers.get(entityKey);\n const unchanged =\n cached !== undefined &&\n cached.generation === record.generation &&\n cached.bytes.length === record.bytes.length &&\n cached.bytes.every((value, index) => value === record.bytes[index]);\n if (!unchanged) {\n const uploaded = runtime.device.queue.writeBuffer(buffer.handle, offset, record.bytes);\n if (!uploaded.ok) throw uploaded.error;\n // Publish the generation only after the complete 160B queue write succeeds.\n frameState.probeBlendBuffers.set(entityKey, {\n generation: record.generation,\n bytes: new Uint8Array(record.bytes),\n });\n }\n return { buffer: buffer.handle, offset };\n}\n\nexport function resolveGeometryInstancesBindGroup(\n c: _InternalRenderPipelineContext,\n instanceBuffer: Buffer,\n probeBuffer?: Buffer,\n): BindGroup {\n const { runtime, pipelineState, frameState, bindGroupCounts } = c;\n const layout =\n probeBuffer === undefined\n ? pipelineState.instancesBindGroupLayout\n : pipelineState.probeInstancesBindGroupLayout;\n if (layout === undefined) throw new Error('probe instances bind-group layout is unavailable');\n return getOrCreateFromChain(\n frameState.instancesBgShared,\n probeBuffer === undefined ? [layout, instanceBuffer] : [layout, instanceBuffer, probeBuffer],\n probeBuffer === undefined ? 'instances-no-probe' : 'instances-probe',\n () => {\n const result = runtime.device.createBindGroup({\n label: 'pbr-instances-bg',\n layout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: { buffer: instanceBuffer },\n },\n },\n ...(probeBuffer === undefined\n ? []\n : [\n {\n binding: 1,\n resource: {\n kind: 'buffer' as const,\n value: { buffer: probeBuffer, offset: 0, size: PROBE_BLEND_RECORD_BYTE_SIZE },\n },\n },\n ]),\n ],\n });\n if (!result.ok) throw result.error;\n return result.value;\n },\n bindGroupCounts,\n );\n}\n","// @forgeax/engine-runtime - RenderSystem record stage: main-pass sprite draws.\n// feat-20260704 M5/w31: further-split from main-pass.ts (AC-05 <=1500 lines/file).\n// recordSpritePass + sprite entity/transparent/instance-buffer helpers, moved verbatim.\n\nimport type { World } from '@forgeax/engine-ecs';\nimport {\n type BindGroup,\n type BindGroupEntry,\n type Buffer,\n type RenderPipeline,\n RhiError,\n type RhiRenderPassEncoder,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport type { Handle, MaterialRenderState } from '@forgeax/engine-types';\nimport { GpuBuffer } from '../gpu-resource';\nimport {\n GPU_BUFFER_USAGE_COPY_DST,\n GPU_BUFFER_USAGE_STORAGE,\n GPU_BUFFER_USAGE_UNIFORM,\n} from '../gpu-usage';\nimport {\n assembleMaterialWithSkylightEntries,\n type SkylightBindGroupResources,\n} from '../ibl/skylight-bind-group';\nimport type { InstanceBufferCacheEntry } from '../instance-buffer-cache';\nimport { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';\nimport {\n isStandardPbrMaterialShader,\n SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET,\n} from '../pbr-pipeline';\nimport {\n buildBeginRenderPassDescriptor,\n standardTopologyVariantSet,\n variantSetFromVertexLayoutProjection,\n} from '../pipeline-spec';\nimport type { MaterialSnapshot, SpriteInstancesSnapshot } from '../render-system-extract';\nimport { worldEntityKey } from './frame-snapshot';\nimport { resolveGeometryInstancesBindGroup, resolveProbeBlendBuffer } from './main-pass-geometry';\nimport {\n BUILTIN_USER_REGION_TEXTURE_FIELDS,\n defaultViewForUserRegionField,\n entityHasTransparentSubmesh,\n residentTextureView,\n selectMaterialGroup2,\n} from './main-pass-material';\nimport {\n extractEntryResourceHandle,\n getOrCreatePerEntity,\n MAX_UNIFORM_INSTANCES,\n MESH_PER_ENTITY_STRIDE,\n packInstanceStorageBuffer,\n} from './mesh-ssbo';\nimport type { _InternalRenderPipelineContext } from './render-context';\nimport { MATERIAL_PER_ENTITY_STRIDE, STANDARD_PBR_UBO_SIZE } from './render-context';\n\nexport type { SpriteInstancesSnapshot };\n\n/**\n * Build the sprite material's Standard user-region from the shared field-order\n * owner. The sprite shader uses the same Standard material bind-group layout;\n * keeping this projection derived from the shared list prevents IBL injection\n * from moving ahead of newly added material texture pairs.\n */\nexport function buildSpritePassBaseMaterialEntries(\n pipelineState: _InternalRenderPipelineContext['pipelineState'],\n spriteTexView: TextureView,\n): BindGroupEntry[] {\n const entries: BindGroupEntry[] = [\n {\n binding: 0,\n resource: {\n kind: 'buffer' as const,\n value: {\n buffer: pipelineState.materialUniformBuffer.buffer,\n offset: 0,\n size: STANDARD_PBR_UBO_SIZE,\n },\n },\n },\n ];\n for (const [index, field] of BUILTIN_USER_REGION_TEXTURE_FIELDS.entries()) {\n const view =\n field === 'baseColorTexture'\n ? spriteTexView\n : defaultViewForUserRegionField(field, pipelineState);\n entries.push(\n {\n binding: 1 + index * 2,\n resource: {\n kind: 'sampler' as const,\n value: index === 0 ? pipelineState.nearestSampler : pipelineState.defaultSampler,\n },\n },\n {\n binding: 2 + index * 2,\n resource: { kind: 'textureView' as const, value: view },\n },\n );\n }\n return entries;\n}\n\n/**\n * Build the interleaved sprite instance payload consumed by this record owner.\n * The extract stage validates the two packed arrays before they reach this\n * function, so the record path has one source of count-mismatch errors.\n */\nexport function interleaveSpriteInstanceBuffer(\n transforms: Float32Array,\n regions: Float32Array,\n includePrevious = false,\n): Float32Array {\n const count = transforms.length / 16;\n const stride = includePrevious ? 36 : 20;\n const regionOffset = includePrevious ? 32 : 16;\n const out = new Float32Array(count * stride);\n for (let i = 0; i < count; i++) {\n const dstBase = i * stride;\n const transformBase = i * 16;\n const regionBase = i * 4;\n for (let k = 0; k < 16; k++) out[dstBase + k] = transforms[transformBase + k] ?? 0;\n if (includePrevious) {\n for (let k = 0; k < 16; k++) {\n out[dstBase + 16 + k] = transforms[transformBase + k] ?? 0;\n }\n }\n for (let k = 0; k < 4; k++) {\n out[dstBase + regionOffset + k] = regions[regionBase + k] ?? 0;\n }\n }\n return out;\n}\n\n/**\n * Check whether the existing per-entity sprite buffer still matches the\n * extract snapshot and interleaved byte count.\n */\nexport function spriteInstancesCacheHit(\n entry: InstanceBufferCacheEntry | undefined,\n snapshot: SpriteInstancesSnapshot,\n requestedBytes: number,\n): boolean {\n return (\n entry !== undefined &&\n entry.uploadedArchVersion === snapshot.archVersion &&\n entry.uploadedByteLength === requestedBytes\n );\n}\n\n/**\n * Decide whether the LDR record needs the transparent sprite sub-pass. This\n * remains beside the sprite record owner so the frame stage and draw stage\n * share the same transparent-material rule.\n */\nexport function computeSplitLdrSprite(\n validatedOrdered: readonly (\n | {\n readonly source: {\n readonly material: MaterialSnapshot;\n readonly materials?: readonly MaterialSnapshot[];\n };\n }\n | undefined\n )[],\n tonemapActive: boolean,\n): boolean {\n if (tonemapActive) return false;\n for (const entry of validatedOrdered) {\n if (entry === undefined) continue;\n const materials = entry.source.materials;\n if (materials !== undefined) {\n if (materials.some((material) => material.transparent === true)) return true;\n } else if (entry.source.material.transparent === true) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * feat-20260704 M3/w19: LDR sprite split sub-pass, extracted verbatim from\n * recordMainPass. Runs after the geometry pass when there are sprite / LDR\n * transparent entities and the split path is active (splitLdrSprite && a raw\n * unorm swap-chain view exists). Ends the geometry `pass`, opens a `spritePass`\n * on the resolved transparent-pass view (loadOp=load), draws the sprite / sprite-lit\n * entities (fold-instanced where possible) then the generic per-submesh\n * transparent PBR submeshes, and ends the sprite pass. Returns the updated\n * `geometryPassEnded` flag so the caller skips the unconditional pass.end().\n *\n * @internal\n */\nexport function recordSpritePass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n matchedIndices: Set<number> | null,\n materialSlotIndices: readonly (readonly number[])[],\n sampleCount: number,\n resolveMaterialBindGroup: (\n materialSlot: number,\n submeshMaterial: MaterialSnapshot,\n entityKey: number,\n materialWorld: World,\n ) => BindGroup,\n skylightResources: SkylightBindGroupResources,\n graphPass?: RhiRenderPassEncoder,\n): boolean {\n const {\n runtime,\n pipelineState,\n encoder,\n msaaActive,\n ldrSpritePassView,\n ldrSpriteColorView,\n geometryDepthView,\n viewBindGroup,\n meshBindGroup,\n hdrpClusterBindGroup,\n viewBindGroupDynamicOffset = 0,\n splitLdrSprite,\n } = c;\n const clusteredLighting = c.standardLighting?.kind === 'clustered';\n const meshGroup2 = clusteredLighting ? hdrpClusterBindGroup : meshBindGroup;\n // The split pass is also used by the no-tone linear-LDR route. That route\n // keeps transparent draws in the graph-owned rgba16float attachment, so\n // sprite shaders must use their linear/HDR fragment entry point even though\n // the camera itself has no tone map enabled.\n const spriteIsHdr =\n c.tonemapActive || transparentPassColorFormat(c, pipelineState) === 'rgba16float';\n let geometryPassEnded = false;\n if (splitLdrSprite && (graphPass !== undefined || ldrSpritePassView !== null)) {\n if (graphPass === undefined) {\n pass.end();\n geometryPassEnded = true;\n }\n\n // feat-20260604 M2 / w9 (F-1): under MSAA the sprite sub-pass writes the\n // count=4 transparent-pass view of the SAME multisample texture the\n // geometry pass wrote (loadOp=load preserves geometry under sprites) and\n // resolves the combined result to the single-sample transparent-pass\n // view at this (last) pass end. Depth reuses the shared count=4\n // multisample depth (depthLoadOp=load preserves sprite-vs-mesh occlusion).\n // The single-\n // sample path is byte-for-byte unchanged (writes the swap-chain view).\n const spriteColorView = msaaActive ? ldrSpriteColorView : ldrSpritePassView;\n // sprite-split sub-pass: forward shape with both color and depth loaded\n // (preserves prior content from the main forward pass under the sprites).\n // Stencil ops auto-emitted by the helper because depthFormat carries\n // stencil8.\n const spritePass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n {\n // SSOT for the sprite-pass color format is the resolved transparent\n // attachment. Native linear-LDR frames use graph-owned `ldrColor`\n // (possibly rgba16float); swap-chain fallback frames use their raw\n // storage format. WebGPU requires the attachment format and PSO\n // target to match, so both are resolved by the same helper.\n colorFormats: [transparentPassColorFormat(c) as GPUTextureFormat],\n depthFormat: 'depth24plus-stencil8',\n sampleCount: msaaActive ? 4 : 1,\n },\n {\n colorViews: [spriteColorView],\n depthView: geometryDepthView,\n ...(msaaActive ? { resolveTargets: [ldrSpritePassView] } : {}),\n },\n 'forward',\n { colorLoadOp: 'load', depthLoadOp: 'load' },\n ) as never,\n );\n\n spritePass.setBindGroup(0, viewBindGroup as BindGroup, [viewBindGroupDynamicOffset, 0]);\n\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (D-7):\n // sprite PSO resolution migrated from the dedicated boot-time PSO\n // fields (deleted) to the generic per-MaterialShader pipeline cache.\n // feat-20260626-collapse M2 / M2-T2: blend factor pair literal moved\n // to the public `SPRITE_PREMULTIPLIED_ALPHA_BLEND` named constant\n // (re-exported from `@forgeax/engine-runtime`) so each AI user\n // building a transparent material declares the same blend by\n // reference; the previous implicit blend-state factory helper is\n // gone. Cache miss still surfaces as a structured\n // `shader-compile-failed` RhiError mirroring the pre-w14 behaviour.\n //\n // feat-20260608-tilemap-object-layer-rendering M2 / m2-t6 (D-8): sprite\n // pipeline cullMode='none'. H/V flip via negative scale x/y (tilemap\n // per-cell entity TRS form) inverts the triangle winding; cullMode='back'\n // would throw the flipped quad away. The sprite pass runs in the\n // alpha-blend transparent bucket back-to-front already, so cullMode='none'\n // adds no overdraw cost. Pre-feat-20260625 the dedicated spritePipeline\n // hard-coded 'none' (deleted in w14); the generic path must replicate\n // it here or the cullmode-flip dawn smoke goes black on negative-scale.\n const spritePremulBlend: MaterialRenderState = {\n depthWriteEnabled: false,\n depthCompare: 'less-equal',\n cullMode: 'none',\n blend: SPRITE_PREMULTIPLIED_ALPHA_BLEND,\n };\n // bug-20260629: PR #526 added PER_INSTANCE_REGION as a second variant\n // axis on sprite.wgsl. Build BOTH variants here; the per-entity loop\n // picks the right one based on whether the entity carries a\n // SpriteInstances snapshot:\n // - spritePH (PER_INSTANCE_REGION=false): regular per-entity sprites\n // + fold-bucket instanced draws (64-byte mat4 only instance buf);\n // UV region comes from the material UBO `region` slot.\n // - spritePH_withRegion (PER_INSTANCE_REGION=true): SpriteInstances\n // entities with 80-byte interleaved (mat4 64B + region 16B) per\n // instance; UV region comes from `instances[idx].region`.\n //\n // Without spritePH_withRegion the SpriteInstances data was uploaded\n // but the shader read bytes 64-79 as region=0 → black quads.\n //\n // feat-20260624-sprite-lit-shading-model-pure-2d-lighting M1' / t7:\n // sprite-lit walks the same LDR transparent split pass with mirror\n // PSO request shape (only materialShaderId string differs). The\n // sprite-lit PSO is fetched lazily per-entity below since the pass\n // mixes sprite + sprite-lit transparent entities. PSO cache strings\n // are isolated by `materialShaderId` (D-11), no slot collision.\n const spritePH =\n runtime.getMaterialShaderPipeline?.(\n 'forgeax::sprite',\n spriteIsHdr,\n spritePremulBlend,\n 'triangle-list',\n undefined,\n undefined,\n 'forward',\n undefined,\n msaaActive ? 4 : 1,\n // feat-20260625-refactor-sprite-as-transparent-mesh R2 fix-up:\n // the split sub-pass PSO must use the same attachment format as the\n // encoder. Native linear-LDR frames resolve graph-owned `ldrColor`\n // (possibly rgba16float); swap-chain fallback frames resolve their raw\n // storage format. `transparentPassColorFormat` is the single owner for\n // this format so lazy PSO construction cannot fall back to the geometry\n // sRGB view.\n transparentPassColorFormat(c, pipelineState) as GPUTextureFormat,\n ) ?? null;\n const spritePH_withRegion =\n runtime.getMaterialShaderPipeline?.(\n 'forgeax::sprite',\n spriteIsHdr,\n spritePremulBlend,\n 'triangle-list',\n undefined,\n SPRITE_PASS_PER_INSTANCE_REGION_VARIANT_SET,\n 'forward',\n undefined,\n msaaActive ? 4 : 1,\n transparentPassColorFormat(c) as GPUTextureFormat,\n ) ?? null;\n\n // bug-20260629: spritePH===null check moved OUTSIDE the entity loop so the\n // sprite pass is properly ended before returning. Inside the loop the early\n // `return` left spritePass open → render-pass-not-ended error every frame\n // where the pipeline is still being compiled (frame 0 on first load).\n //\n // feat-city-glb Bug 5: a missing sprite PSO must NOT abort the whole\n // sub-pass — the generic per-submesh PBR transparent loop below does not\n // depend on the sprite shader. Only skip the sprite ENTITIES when spritePH\n // is null (fire the diagnostic once, iff a sprite entity is actually\n // present), then fall through to the PBR loop. A PBR-only transparent\n // scene (e.g. a glTF BLEND decal, no sprites) renders regardless of\n // whether sprite.wgsl is in the manifest.\n let spriteUnavailableReported = false;\n const reportSpriteUnavailable = (): void => {\n if (spriteUnavailableReported) return;\n spriteUnavailableReported = true;\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'shader-compile-failed',\n expected:\n 'manifest entries include sprite.wgsl + the engine triple (pbr + unlit + tonemap)',\n hint: 'verify @forgeax/engine-vite-plugin-shader emits manifest.json with the 4 engine entries (sprite.wgsl is required when spawning sprite materials); check vite plugin engineEntries option',\n }),\n );\n };\n\n // feat-20260624 M1' / t7: parallel sprite-lit PSO request — same\n // arg shape, only materialShaderId differs.\n const spriteLitPH =\n runtime.getMaterialShaderPipeline?.(\n 'forgeax::sprite-lit',\n spriteIsHdr,\n spritePremulBlend,\n 'triangle-list',\n undefined,\n // sprite-lit declares the same Standard capability axes as PBR. The\n // boot artifact is intentionally the direct compatibility variant,\n // so a clustered frame must request its explicit Cluster artifact;\n // otherwise the host binds the unified group(2) while the shader\n // still reads the now-cleared direct-light headers.\n standardTopologyVariantSet(c.standardLighting, runtime.device.caps.storageBuffer, false),\n 'forward',\n undefined,\n msaaActive ? 4 : 1,\n transparentPassColorFormat(c) as GPUTextureFormat,\n ) ?? null;\n recordSpriteEntityDraws(\n c,\n spritePass,\n matchedIndices,\n skylightResources,\n spritePH,\n spritePH_withRegion,\n spriteLitPH,\n reportSpriteUnavailable,\n );\n\n // feat-city-glb Bug 5 (per-submesh transparency): generic per-submesh PBR\n // draws in the LDR blend sub-pass. The sprite loop above handles only true\n // sprite / sprite-lit entities (whole-mesh sprite PSO). EVERY non-sprite\n // transparent material — built-in PBR, single- or multi-submesh, incl.\n // glTF alphaMode=BLEND (the crosswalk decal submesh AND the 4.3-blending\n // window quad) — is drawn here with its real shader + per-submesh\n // geometry, reusing the geometry pass's PBR machinery but rendering into\n // the resolved transparent attachment (colorFormatOverride =\n // transparentPassColorFormat(c)).\n // Opaque submeshes of a mixed mesh were already drawn in the geometry pass\n // (per-submesh skip there).\n //\n // Non-skinned, non-instanced (glTF static meshes): group 2 = the shared\n // frame meshBindGroup with the per-entity dynamic offset; group 3 = the\n // identity instance BG (drawIndexed instanceCount=1). Skinned / instanced\n // transparent submeshes are OOS here (no such content) and fall through.\n recordSpriteTransparentPbrDraws(\n c,\n spritePass,\n matchedIndices,\n materialSlotIndices,\n sampleCount,\n resolveMaterialBindGroup,\n meshGroup2,\n );\n\n if (graphPass === undefined) spritePass.end();\n }\n return geometryPassEnded;\n}\n\n/**\n * feat-20260704 M3/w19: generic per-submesh transparent PBR draws in the LDR\n * blend sub-pass, extracted verbatim from the sprite split pass. Every\n * non-sprite transparent material (built-in PBR, single- or multi-submesh, incl.\n * glTF alphaMode=BLEND) draws here with its real shader + per-submesh geometry,\n * reusing the geometry pass's PBR machinery but rendering into the resolved\n * transparent attachment (colorFormatOverride = transparentPassColorFormat(c)). Opaque submeshes of a\n * mixed mesh were already drawn in the geometry pass (per-submesh skip there).\n * Sprites are handled by the sprite loop; skinned / instanced transparent\n * submeshes are OOS here and fall through.\n *\n * @internal\n */\nfunction recordSpriteTransparentPbrDraws(\n c: _InternalRenderPipelineContext,\n spritePass: RhiRenderPassEncoder,\n matchedIndices: Set<number> | null,\n materialSlotIndices: readonly (readonly number[])[],\n sampleCount: number,\n resolveMaterialBindGroup: (\n materialSlot: number,\n submeshMaterial: MaterialSnapshot,\n entityKey: number,\n materialWorld: World,\n ) => BindGroup,\n meshGroup2: BindGroup | null,\n): void {\n const { runtime, pipelineState, validatedOrdered } = c;\n const isHdrTarget =\n c.tonemapActive || transparentPassColorFormat(c, pipelineState) === 'rgba16float';\n let lastPbrSubPipelineHandle: typeof pipelineState.unlitPipeline = null;\n let lastPbrSubVertexBuffer: GpuBuffer | null = null;\n let lastPbrSubIndexBuffer: GpuBuffer | null = null;\n for (let i = 0; i < validatedOrdered.length; i++) {\n const entry = validatedOrdered[i];\n if (entry === undefined) continue;\n if (matchedIndices !== null && !matchedIndices.has(entry.renderableIndex)) continue;\n // Sprites are handled by the sprite loop above; skip them here.\n const entShaderId = entry.source.material.materialShaderId;\n const entIsSprite = entShaderId === 'forgeax::sprite' || entShaderId === 'forgeax::sprite-lit';\n if (entIsSprite) continue;\n // Only entities that carry at least one transparent submesh reach a draw\n // (single-submesh transparent PBR and mixed opaque+transparent meshes).\n if (!entityHasTransparentSubmesh(entry.source)) continue;\n // Skinned / instanced transparent submeshes are not supported in this\n // sub-pass path (no such content today); skip to avoid mis-binding.\n if (entry.source.skin !== undefined || entry.source.instances !== undefined) continue;\n\n const matsForRebind = entry.source.materials;\n if (entry.mesh.vertexBuffer !== lastPbrSubVertexBuffer) {\n spritePass.setVertexBuffer(0, entry.mesh.vertexBuffer.handle);\n lastPbrSubVertexBuffer = entry.mesh.vertexBuffer;\n }\n if (\n entry.mesh.indexed &&\n entry.mesh.indexBuffer !== null &&\n entry.mesh.indexBuffer !== lastPbrSubIndexBuffer\n ) {\n spritePass.setIndexBuffer(entry.mesh.indexBuffer.handle, entry.mesh.indexFormat);\n lastPbrSubIndexBuffer = entry.mesh.indexBuffer;\n }\n for (let smIdx = 0; smIdx < entry.mesh.submeshes.length; smIdx++) {\n const sm = entry.mesh.submeshes[smIdx];\n if (sm === undefined) continue;\n const matSlotIdx = sm.materialSlot;\n const submeshMaterial = matsForRebind[matSlotIdx] ?? entry.source.material;\n // Only transparent submeshes belong in this blend sub-pass; opaque\n // submeshes were drawn in the geometry pass.\n if (submeshMaterial.transparent !== true) continue;\n const smShaderId = submeshMaterial.materialShaderId;\n if (smShaderId === undefined) continue;\n const probeBlendAvailable =\n runtime.device.caps.storageBuffer &&\n entry.source.probeBlendRecord !== undefined &&\n isStandardPbrMaterialShader(smShaderId);\n const probeBinding = probeBlendAvailable\n ? resolveProbeBlendBuffer(\n c,\n entry.source.probeBlendRecord,\n worldEntityKey(entry.source.worldId, entry.source.entityKey),\n )\n : undefined;\n const identityInstBg = resolveGeometryInstancesBindGroup(\n c,\n pipelineState.identityInstanceBuffer,\n probeBinding?.buffer,\n );\n if (probeBinding === undefined) spritePass.setBindGroup(3, identityInstBg);\n else spritePass.setBindGroup(3, identityInstBg, [probeBinding.offset]);\n const subVariantSet = standardTopologyVariantSet(\n c.standardLighting,\n runtime.device.caps.storageBuffer,\n entry.mesh.layoutProjection.attributes.some((attribute) => attribute.key === 'color'),\n probeBlendAvailable,\n );\n const projectionVariantSetResult = variantSetFromVertexLayoutProjection(\n entry.mesh.layoutProjection,\n subVariantSet,\n );\n if (!projectionVariantSetResult.ok) {\n runtime.errorRegistry.fire(projectionVariantSetResult.error);\n continue;\n }\n const projectionVariantSet = projectionVariantSetResult.value;\n const subPipelineEntry =\n c.runtime.getMaterialShaderPipelineEntry?.(\n smShaderId,\n isHdrTarget,\n submeshMaterial.renderState,\n sm.topology,\n entry.mesh.indexFormat,\n projectionVariantSet,\n 'forward',\n undefined,\n sampleCount,\n // Non-sRGB blend view (same override the sprite path uses).\n transparentPassColorFormat(c) as GPUTextureFormat,\n undefined,\n undefined,\n undefined,\n entry.mesh.layoutProjection,\n ) ?? null;\n if (subPipelineEntry === null) continue;\n const submeshContract = subPipelineEntry.group2Contract;\n const submeshGroup2 = selectMaterialGroup2(meshGroup2, c.meshBindGroup, submeshContract);\n if (submeshGroup2 === null) continue;\n spritePass.setBindGroup(2, submeshGroup2, [i * MESH_PER_ENTITY_STRIDE]);\n\n // Bind the per-submesh material BG first (mirrors the geometry pass\n // order), then resolve the PSO; a first-frame async-compile miss skips\n // only the draw, not the BG (one transient frame, PSO flows in next).\n const materialSlot = materialSlotIndices[i]?.[matSlotIdx] ?? materialSlotIndices[i]?.[0] ?? 0;\n const subBg = resolveMaterialBindGroup(\n materialSlot,\n submeshMaterial,\n entry.source.entityKey,\n entry.world ?? c.world,\n );\n spritePass.setBindGroup(1, subBg, [materialSlot * MATERIAL_PER_ENTITY_STRIDE]);\n\n const subPipeline = subPipelineEntry.pipeline;\n\n if (lastPbrSubPipelineHandle !== subPipeline) {\n spritePass.setPipeline(subPipeline);\n lastPbrSubPipelineHandle = subPipeline;\n }\n if (entry.mesh.indexed) {\n spritePass.drawIndexed(sm.indexCount, 1, sm.indexOffset, 0, 0);\n } else {\n spritePass.draw(sm.vertexCount, 1, 0, 0);\n }\n }\n }\n}\n\n/**\n * feat-20260704 M3/w19: per-entity sprite / sprite-lit draw loop for the LDR\n * blend sub-pass, extracted verbatim from the sprite split pass. Selects the\n * sprite vs sprite-lit PSO per entity, resolves the per-entity / fold-bucket\n * instance buffer (fold-instanced drawIndexed where a fold bucket applies and\n * the entity has no explicit Instances), uploads the per-entity sprite material\n * UBO slice, binds view / material / mesh / instances groups, and issues the\n * draw. Non-sprite transparent submeshes are drawn separately\n * (recordSpriteTransparentPbrDraws). The loop-invariant sprite PSO handles + the\n * once-per-frame sprite-unavailable diagnostic are threaded in.\n *\n * @internal\n */\nfunction recordSpriteEntityDraws(\n c: _InternalRenderPipelineContext,\n spritePass: RhiRenderPassEncoder,\n matchedIndices: Set<number> | null,\n skylightResources: SkylightBindGroupResources,\n spritePH: RenderPipeline | null,\n spritePH_withRegion: RenderPipeline | null,\n spriteLitPH: RenderPipeline | null,\n reportSpriteUnavailable: () => void,\n): void {\n const {\n runtime,\n world,\n store,\n pipelineState,\n frameState,\n bindGroupCounts,\n validatedOrdered,\n meshBindGroup,\n foldDispatchPlan,\n materialSlotIndices,\n } = c;\n let lastSpritePipelineHandle: RenderPipeline | null = null;\n let lastSpriteVertexBuffer: GpuBuffer | null = null;\n let lastSpriteIndexBuffer: GpuBuffer | null = null;\n for (let i = 0; i < validatedOrdered.length; i++) {\n const spriteEntry = validatedOrdered[i];\n // feat-20260625 M3 / w13: sub-pass entity filter migrated from\n // `shadingModel === 'sprite'` to `transparent === true` — the\n // shadingModel arm is gone post-feat (plan-strategy D-3).\n if (spriteEntry === undefined || spriteEntry.source.material.transparent !== true) continue;\n // feat-city-glb Bug 5 (per-submesh transparency): this loop is the\n // SPRITE path (whole-mesh sprite / sprite-lit PSO). Non-sprite\n // transparent materials (built-in PBR, incl. glTF alphaMode=BLEND) are\n // drawn per-submesh with their real shader in the dedicated PBR loop\n // below — so skip them here. Previously the 4.3-blending window (a PBR\n // material) was drawn through here with the sprite shader; it now flows\n // through the PBR loop, which is both correct and multi-submesh-capable.\n {\n const sid = spriteEntry.source.material.materialShaderId;\n const isSpriteShader = sid === 'forgeax::sprite' || sid === 'forgeax::sprite-lit';\n if (!isSpriteShader) continue;\n }\n // feat-20260622-chunk-gpu-instancing-sprite-tilemap M1 / w4-record-swap\n // (D-1): fold-bucket non-head member — skip; the bucket head emits one\n // instanced drawIndexed covering all members.\n if (foldDispatchPlan?.skipIndices.has(i) === true) {\n continue;\n }\n const foldHeadBucket = foldDispatchPlan?.headBuckets.get(i);\n\n // feat-20260609 M2: skip entities that don't match the pass selector.\n if (matchedIndices !== null && !matchedIndices.has(spriteEntry.renderableIndex)) {\n continue;\n }\n\n // feat-20260624 M1' / t7: select sprite vs sprite-lit PSO per\n // entity. Both paths share the LDR sub-pass + the same UBO\n // layout; only the shader module + fragment math differ. PSO\n // cache strings are isolated by materialShaderId (D-11) so\n // routing here keeps the cache slots disjoint.\n //\n // bug-20260629: SpriteInstances entities additionally need the\n // PER_INSTANCE_REGION=true variant so the shader reads UV region\n // from the 80B-per-instance interleaved buffer rather than from\n // the material UBO. Only the base sprite path has the per-instance\n // region variant compiled; sprite-lit + non-instances entities\n // keep the PER_INSTANCE_REGION=false variant.\n const entityShaderId = spriteEntry.source.material.materialShaderId;\n const useRegionVariant =\n entityShaderId !== 'forgeax::sprite-lit' && spriteEntry.source.spriteInstances !== undefined;\n const activeSpritePH =\n entityShaderId === 'forgeax::sprite-lit'\n ? spriteLitPH\n : useRegionVariant\n ? spritePH_withRegion\n : spritePH;\n if (activeSpritePH === null) {\n // Variant not yet compiled — for PER_INSTANCE_REGION=true the\n // variant cache fill is async on first use (mirrors the\n // spritePH===null guard above); falling back to the non-region\n // variant would render black quads (region read returns 0).\n // For sprite-lit the manifest may lack sprite-lit.wgsl; either\n // way fail-safe-skip is the closest the renderer can get to\n // \"show nothing visibly wrong\" without ending the sprite pass\n // (which would drop remaining sprite entities for the frame).\n if (entityShaderId === 'forgeax::sprite') {\n reportSpriteUnavailable();\n } else if (entityShaderId === 'forgeax::sprite-lit') {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'shader-compile-failed',\n expected:\n 'manifest entries include sprite.wgsl + sprite-lit.wgsl (when sprite-lit materials are used) + the engine triple (pbr + unlit + tonemap)',\n hint: 'verify @forgeax/engine-vite-plugin-shader emits manifest.json with sprite.wgsl AND sprite-lit.wgsl entries; check vite plugin engineEntries option',\n }),\n );\n }\n continue;\n }\n if (lastSpritePipelineHandle !== activeSpritePH) {\n spritePass.setPipeline(activeSpritePH);\n lastSpritePipelineHandle = activeSpritePH;\n }\n\n if (spriteEntry.mesh.vertexBuffer !== lastSpriteVertexBuffer) {\n spritePass.setVertexBuffer(0, spriteEntry.mesh.vertexBuffer.handle);\n lastSpriteVertexBuffer = spriteEntry.mesh.vertexBuffer;\n }\n if (\n spriteEntry.mesh.indexBuffer !== null &&\n spriteEntry.mesh.indexBuffer !== lastSpriteIndexBuffer\n ) {\n spritePass.setIndexBuffer(spriteEntry.mesh.indexBuffer.handle, spriteEntry.mesh.indexFormat);\n lastSpriteIndexBuffer = spriteEntry.mesh.indexBuffer;\n }\n\n // Instance buffer resolution: same cap-gate logic as the geometry\n // pass entity loop; sprites with Instances (e.g. hello-sprite-atlas\n // 100-instance walk-cycle) require per-entity storage buffer upload.\n // SSOT mirror of geometry pass instances block above (~line 1610):\n // identical cap-gate sequence (storageBuffer cap → limit-exceeded →\n // cache-lookup → createBuffer → writeBuffer); variable names carry\n // \"sprite\" prefix; logic divergence would be a bug.\n //\n // feat-20260622-chunk-gpu-instancing-sprite-tilemap M1 / w4-record-swap\n // (D-1): when `foldHeadBucket !== undefined` AND the sprite entity has\n // no explicit Instances component, assemble the bucket transforms into\n // a transient instance buffer + override `spriteInstanceCount =\n // bucket.bucketSize`. The mesh slot at `i*MESH_PER_ENTITY_STRIDE` was\n // already overwritten to identity in the mesh SSBO upload loop above,\n // so the shader computes `world = identity * bucket.transforms[idx] *\n // pos`, per-instance correct. Entities with explicit Instances bypass\n // fold (their per-entity Instances semantic wins); bucket key forces\n // such an entity to be a singleton bucket in practice because its\n // material is distinct or unfolded, but defensively check here as a\n // belt-and-suspenders guard.\n let spriteInstanceBuffer: Buffer = pipelineState.identityInstanceBuffer;\n let spriteInstanceCount = 1;\n const spriteInst = spriteEntry.source.instances;\n const useFold = foldHeadBucket !== undefined && spriteInst === undefined;\n if (useFold && foldHeadBucket !== undefined) {\n // w6 (D-8): bucket transient buffer reuse — composite cacheKey from\n // (materialHandle, layer, validatedOrdered head index) so the\n // existing `frameState.instanceBuffers` byteLength/archVersion path\n // covers static steady-state upload-skip. Numeric Map<number,…> key\n // requires a 32-bit-safe fold; we use a negative number-space prefix\n // (-1, -2, ...) by `((materialHandle << 16) | i)` shifted into the\n // negative half so it never collides with positive entity-Instances\n // cacheKeys (which are extracted from Instances component cacheKey\n // numeric ids, always non-negative). The `archVersion` proxy is\n // bucketSize (a structural-shape signal) so static frames hit the\n // cache.\n const bucketCacheKey = -1 - (((foldHeadBucket.materialHandle & 0xffff) << 16) | (i & 0xffff));\n const uniformFallback = runtime.device.caps.storageBuffer === false;\n const bucketPayload = uniformFallback\n ? foldHeadBucket.transforms\n : packInstanceStorageBuffer(foldHeadBucket.transforms);\n const bucketBytes = bucketPayload.byteLength;\n const bucketBufUsage = uniformFallback\n ? GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST\n : GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;\n const cachedBucket = frameState.instanceBuffers.get(bucketCacheKey);\n let activeBucket: InstanceBufferCacheEntry | null = null;\n if (\n cachedBucket !== undefined &&\n cachedBucket.uploadedArchVersion === foldHeadBucket.bucketSize &&\n cachedBucket.uploadedByteLength === bucketBytes\n ) {\n activeBucket = cachedBucket;\n } else if (bucketBytes > 0) {\n const bufRes = runtime.device.createBuffer({\n size: bucketBytes,\n usage: bucketBufUsage,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n } else {\n if (cachedBucket !== undefined && !cachedBucket.buffer.isDestroyed) {\n const r = cachedBucket.buffer.destroy();\n if (!r.ok) runtime.errorRegistry.fire(r.error);\n }\n const newBuf = new GpuBuffer(runtime.device, bufRes.value);\n activeBucket = {\n buffer: newBuf,\n uploadedArchVersion: foldHeadBucket.bucketSize,\n uploadedByteLength: bucketBytes,\n };\n frameState.instanceBuffers.set(bucketCacheKey, activeBucket);\n }\n }\n if (activeBucket !== null) {\n const writeRes = runtime.device.queue.writeBuffer(\n activeBucket.buffer.handle,\n 0,\n bucketPayload,\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n } else {\n spriteInstanceBuffer = activeBucket.buffer.handle;\n spriteInstanceCount = foldHeadBucket.bucketSize;\n }\n }\n } else if (spriteInst !== undefined) {\n const uniformFallback = runtime.device.caps.storageBuffer === false;\n let spriteBufUsage = GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;\n\n if (uniformFallback) {\n if (spriteInst.instanceCount > MAX_UNIFORM_INSTANCES) {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'limit-exceeded',\n expected: `instance count <= ${MAX_UNIFORM_INSTANCES} (uniform fallback cap)`,\n hint: `reduce instance count to ${MAX_UNIFORM_INSTANCES} or use a WebGPU-capable backend`,\n detail: {\n maxStorageBufferBindingSize: MAX_UNIFORM_INSTANCES * 64,\n requestedBytes: spriteInst.instanceCount * 64,\n },\n }),\n );\n spriteInstanceCount = spriteInst.instanceCount;\n spriteInstanceBuffer = pipelineState.identityInstanceBuffer;\n // Sprite shaders do not declare the Standard PBR Probe ABI. A\n // retained scene record must therefore not change their group(3)\n // bind-group shape.\n const spriteInstBg = resolveGeometryInstancesBindGroup(\n c,\n spriteInstanceBuffer,\n undefined,\n );\n spritePass.setBindGroup(3, spriteInstBg);\n spritePass.drawIndexed(spriteEntry.mesh.indexCount, spriteInstanceCount, 0, 0, 0);\n continue;\n }\n spriteBufUsage = GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST;\n }\n\n {\n const instancePayload = uniformFallback\n ? spriteInst.transforms\n : packInstanceStorageBuffer(spriteInst.transforms);\n const requestedBytes = instancePayload.byteLength;\n const cap = runtime.device.limits.maxStorageBufferBindingSize;\n if (typeof cap === 'number' && requestedBytes > cap) {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'limit-exceeded',\n expected: `requestedBytes (${requestedBytes}) <= maxStorageBufferBindingSize (${cap})`,\n hint: 'reduce instance count to fit within device.limits.maxStorageBufferBindingSize, or split transforms across multiple Instances entries',\n detail: {\n maxStorageBufferBindingSize: cap,\n requestedBytes,\n },\n }),\n );\n } else {\n const cachedSprite = frameState.instanceBuffers.get(\n worldEntityKey(spriteEntry.source.worldId, spriteInst.cacheKey),\n );\n let activeSprite: InstanceBufferCacheEntry | null = null;\n if (\n cachedSprite !== undefined &&\n cachedSprite.uploadedArchVersion === spriteInst.archVersion &&\n cachedSprite.uploadedByteLength === requestedBytes\n ) {\n activeSprite = cachedSprite;\n } else if (requestedBytes > 0) {\n const bufRes = runtime.device.createBuffer({\n size: requestedBytes,\n usage: spriteBufUsage,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n } else {\n // feat-20260619 M4 / F12: destroy the old cached buffer\n // before replacing it with the new one (D-6).\n if (cachedSprite !== undefined && !cachedSprite.buffer.isDestroyed) {\n const r = cachedSprite.buffer.destroy();\n if (!r.ok) runtime.errorRegistry.fire(r.error);\n }\n const newBuf = new GpuBuffer(runtime.device, bufRes.value);\n activeSprite = {\n buffer: newBuf,\n uploadedArchVersion: spriteInst.archVersion,\n uploadedByteLength: requestedBytes,\n };\n frameState.instanceBuffers.set(\n worldEntityKey(spriteEntry.source.worldId, spriteInst.cacheKey),\n activeSprite,\n );\n }\n }\n if (activeSprite !== null) {\n const writeRes = runtime.device.queue.writeBuffer(\n activeSprite.buffer.handle,\n 0,\n instancePayload,\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n } else {\n spriteInstanceBuffer = activeSprite.buffer.handle;\n spriteInstanceCount = Math.max(1, spriteInst.instanceCount);\n }\n }\n }\n }\n }\n\n // feat-20260625-sprite-instances-and-tilemap-terrain-static-batch\n // M3 / w11: SpriteInstances 80B-per-instance interleaved upload path.\n // SSOT for the per-entity 2D mat4 + per-instance UV region buffer\n // (plan-strategy D-1 interleaved single buffer + single binding slot;\n // D-9 cacheKey = entity packed u32). The extract-stage validator\n // (M3 / w10) enforces the XOR contract `Instances XOR SpriteInstances`\n // (sprite-instances-mutually-exclusive-with-instances), so the\n // legacy `spriteInst` block above and this block are never both\n // active for the same entity.\n const _si = resolveSpriteInstancesBuffer(\n c,\n spriteEntry,\n spriteInstanceBuffer,\n spriteInstanceCount,\n );\n spriteInstanceBuffer = _si.buffer;\n spriteInstanceCount = _si.count;\n\n // sprite-lit's clustered variant declares the unified Standard group(2)\n // contract, while the regular sprite variants keep the direct mesh\n // contract. Select the resource from the same capability axis used to\n // request the pipeline; binding the ordinary mesh group to the clustered\n // sprite-lit pipeline is rejected by WebGPU before the draw is recorded.\n const spriteGroup2 =\n entityShaderId === 'forgeax::sprite-lit' && c.standardLighting?.kind === 'clustered'\n ? c.hdrpClusterBindGroup\n : meshBindGroup;\n\n // M3 / w12: LDR sprite split pass per-entity instances BG cache. Sprite\n // shaders do not declare the Standard PBR Probe ABI, so retained probe\n // records stay out of this bind-group path.\n const spriteInstancesBg = resolveGeometryInstancesBindGroup(c, spriteInstanceBuffer, undefined);\n\n spritePass.setBindGroup(2, spriteGroup2 as BindGroup, [i * MESH_PER_ENTITY_STRIDE]);\n\n // Per-entity sprite material bind group: same standard PBR user-region\n // layout as in the geometry pass sprite branch + Skylight merged entries\n // the geometry pass sprite branch + Skylight merged entries (same\n // skylightResources in scope from above). Texture view is resolved\n // from the sprite material's baseColorTexture handle.\n const spriteTexHandle = spriteEntry.source.material.baseColorTexture as\n | Handle<'TextureAsset', 'shared'>\n | undefined;\n let spriteTexView = pipelineState.defaultWhiteTextureView;\n if (spriteTexHandle !== undefined) {\n const tv = residentTextureView(spriteEntry.world ?? world, store, runtime, spriteTexHandle);\n if (tv !== undefined) spriteTexView = tv as never;\n }\n const spritePassBaseMaterialEntries = buildSpritePassBaseMaterialEntries(\n pipelineState,\n spriteTexView,\n );\n const spritePassMergedEntries = assembleMaterialWithSkylightEntries(\n spritePassBaseMaterialEntries,\n skylightResources,\n );\n\n // Sprite-pass material BG cache: keyed on shader id (shared across all\n // sprite entities) so entities using the same atlas texture share one\n // BindGroup instead of creating one per entity (O5 fix — inner WeakMap\n // chain naturally deduplicates by GPU resource object identity, so two\n // entities with different atlases still get distinct BGs).\n const spritePassBg: BindGroup = getOrCreatePerEntity(\n frameState.materialBgShared,\n 'forgeax::sprite',\n spritePassMergedEntries.map((e) => extractEntryResourceHandle(e)),\n 'sprite-pass-material',\n () => {\n const result = runtime.device.createBindGroup({\n label: 'sprite-pass-material-bg',\n layout: pipelineState.materialBindGroupLayout,\n entries: spritePassMergedEntries,\n });\n if (!result.ok) throw result.error;\n return result.value;\n },\n bindGroupCounts,\n );\n\n const materialSlot = materialSlotIndices[i]?.[0] ?? 0;\n spritePass.setBindGroup(1, spritePassBg, [materialSlot * MATERIAL_PER_ENTITY_STRIDE]);\n spritePass.setBindGroup(3, spriteInstancesBg);\n spritePass.drawIndexed(spriteEntry.mesh.indexCount, spriteInstanceCount, 0, 0, 0);\n }\n}\n\n/**\n * feat-20260704 M3/w19: resolve the interleaved SpriteInstances (@group(3))\n * buffer + instanceCount for a sprite entity in the LDR blend sub-pass,\n * extracted verbatim from recordSpriteEntityDraws. Uploads the interleaved\n * mat4 + per-instance UV region transforms (cache-keyed on the snapshot); on\n * over-cap fires the structured limit-exceeded error and leaves the passed-in\n * fallback buffer/count. Returns the resolved (or unchanged) buffer + count.\n *\n * @internal\n */\nfunction resolveSpriteInstancesBuffer(\n c: _InternalRenderPipelineContext,\n spriteEntry: _InternalRenderPipelineContext['validatedOrdered'][number],\n fallbackBuffer: Buffer,\n fallbackCount: number,\n): { buffer: Buffer; count: number } {\n const { runtime, frameState } = c;\n let buffer = fallbackBuffer;\n let count = fallbackCount;\n const spriteInstancesSnap: SpriteInstancesSnapshot | undefined =\n spriteEntry.source.spriteInstances;\n if (spriteInstancesSnap !== undefined) {\n const uniformFallback = runtime.device.caps.storageBuffer === false;\n const interleaved = interleaveSpriteInstanceBuffer(\n spriteInstancesSnap.transforms,\n spriteInstancesSnap.regions,\n !uniformFallback,\n );\n const requestedBytes = interleaved.byteLength;\n const cap = runtime.device.limits.maxStorageBufferBindingSize;\n if (typeof cap === 'number' && requestedBytes > cap) {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'limit-exceeded',\n expected: `requestedBytes (${requestedBytes}) <= maxStorageBufferBindingSize (${cap})`,\n hint: 'reduce SpriteInstances instance count to fit within device.limits.maxStorageBufferBindingSize (144 bytes per instance: current mat4 64B + previous mat4 64B + region 16B)',\n detail: {\n maxStorageBufferBindingSize: cap,\n requestedBytes,\n },\n }),\n );\n } else {\n const cachedSpriteInst = frameState.instanceBuffers.get(\n worldEntityKey(spriteEntry.source.worldId, spriteInstancesSnap.cacheKey),\n );\n let activeSpriteInst: InstanceBufferCacheEntry | null = null;\n if (spriteInstancesCacheHit(cachedSpriteInst, spriteInstancesSnap, requestedBytes)) {\n activeSpriteInst = cachedSpriteInst ?? null;\n } else if (requestedBytes > 0) {\n const bufRes = runtime.device.createBuffer({\n size: requestedBytes,\n usage:\n (uniformFallback ? GPU_BUFFER_USAGE_UNIFORM : GPU_BUFFER_USAGE_STORAGE) |\n GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n } else {\n if (cachedSpriteInst !== undefined && !cachedSpriteInst.buffer.isDestroyed) {\n const r = cachedSpriteInst.buffer.destroy();\n if (!r.ok) runtime.errorRegistry.fire(r.error);\n }\n const newBuf = new GpuBuffer(runtime.device, bufRes.value);\n activeSpriteInst = {\n buffer: newBuf,\n uploadedArchVersion: spriteInstancesSnap.archVersion,\n uploadedByteLength: requestedBytes,\n };\n frameState.instanceBuffers.set(\n worldEntityKey(spriteEntry.source.worldId, spriteInstancesSnap.cacheKey),\n activeSpriteInst,\n );\n }\n }\n if (activeSpriteInst !== null && requestedBytes > 0) {\n const writeRes = runtime.device.queue.writeBuffer(\n activeSpriteInst.buffer.handle,\n 0,\n interleaved,\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n } else {\n buffer = activeSpriteInst.buffer.handle;\n count = spriteInstancesSnap.instanceCount;\n }\n }\n }\n }\n return { buffer, count };\n}\n\nfunction transparentPassColorFormat(\n c: _InternalRenderPipelineContext,\n pipelineState: _InternalRenderPipelineContext['pipelineState'] = c.pipelineState,\n): string {\n if (c.transparentColorFormat !== undefined) return c.transparentColorFormat;\n if (!c.runtime.device.caps.storageBuffer) return pipelineState.colorAttachmentFormat;\n return pipelineState.format;\n}\n","import {\n type BindGroup,\n type BindGroupEntry,\n type Buffer,\n type RenderPipeline,\n RhiError,\n type RhiQueue,\n type RhiRenderPassEncoder,\n} from '@forgeax/engine-rhi';\nimport type { MaterialRenderState, PassSelector } from '@forgeax/engine-types';\nimport { GpuBuffer } from '../gpu-resource';\nimport {\n GPU_BUFFER_USAGE_COPY_DST,\n GPU_BUFFER_USAGE_STORAGE,\n GPU_BUFFER_USAGE_UNIFORM,\n} from '../gpu-usage';\nimport { assembleMaterialWithSkylightEntries } from '../ibl/skylight-bind-group';\nimport type { InstanceBufferCacheEntry } from '../instance-buffer-cache';\nimport {\n buildPbrMaterialUserRegionEntries,\n createPbrSkinMeshBindGroupEntries,\n pbrSkinMeshDynamicOffsets,\n SHADOW_CASTER_SHADER_ID,\n shadowCasterVariantSet,\n} from '../pbr-pipeline';\nimport { COOKIE_MATRIX_BYTES } from '../prepare/extended-lighting/resources';\nimport type { DispatchEntry, ExtractedLights } from '../render-system-extract';\nimport { matchPass } from '../systems/pass-selector';\nimport { worldEntityKey } from './frame-snapshot';\nimport { resolveGeometryInstancesBindGroup } from './main-pass-geometry';\nimport {\n getOrCreateFromChain,\n MAX_UNIFORM_INSTANCES,\n MESH_PER_ENTITY_STRIDE,\n MESH_SSBO_BYTES,\n MESH_UBO_FULL_ARRAY_BYTES,\n packInstanceStorageBuffer,\n} from './mesh-ssbo';\nimport type { _InternalRenderPipelineContext } from './render-context';\nimport { STANDARD_PBR_UBO_SIZE } from './render-context';\nimport { POINTS_LINES_VIEW_BYTES, pointShadowViewOffset, VIEW_UNIFORM_BYTES } from './view-ubo';\n\nexport const SHADOW_CASTER_SLOT_STRIDE = 256;\nexport const SHADOW_CASTER_BUFFER_SIZE = SHADOW_CASTER_SLOT_STRIDE * 8;\n\nexport function directionalShadowCasterOffset(cascadeIndex: number): number {\n return SHADOW_CASTER_SLOT_STRIDE * cascadeIndex;\n}\n\nexport function spotShadowCasterOffset(tile: number): number {\n return SHADOW_CASTER_SLOT_STRIDE * (4 + tile);\n}\n\nexport function writeShadowCasterUniforms(\n queue: RhiQueue,\n buffer: Buffer,\n lights: ExtractedLights,\n): void {\n for (let cascade = 0; cascade < 4; cascade += 1) {\n const written = queue.writeBuffer(\n buffer,\n directionalShadowCasterOffset(cascade),\n new Uint32Array([cascade, 0, 0, 0]),\n );\n if (!written.ok) throw written.error;\n }\n for (const snapshot of lights.spot) {\n const tile = snapshot.shadowAtlasTile;\n if (tile < 0 || tile >= 4 || snapshot.lightViewProj === undefined) continue;\n const offset = spotShadowCasterOffset(tile);\n const header = queue.writeBuffer(buffer, offset, new Uint32Array([0, 1, 0, 0]));\n if (!header.ok) throw header.error;\n const matrix = queue.writeBuffer(buffer, offset + 16, snapshot.lightViewProj);\n if (!matrix.ok) throw matrix.error;\n }\n}\n\nfunction ensureTypedShadowViewBg(\n c: _InternalRenderPipelineContext,\n viewOffset: number,\n cascadeOffset: number,\n variant: string,\n): BindGroup | null {\n const { runtime, frameState, pipelineState } = c;\n const shadowSampler = pipelineState.perPassResources.shadowSampler;\n if (shadowSampler === null) return null;\n const extendedLighting = pipelineState.extendedLightingAvailable ?? false;\n const iesProfileTextureView = pipelineState.iesProfileTextureView;\n const cookieTextureView = pipelineState.cookieTextureView;\n const cookieMatrixBuffer = pipelineState.cookieMatrixBuffer;\n const ltcLambertTextureView = pipelineState.ltcLambertTextureView;\n const ltcGgxTextureView = pipelineState.ltcGgxTextureView;\n const extendedLightingCacheKeys: object[] = [];\n const extendedLightingEntries: BindGroupEntry[] = [];\n if (extendedLighting) {\n if (\n iesProfileTextureView === undefined ||\n cookieTextureView === undefined ||\n cookieMatrixBuffer === undefined ||\n ltcLambertTextureView === undefined ||\n ltcGgxTextureView === undefined\n ) {\n return null;\n }\n extendedLightingCacheKeys.push(\n pipelineState.defaultSampler,\n iesProfileTextureView,\n cookieTextureView,\n ltcLambertTextureView,\n ltcGgxTextureView,\n cookieMatrixBuffer,\n );\n extendedLightingEntries.push(\n {\n binding: 9,\n resource: { kind: 'sampler', value: pipelineState.defaultSampler },\n },\n {\n binding: 11,\n resource: { kind: 'textureView', value: iesProfileTextureView },\n },\n {\n binding: 12,\n resource: { kind: 'textureView', value: cookieTextureView },\n },\n {\n binding: 13,\n resource: { kind: 'textureView', value: ltcLambertTextureView },\n },\n {\n binding: 14,\n resource: { kind: 'textureView', value: ltcGgxTextureView },\n },\n {\n binding: 15,\n resource: {\n kind: 'buffer',\n value: { buffer: cookieMatrixBuffer, size: COOKIE_MATRIX_BYTES },\n },\n },\n );\n }\n const projectorAvailable = pipelineState.projectorAvailable !== false;\n try {\n return getOrCreateFromChain(\n frameState.viewBindGroupCache,\n [\n pipelineState.viewUniformBuffer,\n pipelineState.shadowFallbackTextureView,\n shadowSampler,\n pipelineState.shadowAtlasFallbackTextureView,\n pipelineState.shadowParamsBuffer,\n pipelineState.shadowCasterCascadeBuffer,\n pipelineState.shadowFallbackTextureView,\n ...(extendedLighting\n ? extendedLightingCacheKeys\n : projectorAvailable\n ? [pipelineState.defaultWhiteTextureView, pipelineState.defaultSampler]\n : []),\n pipelineState.pointsLinesViewBuffer ?? pipelineState.viewUniformBuffer,\n ],\n variant,\n () => {\n const created = runtime.device.createBindGroup({\n label: variant,\n layout: pipelineState.viewBindGroupLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.viewUniformBuffer,\n offset: viewOffset,\n size: VIEW_UNIFORM_BYTES,\n },\n },\n },\n {\n binding: 3,\n resource: { kind: 'textureView', value: pipelineState.shadowFallbackTextureView },\n },\n {\n binding: 4,\n resource: { kind: 'sampler', value: shadowSampler },\n },\n {\n binding: 5,\n resource: {\n kind: 'textureView',\n value: pipelineState.shadowAtlasFallbackTextureView,\n },\n },\n {\n binding: 6,\n resource: { kind: 'buffer', value: { buffer: pipelineState.shadowParamsBuffer } },\n },\n {\n binding: 7,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.shadowCasterCascadeBuffer,\n offset: cascadeOffset,\n size: POINTS_LINES_VIEW_BYTES,\n },\n },\n },\n {\n binding: 8,\n resource: { kind: 'textureView', value: pipelineState.shadowFallbackTextureView },\n },\n ...extendedLightingEntries,\n {\n binding: 10,\n resource: {\n kind: 'buffer',\n value: {\n buffer: pipelineState.pointsLinesViewBuffer ?? pipelineState.viewUniformBuffer,\n size: 80,\n },\n },\n },\n ...(!extendedLighting && projectorAvailable\n ? [\n {\n binding: 11,\n resource: {\n kind: 'textureView' as const,\n value: pipelineState.defaultWhiteTextureView,\n },\n },\n {\n binding: 12,\n resource: { kind: 'sampler' as const, value: pipelineState.defaultSampler },\n },\n ]\n : []),\n ],\n });\n if (!created.ok) throw created.error;\n return created.value;\n },\n c.bindGroupCounts,\n );\n } catch (error) {\n if (error instanceof RhiError) {\n runtime.errorRegistry.fire(error);\n return null;\n }\n throw error;\n }\n}\n\ninterface ShadowDispatch {\n readonly materialShaderId: string;\n readonly renderState: MaterialRenderState | undefined;\n}\n\ntype ShadowDispatchMap = ReadonlyMap<number, ReadonlyMap<number, ShadowDispatch>>;\n\nfunction shadowShaderMap(c: _InternalRenderPipelineContext): ShadowDispatchMap {\n const shaders = new Map<number, Map<number, ShadowDispatch>>();\n for (const entry of c.dispatch) {\n if (entry.tags.LightMode === 'ShadowCaster' && entry.materialShaderId !== undefined) {\n let byMaterial = shaders.get(entry.renderableIndex);\n if (byMaterial === undefined) {\n byMaterial = new Map<number, ShadowDispatch>();\n shaders.set(entry.renderableIndex, byMaterial);\n }\n byMaterial.set(entry.materialHandle, {\n materialShaderId: entry.materialShaderId,\n renderState: entry.renderState,\n });\n }\n }\n return shaders;\n}\n\nfunction shadowPipeline(c: _InternalRenderPipelineContext): RenderPipeline | null {\n return (\n c.runtime.getMaterialShaderPipeline?.(\n SHADOW_CASTER_SHADER_ID,\n false,\n undefined,\n 'triangle-list',\n undefined,\n shadowCasterVariantSet(c.runtime.device.caps.storageBuffer, false),\n 'shadow-caster',\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n 'pbr',\n ) ?? null\n );\n}\n\nfunction skinnedShadowPipeline(\n c: _InternalRenderPipelineContext,\n entry: _InternalRenderPipelineContext['validatedOrdered'][number],\n): RenderPipeline | null {\n return (\n c.runtime.getMaterialShaderPipeline?.(\n SHADOW_CASTER_SHADER_ID,\n false,\n undefined,\n entry.mesh.submeshes[0]?.topology ?? 'triangle-list',\n entry.mesh.indexFormat,\n shadowCasterVariantSet(c.runtime.device.caps.storageBuffer, true),\n 'shadow-caster',\n undefined,\n 1,\n undefined,\n undefined,\n undefined,\n undefined,\n entry.mesh.layoutProjection,\n undefined,\n 'pbr-skin',\n ) ?? null\n );\n}\n\nfunction skinnedShadowMeshBindGroup(\n c: _InternalRenderPipelineContext,\n entry: _InternalRenderPipelineContext['validatedOrdered'][number],\n): BindGroup | null {\n const skin = entry.source.skin;\n const layout = c.pipelineState.pbrSkinMeshBindGroupLayout;\n const allocator = c.pipelineState.skinPaletteAllocator;\n if (skin === undefined || layout === null || allocator === null) return null;\n return getOrCreateFromChain(\n c.frameState.meshBindGroupCache,\n [c.pipelineState.meshStorageBuffer.buffer, skin.buffer],\n 'shadow-pbr-skin-mesh',\n () => {\n const created = c.runtime.device.createBindGroup({\n label: 'shadow-pbr-skin-mesh-bg',\n layout,\n entries: createPbrSkinMeshBindGroupEntries(\n c.pipelineState.meshStorageBuffer.buffer,\n c.runtime.device.caps.storageBuffer ? MESH_SSBO_BYTES : MESH_UBO_FULL_ARRAY_BYTES,\n skin.buffer,\n allocator.bindingWindowBytes,\n ),\n });\n if (!created.ok) throw created.error;\n return created.value;\n },\n c.bindGroupCounts,\n );\n}\n\nexport function encodeDirectionalShadowPass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n cascadeIndex: number,\n viewport: { readonly x: number; readonly y: number; readonly w: number; readonly h: number },\n): void {\n if (c.directionalShadowCacheReuse || c.meshBindGroup === null) return;\n const pipeline = shadowPipeline(c);\n const viewBg = ensureTypedShadowViewBg(\n c,\n 0,\n directionalShadowCasterOffset(cascadeIndex),\n `view-shadow-directional-${cascadeIndex}`,\n );\n const materialBg = ensureSpotShadowMaterialBg(c);\n if (pipeline === null || viewBg === null || materialBg === null) return;\n c.frameState.directionalShadowCacheRecorded = true;\n pass.setViewport(viewport.x, viewport.y, viewport.w, viewport.h, 0, 1);\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, viewBg, [0, 0]);\n pass.setBindGroup(1, materialBg, [0]);\n recordShadowCasterDraws(\n c,\n pass,\n pipeline,\n c.meshBindGroup,\n buildMatchedRenderableIndices(c.dispatch, { LightMode: ['ShadowCaster'] }),\n shadowShaderMap(c),\n );\n}\n\nexport function encodePointShadowPass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n snapshotIndex: number,\n face: number,\n): void {\n const snapshot = c.frameState.pointShadowSnapshots[snapshotIndex];\n if (snapshot === undefined || c.meshBindGroup === null) return;\n const pipeline = shadowPipeline(c);\n const viewBg = ensureTypedShadowViewBg(\n c,\n pointShadowViewOffset(snapshot.shadowAtlasLayer, face),\n 0,\n `view-shadow-point-${snapshot.shadowAtlasLayer}-${face}`,\n );\n const materialBg = ensureSpotShadowMaterialBg(c);\n if (pipeline === null || viewBg === null || materialBg === null) return;\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, viewBg, [0, 0]);\n pass.setBindGroup(1, materialBg, [0]);\n recordShadowCasterDraws(\n c,\n pass,\n pipeline,\n c.meshBindGroup,\n buildMatchedRenderableIndices(c.dispatch, { LightMode: ['ShadowCaster'] }),\n shadowShaderMap(c),\n );\n}\n\nexport function encodeSpotShadowPass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n snapshotIndex: number,\n): void {\n const snapshot = c.frameState.spotShadowSnapshots.filter(\n (candidate) => candidate.shadowAtlasTile >= 0 && candidate.lightViewProj !== undefined,\n )[snapshotIndex];\n if (\n snapshot === undefined ||\n snapshot.shadowAtlasTile < 0 ||\n snapshot.lightViewProj === undefined ||\n c.meshBindGroup === null\n ) {\n return;\n }\n const pipeline = shadowPipeline(c);\n const viewBg = ensureTypedShadowViewBg(\n c,\n 0,\n spotShadowCasterOffset(snapshot.shadowAtlasTile),\n `view-shadow-spot-${snapshot.shadowAtlasTile}`,\n );\n const materialBg = ensureSpotShadowMaterialBg(c);\n if (pipeline === null || viewBg === null || materialBg === null) return;\n const tileSize = c.pipelineState.perPassResources.shadowMapSize;\n const tile = snapshot.shadowAtlasTile;\n pass.setViewport(\n (tile % 2) * tileSize,\n Math.floor(tile / 2) * tileSize,\n tileSize,\n tileSize,\n 0,\n 1,\n );\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, viewBg, [0, 0]);\n pass.setBindGroup(1, materialBg, [0]);\n // Reuse the shared caster recorder. The compact spot-only loop used to\n // depend on instance bindings created by a directional pass, so a scene\n // containing only a SpotLight opened the atlas pass but emitted no caster\n // draws.\n recordShadowCasterDraws(\n c,\n pass,\n pipeline,\n c.meshBindGroup,\n buildMatchedRenderableIndices(c.dispatch, { LightMode: ['ShadowCaster'] }),\n shadowShaderMap(c),\n );\n}\n\n/**\n * feat-20260609 M2: filter dispatch entries by a {@link PassSelector}.\n *\n * Each dispatch entry carries `tags` (a free key-value map) sourced from the\n * material's per-pass tags. The selector is matched entry-by-entry via\n * {@link matchPass}; entries whose tags satisfy the selector are returned.\n * An empty selector returns the input array unchanged (match-all semantics).\n *\n * @param dispatch Per-frame dispatch entries (from the extract stage).\n * @param selector Pipeline-specific pass selector (e.g. `{ LightMode: ['Forward'] }`).\n * @returns Dispatch entries whose tags match the selector.\n */\nexport function filterDispatchBySelector(\n dispatch: readonly DispatchEntry[],\n selector: PassSelector,\n): readonly DispatchEntry[] {\n if (Object.keys(selector).length === 0) return dispatch;\n return dispatch.filter((e) => matchPass(e.tags, selector));\n}\n\n/**\n * feat-20260609 M2: build a set of renderable indices whose dispatch entries\n * match the given selector. Used by the record pass closures to skip entities\n * that do not belong to the current pass.\n *\n * Returns null when the dispatch array is empty (no dispatch-based filtering\n * to apply — draw all entities). Returns an empty set when dispatch is\n * non-empty but no entries matched (draw nothing). Returns a populated set\n * when at least one dispatch entry matched.\n */\nexport function buildMatchedRenderableIndices(\n dispatch: readonly DispatchEntry[],\n selector: PassSelector,\n): Set<number> | null {\n // PRODUCTION INVARIANT: in real frames extractFrame always populates\n // dispatch[] for every visible renderable (Forward + ShadowCaster tags\n // emitted per validated entity, including the default-material handle=0\n // path — see render-system-extract.ts default-material dispatch emission).\n // The empty-dispatch null fallback below exists ONLY for unit-test\n // fixtures that mock dispatch out (early w-* tests written before\n // dispatch existed). Returning null causes the downstream loop to skip\n // selector filtering, preserving back-compat for those fixtures. If a\n // future refactor moves dispatch population earlier or makes it\n // conditional, the test fixtures should be updated rather than this\n // fallback widened to production.\n if (dispatch.length === 0) return null;\n const filtered = filterDispatchBySelector(dispatch, selector);\n const set = new Set<number>();\n for (const e of filtered) {\n set.add(e.renderableIndex);\n }\n return set;\n}\n\n/**\n * Build the material handles whose dispatch entries match a graph pass.\n *\n * A renderable can own more than one material pass, so renderable-level\n * filtering is insufficient for geometry recording: a Deferred graph pass\n * must not draw the same renderable's Forward-only material. Keep the\n * renderable key in the result so mixed-material meshes retain their\n * per-submesh routing.\n */\nexport function buildMatchedMaterialHandlesByRenderable(\n dispatch: readonly DispatchEntry[],\n selector: PassSelector,\n): ReadonlyMap<number, ReadonlySet<number>> | null {\n if (dispatch.length === 0) return null;\n const matched = filterDispatchBySelector(dispatch, selector);\n const handlesByRenderable = new Map<number, Set<number>>();\n for (const entry of matched) {\n const handles = handlesByRenderable.get(entry.renderableIndex);\n if (handles === undefined) {\n handlesByRenderable.set(entry.renderableIndex, new Set([entry.materialHandle]));\n } else {\n handles.add(entry.materialHandle);\n }\n }\n return handlesByRenderable;\n}\n\n/**\n * feat-20260704 M3/w20: per-entity directional shadow-caster draw loop,\n * extracted verbatim from {@link encodeDirectionalShadowPass}. Walks `c.validatedOrdered`,\n * selects the per-entity shadow PSO (default vertex-only caster or a custom\n * cutout caster), binds the per-entity mesh dynamic-offset + instance buffer,\n * and issues the per-submesh depth draws. `shadowPass` view/material bind\n * groups (@group 0/1) are already set by the caller; this loop owns @group\n * 2/3 + the vertex/index/pipeline de-dup state. Receives the explicit\n * `_InternalRenderPipelineContext` (`c`) plus the caller-resolved shadow\n * pipeline, mesh bind group, pass-selector match set, and per-material\n * ShadowCaster dispatch map so no cross-function mutable state is introduced.\n */\nfunction recordShadowCasterDraws(\n c: _InternalRenderPipelineContext,\n shadowPass: RhiRenderPassEncoder,\n shadowPipeline: RenderPipeline,\n shadowMeshBindGroup: BindGroup,\n matchedIndices: Set<number> | null,\n shadowDispatchByRenderableIdx: ShadowDispatchMap,\n): void {\n const { runtime, pipelineState, validatedOrdered } = c;\n // M-3 / w12: vertexBuffer/indexBuffer state locals migrate to GpuBuffer\n // (the wrapper) -- the de-dup compare uses wrapper identity (one wrapper\n // per RHI handle from gpuStore), and `.handle` is passed to the RHI\n // setVertexBuffer / setIndexBuffer call.\n let shadowLastVertexBuffer: GpuBuffer | null = null;\n let shadowLastIndexBuffer: GpuBuffer | null = null;\n // bug-20260619-csm RC-3 (D-3): track the currently-bound shadow PSO so\n // per-entity setPipeline only fires on change (same de-dup discipline as\n // vertex/index buffers above). The default-shadow-caster PSO is already\n // bound by the setPipeline call above; the loop switches to a custom\n // ShadowCaster PSO when a material supplies one.\n let shadowLastPipeline: RenderPipeline = shadowPipeline;\n\n for (let i = 0; i < validatedOrdered.length; i++) {\n const entry = validatedOrdered[i];\n if (entry === undefined) continue;\n\n // feat-20260609 M2: skip entities that don't match the pass selector.\n if (matchedIndices !== null && !matchedIndices.has(entry.renderableIndex)) continue;\n\n if (entry.source.skin !== undefined) {\n const skinPipeline = skinnedShadowPipeline(c, entry);\n if (skinPipeline === null) continue;\n if (skinPipeline !== shadowLastPipeline) {\n shadowPass.setPipeline(skinPipeline);\n shadowLastPipeline = skinPipeline;\n }\n }\n // feat-20260604-mesh-topology-debug-draw M5 / w14 (AC-09, D-A6): the\n // shadow caster PSO is triangle-list; it only projects triangle faces.\n // line-list / line-strip / point-list meshes have no surface to cast a\n // shadow, so skip them here. triangle-strip is still a face topology\n // and projects (the shadow PSO's fixed triangle-list rasterizes its\n // expanded triangles correctly enough for the depth pass).\n //\n // feat-20260608 M4 / w16: per-submesh shadow draw — iterate submeshes\n // and skip non-triangle submeshes individually (each submesh may differ).\n const shadowSubmeshes = entry.mesh.submeshes;\n const hasAnyShadowSubmesh = shadowSubmeshes.some(\n (sm) => sm.topology === 'triangle-list' || sm.topology === 'triangle-strip',\n );\n if (!hasAnyShadowSubmesh) {\n continue;\n }\n\n if (entry.mesh.vertexBuffer !== shadowLastVertexBuffer) {\n shadowPass.setVertexBuffer(0, entry.mesh.vertexBuffer.handle);\n shadowLastVertexBuffer = entry.mesh.vertexBuffer;\n }\n if (entry.mesh.indexed && entry.mesh.indexBuffer !== shadowLastIndexBuffer) {\n // indexed=true implies indexBuffer is non-null GpuBuffer.\n if (entry.mesh.indexBuffer !== null) {\n shadowPass.setIndexBuffer(entry.mesh.indexBuffer.handle, entry.mesh.indexFormat);\n shadowLastIndexBuffer = entry.mesh.indexBuffer;\n }\n }\n\n if (entry.source.skin !== undefined) {\n const skinMeshBindGroup = skinnedShadowMeshBindGroup(c, entry);\n if (skinMeshBindGroup === null) continue;\n shadowPass.setBindGroup(\n 2,\n skinMeshBindGroup,\n pbrSkinMeshDynamicOffsets(i * MESH_PER_ENTITY_STRIDE, entry.source.skin.byteOffset),\n );\n } else {\n shadowPass.setBindGroup(2, shadowMeshBindGroup, [i * MESH_PER_ENTITY_STRIDE]);\n }\n\n // C1 + C2 (w12): per-entity instance buffer + instanceCount\n let shadowInstanceBuffer: Buffer = pipelineState.identityInstanceBuffer;\n let shadowInstanceCount = 1;\n const shadowInst = entry.source.instances;\n if (shadowInst?.instanceCount === 0) continue;\n if (shadowInst !== undefined) {\n const uniformFallback = runtime.device.caps.storageBuffer === false;\n // Over-cap uniform fallback can't fit the per-instance window — bind\n // identity and let the shader collapse (same semantics as the main\n // pass). Otherwise build/upload the per-entity instance buffer: storage\n // by default, uniform when the device lacks storage buffers.\n if (uniformFallback && shadowInst.instanceCount > MAX_UNIFORM_INSTANCES) {\n shadowInstanceCount = shadowInst.instanceCount;\n shadowInstanceBuffer = pipelineState.identityInstanceBuffer;\n } else {\n const bufUsage = uniformFallback\n ? GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST\n : GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;\n const instancePayload = uniformFallback\n ? shadowInst.transforms\n : packInstanceStorageBuffer(shadowInst.transforms);\n const requestedBytes = instancePayload.byteLength;\n const cached = c.frameState.instanceBuffers.get(\n worldEntityKey(entry.source.worldId, shadowInst.cacheKey),\n );\n let active: InstanceBufferCacheEntry | null = null;\n if (\n cached !== undefined &&\n cached.uploadedArchVersion === shadowInst.archVersion &&\n cached.uploadedByteLength === requestedBytes\n ) {\n active = cached;\n } else if (requestedBytes > 0) {\n const bufRes = runtime.device.createBuffer({\n size: requestedBytes,\n usage: bufUsage,\n mappedAtCreation: false,\n });\n if (!bufRes.ok) {\n runtime.errorRegistry.fire(bufRes.error);\n } else {\n // feat-20260619 M4 / F12: destroy the old cached buffer\n // before replacing it with the new one (D-6).\n if (cached !== undefined && !cached.buffer.isDestroyed) {\n const r = cached.buffer.destroy();\n if (!r.ok) runtime.errorRegistry.fire(r.error);\n }\n const newBuffer = new GpuBuffer(runtime.device, bufRes.value);\n active = {\n buffer: newBuffer,\n uploadedArchVersion: shadowInst.archVersion,\n uploadedByteLength: requestedBytes,\n };\n c.frameState.instanceBuffers.set(\n worldEntityKey(entry.source.worldId, shadowInst.cacheKey),\n active,\n );\n }\n }\n if (active !== null) {\n const writeRes = runtime.device.queue.writeBuffer(\n active.buffer.handle,\n 0,\n instancePayload,\n );\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n } else {\n shadowInstanceBuffer = active.buffer.handle;\n shadowInstanceCount = Math.max(1, shadowInst.instanceCount);\n }\n }\n }\n }\n\n // Bind per-entity instances BG for @group(3) (or fallback identity).\n // D-4: write end of the HDRP shadow-instances producer/consumer pair.\n // outerKey = worldEntityKey(entry.source.worldId, entry.source.entityKey),\n // handle = shadowInstanceBuffer; the HDRP main pass read end (:3820 below)\n // must look up the same (compositeKey, instBuffer) leaf or the shadow\n // instances silently drop.\n const shadowInstancesBg = resolveGeometryInstancesBindGroup(c, shadowInstanceBuffer);\n shadowPass.setBindGroup(3, shadowInstancesBg);\n // feat-20260608 M4 / w16: per-submesh shadow draw loop.\n // Only draw submeshes whose topology is triangle-list or triangle-strip\n // (line-list / point-list submeshes cast no shadow and are skipped).\n for (const sm of shadowSubmeshes) {\n if (sm.topology !== 'triangle-list' && sm.topology !== 'triangle-strip') {\n continue;\n }\n\n // Resolve the ShadowCaster PSO for the material bound to this submesh.\n // Built-in materials normally use the shared vertex-only caster, but an\n // authored `cullMode:'none'`/`frontFace` must still reach that PSO so\n // two-sided casters (such as the Three.js teapot) populate the atlas\n // from both faces. Custom ShadowCaster shaders retain their own path.\n const submeshMaterial = entry.source.materials[sm.materialSlot] ?? entry.source.material;\n const shadowDispatch = shadowDispatchByRenderableIdx\n .get(entry.renderableIndex)\n ?.get(submeshMaterial.materialHandle ?? 0);\n const entryShadowShaderId = shadowDispatch?.materialShaderId;\n const entryShadowRenderState = shadowDispatch?.renderState;\n // A skinned caster's pipeline was selected above together with its\n // two-binding mesh/palette group. Keep that pairing for every submesh;\n // resetting to the static shadow pipeline here would bind the skin\n // group against `pbr-pl` and Dawn rejects the draw at submit time.\n let entryShadowPipeline =\n entry.source.skin !== undefined ? shadowLastPipeline : shadowPipeline;\n if (\n entry.source.skin === undefined &&\n entryShadowShaderId !== undefined &&\n (entryShadowShaderId !== 'forgeax::default-shadow-caster' ||\n entryShadowRenderState !== undefined)\n ) {\n // On a cache miss (async build in flight / build failure), fall back\n // to the default PSO so the caster still writes depth rather than\n // dropping its draw.\n entryShadowPipeline =\n runtime.getMaterialShaderPipeline?.(\n entryShadowShaderId,\n false, // isHdr — shadow depth pass is always LDR\n entryShadowRenderState,\n 'triangle-list', // topology — shadow PSO targets triangle-list\n undefined, // indexFormat\n undefined, // variantSet — shadow caster has no variant axes\n 'shadow-caster', // passKind\n ) ?? shadowPipeline;\n }\n if (entryShadowPipeline !== shadowLastPipeline && entryShadowPipeline !== null) {\n shadowPass.setPipeline(entryShadowPipeline);\n shadowLastPipeline = entryShadowPipeline;\n }\n if (entry.mesh.indexed) {\n shadowPass.drawIndexed(sm.indexCount, shadowInstanceCount, sm.indexOffset, 0, 0);\n } else {\n shadowPass.draw(sm.vertexCount, shadowInstanceCount, 0, 0);\n }\n }\n }\n}\n\n/**\n * Build (or reuse) the dummy `shadow-material-singleton` @group(1) BG for the\n * spot shadow caster pass. The vertex-only shadow_caster shader never consumes\n * @group(1) but the PSO's BGL must validate. Reuses the same singleton Map\n * entry encodeDirectionalShadowPass / encodePointShadowPass write so the three paths share\n * one allocation per frame (D-6).\n */\nfunction ensureSpotShadowMaterialBg(c: _InternalRenderPipelineContext): BindGroup | null {\n const { runtime, frameState, pipelineState } = c;\n const cached = frameState.singletonMaterialCache.get('shadow-material-singleton');\n if (cached !== undefined) return cached;\n const fb = pipelineState.skylightFallback;\n const fallbackEntries: BindGroupEntry[] = buildPbrMaterialUserRegionEntries().map((entry) => {\n if (entry.buffer !== undefined) {\n return {\n binding: entry.binding,\n resource: {\n kind: 'buffer' as const,\n value: {\n buffer: pipelineState.materialUniformBuffer.buffer,\n offset: 0,\n size: STANDARD_PBR_UBO_SIZE,\n },\n },\n };\n }\n if (entry.sampler !== undefined) {\n return {\n binding: entry.binding,\n resource: { kind: 'sampler' as const, value: pipelineState.defaultSampler },\n };\n }\n return {\n binding: entry.binding,\n resource: {\n kind: 'textureView' as const,\n value:\n entry.binding === 6\n ? pipelineState.defaultNormalTextureView\n : pipelineState.fallbackTextureView,\n },\n };\n });\n const merged =\n fb !== null\n ? assembleMaterialWithSkylightEntries(fallbackEntries, {\n irradianceView: fb.irradianceView,\n irradianceSampler: fb.sampler,\n prefilterView: fb.prefilterView,\n prefilterSampler: fb.sampler,\n brdfLutView: fb.brdfLutView,\n brdfLutSampler: fb.sampler,\n intensityBuffer: fb.intensityBuffer,\n })\n : fallbackEntries;\n const r = runtime.device.createBindGroup({\n label: 'shadow-material-bg',\n layout: pipelineState.materialBindGroupLayout,\n entries: merged,\n });\n if (!r.ok) {\n runtime.errorRegistry.fire(r.error);\n return null;\n }\n c.bindGroupCounts.createBindGroup += 1;\n c.bindGroupCounts.keys.push('shadow-material-singleton');\n frameState.singletonMaterialCache.set('shadow-material-singleton', r.value);\n return r.value;\n}\n","import type { World } from '@forgeax/engine-ecs';\nimport { probeVideoHighPerfUpload } from '@forgeax/engine-graphics-extras';\nimport {\n type BindGroup,\n RhiError,\n type RhiRenderPassEncoder,\n type TextureView,\n} from '@forgeax/engine-rhi';\nimport type { Handle, PassKind, PassSelector } from '@forgeax/engine-types';\nimport { createHdrpUnifiedBindGroup, getOrCreateHdrpBuffers } from '../hdrp-buffers';\nimport { getOrCreateIblCache } from '../ibl/IblPipelineCache';\nimport type { SkylightBindGroupResources } from '../ibl/skylight-bind-group';\nimport { buildBeginRenderPassDescriptor, standardTopologyBindGroupReady } from '../pipeline-spec';\nimport { POINTS_LINES_MATERIAL_SHADER_ID } from '../points-lines/record';\nimport type { ReflectionProbeSelectionResult } from '../reflection/projection';\nimport type { RenderRecordPhase } from '../render-contract';\nimport type { MaterialSnapshot } from '../render-system-extract';\nimport { resolveReflectionProbeBinding } from './frame-lighting';\nimport { recordGeometryDraws } from './main-pass-geometry';\nimport {\n applyMaterialTextureUvScales,\n applyParamSnapshotToUbo,\n buildPerSubmeshMaterialBg as buildPerSubmeshMaterialBgImpl,\n detectNineSliceScaleTooSmall,\n type PerSubmeshMaterialBgDeps,\n residentTextureView,\n writePbrMaterialUboPayload,\n} from './main-pass-material';\nimport { recordSpritePass } from './main-pass-sprite-draws';\nimport type { _InternalRenderPipelineContext } from './render-context';\nimport { MATERIAL_PER_ENTITY_STRIDE, STANDARD_PBR_UBO_SIZE } from './render-context';\nimport {\n buildMatchedMaterialHandlesByRenderable,\n buildMatchedRenderableIndices,\n} from './shadow-pass';\n\nexport function standardReflectionProbeIndex(\n selection: ReflectionProbeSelectionResult,\n): number | undefined {\n return resolveReflectionProbeBinding(selection).probeIndex;\n}\n\nconst ZERO_SKYLIGHT_PAYLOAD = new Float32Array([0, 0, 0, 0, 0, 0, 0, 1]);\n\nexport type MainPassOptions = {\n readonly colorViews?: readonly (TextureView | null)[];\n readonly colorFormats?: readonly GPUTextureFormat[];\n readonly depthView?: TextureView | null;\n readonly passKind?: PassKind;\n readonly clearColor?: readonly [number, number, number, number];\n readonly recordMode?: 'opaque' | 'transmission' | 'transparent';\n readonly transmissionBackdropView?: TextureView | null;\n};\n\nconst TRANSMISSION_VARIANT_SET = 'TRANSMISSION_AVAILABLE=true';\n\nfunction isTransmissionMaterial(material: MaterialSnapshot): boolean {\n return (\n material.materialShaderId === 'forgeax::default-standard-pbr' &&\n typeof material.paramSnapshot?.transmission === 'number' &&\n material.paramSnapshot.transmission > 0\n );\n}\n\nfunction matchesRecordMode(\n material: MaterialSnapshot,\n mode: 'opaque' | 'transmission' | 'transparent',\n): boolean {\n const transmission = isTransmissionMaterial(material);\n if (mode === 'transmission') return transmission;\n if (mode === 'transparent') return material.transparent === true && !transmission;\n return !transmission && material.transparent !== true;\n}\n\nfunction matchedMaterialsForRecordMode(\n c: _InternalRenderPipelineContext,\n matchedMaterials: ReadonlyMap<number, ReadonlySet<number>> | null,\n mode: 'opaque' | 'transmission' | 'transparent' | undefined,\n): ReadonlyMap<number, ReadonlySet<number>> | null {\n if (mode === undefined) return matchedMaterials;\n const filtered = new Map<number, ReadonlySet<number>>();\n for (const entry of c.validatedOrdered) {\n const dispatchHandles = matchedMaterials?.get(entry.renderableIndex);\n if (matchedMaterials !== null && dispatchHandles === undefined) continue;\n const candidateHandles =\n dispatchHandles ??\n (mode === 'transmission'\n ? []\n : entry.source.materials.map((material) => material.materialHandle ?? 0));\n const handles = new Set<number>();\n for (const handle of candidateHandles) {\n const material =\n entry.source.materials.find((candidate) => (candidate.materialHandle ?? 0) === handle) ??\n entry.source.material;\n if (matchesRecordMode(material, mode)) handles.add(handle);\n }\n if (handles.size > 0) filtered.set(entry.renderableIndex, handles);\n }\n return filtered;\n}\n\n/**\n * feat-20260529-rendergraph-pass-abstraction M4 / w13b: main forward\n * (geometry) pass recording, extracted verbatim from recordFrame. Uses the\n * SHARED frame encoder (c.encoder); the geometry + optional LDR sprite-split\n * sub-pass write into geometryColorView (HDR target or swap-chain view).\n * Driven by the render-graph 'main' pass execute closure.\n */\nexport function recordMainPass(\n c: _InternalRenderPipelineContext,\n selector?: PassSelector,\n options?: MainPassOptions,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const {\n runtime,\n world,\n store,\n pipelineState,\n encoder,\n clear,\n geometryColorView,\n geometryDepthView,\n validatedOrdered,\n viewBindGroup,\n viewBindGroupDynamicOffset = 0,\n meshBindGroup,\n frameState,\n bindGroupCounts,\n skylight,\n skylightCount,\n skyboxActive,\n splitLdrSprite,\n msaaActive,\n geometryColorResolveView,\n dispatch,\n hdrpClusterBindGroup,\n materialSlotIndices,\n materialSlots,\n materialSlotOwners,\n materialSlotCount,\n } = c;\n // bug-20260615 M3 / m3-1: sampleCount is threaded through every\n // getMaterialShaderPipeline call site so the cache key / builder\n // disambiguate count=1 vs count=4 PSOs. Derived from the per-camera\n // msaaActive boolean (already on the context).\n const sampleCount = msaaActive ? 4 : 1;\n const passKind = options?.passKind ?? 'forward';\n const recordMode = options?.recordMode;\n const transmissionBackdropView = options?.transmissionBackdropView;\n if (recordMode === 'transmission' && transmissionBackdropView == null) {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'transmissionBackdropView != null for transmission record mode',\n hint: 'the typed Standard transmission pass must resolve its private backdrop view',\n });\n }\n const colorViews = options?.colorViews ?? [geometryColorView];\n const colorFormats = options?.colorFormats ?? [\n (c.tonemapActive || c.transparentColorFormat === 'rgba16float'\n ? 'rgba16float'\n : pipelineState.colorAttachmentFormat) as GPUTextureFormat,\n ];\n const targetDepthView = options?.depthView ?? geometryDepthView;\n const clearColor = options?.clearColor ?? clear;\n // feat-20260623-world-space-video-asset M4 / w17 (D-2 / AC-09): high-perf\n // GPUExternalTexture upload availability for video sources, resolved by the\n // explicit RhiCaps-based capability probe. The probe checks\n // backendKind==='webgpu' AND `importExternalTexture` method presence; the\n // latter is absent today (OOS-5), so this is false and the general\n // copyExternalImageToTexture path (w16) is the sole route. The branch exists\n // so the AC-09 two-path reserved hook is code-review-verifiable, not a TODO.\n const videoHighPerfAvailable = probeVideoHighPerfUpload(runtime.device);\n // The prepared Standard topology is the frame authority. Do not infer the\n // shader lane from a resource that may be absent after a failed rebuild: a\n // clustered frame with no unified group must fail closed, never fall back to\n // a direct-lighting shader with an incompatible group(2) contract.\n const clusteredLighting = c.standardLighting?.kind === 'clustered';\n // A clustered topology still needs the unified group for every actual\n // material draw. A camera-only/clear frame has no group(2) consumer yet;\n // treating that harmless absence as a frame error would make the full\n // clustered ABI incompatible with valid zero-renderable frames.\n const clusteredBindGroupMissing =\n validatedOrdered.length > 0 &&\n !standardTopologyBindGroupReady(c.standardLighting, hdrpClusterBindGroup);\n // Standard clustered lighting swaps the\n // group(2) bindGroup for the unified 7-entry layout (mesh SSBO at binding 0\n // + cluster 4 buffer at bindings 3..6). The dynamic offset\n // (`i * MESH_PER_ENTITY_STRIDE`) stays valid because the unified BGL binds\n // the SAME mesh SSBO at binding 0; the cluster-forward shader reads the\n // cluster bindings off the rest of the layout. Plan D-1 (URP path zero\n // change) is preserved — when clustered lighting is not selected the\n // ordinary mesh bind group path runs verbatim.\n // feat-20260612-hdrp-ssao wiring fix: when the HDRP forward pass resolved a\n // real `ssaoBlurred` view (stashed on ctx by the pass execute closure), build\n // the unified group(2) bind group with that view at binding 7 so fs_main reads\n // the actual occlusion factor instead of the 1x1 white fallback. The default\n // `hdrpClusterBindGroup` (built ahead of graph.execute) always carries the\n // fallback because the transient SSAO texture does not exist that early.\n // Built per frame (the SSAO target is a graph transient, so no cross-frame\n // cache); HDRP-only and SSAO-only, so URP and SSAO-off paths are untouched.\n let hdrpSsaoBindGroup: BindGroup | null = null;\n if (clusteredLighting && hdrpClusterBindGroup !== null && c.hdrpSsaoBlurredView !== undefined) {\n const hdrpBuffers = getOrCreateHdrpBuffers(\n runtime,\n frameState.installedPipelineConfig?.clusterGrid,\n );\n if (hdrpBuffers !== null) {\n hdrpSsaoBindGroup = createHdrpUnifiedBindGroup(\n runtime,\n hdrpBuffers,\n pipelineState.meshStorageBuffer.buffer,\n { enabled: true, ssaoBlurredView: c.hdrpSsaoBlurredView },\n );\n }\n }\n const meshGroup2: BindGroup | null = clusteredLighting\n ? (hdrpSsaoBindGroup ?? hdrpClusterBindGroup)\n : meshBindGroup;\n // ── Geometry (main colour) pass ──────────────────────────────────\n // D-2: tracks whether the geometry pass was explicitly ended inside\n // the `if (validatedOrdered.length > 0)` block (sprite split path),\n // to avoid a double-end at the unconditional `pass.end()` below.\n let geometryPassEnded = false;\n // feat-20260531-skybox-env-background M2 / w8: condition main colour\n // loadOp on skyboxActive (AC-05). When skybox is active, the skybox\n // pass writes the far plane + cubemap colour to hdrColor before main;\n // main must load (not clear) to composite geometry on top. Depth\n // loadOp stays 'clear' -- skybox does not write depth, so main's\n // depth test naturally covers skybox pixels with foreground geometry.\n const mainColorLoadOp = skyboxActive ? 'load' : 'clear';\n // feat-20260604 M2 / w9-w10: MSAA resolve placement. When MSAA is active the\n // geometry pass writes a count=4 multisample target. The resolve to the\n // single-sample output (LDR swap-chain view / HDR hdrColor) happens at the\n // LAST pass that writes that multisample target: the main pass itself when\n // there is no LDR sprite split, or the sprite sub-pass end when there is\n // (F-1 -- geometry + sprites share one multisample texture; resolving at the\n // main pass would drop the sprites drawn after). The sprite sub-pass is\n // LDR-only, so under HDR the main pass always resolves.\n const mainPassResolves =\n passKind === 'forward' && msaaActive && geometryColorResolveView !== null && !splitLdrSprite;\n // forward main pass: depth24plus-stencil8 auto-emits stencil ops via the\n // helper's stencil-op gate (plan-strategy M4 R3/R5 stencil-op SSOT).\n // mainColorLoadOp toggles between 'clear' and 'load' (skyboxActive case).\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n {\n colorFormats,\n depthFormat: 'depth24plus-stencil8',\n sampleCount: msaaActive ? 4 : 1,\n },\n {\n colorViews,\n depthView: targetDepthView,\n ...(mainPassResolves ? { resolveTargets: [geometryColorResolveView] } : {}),\n },\n passKind,\n {\n colorLoadOp: mainColorLoadOp,\n clearColor: {\n r: clearColor[0] ?? 0,\n g: clearColor[1] ?? 0,\n b: clearColor[2] ?? 0,\n a: clearColor[3] ?? 1,\n },\n },\n ) as never,\n );\n\n // Geometry submission block: setPipeline + 4 bind groups + per-entity\n // material uploads + drawIndexed.\n\n // feat-20260609 M2: filter entities by pass selector.\n const matchedIndices =\n selector !== undefined ? buildMatchedRenderableIndices(dispatch, selector) : null;\n const selectorMatchedMaterials =\n selector !== undefined ? buildMatchedMaterialHandlesByRenderable(dispatch, selector) : null;\n const matchedMaterials = matchedMaterialsForRecordMode(c, selectorMatchedMaterials, recordMode);\n const recordContext =\n recordMode === undefined\n ? c\n : {\n ...c,\n splitLdrSprite: recordMode === 'transparent' ? false : c.splitLdrSprite,\n validatedOrdered: c.validatedOrdered.map((entry) => ({\n ...entry,\n ...(recordMode === 'transmission' ? { variantSet: TRANSMISSION_VARIANT_SET } : {}),\n })),\n };\n\n if (clusteredBindGroupMissing) {\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'clustered Standard frame has a unified group(2) BindGroup',\n hint: 'repair the clustered buffer/layout admission before retrying the frame; direct URP fallback is unsafe',\n }),\n );\n }\n\n if (validatedOrdered.length > 0 && !clusteredBindGroupMissing) {\n // feat-20260518-pbr-direct-lighting-mvp M5 / w22.10 (D-4 + D-9 +\n // AC-07 std140): per-entity material slice grew from 32 B (legacy\n // baseColor:vec4 + metallic + roughness + 8B padding) to 48 B\n // mirroring the post-w22.10 `Material` WGSL struct field-for-field\n // (see STANDARD_PBR_UBO_SIZE JSDoc in render-system.ts). The dynamic-\n // offset stride is MATERIAL_PER_ENTITY_STRIDE; the BindGroup entry's\n // `size` remains the derived material payload size.\n const MATERIAL_SLICE = STANDARD_PBR_UBO_SIZE;\n // feat-20260515 M3 / T-M3-05 (research F-6 fix): materialBindGroup now\n // carries 3 entries -- the per-entity material UBO (binding 0,\n // dynamic-offset retained from D-P9), the default sampler (binding 1,\n // pipelineState.defaultSampler from createRenderer; research F-5\n // linear min/mag/mipmap + repeat addressMode), and the texture-view\n // (binding 2, resolved from MaterialSnapshot.baseColorTexture via\n // AssetRegistry.getTextureGpuView when present, falling back to the\n // pipelineState.fallbackTextureView 1x1 white pixel).\n //\n // The first validated renderable's material is sampled to choose the\n // texture-view (M3 milestone simplification; M5 lifts this to\n // per-entity slot writes once UV-driven sampling lands).\n //\n // feat-20260517-merge-mesh-renderer-material-renderer M3 / w10\n // (this commit): the prior structural cast over `firstMaterial`\n // (used to reach `baseColorTexture` before the snapshot carried\n // it as a first-class field) is removed in favour of direct\n // snapshot field access. `MaterialSnapshot` (extract-stage SSOT)\n // already declares `baseColorTexture` (M2 / w6); record reads it\n // directly with no asset registry round-trip and no cast --\n // Pipeline Isolation: extract owns the asset to snapshot\n // translation; record consumes the snapshot POD only (charter\n // proposition 5 consistent abstraction; AC-07 reverse-grep gate\n // `scripts/forgeax/check-render-record-no-material-asset-get.mjs`\n // forbids both the cast pattern and a direct material asset\n // typed-lookup regrowth in this file).\n // bug-20260522-per-entity-material-texture-binding D-1/D-2:\n // the pre-loop `firstMaterial` / `materialTextureView` / `\n // baseMaterialEntries` / single shared `materialBindGroup` are\n // removed. Each entity now creates its own per-entity material BG\n // inside the draw loop, resolving binding=2 from its own\n // `entry.source.material.baseColorTexture` (mirroring sprite path).\n //\n // feat-20260520-skylight-ibl-cubemap M3 round-4 / t48 amend: the\n // 14-entry merged BG (7 material + 7 Skylight) is now assembled per\n // entity inside the draw loop. The Skylight part stays scene-level\n // (single `skylightResources` resolved once below); only the first 7\n // material entries are rebuilt per-entity with the correct\n // per-entity textureView at binding=2.\n const skylightFallback = pipelineState.skylightFallback;\n if (skylightFallback === null) {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected: 'pipelineState.skylightFallback != null when PBR pipeline is active',\n hint: 'createRenderer must allocate skylightFallback alongside the PBR pipeline (D-5 round-4)',\n });\n }\n // feat-20260520-skylight-ibl-cubemap M4 round-4 / t60 (D-5 round-4):\n // select active vs fallback Skylight resources by `skylightCount` from\n // the extract stage. Active path reaches into the per-device\n // `IblPipelineCache` slots (irradianceView / prefilterView / brdfLutView)\n // populated by the internal equirect-to-cubemap projection; fallback uses the\n // 1x1-zero identity bundle that converges ambient to 0 (D-4 physical\n // convergence -- no `if (hasSkylight)` shader branch).\n // The samplers are reused from `skylightFallback.sampler` for both\n // paths (linear / clamp-to-edge is correct for IBL cube + 2D LUT\n // sampling either way). The intensity uniform is rewritten per-frame\n // when active so `sampleIblSpecular * intensity` carries the user's\n // Skylight.intensity value; fallback keeps intensity=0 (createSkylightFallback\n // seed) so ambient = 0 even when the same buffer is shared.\n let activeViews: { irr: TextureView; pref: TextureView; brdf: TextureView } | undefined;\n // Per-frame Skylight uniform: std140 32 B = [intensity, colorR, colorG,\n // colorB, rotation quaternion]. Default to all-zero so a transition from \"has Skylight\" ->\n // \"no Skylight\" does not leak the prior frame's ambient (intensity 0\n // muzzles everything, including the white fallback irradiance cube).\n runtime.device.queue.writeBuffer(skylightFallback.intensityBuffer, 0, ZERO_SKYLIGHT_PAYLOAD);\n if (skylight !== undefined && skylightCount >= 1) {\n // A Skylight exists. Write its intensity + color regardless of whether\n // a cubemap is bound: with a cubemap the IBL views below light the\n // ambient; WITHOUT one, the white fallback irradiance cube + this color\n // give an instant solid-color ambient (downstream integration #4) with\n // no async precompute. The white fallback only contributes when a\n // Skylight is present because the zero-payload above sets intensity 0\n // when no Skylight exists.\n const [cr, cg, cb] = skylight.color;\n const [qx, qy, qz, qw] = skylight.rotation;\n const uniformPayload = new Float32Array([skylight.intensity, cr, cg, cb, qx, qy, qz, qw]);\n runtime.device.queue.writeBuffer(skylightFallback.intensityBuffer, 0, uniformPayload);\n const cache = getOrCreateIblCache(runtime.deviceScope);\n if (\n cache.irradianceView !== undefined &&\n cache.prefilterView !== undefined &&\n cache.brdfLutView !== undefined\n ) {\n activeViews = {\n irr: cache.irradianceView,\n pref: cache.prefilterView,\n brdf: cache.brdfLutView,\n };\n }\n }\n const skylightResources =\n activeViews !== undefined\n ? {\n irradianceView: activeViews.irr,\n irradianceSampler: skylightFallback.sampler,\n prefilterView: activeViews.pref,\n prefilterSampler: skylightFallback.sampler,\n brdfLutView: activeViews.brdf,\n brdfLutSampler: skylightFallback.sampler,\n intensityBuffer: skylightFallback.intensityBuffer,\n }\n : {\n irradianceView: skylightFallback.irradianceView,\n irradianceSampler: skylightFallback.sampler,\n prefilterView: skylightFallback.prefilterView,\n prefilterSampler: skylightFallback.sampler,\n brdfLutView: skylightFallback.brdfLutView,\n brdfLutSampler: skylightFallback.sampler,\n intensityBuffer: skylightFallback.intensityBuffer,\n };\n // Per-entity material uploads (D-P9 retained path).\n // feat-20260613 fix-issue-1 (D-8 channelMap split): the payload mirrors\n // the post-split sidecar paramSchema for default-standard-pbr (14 entries\n // packed std140 across a 96 B schema tail):\n // [0..3] baseColor vec4<f32> (offset 0)\n // [4] metallic f32 (offset 16)\n // [5] roughness f32 (offset 20)\n // [6] metallicChannel f32 (offset 24)\n // [7] roughnessChannel f32 (offset 28)\n // [8] aoChannel f32 (offset 32)\n // [9] extraChannel f32 (offset 36)\n // [12..14] emissive vec3<f32> (offset 48, vec3 align=16)\n // [15] emissiveIntensity f32 (offset 60)\n // [16] occlusionStrength f32 (offset 64)\n // Channel selectors default to (B,G,R,_) = (2,1,0,0) per glTF 2.0\n // KHR_materials_pbrSpecularGlossiness ARM packing; the fragment casts\n // each f32 to u32 at the pick_channel call site. The full 128 B bind window is\n // overwritten per-entity so unlit entities still produce a deterministic\n // payload (charter P3 explicit failure: zero-init via fresh ArrayBuffer).\n //\n // Material snapshots are interned by extract-owned identity before this\n // pass. Repeated scene instances therefore share one 256-byte UBO slot;\n // materialSlotIndices maps each authored submesh material to that slot.\n // feat-city-glb Bug 5 (per-submesh transparency): shared per-submesh\n // material bind-group assembly, called by BOTH the geometry pass and the\n // LDR blend sub-pass so a transparent PBR submesh binds the identical\n // metallic/roughness/normal/emissive/occlusion + Skylight layout\n // the geometry pass uses (the sub-pass previously bound a sprite-only BG,\n // which cannot render a PBR decal). Captures only frame-stable closure\n // state; the caller passes the per-submesh material snapshot + entityKey\n // (for video texture routing) and sets the dynamic UBO offset itself.\n const perSubmeshMaterialBgDeps: PerSubmeshMaterialBgDeps = {\n runtime,\n pipelineState,\n world,\n store,\n materialSlice: MATERIAL_SLICE,\n videoHighPerfAvailable,\n skylightResources,\n resolveRenderTargetTextureSource: runtime.resolveRenderTargetTextureSource,\n resolveReflectionProbeResources: (materialWorld, entityKey) => {\n const reflectionProbes = c.reflectionProbes;\n if (reflectionProbes === undefined) return undefined;\n const selection = reflectionProbes.selections.get(`${materialWorld.identity}:${entityKey}`);\n if (selection === undefined) return undefined;\n const binding = resolveReflectionProbeBinding(selection, reflectionProbes.table);\n if (binding.useSkylight || binding.probeIndex === undefined) return undefined;\n const row = reflectionProbes.table.rows.find(\n (candidate) => candidate.index === binding.probeIndex,\n );\n if (\n row?.filteredView === undefined ||\n row.sampler === undefined ||\n row.uniformBuffer === undefined\n ) {\n return undefined;\n }\n const probeResources: SkylightBindGroupResources = {\n irradianceView: skylightResources.irradianceView,\n irradianceSampler: skylightResources.irradianceSampler,\n prefilterView: row.filteredView,\n prefilterSampler: row.sampler,\n brdfLutView: skylightResources.brdfLutView,\n brdfLutSampler: skylightResources.brdfLutSampler,\n intensityBuffer: row.uniformBuffer,\n };\n return probeResources;\n },\n materialBgShared: frameState.materialBgShared,\n materialBgAssemblyCache: c.materialBgAssemblyCache,\n bindGroupCounts,\n ...(transmissionBackdropView === undefined ? {} : { transmissionBackdropView }),\n };\n const buildPerSubmeshMaterialBg = (\n submeshMaterial: MaterialSnapshot,\n entityKey: number,\n materialWorld: World = world,\n ): BindGroup =>\n buildPerSubmeshMaterialBgImpl(\n perSubmeshMaterialBgDeps,\n submeshMaterial,\n entityKey,\n materialWorld,\n );\n\n const cachedMaterialUboPayload = c.materialUboPayloadCache;\n let materialUboPayload: Uint8Array;\n if (\n cachedMaterialUboPayload?.materialSlots === materialSlots &&\n cachedMaterialUboPayload.materialSlotCount === materialSlotCount\n ) {\n materialUboPayload = cachedMaterialUboPayload.payload;\n } else {\n materialUboPayload = new Uint8Array(materialSlotCount * MATERIAL_PER_ENTITY_STRIDE);\n const slotPayload = new Uint8Array(STANDARD_PBR_UBO_SIZE);\n const slotPayloadF32 = new Float32Array(\n slotPayload.buffer,\n slotPayload.byteOffset,\n slotPayload.byteLength / 4,\n );\n for (let materialSlot = 0; materialSlot < materialSlots.length; materialSlot += 1) {\n const mat = materialSlots[materialSlot];\n const entry = validatedOrdered[materialSlotOwners[materialSlot] ?? -1];\n if (mat === undefined || entry === undefined) continue;\n\n // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w13 (D-2):\n // single unified Material UBO write path. Sprite materials now flow\n // through the same `buildPbrMaterialUboPayload` baseline +\n // `applyParamSnapshotToUbo` generic std140 overlay every other\n // paramSchema-driven material uses. Extract folds the sprite-specific\n // user inputs into the UBO-aligned paramSnapshot vec4 entries\n // (colorTint / region / pivotAndSize / slicesAndMode); the writer\n // walks `derive(paramSchema).uboLayout.entries` and writes each at\n // its std140 offset. The legacy sprite-specific UBO builder + the\n // sprite-vs-PBR branch are gone (AC-03).\n writePbrMaterialUboPayload(slotPayloadF32, mat);\n // Schema-driven paramSnapshot overlay generalised in feat-20260625\n // M1 / w3: the writer walks `derive(paramSchema).uboLayout.entries`\n // and writes each numeric field at its std140 offset (plan-strategy\n // section 2 D-2). The engine's stock PBR material ships\n // `paramSnapshot: undefined`, so this is a no-op on the default\n // PBR path -- the explicit field writes in buildPbrMaterialUboPayload\n // already cover every byte. User shaders carrying a paramSnapshot\n // (including the post-ablation sprite path) get their fields\n // written at the derive-computed offsets; R-H gate keeps the\n // helper snapshot-only, no asset get.\n const materialShaderId = mat.materialShaderId;\n const schema =\n mat.materialParamSchema ??\n (materialShaderId !== undefined ? runtime.getParamSchema?.(materialShaderId) : undefined);\n applyParamSnapshotToUbo(slotPayloadF32, schema, mat.paramSnapshot);\n applyMaterialTextureUvScales(slotPayloadF32, mat, world);\n // Missing-texture detection: structural debug-pink fallback overrides\n // the baseColor/colorTint slot when a bound baseColorTexture handle\n // resolves to no GPU view. Runs for every textured material path\n // (sprite / sprite-lit / standard-pbr / pbr-skin / unlit) — the bound\n // texture would otherwise silently fall back to the 1x1 white view in\n // the per-submesh BG (main-pass-material.ts), rendering flat with no\n // warn / RhiError. Mirroring the telemetry here makes a missing/failed\n // GLB texture immediately diagnosable instead of a silent flat render\n // (feat-future-pbr-missing-texture-fallback-explicit; feedback\n // 2026-07-04-glb-pbr-textures-not-applied-flat-render).\n //\n // Reads only `mat.baseColorTexture` + the GPU view registry (plan R-H\n // gate: no asset.get<MaterialAsset> reach-back). The debug-pink write\n // lands on f32[0..2], which is baseColor.rgb for the PBR/skin UBO and\n // colorTint.rgb for the sprite UBO — same offset, so one override\n // covers both.\n {\n const matHandleRaw = mat.baseColorTexture as Handle<'TextureAsset', 'shared'> | undefined;\n if (matHandleRaw !== undefined) {\n const view = residentTextureView(entry.world ?? world, store, runtime, matHandleRaw);\n if (view === undefined) {\n const rawId: number = matHandleRaw;\n if (!frameState.warnedMissingBaseColorTextureHandles.has(rawId)) {\n frameState.warnedMissingBaseColorTextureHandles.add(rawId);\n console.warn(\n `[forgeax] baseColor texture ${rawId} missing GPU view, rendering debug pink (shader=${materialShaderId ?? '<none>'} entityIndex=${entry.renderableIndex})`,\n );\n }\n runtime.errorRegistry.fire(\n new RhiError({\n code: 'asset-not-registered',\n expected: 'material baseColor TextureAsset uploaded to GPU',\n hint: 'register + uploadTexture the baseColor texture before draw([world], { cameraOwner: 0, resourceOwner: 0 }); rendering falls back to debug pink until then',\n detail: { assetHandle: rawId },\n }),\n );\n // Debug pink override on slot 0 baseColor/colorTint.rgb (alpha preserved).\n slotPayloadF32[0] = 1.0;\n slotPayloadF32[1] = 0.4;\n slotPayloadF32[2] = 0.7;\n }\n }\n }\n\n materialUboPayload.set(slotPayload, materialSlot * MATERIAL_PER_ENTITY_STRIDE);\n }\n\n // Material UBO slots can share one snapshot identity, but nine-slice\n // validity depends on each entity's transform. Preserve diagnostics per\n // renderable instead of inheriting the first owner of a shared slot.\n for (const entry of validatedOrdered) {\n const mat = entry.source.material;\n const materialShaderId = mat.materialShaderId;\n if (materialShaderId !== 'forgeax::sprite' && materialShaderId !== 'forgeax::sprite-lit')\n continue;\n const slicesAndMode = mat.paramSnapshot?.slicesAndMode as readonly number[] | undefined;\n if (slicesAndMode === undefined || slicesAndMode.length < 4) continue;\n const slicesArr: readonly [number, number, number, number] = [\n slicesAndMode[0] ?? 0,\n slicesAndMode[1] ?? 0,\n slicesAndMode[2] ?? 0,\n slicesAndMode[3] ?? 0,\n ];\n if (slicesArr[0] === 0 && slicesArr[1] === 0 && slicesArr[2] === 0 && slicesArr[3] === 0)\n continue;\n detectNineSliceScaleTooSmall(\n entry.source.transform.world,\n slicesArr,\n entry.renderableIndex,\n frameState.warnedNineSliceScaleEntities,\n runtime.metrics,\n );\n }\n c.materialUboPayloadCache = {\n materialSlots,\n materialSlotCount,\n payload: materialUboPayload,\n };\n }\n\n // All material slots are staged before the first geometry draw. One\n // stride-shaped upload preserves every dynamic offset while avoiding one\n // queue call per material; the RHI still validates alignment and bounds at\n // this single owner-level write boundary.\n const materialUboUpload = runtime.device.queue.writeBuffer(\n pipelineState.materialUniformBuffer.buffer,\n 0,\n materialUboPayload,\n );\n if (!materialUboUpload.ok) throw materialUboUpload.error;\n // Static material resources are a property of the frame-local material\n // slot, not of each submesh draw. Resolve them once here so the geometry\n // loop only selects a prepared binding. Video fields remain entity-bound:\n // their current frame view is keyed by entityKey and must be resolved at\n // the draw site.\n const preparedMaterialBindGroups = new Array<BindGroup | undefined>(materialSlotCount);\n for (let materialSlot = 0; materialSlot < materialSlotCount; materialSlot += 1) {\n const material = materialSlots[materialSlot];\n if (material === undefined || (material.videoTextureFields?.size ?? 0) > 0) continue;\n const owner = validatedOrdered[materialSlotOwners[materialSlot] ?? -1];\n if (owner === undefined) continue;\n preparedMaterialBindGroups[materialSlot] = buildPerSubmeshMaterialBg(\n material,\n owner.source.entityKey,\n owner.world ?? world,\n );\n }\n const resolveMaterialBindGroup = (\n materialSlot: number,\n material: MaterialSnapshot,\n entityKey: number,\n materialWorld: World = world,\n ): BindGroup =>\n material.materialShaderId !== POINTS_LINES_MATERIAL_SHADER_ID\n ? (preparedMaterialBindGroups[materialSlot] ??\n buildPerSubmeshMaterialBg(material, entityKey, materialWorld))\n : buildPerSubmeshMaterialBg(material, entityKey, materialWorld);\n\n pass.setBindGroup(0, viewBindGroup as BindGroup, [viewBindGroupDynamicOffset, 0]);\n\n // Track which (mesh-vertex-buffer, mesh-index-buffer, pipeline) combo\n // was last bound so consecutive entities sharing the same combo skip\n // the redundant rebinds (cheap GPU cost; net wins on workloads where\n // most entities share BUILTIN_CUBE + unlit). Initial nulls force the\n // first iteration to bind unconditionally.\n // M-3 / w12: vertexBuffer/indexBuffer state locals migrate to GpuBuffer.\n const recordGeometry = (): void => {\n recordGeometryDraws(\n recordContext,\n pass,\n matchedMaterials,\n materialSlotIndices,\n sampleCount,\n meshGroup2,\n meshBindGroup,\n resolveMaterialBindGroup,\n passKind,\n );\n };\n if (c.profilePhase === undefined) {\n recordGeometry();\n } else {\n const passName = passKind === 'deferred' ? 'g-buffer' : 'forward';\n c.profilePhase(\n `record/graph-execute/${passName}/geometry-loop` as RenderRecordPhase,\n recordGeometry,\n );\n }\n\n // D-2: LDR sprite pass. Runs after the geometry pass when there are\n // sprite entities in the draw list and the LDR path is active.\n // The geometry pass used the bgra8unorm-srgb sRGB view (hardware sRGB\n // encoding for unlit/standard/pbr output). The sprite pass uses the\n // bgra8unorm storage view (loadOp=load) so the sprite LDR pipeline\n // (target=bgra8unorm, blend=premultiplied-alpha) can write over the\n // already-encoded geometry pixels. Depth is loaded from the geometry\n // pass so sprite-vs-mesh occlusion (depthCompare=less-equal) is\n // preserved (plan-strategy §2 D-2 + §4 R-4).\n if (passKind === 'forward' && recordMode === undefined) {\n geometryPassEnded = recordSpritePass(\n c,\n pass,\n matchedIndices,\n materialSlotIndices,\n sampleCount,\n resolveMaterialBindGroup,\n skylightResources,\n graphPass,\n );\n }\n } // end if (validatedOrdered.length > 0) -- Case E falls through to pass.end()\n\n if (!geometryPassEnded && graphPass === undefined) {\n pass.end();\n }\n}\n\nexport function encodeMainPass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n selector?: PassSelector,\n options?: MainPassOptions,\n): void {\n recordMainPass(c, selector, options, pass);\n}\n","import type { ResolveContext } from '@forgeax/engine-render-graph';\nimport { RhiError, type RhiRenderPassEncoder, type TextureView } from '@forgeax/engine-rhi';\nimport { toShared } from '@forgeax/engine-types';\nimport { buildBeginRenderPassDescriptor } from '../pipeline-spec';\nimport { FXAA_POST_PROCESS_ID } from '../render-contract';\nimport { resolveOutputDither } from '../render-pipeline';\nimport type { BloomFrameReceipts } from './frame-snapshot';\nimport { getOrCreateFromChain } from './mesh-ssbo';\nimport type { _InternalRenderPipelineContext } from './render-context';\nimport { VIEW_UNIFORM_BYTES } from './view-ubo';\n\n/**\n * feat-20260531-skybox-env-background M2 / w8: skybox pass recording stub.\n * Renders a fullscreen triangle that samples a cubemap using the camera's\n * inverseViewProj from the View UBO and writes the result to the hdrColor\n * render target. The pass runs after shadow and before main (D-1 topology).\n *\n * This stub early-returns when skyboxActive is false -- the actual execute\n * body is implemented in M3 / w16 (recordSkyboxPass execute). The render-\n * graph still declares the pass so the compile() step validates the\n * dependency edges (shadow -> skybox -> main) even before the execute\n * body is filled in.\n */\nexport function recordSkyboxPass(\n c: _InternalRenderPipelineContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n // Early-return when skybox is not active (no SkyboxBackground entity,\n // or tonemap is disabled -- plan-strategy D-2 NOTE). The graph still\n // compiles because the pass declaration is unconditional; only the\n // execute body is gated on skyboxActive.\n if (!c.skyboxActive) return;\n const skyboxSnapshot = c.skybox;\n if (skyboxSnapshot === undefined) return;\n\n const { runtime, store, encoder, pipelineState } = c;\n\n // Guard: hdrColorView must be allocated (tonemapActive implies it)\n const hdrColorView = pipelineState.perPassResources.hdrColorView;\n if (graphPass === undefined && hdrColorView === null) return;\n\n // feat-20260604 M2 / w10: under MSAA the skybox + main passes share the\n // count=4 multisample target (hdrColorMsaa); only the main pass (last to\n // write) resolves to the single-sample hdrColor (D-8 -- avoids a wasteful\n // mid-chain resolve). The skybox pass writes the multisample target with no\n // resolveTarget and uses the count=4 skybox pipeline variant.\n const skyboxColorView =\n graphPass === undefined\n ? c.msaaActive\n ? pipelineState.perPassResources.hdrColorMsaaView\n : hdrColorView\n : null;\n if (graphPass === undefined && skyboxColorView === null) return;\n\n // Guard: pipeline resources must exist (null when manifest has no\n // skybox entry -- legacy manifests continue to boot)\n const skyboxPipeline = c.msaaActive\n ? pipelineState.perPassResources.skyboxPipelineMsaa\n : pipelineState.perPassResources.skyboxPipeline;\n const skyboxBgl = pipelineState.perPassResources.skyboxBindGroupLayout;\n const skyboxSampler = pipelineState.perPassResources.skyboxSampler;\n const skyboxRotationBuffer = pipelineState.perPassResources.skyboxRotationBuffer;\n if (\n skyboxPipeline === null ||\n skyboxBgl === null ||\n skyboxSampler === null ||\n skyboxRotationBuffer === null\n )\n return;\n\n const rotation = skyboxSnapshot.rotation;\n const rotationUpload = runtime.device.queue.writeBuffer(\n skyboxRotationBuffer,\n 0,\n new Float32Array([rotation[0], rotation[1], rotation[2], rotation[3]]),\n );\n if (!rotationUpload.ok) throw rotationUpload.error;\n\n // Resolve cubemap GPU view from AssetRegistry. Returns undefined if\n // the cubemap has not been uploaded yet (async equirect upload in\n // progress). In that case, degradation to main pass loadOp:'clear'\n // is handled by the passCtx.skyboxActive gate above -- if the\n // cubemap isn't ready, skyboxActive is already false (see w18).\n const cubemapView = store.getCubemapGpuView(\n toShared<'EquirectAsset'>(skyboxSnapshot.equirectHandle),\n );\n if (cubemapView === undefined) return;\n\n // Identity-cached skybox BindGroup keyed on the cubemap GpuView. The only\n // varying binding is the cubemap view (sampler + View UBO are stable); it is\n // recreated on each internal equirect-to-cubemap projection (which may happen\n // mid-app asynchronously), so keying on its identity rebuilds exactly when the\n // cubemap changes. This supersedes the prior `hdrTextureWidth`/`Height`\n // size-guard, which tracked the wrong resource (the skybox BindGroup never\n // binds hdrColor -- it writes the color attachment) and missed cubemap\n // re-projections that reused the old cached bind group.\n const skyboxBg = getOrCreateFromChain(\n c.frameState.postProcessBgCache,\n [cubemapView],\n 'skybox',\n () => {\n const skyboxBgRes = runtime.device.createBindGroup({\n label: 'skybox-bg',\n layout: skyboxBgl,\n entries: [\n {\n binding: 0,\n resource: { kind: 'textureView', value: cubemapView },\n },\n {\n binding: 1,\n resource: { kind: 'sampler', value: skyboxSampler },\n },\n {\n binding: 2,\n resource: {\n kind: 'buffer',\n value: { buffer: pipelineState.viewUniformBuffer, size: VIEW_UNIFORM_BYTES },\n },\n },\n {\n binding: 3,\n resource: {\n kind: 'buffer',\n value: { buffer: skyboxRotationBuffer },\n },\n },\n ],\n });\n if (!skyboxBgRes.ok) throw skyboxBgRes.error;\n return skyboxBgRes.value;\n },\n c.bindGroupCounts,\n );\n\n // Skybox pass: clear hdrColor (first pass writing to it),\n // draw fullscreen triangle, write cubemap colour.\n // No depth/stencil -- skybox is the far plane; main pass depth test rejects\n // occluded skybox pixels (plan-strategy D-1). HDR target ('rgba16float') is\n // declared on specAttachments for descriptor parity, even though color-only\n // policies do not gate on format.\n const skyboxPass =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['rgba16float'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [skyboxColorView as TextureView] },\n 'skybox',\n ) as never,\n );\n\n skyboxPass.setPipeline(skyboxPipeline);\n skyboxPass.setBindGroup(0, skyboxBg);\n skyboxPass.draw(3);\n if (graphPass === undefined) skyboxPass.end();\n}\n\nexport function encodeSkyboxPass(\n c: _InternalRenderPipelineContext,\n pass: RhiRenderPassEncoder,\n): void {\n recordSkyboxPass(c, pass);\n}\n\n/**\n * feat-20260529-rendergraph-pass-abstraction M4 / w13c: FXAA post-process\n * fullscreen pass, extracted verbatim from recordFrame. copyTextureToTexture\n * (swap-chain -> intermediate) then a fullscreen FXAA fragment pass writes\n * the anti-aliased result back into the swap-chain view, all on the SHARED\n * frame encoder (c.encoder). The pre-pass copy stays inside this closure\n * (graph first version models copy as a pass-internal op, not a separate\n * graph node). Gated on camera.antialias==='fxaa'. Driven by the 'fxaa'\n * graph pass.\n */\n// ── feat-20260531-bloom-first-declarative-render-graph-pass / w14 ──\n// Bloom execute closure placeholders. Real implementations in w15.\n// The graph must declare execute callbacks for addPass; these empty stubs\n// keep compile() satisfied until w15 fills in the actual record logic.\n//\n// Gate: bloom === 'off' || !tonemapActive => early-return (AC-04/AC-05).\n// The closures receive RenderPipelineContext and route to w15 record functions.\n\nconst EMPTY_BLOOM_RECEIPTS: BloomFrameReceipts = {\n uploadCount: 0,\n bindGroupCount: 0,\n encodeCount: 0,\n};\n\nfunction updateBloomReceipts(\n c: _InternalRenderPipelineContext,\n field: keyof BloomFrameReceipts,\n): void {\n const current = c.frameState.bloomFrameReceipts ?? EMPTY_BLOOM_RECEIPTS;\n c.frameState.bloomFrameReceipts = {\n ...current,\n [field]: current[field] + 1,\n };\n}\n\nfunction stageBloomUpload(c: _InternalRenderPipelineContext): void {\n updateBloomReceipts(c, 'uploadCount');\n}\n\nfunction stageBloomBindGroup(c: _InternalRenderPipelineContext): void {\n updateBloomReceipts(c, 'bindGroupCount');\n}\n\nfunction stageBloomEncode(c: _InternalRenderPipelineContext): void {\n updateBloomReceipts(c, 'encodeCount');\n}\n\nfunction throwBloomRecordFailure(expected: string): never {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected,\n hint: 'repair the Bloom candidate resources before retrying the frame',\n });\n}\n\nexport function recordBloomBrightPass(\n _c: _InternalRenderPipelineContext,\n resolve?: ResolveContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const { runtime, encoder, camera, tonemapActive, frameState, bindGroupCounts } = _c;\n const pp = _c.bloomResources;\n\n // Double gate: bloom=off => zero-overhead; tonemap=none => no HDR domain\n if (camera.bloom !== 'on' || !tonemapActive) return;\n if (pp === null || pp === undefined) {\n throwBloomRecordFailure('Bloom persistent resources are ready before bright-pass encoding');\n }\n if (\n pp.bloomBrightPipeline === null ||\n pp.bloomBrightBindGroupLayout === null ||\n pp.bloomSampler === null ||\n pp.bloomBrightParamsBuffer === null\n ) {\n throwBloomRecordFailure('Bloom bright pass has pipeline, layout, sampler, and params buffer');\n }\n\n // M1 / w7: bloom intermediate textures owned by render-graph. Resolve\n // the GPU TextureView via the resolve context passed by graph.execute().\n const bloomBrightView = resolve?.resolve('bloomBright') as TextureView | undefined;\n const hdrColorView = resolve?.resolve('hdrColor') as TextureView | undefined;\n if (!bloomBrightView || !hdrColorView) {\n throwBloomRecordFailure('Bloom bright pass resolves its source and target views');\n }\n const bglBright = pp.bloomBrightBindGroupLayout;\n const bloomSampler = pp.bloomSampler;\n const paramsBuffer = pp.bloomBrightParamsBuffer;\n\n // 2. Write threshold UBO (16 B std140: threshold f32 + 12 B pad).\n const brightParams = new Float32Array(4);\n brightParams[0] = camera.bloomThreshold;\n brightParams[1] = 0;\n brightParams[2] = 0;\n brightParams[3] = 0;\n const paramsWrite = runtime.device.queue.writeBuffer(paramsBuffer, 0, brightParams);\n if (!paramsWrite.ok) throw paramsWrite.error;\n stageBloomUpload(_c);\n\n // 3. Identity-cached BindGroup (1 tex + 1 sampler + 1 UBO). Keyed on the\n // graph-resolved hdrColor TextureView: resize retires hdrColor and the new\n // view yields a WeakMap miss -> rebuild referencing the live texture.\n const bindGroup = getOrCreateFromChain(\n frameState.postProcessBgCache,\n [hdrColorView],\n 'bloom-bright',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'bloom-bright-bg',\n layout: bglBright,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: hdrColorView } },\n { binding: 1, resource: { kind: 'sampler', value: bloomSampler } },\n { binding: 2, resource: { kind: 'buffer', value: { buffer: paramsBuffer } } },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n bindGroupCounts,\n );\n\n // 4. Render pass into the 1/2-res intermediate.\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['rgba16float'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [bloomBrightView] },\n 'bloom-bright',\n ) as never,\n );\n pass.setPipeline(pp.bloomBrightPipeline);\n pass.setBindGroup(0, bindGroup);\n stageBloomBindGroup(_c);\n pass.draw(3, 1, 0, 0);\n stageBloomEncode(_c);\n if (graphPass === undefined) pass.end();\n}\n\nexport function recordBloomBlurHPass(\n _c: _InternalRenderPipelineContext,\n resolve?: ResolveContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const { runtime, encoder, camera, targetW, tonemapActive, frameState, bindGroupCounts } = _c;\n const pp = _c.bloomResources;\n\n if (camera.bloom !== 'on' || !tonemapActive) return;\n if (pp === null || pp === undefined) {\n throwBloomRecordFailure('Bloom persistent resources are ready before blur-H encoding');\n }\n if (\n pp.bloomBlurHPipeline === null ||\n pp.bloomBlurBindGroupLayout === null ||\n pp.bloomSampler === null ||\n pp.bloomBlurHParamsBuffer === null\n ) {\n throwBloomRecordFailure('Bloom blur-H pass has pipeline, layout, sampler, and params buffer');\n }\n\n // M1 / w7: bloom intermediate textures owned by render-graph. Resolve\n // via the resolve context passed by graph.execute().\n const bloomBlurHView = resolve?.resolve('bloomBlurH') as TextureView | undefined;\n const bloomBrightView = resolve?.resolve('bloomBright') as TextureView | undefined;\n if (!bloomBlurHView || !bloomBrightView) {\n throwBloomRecordFailure('Bloom blur-H pass resolves its source and target views');\n }\n const bglBlur = pp.bloomBlurBindGroupLayout;\n const bloomSampler = pp.bloomSampler;\n const paramsBuffer = pp.bloomBlurHParamsBuffer;\n\n // 2. Write H-axis blur params into the H-only UBO (bug-20260625: a separate\n // buffer per axis so V's write cannot clobber H's before the GPU runs).\n // H-axis: texel offset along x only.\n const bw = Math.floor(targetW / 2);\n const blurParams = new Float32Array(4);\n blurParams[0] = bw > 0 ? 1.0 / bw : 1.0; // texelSize.x\n blurParams[1] = 0; // texelSize.y = 0 for H pass\n blurParams[2] = camera.bloomBlurRadius;\n blurParams[3] = 0;\n const paramsWrite = runtime.device.queue.writeBuffer(paramsBuffer, 0, blurParams);\n if (!paramsWrite.ok) throw paramsWrite.error;\n stageBloomUpload(_c);\n\n // 3. Identity-cached BindGroup (reads bloomBright from graph). Keyed on the\n // graph-resolved bloomBright view so resize rebuilds against the new texture.\n const bindGroup = getOrCreateFromChain(\n frameState.postProcessBgCache,\n [bloomBrightView],\n 'bloom-blur-h',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'bloom-blur-h-bg',\n layout: bglBlur,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: bloomBrightView } },\n { binding: 1, resource: { kind: 'sampler', value: bloomSampler } },\n { binding: 2, resource: { kind: 'buffer', value: { buffer: paramsBuffer } } },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n bindGroupCounts,\n );\n\n // 4. Render pass into bloomBlurH intermediate (graph-owned).\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['rgba16float'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [bloomBlurHView] },\n 'bloom-blur',\n ) as never,\n );\n pass.setPipeline(pp.bloomBlurHPipeline);\n pass.setBindGroup(0, bindGroup);\n stageBloomBindGroup(_c);\n pass.draw(3, 1, 0, 0);\n stageBloomEncode(_c);\n if (graphPass === undefined) pass.end();\n}\n\nexport function recordBloomBlurVPass(\n _c: _InternalRenderPipelineContext,\n resolve?: ResolveContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const { runtime, encoder, camera, targetH, tonemapActive, frameState, bindGroupCounts } = _c;\n const pp = _c.bloomResources;\n\n if (camera.bloom !== 'on' || !tonemapActive) return;\n if (pp === null || pp === undefined) {\n throwBloomRecordFailure('Bloom persistent resources are ready before blur-V encoding');\n }\n if (\n pp.bloomBlurVPipeline === null ||\n pp.bloomBlurBindGroupLayout === null ||\n pp.bloomSampler === null ||\n pp.bloomBlurVParamsBuffer === null\n ) {\n throwBloomRecordFailure('Bloom blur-V pass has pipeline, layout, sampler, and params buffer');\n }\n\n // M1 / w7: bloom intermediate textures owned by render-graph. Resolve\n // via the resolve context passed by graph.execute().\n const bloomBlurVView = resolve?.resolve('bloomBlurV') as TextureView | undefined;\n const bloomBlurHView = resolve?.resolve('bloomBlurH') as TextureView | undefined;\n if (!bloomBlurVView || !bloomBlurHView) {\n throwBloomRecordFailure('Bloom blur-V pass resolves its source and target views');\n }\n const bglBlur = pp.bloomBlurBindGroupLayout;\n const bloomSampler = pp.bloomSampler;\n const paramsBuffer = pp.bloomBlurVParamsBuffer;\n\n // 2. Write V-axis blur params into the V-only UBO (bug-20260625: separate\n // buffer per axis -- see the H pass comment).\n // V-axis: texel offset along y only.\n const bh = Math.floor(targetH / 2);\n const blurParams = new Float32Array(4);\n blurParams[0] = 0; // texelSize.x = 0 for V pass\n blurParams[1] = bh > 0 ? 1.0 / bh : 1.0; // texelSize.y\n blurParams[2] = camera.bloomBlurRadius;\n blurParams[3] = 0;\n const paramsWrite = runtime.device.queue.writeBuffer(paramsBuffer, 0, blurParams);\n if (!paramsWrite.ok) throw paramsWrite.error;\n stageBloomUpload(_c);\n\n // 3. Identity-cached BindGroup (reads bloomBlurH from graph). Keyed on the\n // graph-resolved bloomBlurH view so resize rebuilds against the new texture.\n const bindGroup = getOrCreateFromChain(\n frameState.postProcessBgCache,\n [bloomBlurHView],\n 'bloom-blur-v',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'bloom-blur-v-bg',\n layout: bglBlur,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: bloomBlurHView } },\n { binding: 1, resource: { kind: 'sampler', value: bloomSampler } },\n { binding: 2, resource: { kind: 'buffer', value: { buffer: paramsBuffer } } },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n bindGroupCounts,\n );\n\n // 4. Render pass into bloomBlurV intermediate (graph-owned).\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['rgba16float'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [bloomBlurVView] },\n 'bloom-blur',\n ) as never,\n );\n pass.setPipeline(pp.bloomBlurVPipeline);\n pass.setBindGroup(0, bindGroup);\n stageBloomBindGroup(_c);\n pass.draw(3, 1, 0, 0);\n stageBloomEncode(_c);\n if (graphPass === undefined) pass.end();\n}\n\nexport function recordBloomCompositePass(\n _c: _InternalRenderPipelineContext,\n resolve?: ResolveContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const { runtime, encoder, camera, tonemapActive, frameState, bindGroupCounts } = _c;\n const pp = _c.bloomResources;\n\n if (camera.bloom !== 'on' || !tonemapActive) return;\n if (pp === null || pp === undefined) {\n throwBloomRecordFailure('Bloom persistent resources are ready before composite encoding');\n }\n if (\n pp.bloomCompositePipeline === null ||\n pp.bloomCompositeBindGroupLayout === null ||\n pp.bloomSampler === null ||\n pp.bloomCompositeParamsBuffer === null\n ) {\n throwBloomRecordFailure(\n 'Bloom composite pass has pipeline, layout, sampler, and params buffer',\n );\n }\n\n // M1 / w7: hdrColor + bloomBlurV textures owned by render-graph.\n // bug-20260625: composite READS hdrColor (scene, binding 0) and WRITES the\n // separate hdrComposited target -- never the same texture in one pass.\n const hdrColorView = resolve?.resolve('hdrColor') as TextureView | undefined;\n const bloomBlurVView = resolve?.resolve('bloomBlurV') as TextureView | undefined;\n const hdrCompositedView = resolve?.resolve('hdrComposited') as TextureView | undefined;\n if (!hdrColorView || !bloomBlurVView || !hdrCompositedView) {\n throwBloomRecordFailure('Bloom composite pass resolves its source and target views');\n }\n const bglComposite = pp.bloomCompositeBindGroupLayout;\n const bloomSampler = pp.bloomSampler;\n const paramsBuffer = pp.bloomCompositeParamsBuffer;\n\n // 1. Write composite params UBO (16 B std140: intensity + 12 B pad).\n const compositeParams = new Float32Array(4);\n compositeParams[0] = camera.bloomIntensity;\n compositeParams[1] = 0;\n compositeParams[2] = 0;\n compositeParams[3] = 0;\n const paramsWrite = runtime.device.queue.writeBuffer(paramsBuffer, 0, compositeParams);\n if (!paramsWrite.ok) throw paramsWrite.error;\n stageBloomUpload(_c);\n\n // 2. Identity-cached BindGroup (2 tex: hdrColor + bloomBlurV, 1 sampler,\n // 1 UBO). Keys on both sampled views: resize retires both hdrColor and\n // bloomBlurV, so a two-node chain rebuilds when either identity changes.\n const bindGroup = getOrCreateFromChain(\n frameState.postProcessBgCache,\n [hdrColorView, bloomBlurVView],\n 'bloom-composite',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'bloom-composite-bg',\n layout: bglComposite,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: hdrColorView } },\n { binding: 1, resource: { kind: 'textureView', value: bloomBlurVView } },\n { binding: 2, resource: { kind: 'sampler', value: bloomSampler } },\n {\n binding: 3,\n resource: { kind: 'buffer', value: { buffer: paramsBuffer } },\n },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n bindGroupCounts,\n );\n\n // 3. Render pass: write the separate hdrComposited target (bug-20260625).\n // The fragment shader outputs the COMPLETE composited colour\n // (scene + intensity*bloom, sampling scene from hdrColor itself), so the\n // destination needs no prior content -> loadOp='clear' (no stale dependency\n // on hdrComposited's previous-frame content, and no in-place hazard).\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['rgba16float'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [hdrCompositedView] },\n 'bloom-composite',\n { colorLoadOp: 'clear' },\n ) as never,\n );\n pass.setPipeline(pp.bloomCompositePipeline);\n pass.setBindGroup(0, bindGroup);\n stageBloomBindGroup(_c);\n pass.draw(3, 1, 0, 0);\n stageBloomEncode(_c);\n if (graphPass === undefined) pass.end();\n}\n\nexport function recordFxaaPass(\n c: _InternalRenderPipelineContext,\n resolve: ResolveContext,\n graphPass?: RhiRenderPassEncoder,\n): void {\n const { runtime, pipelineState, encoder, camera, currentTexture } = c;\n // FXAA samples the graph-owned LDR target and writes the current surface.\n // The surface is an output attachment only: no COPY_SRC usage, no\n // copyTextureToTexture, and no backend-specific surface sampling path.\n const fxaaActive = camera.antialias === 'fxaa';\n if (\n fxaaActive &&\n pipelineState.perPassResources.fxaaPipeline !== null &&\n pipelineState.perPassResources.fxaaBindGroupLayout !== null &&\n pipelineState.perPassResources.fxaaSampler !== null &&\n runtime.getPostProcessParamsBuffer !== undefined\n ) {\n const inputView = resolve.resolve('ldrColor') as TextureView | undefined;\n if (inputView === undefined) return;\n\n const fxaaParams = runtime.getPostProcessParamsBuffer(FXAA_POST_PROCESS_ID);\n if (fxaaParams === undefined) return;\n const params = new Float32Array(4);\n params[0] = resolveOutputDither(c.frameState.installedPipelineConfig) ? 1 : 0;\n const paramsWrite = runtime.device.queue.writeBuffer(fxaaParams, 0, params);\n if (!paramsWrite.ok) throw paramsWrite.error;\n\n // Compose the 3-entry FXAA BindGroup (input texture + sampler + params).\n // graph view identity changes when the graph reallocates on resize, so\n // the identity-keyed cache rebuilds against the live target. The params\n // buffer is also a key so a device recovery cannot retain a bind group\n // pointing at the retired resource.\n const fxaaBglLayout = pipelineState.perPassResources.fxaaBindGroupLayout;\n const fxaaSampler = pipelineState.perPassResources.fxaaSampler;\n const fxaaBg = getOrCreateFromChain(\n c.frameState.postProcessBgCache,\n [inputView, fxaaParams],\n 'fxaa',\n () => {\n const fxaaBgRes = runtime.device.createBindGroup({\n label: 'fxaa-bg',\n layout: fxaaBglLayout,\n entries: [\n {\n binding: 0,\n resource: {\n kind: 'textureView',\n value: inputView,\n },\n },\n {\n binding: 1,\n resource: { kind: 'sampler', value: fxaaSampler },\n },\n {\n binding: 2,\n resource: { kind: 'buffer', value: { buffer: fxaaParams } },\n },\n ],\n });\n if (!fxaaBgRes.ok) throw fxaaBgRes.error;\n return fxaaBgRes.value;\n },\n c.bindGroupCounts,\n );\n\n const fxaaColorFormat = runtime.device.caps.storageBuffer\n ? pipelineState.format\n : pipelineState.colorAttachmentFormat;\n let fxaaPass = graphPass;\n if (fxaaPass === undefined) {\n const fxaaOutputView = runtime.device.createTextureView(currentTexture, {\n format: fxaaColorFormat as GPUTextureFormat,\n });\n if (!fxaaOutputView.ok) {\n runtime.errorRegistry.fire(fxaaOutputView.error);\n return;\n }\n fxaaPass = encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n {\n colorFormats: [fxaaColorFormat as GPUTextureFormat],\n depthFormat: undefined,\n sampleCount: 1,\n },\n { colorViews: [fxaaOutputView.value] },\n 'fxaa',\n ) as never,\n );\n }\n fxaaPass.setPipeline(pipelineState.perPassResources.fxaaPipeline);\n fxaaPass.setBindGroup(0, fxaaBg);\n fxaaPass.draw(3, 1, 0, 0);\n if (graphPass === undefined) fxaaPass.end();\n }\n}\n","// @forgeax/engine-runtime - FullscreenPostProcessPass primitive\n// (feat-20260604-resource-owning-render-graph-and-fullscreen-postpr M2 / w13).\n//\n// A declarative fullscreen post-process pass that:\n// - Uses the `fullscreen_triangle` vertex shader (common.wgsl:194, SSOT — not rewritten)\n// - Supports optional params UBO (FXAA has no params, tonemap has params — plan-strategy D-4 /\n// Finding M2-1)\n// - Auto-builds: input-texture BGL, pipeline, offscreen RT, ViewTarget ping-pong (KB-2),\n// and swap-chain non-srgb storage view write (R-COLORSPACE)\n// - Reads input texture, writes to declared color target with fullscreen 3-vertex draw\n//\n// Registered through the feature host ({source, params, reads?}) — a parallel\n// channel to installMaterialArtifact (D-4: material shader = 4-BGL / 12-float vertex / depth /\n// triangle-list; fullscreen post-process = 0 vertex buffer / no depth / input-texture BGL).\n\nimport type {\n BindGroup,\n BindGroupLayout,\n Buffer,\n RhiDevice,\n RhiError,\n RhiRenderPassEncoder,\n Sampler,\n TextureView,\n} from '@forgeax/engine-rhi';\nimport { GPU_SHADER_STAGE_FRAGMENT } from './gpu-stage';\nimport type { BglKind } from './pipeline-spec';\nimport { buildBindGroupLayoutDescriptor, type PipelineSpec } from './pipeline-spec';\n\n// Default fullscreen-post spec stub. The dispatcher's 'fullscreen-post' arm\n// reads spec.attachments.depthFormat / colorFormats[0] to derive the texture\n// binding's sampleType (R3 fix). Default colorFormats=['rgba16float'] gives\n// the historical 'float' / 'filtering' shape preserved across all existing\n// post-process call sites.\nconst FULLSCREEN_DEFAULT_SPEC: PipelineSpec = Object.freeze({\n shader: { id: '', passKind: 'forward', variantSet: undefined },\n attachments: {\n colorFormats: ['rgba16float'] as readonly GPUTextureFormat[],\n depthFormat: undefined,\n sampleCount: 1,\n },\n geometry: { topology: 'triangle-list', vertexLayout: {} },\n renderState: undefined,\n}) as PipelineSpec;\n\n// ─── Post-process read sample type union ─────────────────────────────────\n\n/**\n * Declared sample type for a post-process read entry.\n *\n * Closed union (plan-strategy D-7): only `'depth'` is an explicit sampleType\n * discriminant; color inputs are the default (bare `string` or un-suffixed\n * `{ key }`). Future texture types (`r32float`, etc.) are add-only.\n *\n * AI-user affordance: IDE autocomplete exposes `'depth'` at the register call\n * site; misspellings are caught by the type system (AC-08).\n */\nexport type PostProcessReadSampleType = 'depth';\n\n// ─── Post-process shader entry (owned by the fullscreen feature host) ──────\n\n/**\n * A fullscreen post-process shader entry owned by the feature host.\n *\n * Analogous to MaterialShaderEntry in the ShaderCatalog but with post-process-specific\n * fields: the input-texture + sampler BGL is auto-built by the primitive,\n * no paramSchema (params are passed inline via a {type, value} struct — plan-strategy D-4).\n *\n * `params` carries the WGSL struct definition + default value. When `params` is\n * `undefined`, the post-process shader has no params UBO. Special graph-owned\n * passes such as FXAA may still register an internal policy UBO separately.\n *\n * `reads` declares graph resource keys this pass samples as input texture(s).\n * If omitted, the pass samples the swap-chain color attachment (default path).\n *\n * Structured reads (plan-strategy D-1): each entry can be a bare string\n * (backward-compatible color input) or an object `{ key, sampleType? }`.\n * When `sampleType` is `'depth'`, the dispatcher resolves a depth-only view\n * and binds it at depthTex@3 / depthSampler@4 in the fullscreen bind group.\n */\nexport interface PostProcessShaderEntry {\n /** Composed WGSL source for the fragment stage (post-naga_oil). */\n readonly source: string;\n /**\n * Params UBO schema. When undefined, the generic shader has no uniform buffer\n * and the BGL degrades to 2 entries (texture@0 + sampler@1). When present, the\n * primitive eager-creates a params UBO (at register, sized `byteSize`) and binds\n * it at bindgroup(1) binding(2) as part of a 3-entry BGL\n * (texture@0 + sampler@1 + buffer@2). feat-20260621 M-A2 / D-2.\n */\n readonly params?: PostProcessParamsSchema | undefined;\n /**\n * Graph resource keys this post-process reads (as input textures).\n * The primitive binds the first read as its input texture at @group(1)\n * @binding(0) (the sampler is @group(1) @binding(1); group 0 is reserved for a\n * future view bind group — dispatchFullscreenPass calls setBindGroup(1, ...)).\n * When empty or omitted, the pass reads the swap-chain directly.\n *\n * Each entry is either a bare string (backward-compatible color input) or an\n * object `{ key: string; sampleType?: PostProcessReadSampleType }` for typed\n * reads (e.g. `{ key: 'depth', sampleType: 'depth' }` for depth sampling).\n * Bare strings and `{ key }` without `sampleType` are equivalent — both\n * represent a color input (plan-strategy D-1 / D-7).\n */\n readonly reads?: readonly (string | PostProcessReadEntry)[] | undefined;\n}\n\nfunction postProcessSourceDigest(source: string): string {\n let first = 0x811c9dc5;\n let second = 0x9e3779b9;\n for (let index = 0; index < source.length; index += 1) {\n const code = source.charCodeAt(index);\n first = Math.imul(first ^ code, 0x01000193);\n second = Math.imul(second ^ (code + index), 0x01000193);\n }\n return `${source.length.toString(16)}-${(first >>> 0).toString(16).padStart(8, '0')}-${(second >>> 0).toString(16).padStart(8, '0')}`;\n}\n\n/** Content-addressed PSO label shared by the post-process pipeline factory. */\nexport function postProcessShaderPipelineLabel(identity: string, source: string): string {\n return `post-process-${identity}-pso-${postProcessSourceDigest(source)}`;\n}\n\n/** Content-addressed shader-module label shared by prewarm and lazy paths. */\nexport function postProcessShaderModuleLabel(identity: string, source: string): string {\n return `${postProcessShaderPipelineLabel(identity, source)}-module`;\n}\n\n/**\n * Stable declaration identity used by graph admission and the renderer's\n * device-bound pipeline cache. Shader source, bind-group-affecting params,\n * and graph reads must move together when a feature reuses its identity.\n */\nexport function postProcessShaderEntrySignature(entry: PostProcessShaderEntry): string {\n return JSON.stringify({\n source: entry.source,\n params:\n entry.params === undefined\n ? undefined\n : {\n byteSize: entry.params.byteSize,\n defaultValue: Array.from(entry.params.defaultValue),\n },\n reads: entry.reads,\n });\n}\n\n/** Whether a feature binding opts into the temporal multi-read contract. */\nexport function isTemporalFullscreenBinding(values: Readonly<Record<string, unknown>>): boolean {\n return (\n values.temporal !== undefined ||\n values.shader === 'forgeax.taa-resolve' ||\n values.shader === 'forgeax.motion-blur'\n );\n}\n\n/**\n * Structured read entry for a post-process shader.\n *\n * `key` is the graph resource key (matching a graph color target).\n * `sampleType` is an optional type discriminant (D-1 SSOT); when omitted\n * the entry is treated as a color input (same as a bare string).\n */\nexport interface PostProcessReadEntry {\n readonly key: string;\n readonly sampleType?: PostProcessReadSampleType | undefined;\n}\n\n/**\n * Params schema: the WGSL struct definition + default byte array for a post-process\n * UBO. The primitive allocates a GPU buffer of `byteSize` and uploads `defaultValue`\n * at register time; the UBO is then updated per-frame via the data-driven\n * `PostProcessParams` ECS component (component `data` -> extract snapshot ->\n * dispatchFullscreenPass `queue.writeBuffer`), NOT via an imperative setter.\n * feat-20260621 M-A1/M-A2 / D-1.\n */\nexport interface PostProcessParamsSchema {\n /** Byte size of the WGSL params struct (must be UBO-aligned, min 16 B). */\n readonly byteSize: number;\n /** Default UBO contents (length must equal `byteSize`). */\n readonly defaultValue: Uint8Array;\n}\n\n// ─── Context passed to typed fullscreen feature injectors ─────────────────\n\n/**\n * The minimal surface a `registerFullscreenPostProcess` injector receives.\n * Contains the RHI device (for creating BGLs / pipelines / samplers) and the\n * error registry for structured failure reporting.\n */\nexport interface FullscreenPostProcessDeviceContext {\n readonly device: RhiDevice;\n readonly errorRegistry: {\n fire(error: RhiError): void;\n };\n}\n\n// ─── Built-in fullscreen post-process BGL + pipeline state ───────────────\n\n// Fullscreen bind-group layout: a single input-texture binding (0) +\n// a single sampler binding (1). The descriptor SSOT moved to\n// buildBindGroupLayoutDescriptor(spec, { kind: 'fullscreen-post' }) in\n// pipeline-spec.ts (D-13 round-2).\n//\n// Historical context: this BGL was duplicated across recordFxaaPass +\n// register-default-post-process before convergence (feat-20260609 framebuffers\n// demo M5R2 / T-12-a). R3 historical bug: the descriptor wrote sampleType:\n// 'float' for every input including depth32float views, tripping wgpu's\n// Filtering sampler vs UnfilterableFloat / Depth texture static-sample-pair\n// validation. The dispatcher derives sampleType from spec.attachments\n// (depth32float -> 'depth' + 'comparison' sampler; r32float ->\n// 'unfilterable-float'; else -> 'float' + 'filtering').\n\n/**\n * Create a linear clamp-to-edge sampler — reused across all fullscreen passes\n * (identical to the recordFxaaPass sampler).\n */\nfunction createFullscreenSampler(device: RhiDevice): Sampler | null {\n const res = device.createSampler({\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n magFilter: 'linear',\n minFilter: 'linear',\n });\n if (!res.ok) return null;\n return res.value;\n}\n\n/**\n * Create a non-filtering depth sampler for post-process passes that read the\n * camera scene depth (plan-strategy D-2: nearest + clamp-to-edge).\n * Aligns with the SSAO depth sampler shape (render-graph-primitives.ts:634-647)\n * — NOT a comparison sampler (D-2 rejects comparison because the post-process\n * shader reads raw depth values via `textureSampleLevel`, not PCF shadow lookup).\n */\nfunction createDepthSampler(device: RhiDevice): Sampler | null {\n const res = device.createSampler({\n magFilter: 'nearest',\n minFilter: 'nearest',\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n });\n if (!res.ok) return null;\n return res.value;\n}\n\n/**\n * Check whether the entry's {@link PostProcessShaderEntry.reads} declares a read\n * with `sampleType: 'depth'`. Used by {@link buildFullscreenPostProcessPass} to\n * select between the single-sample and multisample depth BGL variants and the\n * existing color-only kinds.\n */\nexport function entryHasDepthRead(entry: PostProcessShaderEntry): boolean {\n if (!entry.reads) return false;\n return entry.reads.some((r) => typeof r !== 'string' && r.sampleType === 'depth');\n}\n\n/**\n * Byte size of the minimal params UBO auto-allocated for a depth-reading entry\n * that declares no `params`. The `'fullscreen-post-with-scene-depth'` BGL always\n * declares `params@2`, so a bound UBO must exist even when the shader has no\n * user params (plan D-3: param-less depth effect gets a minimal 16B UBO). 16 B\n * is WebGPU's minimum uniform-buffer binding size.\n */\nexport const DEPTH_MIN_PARAMS_BYTE_SIZE = 16;\n\n// ─── Public: register / build a fullscreen post-process pass ─────────────\n\n/**\n * State of a registered fullscreen post-process pass.\n *\n * Created by the typed fullscreen feature graph and stored per-pass in the render system.\n * The `draw` method is called by the per-frame execute closure.\n */\nexport interface FullscreenPostProcessPassHandle {\n /** The pass name (same as the `color` target key). */\n readonly name: string;\n /** Execute one fullscreen draw: bind input texture, set pipeline, draw 3 vertices. */\n draw(encoder: RhiRenderPassEncoder, inputView: TextureView): void;\n /**\n * The per-frame params UBO this pass binds at group(1) binding(2), or null\n * when `entry.params === undefined` (param-less consumer, 2-entry BGL). The\n * dispatcher writes the snapshot bytes into it before draw and composes it\n * into the bind group via {@link createFullscreenBindGroup}.\n */\n readonly paramsBuffer: Buffer | null;\n}\n\n/**\n * Build a fullscreen post-process pass primitive.\n *\n * Creates BGL, sampler, and pipeline state from the registered shader entry.\n * Returns the pass handle + the BGL + the sampler so the caller can compose\n * bind groups. The BGL + sampler are shared across instances of the same shader.\n *\n * @returns The BGL, sampler, and a factory to create pass handles.\n */\nexport function buildFullscreenPostProcessPass(\n ctx: FullscreenPostProcessDeviceContext,\n entry: PostProcessShaderEntry,\n depthMultisampled = false,\n): {\n bindGroupLayout: BindGroupLayout;\n sampler: Sampler | null;\n depthSampler: Sampler | null;\n extraColorBindings: readonly number[];\n createHandle: (\n name: string,\n pipeline: unknown,\n paramsBuffer: Buffer | null,\n ) => FullscreenPostProcessPassHandle;\n} | null {\n const { device } = ctx;\n\n // Step 1: BGL (input texture + sampler [+ params buffer] [+ depth]).\n // D-13 round-2: route through dispatcher; sampleType derives from\n // spec.attachments (R3 fix). Default spec yields the historical 'float'\n // / 'filtering' shape for color inputs.\n // feat-20260621 D-2: when entry.params is present the BGL is the 3-entry\n // 'fullscreen-post-with-params' kind (adds buffer@2 uniform); otherwise the\n // 2-entry 'fullscreen-post' kind (param-less zero-regression, R-A7).\n // plan-strategy D-3: when entry.reads declares sampleType:'depth', use the\n // 5-entry scene-depth kind; depthMultisampled selects its multisampled\n // texture variant for a 4-sample scene target. params@2 is always present to\n // avoid 2x2 kind explosion.\n const hasDepth = entryHasDepthRead(entry);\n const bglKind: BglKind = hasDepth\n ? depthMultisampled\n ? 'fullscreen-post-with-scene-depth-msaa'\n : 'fullscreen-post-with-scene-depth'\n : entry.params !== undefined\n ? 'fullscreen-post-with-params'\n : 'fullscreen-post';\n const descriptor = buildBindGroupLayoutDescriptor(FULLSCREEN_DEFAULT_SPEC, { kind: bglKind });\n const colorReads = (entry.reads ?? []).filter(\n (read) => typeof read === 'string' || read.sampleType !== 'depth',\n );\n const extraColorCount = Math.max(0, colorReads.length - 1);\n const firstExtraBinding = hasDepth ? 5 : entry.params === undefined ? 2 : 3;\n for (let index = 0; index < extraColorCount; index += 1) {\n descriptor.entries.push({\n binding: firstExtraBinding + index,\n visibility: GPU_SHADER_STAGE_FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n });\n }\n const bglRes = device.createBindGroupLayout(descriptor);\n if (!bglRes.ok) {\n ctx.errorRegistry.fire(bglRes.error);\n return null;\n }\n\n // Step 2: Samplers.\n const sampler = createFullscreenSampler(device);\n const depthSampler = hasDepth ? createDepthSampler(device) : null;\n\n return {\n bindGroupLayout: bglRes.value,\n sampler,\n depthSampler,\n extraColorBindings: Object.freeze(\n Array.from({ length: extraColorCount }, (_, index) => firstExtraBinding + index),\n ),\n createHandle: (name, pipeline, paramsBuffer) => ({\n name,\n paramsBuffer,\n draw(encoder, _inputView) {\n encoder.setPipeline(pipeline as never);\n // The bind group is composed per-frame by the record stage (mirrors\n // recordFxaaPass's lazy bindgroup compose in render-system-record.ts).\n // This draw() method only sets the pipeline — the caller is responsible\n // for bind group composition + setBindGroup before calling draw().\n encoder.draw(3, 1, 0, 0);\n },\n }),\n };\n}\n\n/**\n * Create a fullscreen bind group (lazy, per-frame). Composes the input texture\n * view + the linear sampler into group(1) (texture@0 + sampler@1). When\n * `paramsBuffer` is supplied (feat-20260621 D-2: `entry.params !== undefined`),\n * appends the per-frame params UBO at binding 2 (uniform), matching the 3-entry\n * `'fullscreen-post-with-params'` BGL. Omitting it yields the 2-entry shape\n * param-less consumers degrade to (R-A7).\n *\n * When `depthTexView` + `depthSampler` are supplied (plan-strategy D-3:\n * depth reads present), appends the depth texture view at binding 3 and the\n * non-filtering depth sampler at binding 4, matching the 5-entry\n * `'fullscreen-post-with-scene-depth'` BGL. Both must be supplied together\n * (or both omitted for existing color-only consumers — AC-03 zero-regression).\n */\nexport function createFullscreenBindGroup(\n device: RhiDevice,\n bgl: BindGroupLayout,\n inputView: TextureView,\n sampler: Sampler | null,\n paramsBuffer?: Buffer | null,\n depthTexView?: TextureView | null,\n depthSampler?: Sampler | null,\n additionalViews: readonly { readonly binding: number; readonly view: TextureView }[] = [],\n): BindGroup | null {\n const entries: { binding: number; resource: { kind: string; value: unknown } }[] = [\n { binding: 0, resource: { kind: 'textureView', value: inputView } },\n ];\n if (sampler) {\n entries.push({ binding: 1, resource: { kind: 'sampler', value: sampler } });\n }\n if (paramsBuffer) {\n // RHI buffer binding resource is `{ kind: 'buffer', value: { buffer } }` —\n // the nested `{ buffer }` wrapper is the GPUBufferBinding shape dawn expects\n // (mirrors createRenderer's shadow-probe UBO bindings). Passing the raw\n // handle as `value` makes dawn reject createBindGroup (\"no overload matched\n // ... member 'resource' for array element 2\").\n entries.push({ binding: 2, resource: { kind: 'buffer', value: { buffer: paramsBuffer } } });\n }\n if (depthTexView && depthSampler) {\n entries.push({ binding: 3, resource: { kind: 'textureView', value: depthTexView } });\n entries.push({ binding: 4, resource: { kind: 'sampler', value: depthSampler } });\n }\n for (const additional of additionalViews) {\n entries.push({\n binding: additional.binding,\n resource: { kind: 'textureView', value: additional.view },\n });\n }\n const res = device.createBindGroup({\n label: 'fullscreen-post-process-bg',\n layout: bgl,\n entries: entries as never,\n });\n if (!res.ok) return null;\n return res.value;\n}\n","// @forgeax/engine-render - low-level record/encode graph primitives.\n//\n// Standard owns pass topology through typed-render-graph-primitives. This module\n// retains the RHI-facing record helpers used by that typed graph: SSAO record\n// closures, fullscreen dispatch, depth resolution, and encoding.\n//\n// Public graph assembly does not depend on legacy add* wrappers.\nimport { mat4 } from '@forgeax/engine-math';\nimport type { ResolveContext } from '@forgeax/engine-render-graph';\nimport type {\n Buffer,\n RhiRenderPassEncoder,\n Sampler,\n Texture,\n TextureFormat,\n TextureView,\n} from '@forgeax/engine-rhi';\nimport {\n buildFullscreenPostProcessPass,\n createFullscreenBindGroup,\n entryHasDepthRead,\n} from './fullscreen-post-process-pass';\nimport { buildBeginRenderPassDescriptor } from './pipeline-spec';\nimport { PostProcessError } from './post-process-errors';\nimport { computeProjectionMatrix, computeViewMatrix } from './record/helpers';\nimport { getOrCreateFromChain } from './record/mesh-ssbo';\nimport type { _InternalRenderPipelineContext } from './record/render-context';\nimport { recordFxaaPass } from './record/skybox-post-pass';\nimport type { RenderPipelineContext } from './render-contract';\nimport { getOrCreateSsaoBuffers, getOrCreateSsaoFallbackTexture } from './ssao-buffers';\nimport { getSsaoParameters } from './ssao-config';\n\ntype DepthResolutionContext = Pick<_InternalRenderPipelineContext, 'runtime'> & {\n readonly frameState: {\n readonly perFrameGraph?: {\n readonly getColorTargetTexture: (key: string) => Texture | undefined;\n } | null;\n };\n};\n\ntype RenderGraphRecordContext = _InternalRenderPipelineContext & {\n readonly frameState: _InternalRenderPipelineContext['frameState'] & {\n readonly perFrameGraph?: {\n readonly getColorTargetDescriptor: (\n key: string,\n ) => { readonly format: TextureFormat } | undefined;\n readonly getColorTargetView: (key: string) => TextureView | undefined;\n readonly getColorTargetTexture: (key: string) => Texture | undefined;\n } | null;\n };\n};\n\nfunction requireRenderGraphRecordContext(ctx: RenderPipelineContext): RenderGraphRecordContext {\n if (!('frameState' in ctx) || !('bindGroupCounts' in ctx) || !('geometryDepthKey' in ctx)) {\n throw new Error('typed render graph frame lacks the built-in record context');\n }\n return ctx as RenderGraphRecordContext;\n}\n\n/**\n * Resolve a depth-only view of a graph color target by key.\n *\n * On dawn the BindGroup validation rejects a default-view (aspect=all on a\n * depth+stencil texture) with \"Multiple aspects (Depth|Stencil) selected\".\n * A separate createTextureView({aspect:'depth-only'}) is required.\n *\n * @param internals - internal render pipeline context\n * @param key - graph color-target key to resolve depth from\n * @param label - debug label for the depth-only TextureView\n * @returns a depth-only TextureView, or null if the graph / texture is absent\n * or creation fires a structured error\n */\nexport function resolveDepthOnlyView(\n internals: DepthResolutionContext,\n key: string,\n label: string,\n preferredKey?: string | null,\n): TextureView | null {\n const graph = internals.frameState.perFrameGraph;\n if (graph === null || graph === undefined) return null;\n const preferredTexture =\n preferredKey === null || preferredKey === undefined\n ? undefined\n : graph.getColorTargetTexture(preferredKey);\n const tex = preferredTexture ?? graph.getColorTargetTexture(key);\n if (tex === undefined) return null;\n const res = internals.runtime.device.createTextureView(tex as never, {\n label,\n dimension: '2d',\n aspect: 'depth-only',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!res.ok) {\n internals.runtime.errorRegistry.fire(res.error);\n return null;\n }\n return res.value;\n}\n\n/**\n * Resolve a depth-only view of the graph's hdrDepth texture.\n *\n * Thin delegate to {@link resolveDepthOnlyView} (plan-strategy D-5: extract\n * the shared depth-only view helper, SSAO delegates). Behaviour is byte-identical\n * to the pre-extraction inline version. The SSAO BGL / bindings / sampler are\n * untouched (OOS-4).\n */\nfunction resolveHdrDepthDepthOnlyView(\n internals: DepthResolutionContext,\n hdrDepthKey: string,\n): TextureView | null {\n return resolveDepthOnlyView(internals, hdrDepthKey, 'ssao-hdr-depth-only-view');\n}\n\nfunction ensureSsaoRecordCompanions(internals: _InternalRenderPipelineContext): {\n filteringSampler: Sampler;\n depthSampler: Sampler;\n fallbackRawView: TextureView;\n} | null {\n const pp = internals.pipelineState.perPassResources;\n if (\n pp.ssaoFilteringSampler !== null &&\n pp.ssaoDepthSampler !== null &&\n pp.ssaoFallbackRawView !== null\n ) {\n return {\n filteringSampler: pp.ssaoFilteringSampler,\n depthSampler: pp.ssaoDepthSampler,\n fallbackRawView: pp.ssaoFallbackRawView as TextureView,\n };\n }\n\n const device = internals.runtime.device;\n\n if (pp.ssaoFilteringSampler === null) {\n // Despite the field name, this sampler is non-filtering (NEAREST):\n // bindings 3 (noise sampler) + 8 (ssaoSampler) pair with unfilterable\n // float textures (rgba32float noise / r8unorm ssaoRaw on dawn without\n // float32-filterable). The \"filtering\" label in the field name predates\n // the sampler-type split; the resource itself is non-filtering.\n const res = device.createSampler({\n label: 'ssao-noise-sampler',\n magFilter: 'nearest',\n minFilter: 'nearest',\n mipmapFilter: 'nearest',\n addressModeU: 'repeat',\n addressModeV: 'repeat',\n });\n if (!res.ok) {\n internals.runtime.errorRegistry.fire(res.error);\n return null;\n }\n pp.ssaoFilteringSampler = res.value;\n }\n\n if (pp.ssaoDepthSampler === null) {\n const res = device.createSampler({\n label: 'ssao-depth-sampler',\n magFilter: 'nearest',\n minFilter: 'nearest',\n mipmapFilter: 'nearest',\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n });\n if (!res.ok) {\n internals.runtime.errorRegistry.fire(res.error);\n return null;\n }\n pp.ssaoDepthSampler = res.value;\n }\n\n if (pp.ssaoFallbackRawView === null) {\n const fb = getOrCreateSsaoFallbackTexture(internals.runtime);\n if (fb === null) return null;\n pp.ssaoFallbackRawView = fb.view;\n }\n\n return {\n filteringSampler: pp.ssaoFilteringSampler,\n depthSampler: pp.ssaoDepthSampler,\n fallbackRawView: pp.ssaoFallbackRawView as TextureView,\n };\n}\n\n/**\n * Pack the 256B SSAO uniform payload from the camera + config.ssao.\n *\n * Layout (plan-strategy D-1 + D-C):\n * floats [0..15] view mat4\n * floats [16..31] projection mat4\n * floats [32..47] inverseProjection mat4\n * floats [48..51] intensityPad vec4 (x=intensity, y=radius, z=bias)\n * floats [52..63] trailing zero-pad to round to 256B / 64f UBO alignment.\n */\nfunction buildSsaoUniformPayload(internals: _InternalRenderPipelineContext): Float32Array {\n const { camera, frameState } = internals;\n const sProj = computeProjectionMatrix(camera);\n const sView = computeViewMatrix(camera);\n const invProj = mat4.create();\n mat4.invert(invProj, sProj);\n\n const out = new Float32Array(64);\n out.set(sView, 0);\n out.set(sProj, 16);\n out.set(invProj, 32);\n\n const ssaoConfig = frameState.installedPipelineConfig?.ssao;\n const parameters = getSsaoParameters(\n ssaoConfig !== undefined && ssaoConfig.enabled === true ? ssaoConfig : undefined,\n );\n out[48] = parameters.intensity;\n out[49] = parameters.radius;\n out[50] = parameters.bias;\n return out;\n}\n\n/**\n * recordSsaoCalcPass — fullscreen SSAO occlusion calculation (M8 / w38).\n *\n * Resolves the graph-owned half-resolution ssaoRaw color target, writes the\n * 256 B SSAO uniform (view/proj/invProj/intensity) once per frame, then runs\n * a 3-vertex fullscreen-triangle draw with fs_ssao_calc.\n *\n * Bind group entries (must match the 9-entry SSAO BGL declared in\n * createRenderer.ts; see hdrp-ssao.wgsl §BGL layout):\n * 0 ssao_uniform UBO 5 hdr_depth view\n * 1 ssao_kernel UBO 6 ssao_depth_sampler (non-filtering)\n * 2 ssao_noise_texture 7 fallback ssaoRaw view (calc never samples)\n * 3 ssao_noise_sampler 8 ssaoSampler (unused by calc, BGL slot)\n * 4 gbuffer_normal view\n *\n * Skips with no GPU work when the optional SSAO pipelines are unavailable\n * (manifest without hdrp-ssao.wgsl), when the dedicated BGL is null, when\n * the SSAO buffers fail to allocate, or when the graph cannot resolve the\n * required views.\n */\nexport interface SsaoCalcPassViews {\n readonly output: TextureView;\n readonly normal: TextureView;\n readonly depth: TextureView;\n readonly depthCacheKey: TextureView;\n}\n\nexport function recordSsaoCalcPass(\n _c: _InternalRenderPipelineContext,\n resolveCtx?: ResolveContext,\n ssaoRawKey?: string,\n gbuf0Key?: string,\n hdrDepthKey?: string,\n graphPass?: RhiRenderPassEncoder,\n graphViews?: SsaoCalcPassViews,\n): void {\n const { runtime, pipelineState, encoder } = _c;\n const pp = pipelineState.perPassResources;\n\n if (pp.ssaoCalcPipeline === null || pp.ssaoBgl === null) return;\n if (graphViews === undefined && (resolveCtx === undefined || ssaoRawKey === undefined)) return;\n\n const ssaoRawView =\n graphViews?.output ?? (resolveCtx?.resolve(ssaoRawKey as string) as TextureView | undefined);\n const gbuf0View =\n graphViews?.normal ??\n (gbuf0Key !== undefined\n ? (resolveCtx?.resolve(gbuf0Key) as TextureView | undefined)\n : undefined);\n if (!ssaoRawView || !gbuf0View || (graphViews === undefined && hdrDepthKey === undefined)) return;\n\n // hdrDepth needs a depth-only view (BGL binding 5 sampleType=depth);\n // resolveCtx returns a default all-aspects view that dawn rejects when\n // paired with a depth sampler.\n const hdrDepthView = graphViews?.depth ?? resolveHdrDepthDepthOnlyView(_c, hdrDepthKey as string);\n if (hdrDepthView === null) return;\n\n // Cache key: the graph's pooled hdrDepth view (stable object per size, new\n // object on resize). The depth-only view above is created fresh every frame\n // so it cannot key the cache; the pooled all-aspects view co-varies with it\n // (both are views of the same transient hdrDepth texture) and changes exactly\n // on resize. Used only as a WeakMap key, never bound.\n const hdrDepthPooledView =\n graphViews?.depthCacheKey ??\n (resolveCtx?.resolve(hdrDepthKey as string) as TextureView | undefined);\n if (hdrDepthPooledView === undefined) return;\n\n const ssaoBufs = getOrCreateSsaoBuffers(runtime);\n if (ssaoBufs === null) return;\n\n const noiseViewRes = runtime.device.createTextureView(ssaoBufs.noiseTexture, {\n label: 'hdrp-ssao-noise-view',\n format: 'rgba32float',\n dimension: '2d',\n aspect: 'all',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!noiseViewRes.ok) {\n runtime.errorRegistry.fire(noiseViewRes.error);\n return;\n }\n\n const companions = ensureSsaoRecordCompanions(_c);\n if (companions === null) return;\n\n // Per-frame uniform write (D-C: view+proj+invProj+intensity at one queue\n // call). 256 B Float32Array (64 f32) lands in ssao_uniform UBO offset 0.\n const payload = buildSsaoUniformPayload(_c);\n const writeRes = runtime.device.queue.writeBuffer(ssaoBufs.uniformBuffer, 0, payload);\n if (!writeRes.ok) {\n runtime.errorRegistry.fire(writeRes.error);\n return;\n }\n\n // Identity-cached bind group: 9 entries mirror the BGL declared in\n // createRenderer. Keyed on the graph-pooled gbuf0 + hdrDepth views (both\n // retire + reallocate on resize), so the WeakMap misses after a resize and\n // rebuilds against the live textures. The noise / depth-only views bound\n // below are created fresh each frame but back stable textures; keying on the\n // resize-varying graph views is what makes invalidation correct. Replaces\n // the prior `=== null` slot cache that submitted a destroyed gbuf0/hdrDepth\n // after resize.\n const ssaoBgl = pp.ssaoBgl;\n const bindGroup = getOrCreateFromChain(\n _c.frameState.postProcessBgCache,\n [gbuf0View, hdrDepthPooledView],\n 'ssao-calc',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'ssao-calc-bg',\n layout: ssaoBgl,\n entries: [\n { binding: 0, resource: { kind: 'buffer', value: { buffer: ssaoBufs.uniformBuffer } } },\n { binding: 1, resource: { kind: 'buffer', value: { buffer: ssaoBufs.kernelBuffer } } },\n { binding: 2, resource: { kind: 'textureView', value: noiseViewRes.value } },\n {\n binding: 3,\n resource: { kind: 'sampler', value: companions.filteringSampler },\n },\n { binding: 4, resource: { kind: 'textureView', value: gbuf0View } },\n { binding: 5, resource: { kind: 'textureView', value: hdrDepthView } },\n { binding: 6, resource: { kind: 'sampler', value: companions.depthSampler } },\n { binding: 7, resource: { kind: 'textureView', value: companions.fallbackRawView } },\n { binding: 8, resource: { kind: 'sampler', value: companions.filteringSampler } },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n _c.bindGroupCounts,\n );\n\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['r8unorm'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [ssaoRawView] },\n 'post-process',\n ) as never,\n );\n pass.setPipeline(pp.ssaoCalcPipeline);\n pass.setBindGroup(0, bindGroup);\n pass.draw(3, 1, 0, 0);\n if (graphPass === undefined) pass.end();\n}\n\n/**\n * recordSsaoBlurPass — fullscreen SSAO 4x4 box blur (M8 / w38).\n *\n * Reads the half-resolution ssaoRaw (R8), applies a 16-tap box blur, writes\n * the blurred result to ssaoBlurred. The BGL is the same 9-entry SSAO BGL\n * as the calc pass; the only difference is binding 7 carries the real\n * ssaoRaw view (vs the 1x1 fallback the calc pass binds).\n */\nexport interface SsaoBlurPassViews extends SsaoCalcPassViews {\n readonly raw: TextureView;\n}\n\nexport function recordSsaoBlurPass(\n _c: _InternalRenderPipelineContext,\n resolveCtx?: ResolveContext,\n ssaoBlurredKey?: string,\n ssaoRawKey?: string,\n gbuf0Key?: string,\n hdrDepthKey?: string,\n graphPass?: RhiRenderPassEncoder,\n graphViews?: SsaoBlurPassViews,\n): void {\n const { runtime, pipelineState, encoder } = _c;\n const pp = pipelineState.perPassResources;\n\n if (pp.ssaoBlurPipeline === null || pp.ssaoBgl === null) return;\n if (\n graphViews === undefined &&\n (resolveCtx === undefined || ssaoBlurredKey === undefined || ssaoRawKey === undefined)\n )\n return;\n\n const ssaoBlurredView =\n graphViews?.output ??\n (resolveCtx?.resolve(ssaoBlurredKey as string) as TextureView | undefined);\n const ssaoRawView =\n graphViews?.raw ?? (resolveCtx?.resolve(ssaoRawKey as string) as TextureView | undefined);\n const gbuf0View =\n graphViews?.normal ??\n (gbuf0Key !== undefined\n ? (resolveCtx?.resolve(gbuf0Key) as TextureView | undefined)\n : undefined);\n if (!ssaoBlurredView || !ssaoRawView) return;\n\n // hdrDepth depth-only view (see recordSsaoCalcPass).\n const hdrDepthView =\n graphViews?.depth ??\n (hdrDepthKey !== undefined ? resolveHdrDepthDepthOnlyView(_c, hdrDepthKey) : null);\n // Pooled hdrDepth view for the cache key (the depth-only view above is\n // recreated every frame; see recordSsaoCalcPass).\n const hdrDepthPooledView =\n graphViews?.depthCacheKey ??\n (hdrDepthKey !== undefined\n ? (resolveCtx?.resolve(hdrDepthKey) as TextureView | undefined)\n : undefined);\n\n const ssaoBufs = getOrCreateSsaoBuffers(runtime);\n if (ssaoBufs === null) return;\n\n const noiseViewRes = runtime.device.createTextureView(ssaoBufs.noiseTexture, {\n label: 'hdrp-ssao-noise-view',\n format: 'rgba32float',\n dimension: '2d',\n aspect: 'all',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!noiseViewRes.ok) {\n runtime.errorRegistry.fire(noiseViewRes.error);\n return;\n }\n\n const companions = ensureSsaoRecordCompanions(_c);\n if (companions === null) return;\n\n // The blur reads ssaoRaw via binding 7 + ssaoSampler at binding 8. The\n // remaining slots 0..6 are bound for BGL completeness (BGL is shared with\n // the calc pass): WebGPU requires every BGL slot carry a valid resource\n // even when the active fragment entry does not statically reference it.\n // gbuf0 + hdr_depth views are resolved from the graph; they must exist\n // because the typed SSAO graph declares them as reads on the blur node.\n if (gbuf0View === undefined || hdrDepthView === null || hdrDepthPooledView === undefined) return;\n // Identity-cached bind group keyed on the graph-pooled ssaoRaw + gbuf0 +\n // hdrDepth views (all retire + reallocate on resize). Replaces the prior\n // `=== null` slot cache that submitted destroyed transients after resize.\n const ssaoBgl = pp.ssaoBgl;\n const bindGroup = getOrCreateFromChain(\n _c.frameState.postProcessBgCache,\n [ssaoRawView, gbuf0View, hdrDepthPooledView],\n 'ssao-blur',\n () => {\n const bgRes = runtime.device.createBindGroup({\n label: 'ssao-blur-bg',\n layout: ssaoBgl,\n entries: [\n { binding: 0, resource: { kind: 'buffer', value: { buffer: ssaoBufs.uniformBuffer } } },\n { binding: 1, resource: { kind: 'buffer', value: { buffer: ssaoBufs.kernelBuffer } } },\n { binding: 2, resource: { kind: 'textureView', value: noiseViewRes.value } },\n {\n binding: 3,\n resource: { kind: 'sampler', value: companions.filteringSampler },\n },\n { binding: 4, resource: { kind: 'textureView', value: gbuf0View } },\n { binding: 5, resource: { kind: 'textureView', value: hdrDepthView } },\n { binding: 6, resource: { kind: 'sampler', value: companions.depthSampler } },\n { binding: 7, resource: { kind: 'textureView', value: ssaoRawView } },\n { binding: 8, resource: { kind: 'sampler', value: companions.filteringSampler } },\n ],\n });\n if (!bgRes.ok) throw bgRes.error;\n return bgRes.value;\n },\n _c.bindGroupCounts,\n );\n\n const pass: RhiRenderPassEncoder =\n graphPass ??\n encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n { colorFormats: ['r8unorm'], depthFormat: undefined, sampleCount: 1 },\n { colorViews: [ssaoBlurredView] },\n 'post-process',\n ) as never,\n );\n pass.setPipeline(pp.ssaoBlurPipeline);\n pass.setBindGroup(0, bindGroup);\n pass.draw(3, 1, 0, 0);\n if (graphPass === undefined) pass.end();\n}\n\n/**\n * F-3 fix-up + feat-20260609 M1 / T-3 patch: per-frame fullscreen-post-process\n * dispatcher.\n *\n * Two-branch fan-out by shader id:\n * - `'fxaa'` (engine-built-in hardwire): delegate to `recordFxaaPass`. The\n * FXAA implementation owns its graph input view, surface output attachment,\n * pipeline cache, and bindgroup-resize invalidation; that mechanics is engine-internal and\n * not expressible through the generic public primitive. recordFxaaPass's\n * body is intentionally unchanged across this refactor to preserve the\n * AC-09 dualPassDiff=1069 (hello-fxaa) / 768 (learn-render-4-10-MSAA)\n * byte-equivalence with the pre-feat baseline.\n * - every other id (AI-user path): the M1 patch wires `reads[0]` through the\n * render-graph `resolveCtx` so the bind group samples the upstream\n * graph-owned color target (e.g. the typed scene pass writes `'offscreenColor'`,\n * a custom post-process pass declares `reads: ['offscreenColor']`).\n * Failure modes (charter P3 fail-fast):\n * - `lookupPostProcess(shader) === undefined` -> throw\n * `PostProcessError({code:'post-process-not-found'})`\n * - `reads.length > 0` but `resolveCtx.resolve(reads[0]) === undefined`\n * -> throw `PostProcessError({code:'fullscreen-input-not-found',\n * detail:{readsKey, passName}})`. AI users read err.detail.readsKey\n * to find the missing graph.addColorTarget declaration.\n * On success the dispatcher builds the input-texture BGL + sampler via\n * `buildFullscreenPostProcessPass`, composes the per-frame bind group\n * via `createFullscreenBindGroup`, opens a render pass writing the\n * declared `color` (resolved through the graph's color-target view, or\n * the swap-chain `ctx.view` when the graph has not allocated a target),\n * binds the input bind group at slot 1 (the 0 slot is reserved for\n * future view bind groups), and calls `handle.draw(pass)` which\n * internally does `setPipeline(pipeline)` + `draw(3, 1, 0, 0)` over the\n * fullscreen-triangle vertex shader.\n *\n * Extracted from the addPass execute closure so the topology fan-out is in\n * one named place; the typed graph has a single\n * call site, and future post-process branches (e.g. tonemap migrated onto\n * this dispatcher per OOS-3) extend this function rather than the addPass\n * inline closure.\n */\nfunction dispatchFullscreenPass(\n ctx: RenderPipelineContext,\n name: string,\n shader: string,\n color: string,\n reads: readonly string[],\n resolveCtx?: ResolveContext,\n compositeOverSwapchain = false,\n rawSwapchainOutput = false,\n graphPass?: RhiRenderPassEncoder,\n graphOutputFormat?: GPUTextureFormat,\n graphDepthView?: TextureView,\n paramsOverride?: Uint8Array,\n): void {\n if (shader === 'fxaa') {\n if (resolveCtx === undefined) {\n throw new PostProcessError({\n code: 'fullscreen-input-not-found',\n detail: { readsKey: reads[0] ?? 'ldrColor', passName: name },\n });\n }\n recordFxaaPass(requireRenderGraphRecordContext(ctx), resolveCtx, graphPass);\n return;\n }\n const lookup = ctx.runtime.lookupPostProcess;\n const entry = lookup === undefined ? undefined : lookup(shader);\n if (entry === undefined) {\n throw new PostProcessError({\n code: 'post-process-not-found',\n detail: { id: shader },\n });\n }\n // feat-20260621 M4' composite-over-swap-chain: copy the current swap-chain\n // into the `color` scratch target BEFORE sampling, so the effect reads the\n // already-composited final image (shadows + tonemap + fxaa). Generalises the\n // built-in FXAA copy idiom. The `color` key is BOTH the copy dst and the\n // sampled input (resolve its GPU texture via `${color}::tex` for the copy,\n // its TextureView via `${color}` for the bind group).\n let inputView: TextureView | null;\n if (compositeOverSwapchain) {\n const scratchTex = resolveCtx?.resolve(`${color}::tex`);\n const scratchView = resolveCtx?.resolve(color);\n if (scratchTex === undefined || scratchView === undefined) {\n throw new PostProcessError({\n code: 'fullscreen-input-not-found',\n detail: { readsKey: color, passName: name },\n });\n }\n ctx.encoder.copyTextureToTexture(\n { texture: ctx.currentTexture as never, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },\n { texture: scratchTex as never, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },\n { width: ctx.targetW, height: ctx.targetH, depthOrArrayLayers: 1 },\n );\n inputView = scratchView as TextureView;\n } else if (reads.length === 0) {\n // reads === [] preserves the legacy swap-chain sample path (used by\n // tonemap-style passes that read the framebuffer directly).\n inputView = ctx.view;\n } else {\n // reads with a key MUST resolve through the graph compile output, otherwise\n // the dispatcher throws fullscreen-input-not-found (charter P3 fail-fast).\n const readsKey = reads[0] as string;\n const resolved = resolveCtx?.resolve(readsKey);\n if (resolved === undefined) {\n throw new PostProcessError({\n code: 'fullscreen-input-not-found',\n detail: { readsKey, passName: name },\n });\n }\n inputView = resolved as TextureView;\n }\n if (inputView === null) return;\n\n // ── BGL/Pipeline build (before depth resolution so built.depthSampler is\n // available for the depth threading block below; ctx.msaaActive selects\n // the multisampled depth BGL when the scene target uses sample=4) ───────\n const built = buildFullscreenPostProcessPass(\n { device: ctx.runtime.device, errorRegistry: ctx.runtime.errorRegistry },\n entry,\n ctx.msaaActive,\n );\n if (built === null) return;\n\n // ── plan-strategy D-6: depth read resolution (pipeline-agnostic, AC-02) ────\n // Iterate entry.reads looking for sampleType:'depth' entries. For each depth\n // entry, resolve a depth-only TextureView from the graph via\n // resolveDepthOnlyView, fail-fast on unresolvable keys. The depth sampler\n // is produced by buildFullscreenPostProcessPass (via createDepthSampler,\n // plan-strategy D-2: non-filtering nearest+clamp-to-edge).\n //\n // Both composite and non-composite branches handle depth symmetrically —\n // the depth resolution block is branch-agnostic (AC-02: no URP/HDRP\n // discrimination). Color input logic is unchanged (AC-03 zero-regression).\n let depthTexView: TextureView | null = graphDepthView ?? null;\n let depthSampler: Sampler | null = null;\n if (entry.reads && entry.reads.length > 0) {\n const internals = requireRenderGraphRecordContext(ctx);\n for (const read of entry.reads) {\n if (typeof read !== 'string' && read.sampleType === 'depth') {\n const depthKey = read.key;\n depthTexView ??= resolveDepthOnlyView(\n internals,\n depthKey,\n 'post-process-scene-depth-only-view',\n internals.geometryDepthKey,\n );\n if (depthTexView === null) {\n throw new PostProcessError({\n code: 'fullscreen-input-not-found',\n detail: { readsKey: depthKey, passName: name },\n });\n }\n depthSampler = built.depthSampler;\n }\n }\n }\n\n // feat-20260621 M4' composite-over-swap-chain write target: the swap-chain's\n // NON-srgb storage view (R-COLORSPACE — the scratch holds an already-sRGB-\n // encoded copy, so writing through the srgb view would double-encode; mirrors\n // recordFxaaPass). Otherwise resolve the declared color through the graph and\n // fall back to ctx.view (swap-chain srgb view) for normal post passes.\n let writeView: TextureView | null | undefined;\n // The attachment format follows the actual write target. Graph-owned\n // targets may be linear HDR/LDR textures (for example rgba16float), while\n // the swap-chain path uses the backend-selected surface view format.\n let writeFormat = ctx.pipelineState?.colorAttachmentFormat ?? 'rgba8unorm-srgb';\n if (graphPass !== undefined) {\n // Typed graph passes must write their declared output target. The frame\n // surface view is only the fallback for legacy passes; using it here\n // leaves a typed output target cleared while the next pass samples it.\n writeView = (resolveCtx?.resolve(color) as TextureView | undefined) ?? ctx.view;\n writeFormat = graphOutputFormat ?? writeFormat;\n } else if (rawSwapchainOutput && color === 'swapchain') {\n const rawViewRes = ctx.runtime.device.createTextureView(ctx.currentTexture, {});\n if (!rawViewRes.ok) {\n ctx.runtime.errorRegistry.fire(rawViewRes.error);\n return;\n }\n writeView = rawViewRes.value;\n writeFormat = ctx.pipelineState?.format ?? 'rgba8unorm';\n } else if (compositeOverSwapchain) {\n const storageViewRes = ctx.runtime.device.createTextureView(ctx.currentTexture, {});\n if (!storageViewRes.ok) {\n ctx.runtime.errorRegistry.fire(storageViewRes.error);\n return;\n }\n writeView = storageViewRes.value;\n writeFormat = ctx.pipelineState?.format ?? 'rgba8unorm';\n } else {\n const legacyGraph = requireRenderGraphRecordContext(ctx).frameState.perFrameGraph;\n const graphColorFormat = legacyGraph?.getColorTargetDescriptor(color)?.format;\n if (graphColorFormat !== undefined) writeFormat = graphColorFormat;\n const resolvedColor = (resolveCtx?.resolve(color) as TextureView | undefined) ?? null;\n writeView = legacyGraph?.getColorTargetView(color) ?? resolvedColor ?? ctx.view;\n }\n if (writeView === null || writeView === undefined) return;\n\n // feat-20260621 M-A2 / w8: per-frame data-driven params channel. When the\n // entry declares params, look up the per-id eager-created UBO + the per-frame\n // bytes from the PostProcessParams snapshot, fail-fast on a byteLength\n // mismatch, then writeBuffer + bind the UBO at group(1) binding(2). When\n // entry.params is undefined this whole block is skipped and the BGL degrades\n // to 2-entry (param-less zero-regression, R-A7).\n let paramsBuffer: Buffer | null = null;\n if (entry.params !== undefined) {\n const ubo = ctx.runtime.getPostProcessParamsBuffer?.(shader);\n if (ubo !== undefined) {\n // Typed graph passes may make a narrow, per-pass copy of the payload\n // (for example enabling final-surface dither without changing the\n // camera-owned SSOT). Use it when present, while preserving the normal\n // frame snapshot for legacy callers.\n const data = paramsOverride ?? ctx.postProcessParams.get(shader);\n if (data !== undefined) {\n if (data.byteLength !== entry.params.byteSize) {\n throw new PostProcessError({\n code: 'params-update-size-mismatch',\n detail: { byteSize: entry.params.byteSize, actualLength: data.byteLength },\n });\n }\n const writeResult = ctx.runtime.device.queue.writeBuffer(ubo, 0, data);\n if (!writeResult.ok) return;\n } else {\n const writeResult = ctx.runtime.device.queue.writeBuffer(ubo, 0, entry.params.defaultValue);\n if (!writeResult.ok) return;\n }\n paramsBuffer = ubo;\n }\n } else if (entryHasDepthRead(entry)) {\n // D-3: a param-less depth entry still binds the minimal UBO auto-allocated\n // at register (the 'fullscreen-post-with-scene-depth' BGL always declares\n // params@2). No per-frame write -- the buffer stays zero-filled.\n paramsBuffer = ctx.runtime.getPostProcessParamsBuffer?.(shader) ?? null;\n }\n\n const bindGroup = createFullscreenBindGroup(\n ctx.runtime.device,\n built.bindGroupLayout,\n inputView,\n built.sampler,\n paramsBuffer,\n depthTexView,\n depthSampler,\n built.extraColorBindings.map((binding, index) => {\n const read = entry.reads?.filter(\n (candidate) => typeof candidate === 'string' || candidate.sampleType !== 'depth',\n )[index + 1];\n const key = typeof read === 'string' ? read : read?.key;\n const view = key === undefined ? undefined : resolveCtx?.resolve(key);\n if (view === undefined) {\n throw new PostProcessError({\n code: 'fullscreen-input-not-found',\n detail: { readsKey: key ?? 'additional-read', passName: name },\n });\n }\n return { binding, view: view as TextureView };\n }),\n );\n if (bindGroup === null) return;\n\n // Pipeline source-of-truth (M4 / T-10-a, solving M1 CONCERN-1):\n // RenderSystemRuntime.getPostProcessPipeline is the sync wrapper over the\n // shared shader-module adapter (1-frame warmup). First frame after\n // fullscreen effect registration: shader compile is in flight -> returns null -> we\n // skip the pass for that frame. Second frame onward: cached pipeline is\n // returned synchronously.\n //\n // Color format SSOT: graph-owned writes use their resolved descriptor format;\n // swap-chain writes use the backend-aware surface format in pipelineState.\n // This keeps the PSO target and render-pass attachment identical when a\n // fullscreen pass writes an intermediate rgba16float target (for example\n // tonemap -> FXAA), while preserving the native surface storage/sRGB split.\n const lookupPipeline = ctx.runtime.getPostProcessPipeline;\n if (lookupPipeline === undefined) return;\n const postColorFormat = writeFormat;\n const pipeline = lookupPipeline(shader, built.bindGroupLayout, postColorFormat);\n if (pipeline === null) return;\n const handle = built.createHandle(name, pipeline, paramsBuffer);\n\n // Open a render pass writing into the resolved color target. Fullscreen\n // post-process passes are non-MSAA, depth-less, single-attachment.\n // setBindGroup(1, ...) (group=1 reserved per plan-strategy convention;\n // group=0 is reserved for future view bind groups, mirroring the\n // recordTonemap / recordSkybox pattern that uses slot 0 only when the\n // pipeline declares a single bind group at slot 0).\n const pass =\n graphPass ??\n ctx.encoder.beginRenderPass(\n buildBeginRenderPassDescriptor(\n {\n colorFormats: [writeFormat],\n depthFormat: undefined,\n sampleCount: 1,\n },\n { colorViews: [writeView] },\n 'post-process',\n ) as never,\n );\n pass.setBindGroup(1, bindGroup);\n handle.draw(pass, inputView);\n if (graphPass === undefined) pass.end();\n}\n\nexport function encodeFullscreenPass(\n ctx: RenderPipelineContext,\n pass: RhiRenderPassEncoder,\n input: {\n readonly name: string;\n readonly shader: string;\n readonly color: string;\n readonly reads: readonly string[];\n readonly resolve: ResolveContext;\n readonly outputFormat: GPUTextureFormat;\n readonly rawSwapchainOutput?: boolean | undefined;\n readonly depthView?: TextureView | undefined;\n readonly paramsOverride?: Uint8Array | undefined;\n },\n): void {\n dispatchFullscreenPass(\n ctx,\n input.name,\n input.shader,\n input.color,\n input.reads,\n input.resolve,\n false,\n input.rawSwapchainOutput ?? false,\n pass,\n input.outputFormat,\n input.depthView,\n input.paramsOverride,\n );\n}\n","import type {\n BindGroupLayout,\n Buffer,\n RhiDevice,\n RhiQueue,\n Sampler,\n Texture,\n TextureView,\n} from '@forgeax/engine-rhi';\nimport type { DeviceScope } from '../device/device-scope';\nimport {\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from '../gpu-texture-usage';\nimport { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from '../gpu-usage';\nimport type { RenderFrameState } from '../record/frame-snapshot';\n\ninterface TemporalSurface {\n readonly texture: Texture;\n readonly view: TextureView;\n}\n\nexport interface TemporalGpuState {\n readonly device: RhiDevice;\n readonly scope: DeviceScope;\n readonly childScope: DeviceScope;\n width: number;\n height: number;\n valid: boolean;\n readIndex: 0 | 1;\n pendingIndex: 0 | 1 | undefined;\n readonly color: [TemporalSurface, TemporalSurface];\n readonly temporal: [TemporalSurface, TemporalSurface];\n bindGroupLayout: BindGroupLayout | undefined;\n sampler: Sampler | undefined;\n paramsBuffer: Buffer | undefined;\n committed: boolean;\n}\n\nfunction createSurface(\n device: RhiDevice,\n childScope: DeviceScope,\n label: string,\n width: number,\n height: number,\n): TemporalSurface {\n const texture = device.createTexture({\n label,\n size: { width, height, depthOrArrayLayers: 1 },\n format: 'rgba16float',\n textureBindingViewDimension: undefined,\n usage:\n GPU_TEXTURE_USAGE_COPY_SRC |\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n });\n if (!texture.ok) throw texture.error;\n childScope._adopt('texture', texture.value, (value) => {\n device.destroyTexture(value);\n });\n const view = device.createTextureView(texture.value, {\n label: `${label}.view`,\n dimension: '2d',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!view.ok) throw view.error;\n return { texture: texture.value, view: view.value };\n}\n\nfunction createState(\n device: RhiDevice,\n scope: DeviceScope,\n width: number,\n height: number,\n): TemporalGpuState {\n const childScope = scope.createChild(`${scope.owner}:temporal`);\n try {\n return {\n device,\n scope,\n childScope,\n width,\n height,\n valid: false,\n readIndex: 0,\n pendingIndex: undefined,\n color: [\n createSurface(device, childScope, 'taa-history-color-a', width, height),\n createSurface(device, childScope, 'taa-history-color-b', width, height),\n ],\n temporal: [\n createSurface(device, childScope, 'taa-history-temporal-a', width, height),\n createSurface(device, childScope, 'taa-history-temporal-b', width, height),\n ],\n bindGroupLayout: undefined,\n sampler: undefined,\n paramsBuffer: undefined,\n committed: false,\n };\n } catch (cause) {\n childScope.abandon();\n throw cause;\n }\n}\n\nexport function getTemporalParamsBuffer(state: TemporalGpuState): Buffer {\n if (state.paramsBuffer !== undefined) return state.paramsBuffer;\n const created = state.device.createBuffer({\n label: 'taa-resolve-params',\n size: 16,\n usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,\n mappedAtCreation: false,\n });\n if (!created.ok) {\n if (!state.committed) state.childScope.abandon();\n throw created.error;\n }\n state.childScope._adopt('buffer', created.value, (value) => {\n state.device.destroyBuffer(value);\n });\n const written = state.device.queue.writeBuffer(created.value, 0, new Uint8Array(16));\n if (!written.ok) {\n if (!state.committed) state.childScope.abandon();\n throw written.error;\n }\n state.paramsBuffer = created.value;\n return created.value;\n}\n\nexport function getTemporalGpuState(\n frameState: RenderFrameState,\n device: RhiDevice,\n scope: DeviceScope,\n width: number,\n height: number,\n): TemporalGpuState {\n const staged = frameState.temporalGpuState;\n if (\n staged !== undefined &&\n staged.scope === scope &&\n staged.width === width &&\n staged.height === height\n ) {\n return staged;\n }\n const existing = frameState.activeTemporalGpuState;\n if (\n existing !== undefined &&\n existing.scope === scope &&\n existing.width === width &&\n existing.height === height\n ) {\n return existing;\n }\n const next = createState(device, scope, width, height);\n frameState.temporalGpuState = next;\n return next;\n}\n\nexport function getTemporalBindGroupResources(state: TemporalGpuState): {\n readonly layout: BindGroupLayout;\n readonly sampler: Sampler | null;\n} {\n if (state.bindGroupLayout !== undefined) {\n return {\n layout: state.bindGroupLayout,\n sampler: state.sampler ?? null,\n };\n }\n try {\n const layout = state.device.createBindGroupLayout({\n label: 'taa-resolve-bind-group',\n entries: [\n {\n binding: 0,\n visibility: 2,\n texture: { sampleType: 'unfilterable-float', viewDimension: '2d' },\n },\n { binding: 1, visibility: 2, sampler: { type: 'non-filtering' } },\n {\n binding: 2,\n visibility: 2,\n texture: { sampleType: 'unfilterable-float', viewDimension: '2d' },\n },\n { binding: 3, visibility: 2, sampler: { type: 'non-filtering' } },\n {\n binding: 4,\n visibility: 2,\n texture: { sampleType: 'unfilterable-float', viewDimension: '2d' },\n },\n { binding: 5, visibility: 2, sampler: { type: 'non-filtering' } },\n {\n binding: 6,\n visibility: 2,\n texture: { sampleType: 'unfilterable-float', viewDimension: '2d' },\n },\n { binding: 7, visibility: 2, sampler: { type: 'non-filtering' } },\n { binding: 8, visibility: 2, buffer: { type: 'uniform' } },\n ],\n });\n if (!layout.ok) throw layout.error;\n state.childScope._adopt('binding', layout.value, () => undefined);\n const sampler = state.device.createSampler({\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n magFilter: 'nearest',\n minFilter: 'nearest',\n });\n if (!sampler.ok) throw sampler.error;\n state.childScope._adopt('binding', sampler.value, () => undefined);\n state.bindGroupLayout = layout.value;\n state.sampler = sampler.value;\n return { layout: layout.value, sampler: sampler.value };\n } catch (cause) {\n if (!state.committed) {\n state.childScope.abandon();\n state.bindGroupLayout = undefined;\n state.sampler = undefined;\n }\n throw cause;\n }\n}\n\nexport function temporalReadIndex(state: TemporalGpuState): 0 | 1 {\n return state.readIndex;\n}\n\nexport function temporalWriteIndex(state: TemporalGpuState): 0 | 1 {\n return state.readIndex === 0 ? 1 : 0;\n}\n\nexport function stageTemporalGpuSubmit(state: TemporalGpuState): void {\n state.pendingIndex = state.readIndex === 0 ? 1 : 0;\n}\n\nexport function hasPendingTemporalGpuSubmit(state: TemporalGpuState): boolean {\n return state.pendingIndex !== undefined;\n}\n\nexport function commitTemporalGpuSubmit(state: TemporalGpuState): boolean {\n if (state.pendingIndex === undefined) return false;\n state.readIndex = state.pendingIndex;\n state.pendingIndex = undefined;\n state.valid = true;\n state.committed = true;\n return true;\n}\n\nexport function abortTemporalGpuSubmit(state: TemporalGpuState): void {\n state.pendingIndex = undefined;\n}\n\nexport function retireTemporalGpuState(state: TemporalGpuState): void {\n state.pendingIndex = undefined;\n state.childScope.retire();\n state.valid = false;\n state.committed = false;\n state.bindGroupLayout = undefined;\n state.sampler = undefined;\n state.paramsBuffer = undefined;\n}\n\nexport function retireTemporalGpuStateAfterFence(\n state: TemporalGpuState,\n queue: RhiQueue,\n retiring: Set<TemporalGpuState>,\n onFailure: (cause: unknown) => void,\n): void {\n if (state.childScope.state === 'retired' || state.childScope.state === 'abandoned') return;\n state.childScope.beginRetire();\n retiring.add(state);\n void queue.onSubmittedWorkDone().then(\n () => {\n retiring.delete(state);\n retireTemporalGpuState(state);\n },\n (cause) => {\n retiring.delete(state);\n onFailure(cause);\n retireTemporalGpuState(state);\n },\n );\n}\n","import type {\n GraphAccess,\n GraphResourceResolver,\n GraphTextureView,\n RenderGraphBuilder,\n RenderGraphError,\n ResolveContext,\n} from '@forgeax/engine-render-graph';\nimport { RhiError, type TextureView } from '@forgeax/engine-rhi';\nimport { ok, type PassKind, type PassSelector, type Result } from '@forgeax/engine-types';\nimport {\n GPU_TEXTURE_USAGE_COPY_SRC,\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n} from './gpu-texture-usage';\nimport { buildPerFrameBindGroups } from './record/frame-lighting';\nimport { encodeMainPass } from './record/main-pass';\nimport type {\n _InternalRenderPipelineContext,\n RenderSystemInternals,\n} from './record/render-context';\nimport {\n encodeSkyboxPass,\n recordBloomBlurHPass,\n recordBloomBlurVPass,\n recordBloomBrightPass,\n recordBloomCompositePass,\n} from './record/skybox-post-pass';\nimport { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID } from './render-contract';\nimport {\n encodeFullscreenPass,\n recordSsaoBlurPass,\n recordSsaoCalcPass,\n} from './render-graph-primitives';\nimport type { RenderPipelineFrame, RenderPipelineGpuDrivenProjection } from './render-pipeline';\nimport { createRenderPipelineTarget, type RenderPipelineTarget } from './render-pipeline';\nimport type { OcclusionFrameProjection } from './scene/visibility/occlusion-runtime';\nimport {\n getTemporalBindGroupResources,\n getTemporalGpuState,\n getTemporalParamsBuffer,\n stageTemporalGpuSubmit,\n} from './temporal/gpu';\n\nfunction resolvedView(resources: GraphResourceResolver, view: GraphTextureView): TextureView {\n const result = resources.textureView(view);\n if (!result.ok) throw result.error;\n return result.value;\n}\n\nfunction throwTemporalEncodeFailure(expected: string, cause?: unknown): never {\n throw new RhiError({\n code: 'webgpu-runtime-error',\n expected,\n hint:\n cause === undefined\n ? 'retry the temporal frame after repairing its GPU resource'\n : String(cause),\n });\n}\n\nexport function typedFrameClearColor(frame: RenderPipelineFrame): GPUColor {\n return {\n r: frame.clear[0] ?? 0,\n g: frame.clear[1] ?? 0,\n b: frame.clear[2] ?? 0,\n a: frame.clear[3] ?? 1,\n };\n}\n\nfunction resolvedDepthView(\n frame: RenderPipelineFrame,\n resources: GraphResourceResolver,\n target: RenderPipelineTarget,\n): TextureView {\n const texture = resources.texture(target.texture);\n if (!texture.ok) throw texture.error;\n const view = frame.runtime.device.createTextureView(texture.value, {\n label: 'typed-ssao-depth-only-view',\n dimension: '2d',\n aspect: 'depth-only',\n baseMipLevel: 0,\n mipLevelCount: 1,\n baseArrayLayer: 0,\n arrayLayerCount: 1,\n });\n if (!view.ok) throw view.error;\n return view.value;\n}\n\nfunction legacyResolver(\n resources: GraphResourceResolver,\n targets: Readonly<Record<string, RenderPipelineTarget>>,\n): ResolveContext {\n return {\n resolve: (name) => {\n const target = targets[name];\n return target === undefined ? undefined : resolvedView(resources, target.view);\n },\n };\n}\n\nexport function addTypedSkyboxPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n color: RenderPipelineTarget,\n): Result<void, RenderGraphError> {\n return graph.addRasterPass('skybox', {\n accesses: [{ resource: color.view, usage: 'color-attachment' }],\n colorAttachments: [\n {\n view: color.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: typedFrameClearColor,\n },\n ],\n encode: ({ pass, frame }) => encodeSkyboxPass(frame as _InternalRenderPipelineContext, pass),\n });\n}\n\nexport interface TypedScenePassOptions {\n readonly name: string;\n readonly color: RenderPipelineTarget;\n readonly depth: RenderPipelineTarget;\n readonly resolve?: RenderPipelineTarget | undefined;\n readonly sampled?: readonly RenderPipelineTarget[] | undefined;\n readonly directionalShadow?: RenderPipelineTarget | undefined;\n readonly spotShadow?: RenderPipelineTarget | undefined;\n readonly ssao?: RenderPipelineTarget | undefined;\n readonly selector: PassSelector;\n readonly passKind?: PassKind | undefined;\n readonly colorTargets?: readonly RenderPipelineTarget[] | undefined;\n readonly clearColor?: readonly [number, number, number, number] | undefined;\n readonly colorLoadOp?: GPULoadOp | undefined;\n readonly depthLoadOp?: GPULoadOp | undefined;\n readonly recordMode?: 'opaque' | 'transmission' | 'transparent' | undefined;\n readonly transmissionBackdrop?: GraphTextureView | undefined;\n readonly extraAccesses?: readonly GraphAccess[] | undefined;\n readonly gpuDriven?: RenderPipelineGpuDrivenProjection | undefined;\n readonly occlusion?: OcclusionFrameProjection | undefined;\n}\n\nexport function addTypedScenePass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n options: TypedScenePassOptions,\n): Result<void, RenderGraphError> {\n const colorTargets = options.colorTargets ?? [options.color];\n const accesses: GraphAccess[] = [\n ...colorTargets.map((target) => ({\n resource: target.view,\n usage: 'color-attachment' as const,\n })),\n { resource: options.depth.view, usage: 'depth-stencil-write' },\n ...(options.sampled ?? []).map((target) => ({\n resource: target.view,\n usage: 'sampled-read' as const,\n })),\n ...(options.transmissionBackdrop === undefined\n ? []\n : [{ resource: options.transmissionBackdrop, usage: 'sampled-read' as const }]),\n ...(options.extraAccesses ?? []),\n ...(options.gpuDriven?.accesses ?? []),\n ];\n if (options.resolve !== undefined) {\n accesses.push({ resource: options.resolve.view, usage: 'color-attachment' });\n }\n return graph.addRasterPass(options.name, {\n accesses,\n colorAttachments: colorTargets.map((target, index) => ({\n view: target.view,\n ...(index === 0 && options.resolve !== undefined\n ? { resolveTarget: options.resolve.view }\n : {}),\n loadOp: options.colorLoadOp ?? 'clear',\n storeOp: 'store',\n clearValue: {\n r: options.clearColor?.[0] ?? 0,\n g: options.clearColor?.[1] ?? 0,\n b: options.clearColor?.[2] ?? 0,\n a: options.clearColor?.[3] ?? 1,\n },\n })),\n depthStencilAttachment: {\n view: options.depth.view,\n depthClearValue: 1,\n depthLoadOp: options.depthLoadOp ?? 'clear',\n depthStoreOp: 'store',\n stencilClearValue: 0,\n stencilLoadOp: options.depthLoadOp ?? 'clear',\n stencilStoreOp: 'store',\n },\n occlusionQuerySet: options.occlusion?.querySet,\n encode: ({ pass, frame, resources }) => {\n const colorViews = colorTargets.map((target) => resolvedView(resources, target.view));\n const depthView = resolvedView(resources, options.depth.view);\n const resolveView =\n options.resolve === undefined ? null : resolvedView(resources, options.resolve.view);\n const internal = frame as _InternalRenderPipelineContext;\n const directionalShadow =\n options.directionalShadow === undefined\n ? undefined\n : resolvedView(resources, options.directionalShadow.view);\n const spotShadow =\n options.spotShadow === undefined\n ? undefined\n : resolvedView(resources, options.spotShadow.view);\n const ssao =\n options.ssao === undefined ? undefined : resolvedView(resources, options.ssao.view);\n const transmissionBackdrop =\n options.transmissionBackdrop === undefined\n ? null\n : resolvedView(resources, options.transmissionBackdrop);\n internal.frameState.currentDirectionalShadowView = directionalShadow ?? null;\n internal.frameState.currentSpotShadowView = spotShadow ?? null;\n const groups = buildPerFrameBindGroups(\n internal.runtime as RenderSystemInternals,\n internal.frameState,\n internal.pipelineState,\n internal.validated.length > 0 || options.gpuDriven !== undefined,\n internal.bindGroupCounts,\n {\n directionalShadow,\n spotShadow,\n projector: internal.spotLightProjector?.view ?? internal.volumetricFog?.projectorView,\n projectorSampler:\n internal.spotLightProjector?.sampler ?? internal.volumetricFog?.projectorSampler,\n },\n true,\n internal.standardLighting,\n );\n if (groups.viewBindGroup !== null) {\n options.gpuDriven?.encode(groups.viewBindGroup, pass, resources);\n }\n // The context carries the frame's primary occlusion projection for\n // pipeline construction, but only the pass that owns that projection\n // may begin its query. Forwarding it to deferred/temporal scene passes\n // leaves their descriptors without an occlusionQuerySet and makes Dawn\n // reject beginOcclusionQuery in those passes.\n const activeOcclusion = options.occlusion;\n encodeMainPass(\n {\n ...internal,\n ...(activeOcclusion === undefined ? {} : { occlusion: activeOcclusion }),\n geometryColorView: colorViews[0] ?? null,\n geometryDepthView: depthView,\n geometryColorResolveView: resolveView,\n transparentColorFormat: colorTargets[0]?.format as GPUTextureFormat,\n ...(colorTargets[1]?.format === 'rgba16float'\n ? { reflectionFallbackColorFormat: 'rgba16float' as const }\n : {}),\n msaaActive: colorTargets[0]?.sampleCount === 4,\n viewBindGroup: groups.viewBindGroup,\n meshBindGroup: groups.meshBindGroup,\n hdrpClusterBindGroup: groups.hdrpClusterBindGroup,\n hdrpClusterMembershipBindGroup: groups.hdrpClusterMembershipBindGroup,\n ...(ssao === undefined ? {} : { hdrpSsaoBlurredView: ssao }),\n },\n pass,\n options.selector,\n {\n colorViews,\n colorFormats: colorTargets.map((target) => target.format as GPUTextureFormat),\n depthView,\n passKind: options.passKind ?? 'forward',\n ...(options.clearColor === undefined ? {} : { clearColor: options.clearColor }),\n ...(options.recordMode === undefined ? {} : { recordMode: options.recordMode }),\n ...(options.transmissionBackdrop === undefined\n ? {}\n : { transmissionBackdropView: transmissionBackdrop }),\n },\n );\n if (activeOcclusion !== undefined) {\n const proxyResult = activeOcclusion.encodeProxyBounds(pass);\n if (!proxyResult.ok) throw proxyResult.error;\n }\n },\n });\n}\n\nexport function addTypedFrameObservationPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n target: RenderPipelineTarget,\n pipelineId: 'forgeax::standard',\n): Result<void, RenderGraphError> {\n return graph.addCopyPass('linear-hdr-observation', {\n accesses: [{ resource: target.view, usage: 'copy-src' }],\n encode: ({ frame, resources }) => {\n const internal = frame as _InternalRenderPipelineContext;\n const texture = resources.texture(target.texture);\n if (!texture.ok) throw texture.error;\n internal.frameState.currentFrameObservationSource = {\n texture: texture.value,\n descriptor: {\n texture: texture.value,\n format: target.format,\n size: { width: frame.targetW, height: frame.targetH },\n usage:\n GPU_TEXTURE_USAGE_COPY_SRC |\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n sample: target.sampleCount,\n },\n frameId: internal.frameState.frameNumber,\n pipelineId,\n backendId: frame.runtime.device.caps.backendKind,\n };\n },\n });\n}\n\n/** Publish the same-frame fallback MRT as a detached, copy-readable source. */\nexport function addReflectionFallbackObservationPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n target: RenderPipelineTarget,\n): Result<void, RenderGraphError> {\n return graph.addCopyPass('reflection-fallback-observation', {\n accesses: [{ resource: target.view, usage: 'copy-src' }],\n encode: ({ frame, resources }) => {\n const internal = frame as _InternalRenderPipelineContext;\n const texture = resources.texture(target.texture);\n if (!texture.ok) throw texture.error;\n internal.frameState.reflectionFallbackObservationSource = {\n texture: texture.value,\n descriptor: {\n texture: texture.value,\n format: target.format,\n size: { width: frame.targetW, height: frame.targetH },\n usage:\n GPU_TEXTURE_USAGE_COPY_SRC |\n GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |\n GPU_TEXTURE_USAGE_TEXTURE_BINDING,\n sample: target.sampleCount,\n },\n frameId: internal.frameState.frameNumber,\n pipelineId: 'forgeax::standard',\n backendId: internal.runtime.device.caps.backendKind,\n };\n },\n });\n}\n\nexport interface TypedBloomTargets {\n readonly scene: RenderPipelineTarget;\n readonly composited: RenderPipelineTarget;\n readonly bright: RenderPipelineTarget;\n readonly blurH: RenderPipelineTarget;\n readonly blurV: RenderPipelineTarget;\n}\n\n/** The semantic Bloom pass owner; graph inspection consumes these same identities. */\nexport const TYPED_BLOOM_PASS_NAMES = {\n bright: 'bloom-bright',\n blurH: 'bloom-blur-h',\n blurV: 'bloom-blur-v',\n composite: 'bloom-composite',\n} as const;\n\nexport function addTypedBloomPasses(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n targets: TypedBloomTargets,\n): Result<void, RenderGraphError> {\n const named = {\n hdrColor: targets.scene,\n hdrComposited: targets.composited,\n bloomBright: targets.bright,\n bloomBlurH: targets.blurH,\n bloomBlurV: targets.blurV,\n };\n const descriptors = [\n {\n name: TYPED_BLOOM_PASS_NAMES.bright,\n reads: [targets.scene],\n write: targets.bright,\n encode: recordBloomBrightPass,\n },\n {\n name: TYPED_BLOOM_PASS_NAMES.blurH,\n reads: [targets.bright],\n write: targets.blurH,\n encode: recordBloomBlurHPass,\n },\n {\n name: TYPED_BLOOM_PASS_NAMES.blurV,\n reads: [targets.blurH],\n write: targets.blurV,\n encode: recordBloomBlurVPass,\n },\n {\n name: TYPED_BLOOM_PASS_NAMES.composite,\n reads: [targets.scene, targets.blurV],\n write: targets.composited,\n encode: recordBloomCompositePass,\n },\n ] as const;\n for (const descriptor of descriptors) {\n const added = graph.addRasterPass(descriptor.name, {\n accesses: [\n ...descriptor.reads.map((target) => ({\n resource: target.view,\n usage: 'sampled-read' as const,\n })),\n { resource: descriptor.write.view, usage: 'color-attachment' },\n ],\n colorAttachments: [\n {\n view: descriptor.write.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n },\n ],\n encode: ({ pass, frame, resources }) =>\n descriptor.encode(\n frame as _InternalRenderPipelineContext,\n legacyResolver(resources, named),\n pass,\n ),\n });\n if (!added.ok) return added;\n }\n return ok(undefined);\n}\n\nexport interface TypedSsaoTargets {\n readonly normal: RenderPipelineTarget;\n readonly depth: RenderPipelineTarget;\n readonly raw: RenderPipelineTarget;\n readonly blurred: RenderPipelineTarget;\n}\n\nexport function addTypedSsaoPasses(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n targets: TypedSsaoTargets,\n): Result<void, RenderGraphError> {\n const calc = graph.addRasterPass('ssao-calc', {\n accesses: [\n { resource: targets.normal.view, usage: 'sampled-read' },\n { resource: targets.depth.view, usage: 'sampled-read' },\n { resource: targets.raw.view, usage: 'color-attachment' },\n ],\n colorAttachments: [\n {\n view: targets.raw.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 1, g: 1, b: 1, a: 1 },\n },\n ],\n encode: ({ pass, frame, resources }) => {\n const normal = resolvedView(resources, targets.normal.view);\n const depthCacheKey = resolvedView(resources, targets.depth.view);\n recordSsaoCalcPass(\n frame as _InternalRenderPipelineContext,\n undefined,\n undefined,\n undefined,\n undefined,\n pass,\n {\n output: resolvedView(resources, targets.raw.view),\n normal,\n depth: resolvedDepthView(frame, resources, targets.depth),\n depthCacheKey,\n },\n );\n },\n });\n if (!calc.ok) return calc;\n\n return graph.addRasterPass('ssao-blur', {\n accesses: [\n { resource: targets.raw.view, usage: 'sampled-read' },\n { resource: targets.normal.view, usage: 'sampled-read' },\n { resource: targets.depth.view, usage: 'sampled-read' },\n { resource: targets.blurred.view, usage: 'color-attachment' },\n ],\n colorAttachments: [\n {\n view: targets.blurred.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 1, g: 1, b: 1, a: 1 },\n },\n ],\n encode: ({ pass, frame, resources }) => {\n const normal = resolvedView(resources, targets.normal.view);\n const depthCacheKey = resolvedView(resources, targets.depth.view);\n recordSsaoBlurPass(\n frame as _InternalRenderPipelineContext,\n undefined,\n undefined,\n undefined,\n undefined,\n undefined,\n pass,\n {\n output: resolvedView(resources, targets.blurred.view),\n raw: resolvedView(resources, targets.raw.view),\n normal,\n depth: resolvedDepthView(frame, resources, targets.depth),\n depthCacheKey,\n },\n );\n },\n });\n}\n\nexport interface TypedFullscreenPassOptions {\n readonly name: string;\n readonly shader: string;\n readonly input: RenderPipelineTarget;\n readonly output: RenderPipelineTarget;\n readonly outputOnly?: boolean | undefined;\n readonly rawSwapchainOutput?: boolean | undefined;\n readonly depth?: RenderPipelineTarget | undefined;\n readonly additionalReads?: readonly {\n readonly key: string;\n readonly target: RenderPipelineTarget;\n }[];\n /** Optional per-pass copy of the params UBO payload. */\n readonly paramsTransform?:\n | ((params: Uint8Array | undefined) => Uint8Array | undefined)\n | undefined;\n}\n\nexport interface TypedTemporalResolveTargets {\n readonly scene: RenderPipelineTarget;\n readonly currentTemporal: RenderPipelineTarget;\n readonly depth: RenderPipelineTarget;\n readonly historyColor: RenderPipelineTarget;\n readonly historyTemporal: RenderPipelineTarget;\n readonly writeColor: RenderPipelineTarget;\n readonly writeTemporal: RenderPipelineTarget;\n}\n\nexport function addTypedTemporalResolvePass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n targets: TypedTemporalResolveTargets,\n): Result<void, RenderGraphError> {\n const added = graph.addRasterPass('taa-resolve', {\n accesses: [\n { resource: targets.scene.view, usage: 'sampled-read' },\n { resource: targets.currentTemporal.view, usage: 'sampled-read' },\n { resource: targets.historyColor.view, usage: 'sampled-read' },\n { resource: targets.historyTemporal.view, usage: 'sampled-read' },\n { resource: targets.writeColor.view, usage: 'color-attachment' },\n { resource: targets.writeTemporal.view, usage: 'color-attachment' },\n ],\n colorAttachments: [\n {\n view: targets.writeColor.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n {\n view: targets.writeTemporal.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n },\n ],\n encode: ({ pass, frame, resources }) => {\n const internal = frame as _InternalRenderPipelineContext;\n const state = getTemporalGpuState(\n internal.frameState,\n frame.runtime.device,\n (frame.runtime as import('./record/render-context').RenderSystemRuntime).deviceScope,\n frame.targetW,\n frame.targetH,\n );\n const built = getTemporalBindGroupResources(state);\n const current = resolvedView(resources, targets.scene.view);\n const currentTemporal = resolvedView(resources, targets.currentTemporal.view);\n const historyColor = resolvedView(resources, targets.historyColor.view);\n const historyTemporal = resolvedView(resources, targets.historyTemporal.view);\n const params = getTemporalParamsBuffer(state);\n if (params === undefined || built.sampler === null) {\n throwTemporalEncodeFailure('TAA resolve has an admitted params buffer and sampler');\n }\n const payload = new ArrayBuffer(16);\n new Float32Array(payload).set([\n frame.camera.temporal?.currentJitterUv?.[0] ?? 0,\n frame.camera.temporal?.currentJitterUv?.[1] ?? 0,\n ]);\n const words = new Uint32Array(payload);\n words[2] = state.valid && (frame.camera.temporal?.historyValid ?? true) ? 1 : 0;\n words[3] = frame.camera.temporal?.temporalFrameIndex ?? 0;\n const written = frame.runtime.device.queue.writeBuffer(params, 0, new Uint8Array(payload));\n if (!written.ok)\n throwTemporalEncodeFailure('TAA resolve params upload succeeds', written.error);\n const bindGroup = frame.runtime.device.createBindGroup({\n label: 'taa-resolve-bind-group',\n layout: built.layout,\n entries: [\n { binding: 0, resource: { kind: 'textureView', value: current } },\n { binding: 1, resource: { kind: 'sampler', value: built.sampler } },\n { binding: 2, resource: { kind: 'textureView', value: historyColor } },\n { binding: 3, resource: { kind: 'sampler', value: built.sampler } },\n { binding: 4, resource: { kind: 'textureView', value: historyTemporal } },\n { binding: 5, resource: { kind: 'sampler', value: built.sampler } },\n { binding: 6, resource: { kind: 'textureView', value: currentTemporal } },\n { binding: 7, resource: { kind: 'sampler', value: built.sampler } },\n { binding: 8, resource: { kind: 'buffer', value: { buffer: params } } },\n ] as never,\n });\n if (!bindGroup.ok) {\n throwTemporalEncodeFailure('TAA resolve bind group creation succeeds', bindGroup.error);\n }\n const pipeline = frame.runtime.getPostProcessPipeline?.(\n 'forgeax.taa-resolve',\n built.layout,\n targets.writeColor.format as GPUTextureFormat,\n );\n if (pipeline === null || pipeline === undefined) {\n throwTemporalEncodeFailure('TAA resolve pipeline is ready before frame encoding');\n }\n pass.setPipeline(pipeline);\n pass.setBindGroup(1, bindGroup.value);\n pass.draw(3, 1, 0, 0);\n stageTemporalGpuSubmit(state);\n internal.frameState.temporalGpuState = state;\n },\n });\n return added;\n}\n\nexport function addTypedFullscreenPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n options: TypedFullscreenPassOptions,\n): Result<void, RenderGraphError> {\n return graph.addRasterPass(options.name, {\n accesses: [\n { resource: options.input.view, usage: 'sampled-read' },\n { resource: options.output.view, usage: 'color-attachment' },\n ...(options.depth === undefined\n ? []\n : [{ resource: options.depth.view, usage: 'sampled-read' as const }]),\n ...(options.additionalReads?.map((read) => ({\n resource: read.target.view,\n usage: 'sampled-read' as const,\n })) ?? []),\n ],\n colorAttachments: [\n {\n view: options.output.view,\n loadOp: 'clear',\n storeOp: 'store',\n clearValue: { r: 0, g: 0, b: 0, a: 1 },\n },\n ],\n encode: ({ pass, frame, resources }) => {\n if (options.outputOnly && frame.runtime.lookupPostProcess?.(options.shader) === undefined) {\n return;\n }\n encodeFullscreenPass(frame, pass, {\n name: options.name,\n shader: options.shader,\n color: 'output',\n reads: ['input'],\n resolve: legacyResolver(resources, {\n input: options.input,\n output: options.output,\n ldrColor: options.input,\n 'scene-color': options.input,\n ...(options.depth === undefined ? {} : { 'scene-depth': options.depth }),\n ...(options.additionalReads === undefined\n ? {}\n : Object.fromEntries(options.additionalReads.map((read) => [read.key, read.target]))),\n }),\n outputFormat: options.output.format as GPUTextureFormat,\n ...(options.depth === undefined\n ? {}\n : { depthView: resolvedDepthView(frame, resources, options.depth) }),\n ...(options.rawSwapchainOutput === undefined\n ? {}\n : { rawSwapchainOutput: options.rawSwapchainOutput }),\n ...(options.paramsTransform === undefined\n ? {}\n : {\n paramsOverride: options.paramsTransform(frame.postProcessParams.get(options.shader)),\n }),\n });\n },\n });\n}\n\nexport function addTypedCompositePostEffects(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n effects: readonly string[],\n input: RenderPipelineTarget,\n output: RenderPipelineTarget,\n depth: RenderPipelineTarget,\n size: { readonly width: number; readonly height: number },\n): Result<void, RenderGraphError> {\n let currentInput = input;\n for (let index = 0; index < effects.length; index += 1) {\n const shader = effects[index];\n if (shader === undefined) continue;\n const effectInput = currentInput;\n const scratch = createRenderPipelineTarget(graph, `post-effect-scratch-${index}`, {\n format: output.format as GPUTextureFormat,\n size: 'surface',\n });\n if (!scratch.ok) return scratch;\n const effectOutput =\n index === effects.length - 1\n ? ok(output)\n : createRenderPipelineTarget(graph, `post-effect-output-${index}`, {\n format: output.format as GPUTextureFormat,\n size: 'surface',\n });\n if (!effectOutput.ok) return effectOutput;\n const copied = graph.addCopyPass(`post-effect-copy-${index}`, {\n accesses: [\n { resource: effectInput.view, usage: 'copy-src' },\n { resource: scratch.value.view, usage: 'copy-dst' },\n ],\n encode: ({ encoder, resources }) => {\n const source = resources.texture(effectInput.texture);\n if (!source.ok) throw source.error;\n const destination = resources.texture(scratch.value.texture);\n if (!destination.ok) throw destination.error;\n encoder.copyTextureToTexture(\n { texture: source.value as never, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },\n { texture: destination.value as never, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },\n { width: size.width, height: size.height, depthOrArrayLayers: 1 },\n );\n },\n });\n if (!copied.ok) return copied;\n const effect = addTypedFullscreenPass(graph, {\n name: `post-effect-${index}`,\n shader,\n input: scratch.value,\n output: effectOutput.value,\n depth,\n });\n if (!effect.ok) return effect;\n currentInput = effectOutput.value;\n }\n return ok(undefined);\n}\n\nexport function addTypedOutputTransformPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n input: RenderPipelineTarget,\n output: RenderPipelineTarget,\n options: { readonly outputOnly?: boolean; readonly dither?: boolean } = {},\n): Result<void, RenderGraphError> {\n const outputOnly = options.outputOnly ?? false;\n return addTypedFullscreenPass(graph, {\n name: outputOnly ? 'present' : 'output-transform',\n shader: STANDARD_OUTPUT_TRANSFORM_FEATURE_ID,\n input,\n output,\n outputOnly,\n rawSwapchainOutput: outputOnly,\n ...(options.dither !== undefined\n ? {\n paramsTransform: (params: Uint8Array | undefined): Uint8Array | undefined => {\n if (params === undefined || params.byteLength !== 16) return params;\n const transformed = params.slice();\n new DataView(\n transformed.buffer,\n transformed.byteOffset,\n transformed.byteLength,\n ).setFloat32(12, options.dither === true ? 1 : 0, true);\n return transformed;\n },\n }\n : {}),\n });\n}\n","import type {\n GraphTextureDescriptor,\n RenderGraphBuilder,\n RenderGraphError,\n} from '@forgeax/engine-render-graph';\nimport { ok, type Result } from '@forgeax/engine-types';\nimport type { RenderPipelineFrame, RenderPipelineTarget } from '../render-pipeline';\nimport { createRenderPipelineTarget } from '../render-pipeline';\nimport { addTypedFullscreenPass, addTypedScenePass } from '../typed-render-graph-primitives';\n\nexport interface StandardTemporalDemandInput {\n readonly taa: boolean;\n readonly motionBlur: boolean;\n}\n\nexport interface StandardTemporalDemand {\n readonly consumerIds: readonly ('taa' | 'motion-blur')[];\n readonly targetCount: 0 | 1;\n readonly producerPassCount: 0 | 1;\n readonly historyCount: 0 | 1;\n}\n\nexport interface StandardTemporalDemandDescription {\n readonly consumerCount: number;\n readonly targetCount: 0 | 1;\n readonly producerPassCount: 0 | 1;\n readonly historyCount: 0 | 1;\n readonly byteLength: 0 | 1;\n}\n\n/** Aggregate all temporal consumers before any graph resource is allocated. */\nexport function aggregateTemporalDemand(\n input: StandardTemporalDemandInput,\n): StandardTemporalDemand {\n const consumerIds = [\n ...(input.taa ? (['taa'] as const) : []),\n ...(input.motionBlur ? (['motion-blur'] as const) : []),\n ];\n const requested = consumerIds.length > 0;\n return Object.freeze({\n consumerIds: Object.freeze(consumerIds),\n targetCount: requested ? 1 : 0,\n producerPassCount: requested ? 1 : 0,\n historyCount: input.taa ? 1 : 0,\n });\n}\n\nexport function describeTemporalDemand(\n demand: StandardTemporalDemand,\n): StandardTemporalDemandDescription {\n return {\n consumerCount: demand.consumerIds.length,\n targetCount: demand.targetCount,\n producerPassCount: demand.producerPassCount,\n historyCount: demand.historyCount,\n byteLength: demand.targetCount,\n };\n}\n\nexport type StandardTemporalLane = 'direct' | 'clustered' | 'cpu-webgl2' | 'rhi-null';\n\nexport type StandardTemporalLaneAdmission =\n | {\n readonly status: 'available';\n readonly schema: typeof import('./scene-data').SCENE_DATA_TEMPORAL_V1_SCHEMA;\n readonly producerId: 'forgeax::standard::scene-data';\n readonly structuralOnly: boolean;\n readonly format: 'rgba16float';\n }\n | {\n readonly status: 'unavailable';\n readonly reason: 'capability-missing' | 'producer-missing' | 'no-demand';\n readonly format?: never;\n };\n\nexport function standardTemporalLaneAdmission(input: {\n readonly lane: StandardTemporalLane;\n readonly demand: StandardTemporalDemand;\n readonly capabilities: {\n readonly compute: boolean;\n readonly storageBuffer: boolean;\n readonly rgba16floatRenderable: boolean;\n readonly filterable?: boolean;\n readonly copy?: boolean;\n readonly readback?: boolean;\n readonly producerPresent?: boolean;\n };\n}): StandardTemporalLaneAdmission {\n if (input.demand.targetCount === 0) return { status: 'unavailable', reason: 'no-demand' };\n if (input.capabilities.producerPresent === false)\n return { status: 'unavailable', reason: 'producer-missing' };\n if (\n !input.capabilities.rgba16floatRenderable ||\n input.capabilities.filterable === false ||\n input.capabilities.copy === false ||\n input.capabilities.readback === false\n ) {\n return { status: 'unavailable', reason: 'capability-missing' };\n }\n return {\n status: 'available',\n schema: 'forgeax::scene-data::temporal-v1',\n producerId: 'forgeax::standard::scene-data',\n structuralOnly: input.lane === 'rhi-null',\n format: 'rgba16float',\n };\n}\n\nexport function standardTemporalPostOrder(input: {\n readonly taa: boolean;\n readonly motionBlur: boolean;\n readonly bloom: boolean;\n}): readonly string[] {\n const order = ['scene'];\n if (input.taa || input.motionBlur) order.push('standard-scene-data');\n if (input.taa) order.push('taa-resolve');\n if (input.motionBlur) order.push('motion-blur');\n if (input.bloom) order.push('bloom', 'tone');\n order.push('output');\n return Object.freeze(order);\n}\n\nexport interface StandardSceneDataTargets {\n readonly temporal: RenderPipelineTarget;\n}\n\nconst TEMPORAL_TARGET: GraphTextureDescriptor = {\n format: 'rgba16float',\n size: 'surface',\n sampleCount: 1,\n};\n\n/** The single Standard TAA current-frame producer target. */\nexport function createStandardSceneDataTarget(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n): Result<StandardSceneDataTargets, RenderGraphError> {\n const temporal = createRenderPipelineTarget(graph, 'standard-scene-temporal', TEMPORAL_TARGET);\n return temporal.ok ? ok({ temporal: temporal.value }) : temporal;\n}\n\nexport function addStandardSceneDataPass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n target: RenderPipelineTarget,\n depth: RenderPipelineTarget,\n): Result<void, RenderGraphError> {\n return addTypedScenePass(graph, {\n name: 'standard-scene-data',\n color: target,\n depth,\n selector: { LightMode: ['Deferred', 'Forward'] },\n passKind: 'temporal',\n // The temporal producer re-rasterizes the current scene after the main\n // color pass has populated depth. Its output is a semantic motion target;\n // it must cover the same fragments even when TAA jitter moves the raster\n // edge by a subpixel, while the loaded scene depth remains the consumer's\n // depth-rejection source for Motion Blur/TAA.\n clearColor: [0, 0, -1, 1],\n colorLoadOp: 'clear',\n depthLoadOp: 'load',\n });\n}\n\nexport function addTaaResolvePass(\n graph: RenderGraphBuilder<RenderPipelineFrame>,\n current: RenderPipelineTarget,\n currentTemporal: RenderPipelineTarget,\n previousColor: RenderPipelineTarget,\n previousTemporal: RenderPipelineTarget,\n output: RenderPipelineTarget,\n): Result<void, RenderGraphError> {\n return addTypedFullscreenPass(graph, {\n name: 'taa-resolve',\n shader: 'forgeax.taa-resolve',\n input: current,\n output,\n additionalReads: [\n { key: 'scene-temporal', target: currentTemporal },\n { key: 'taa-history-color', target: previousColor },\n { key: 'taa-history-temporal', target: previousTemporal },\n ],\n });\n}\n"]}
|