@forgeax/engine-render 0.1.21 → 0.1.24
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 +281 -38
- package/dist/assembly/backend-contract.d.ts +13 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -1
- package/dist/assembly/bundler-contract.d.ts +9 -0
- package/dist/assembly/bundler-contract.d.ts.map +1 -0
- package/dist/assembly/device-feature-admission.d.ts +8 -0
- package/dist/assembly/device-feature-admission.d.ts.map +1 -1
- package/dist/assembly/extended-lighting-fallback.d.ts +13 -0
- package/dist/assembly/extended-lighting-fallback.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +7 -235
- 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/assembly/material/assembly.d.ts +3 -2
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/standard-layer-projection.d.ts +10 -0
- package/dist/assembly/material/standard-layer-projection.d.ts.map +1 -0
- package/dist/assembly/material-shader-policy.d.ts +168 -0
- package/dist/assembly/material-shader-policy.d.ts.map +1 -0
- package/dist/assembly/material-shader-prewarm.d.ts +21 -0
- package/dist/assembly/material-shader-prewarm.d.ts.map +1 -0
- package/dist/assembly/mesh-ssbo-grow.d.ts +88 -0
- package/dist/assembly/mesh-ssbo-grow.d.ts.map +1 -0
- package/dist/assembly/recovery/device-loss-fanout.d.ts +14 -0
- package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -0
- package/dist/assembly/recovery/generation.d.ts +46 -0
- package/dist/assembly/recovery/generation.d.ts.map +1 -0
- package/dist/assembly/recovery/recovery-attempt.d.ts +63 -0
- package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -0
- package/dist/assembly/recovery/renderer-recover.d.ts +115 -0
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -0
- package/dist/assembly/renderer-facade.d.ts +10 -0
- package/dist/assembly/renderer-facade.d.ts.map +1 -0
- package/dist/assembly/renderer-frame-transaction.d.ts +17 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-helpers.d.ts +19 -0
- package/dist/assembly/renderer-helpers.d.ts.map +1 -0
- package/dist/assembly/renderer-lifecycle.d.ts +34 -0
- package/dist/assembly/renderer-lifecycle.d.ts.map +1 -1
- package/dist/assembly/shader-prewarm-policy.d.ts +15 -0
- package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready-contract.d.ts +9 -0
- package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +55 -0
- package/dist/assembly/webgpu-ready.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +152 -0
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -0
- package/dist/authoring.mjs +1 -1
- package/dist/{chunk-PCHBPYML.mjs → chunk-GE3SDD72.mjs} +37 -5
- package/dist/chunk-GE3SDD72.mjs.map +1 -0
- package/dist/chunk-KZFTK6DO.mjs +1191 -0
- package/dist/chunk-KZFTK6DO.mjs.map +1 -0
- package/dist/{chunk-FS2KNUQH.mjs → chunk-Q752SHI5.mjs} +332 -568
- package/dist/chunk-Q752SHI5.mjs.map +1 -0
- package/dist/{chunk-6OPXDQ2E.mjs → chunk-RR5L4SRS.mjs} +33 -294
- package/dist/chunk-RR5L4SRS.mjs.map +1 -0
- package/dist/chunk-TFH5I7JJ.mjs +296 -0
- package/dist/chunk-TFH5I7JJ.mjs.map +1 -0
- package/dist/chunk-UQYS7FRM.mjs +1003 -0
- package/dist/chunk-UQYS7FRM.mjs.map +1 -0
- package/dist/chunk-YKB5DQV7.mjs +345 -0
- package/dist/chunk-YKB5DQV7.mjs.map +1 -0
- package/dist/{chunk-5YADUCA7.mjs → chunk-YRUYGA4A.mjs} +1189 -1217
- package/dist/chunk-YRUYGA4A.mjs.map +1 -0
- package/dist/chunk-Z3YYH2MB.mjs +5082 -0
- package/dist/chunk-Z3YYH2MB.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 +27276 -23232
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/device-scope.d.ts +2 -0
- package/dist/device/device-scope.d.ts.map +1 -1
- package/dist/device/gpu-residency.d.ts +32 -5
- 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/frame.d.ts +5 -0
- package/dist/environment/frame.d.ts.map +1 -1
- package/dist/environment/inspection.d.ts +7 -0
- package/dist/environment/inspection.d.ts.map +1 -1
- package/dist/environment/lifecycle.d.ts +20 -2
- 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 +67 -3
- package/dist/errors/recover.d.ts.map +1 -1
- package/dist/errors/render.d.ts +39 -1
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +899 -0
- package/dist/extract/contracts.d.ts.map +1 -0
- 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/features/host.d.ts +2 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +3 -0
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/prepared-graphics-store.d.ts +2 -0
- package/dist/features/prepared-graphics-store.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 +126 -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 +9 -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/ibl/IblPipelineCache.d.ts +7 -6
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +7 -1
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +13 -2
- 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 +60 -148
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/materials.d.ts +34 -10
- package/dist/materials.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +56 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/occlusion-proxy.d.ts +4 -0
- package/dist/occlusion-proxy.d.ts.map +1 -0
- package/dist/pbr-pipeline.d.ts +58 -21
- 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/points-lines/prepare.d.ts +3 -0
- package/dist/points-lines/prepare.d.ts.map +1 -1
- package/dist/points-lines/standard-owner.d.ts +33 -0
- package/dist/points-lines/standard-owner.d.ts.map +1 -0
- 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 +55 -10
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +21 -5
- 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 +20 -2
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +10 -18
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +11 -3
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/recovery-pipeline.d.ts +30 -0
- package/dist/record/recovery-pipeline.d.ts.map +1 -0
- package/dist/record/render-context.d.ts +82 -9
- 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/recovery/render-system-candidate.d.ts +65 -0
- package/dist/recovery/render-system-candidate.d.ts.map +1 -0
- 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 +78 -15
- 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-tail.d.ts +12 -0
- package/dist/render-system-extract-tail.d.ts.map +1 -0
- package/dist/render-system-extract.d.ts +252 -30
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +140 -5
- 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 +122 -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/taa-history-store.d.ts +15 -1
- package/dist/temporal/taa-history-store.d.ts.map +1 -1
- package/dist/temporal/transaction.d.ts +5 -0
- package/dist/temporal/transaction.d.ts.map +1 -1
- 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 +19 -1
- package/src/__tests__/device-loss-fanout.unit.test.ts +107 -0
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +21 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +59 -3
- package/src/__tests__/environment-generation.integration.test.ts +39 -0
- package/src/__tests__/evidence-identity.ts +13 -0
- package/src/__tests__/evidence-identity.unit.test.ts +24 -0
- package/src/__tests__/expose-renderer-errors.unit.test.ts +34 -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 +154 -6
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +4 -1
- 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__/ibl/face-uniforms.unit.test.ts +2 -0
- package/src/__tests__/ibl-residency-publication.unit.test.ts +113 -0
- 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 +41 -9
- package/src/__tests__/material-cooked-projection.unit.test.ts +19 -1
- package/src/__tests__/material-static-dynamic-route.unit.test.ts +29 -0
- package/src/__tests__/material-stride-surface.unit.test.ts +7 -3
- package/src/__tests__/materials-standard-contract.unit.test.ts +104 -0
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +1 -1
- 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__/physical-clearcoat.integration.test.ts +89 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
- package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +1 -1
- 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__/recover-error-policy-owner.unit.test.ts +6 -3
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +140 -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 +160 -17
- package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +47 -0
- package/src/__tests__/renderer-generation-assembly.unit.test.ts +77 -0
- package/src/__tests__/renderer-generation-failure.unit.test.ts +108 -0
- package/src/__tests__/renderer-producer-root-matrix.integration.test.ts +33 -0
- package/src/__tests__/renderer-recovery-capability-matrix.unit.test.ts +59 -0
- package/src/__tests__/renderer-recovery-contract.unit.test.ts +73 -0
- package/src/__tests__/renderer-recovery-lifecycle.unit.test.ts +216 -0
- package/src/__tests__/renderer-target-history-recovery.integration.test.ts +80 -0
- package/src/__tests__/shader-manifest-fixture.ts +13 -16
- package/src/__tests__/shader-stage-surface.unit.test.ts +1 -1
- 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-layer-projection.unit.test.ts +23 -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 +111 -32
- 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/__tests__/volumetric-fog-topology.unit.test.ts +3 -1
- package/src/assembly/backend-contract.ts +13 -0
- package/src/assembly/bundler-contract.ts +9 -0
- package/src/assembly/device-feature-admission.ts +26 -9
- package/src/assembly/extended-lighting-fallback.ts +216 -0
- package/src/assembly/factory.ts +81 -9634
- package/src/assembly/host-contract.ts +10 -0
- package/src/assembly/material/assembly.ts +18 -2
- package/src/assembly/material/standard-layer-projection.ts +16 -0
- package/src/assembly/material-shader-policy.ts +854 -0
- package/src/assembly/material-shader-prewarm.ts +88 -0
- package/src/assembly/mesh-ssbo-grow.ts +270 -0
- package/src/assembly/recovery/device-loss-fanout.ts +89 -0
- package/src/assembly/recovery/generation.ts +141 -0
- package/src/assembly/recovery/recovery-attempt.ts +800 -0
- package/src/assembly/recovery/renderer-recover.ts +906 -0
- package/src/assembly/renderer-facade.ts +342 -0
- package/src/assembly/renderer-frame-transaction.ts +45 -0
- package/src/assembly/renderer-helpers.ts +99 -0
- package/src/assembly/renderer-lifecycle.ts +159 -0
- package/src/assembly/shader-prewarm-policy.ts +157 -0
- package/src/assembly/webgpu-ready-contract.ts +14 -0
- package/src/assembly/webgpu-ready.ts +4079 -0
- package/src/assembly/webgpu-renderer.ts +4095 -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/camera.ts +1 -1
- 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/debug-draw-glue.ts +1 -1
- package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
- package/src/device/device-scope.ts +35 -6
- package/src/device/gpu-residency.ts +334 -35
- package/src/device/lifecycle-transaction.ts +12 -0
- package/src/environment/frame.ts +6 -0
- package/src/environment/inspection.ts +10 -0
- package/src/environment/lifecycle.ts +122 -9
- package/src/errors/gpu-driven.ts +92 -0
- package/src/errors/index.ts +1 -0
- package/src/errors/recover.ts +108 -5
- package/src/errors/render.ts +72 -1
- package/src/extract/camera.ts +3 -3
- package/src/extract/contracts.ts +974 -0
- package/src/extract/gpu-driven.ts +108 -0
- package/src/extract/visibility.ts +0 -23
- package/src/features/host.ts +16 -0
- package/src/features/prepared-gpu-work.ts +20 -2
- package/src/features/prepared-graphics-store.ts +17 -0
- 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 +1046 -39
- package/src/gpu-driven/view-gpu.ts +411 -29
- package/src/gpu-scene-schema.ts +13 -0
- package/src/gpu-scene.ts +137 -67
- package/src/gpu-usage.ts +0 -1
- package/src/hdrp-buffers.ts +6 -6
- package/src/ibl/IblPipelineCache.ts +134 -50
- package/src/ibl/skylight-bind-group.ts +26 -0
- package/src/index.ts +83 -1
- package/src/inspection-types.ts +220 -1
- package/src/internal.ts +38 -0
- package/src/light-buffer-layout.ts +157 -324
- package/src/materials.ts +278 -47
- package/src/mesh-material-bindings.ts +59 -0
- package/src/occlusion-proxy.ts +64 -0
- package/src/pbr-pipeline.ts +290 -60
- 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/points-lines/__tests__/cache-recovery.unit.test.ts +22 -0
- package/src/points-lines/prepare.ts +9 -0
- package/src/points-lines/standard-owner.ts +403 -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__/frame-targets-recovery.unit.test.ts +60 -0
- package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +26 -1
- package/src/record/__tests__/mesh-ssbo.unit.test.ts +38 -0
- package/src/record/__tests__/recovery-pipeline.unit.test.ts +124 -0
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +28 -13
- package/src/record/__tests__/standard-pbr-ubo-layout.unit.test.ts +47 -4
- package/src/record/__tests__/temporal-payload.unit.test.ts +29 -28
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +21 -2
- package/src/record/frame-lighting.ts +252 -53
- package/src/record/frame-snapshot.ts +72 -12
- package/src/record/frame-targets.ts +11 -1
- package/src/record/frame.ts +416 -95
- package/src/record/gpu-timing.ts +108 -44
- package/src/record/helpers.ts +1 -59
- package/src/record/main-pass-geometry.ts +434 -44
- package/src/record/main-pass-material.ts +324 -210
- package/src/record/main-pass-sprite-draws.ts +58 -92
- package/src/record/main-pass.ts +94 -6
- package/src/record/mesh-ssbo.ts +79 -46
- package/src/record/recovery-pipeline.ts +695 -0
- package/src/record/render-context.ts +99 -7
- package/src/record/shadow-pass.ts +66 -40
- package/src/record/typed-frame-graph.ts +270 -84
- package/src/record/view-ubo.ts +17 -27
- package/src/recovery/render-system-candidate.ts +839 -0
- 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 +82 -12
- package/src/render-pipeline.ts +5 -0
- package/src/render-system-extract-tail.ts +2983 -0
- package/src/render-system-extract.ts +290 -2784
- package/src/render-system.ts +1597 -1192
- 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 +972 -184
- 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 +30 -1
- package/src/temporal/frame.ts +14 -1
- package/src/temporal/taa-history-store.ts +46 -2
- package/src/temporal/temporal-view.ts +1 -1
- package/src/temporal/transaction.ts +9 -0
- package/src/temporal/view.ts +11 -0
- package/src/tilemap-chunk-extract-system.ts +5 -5
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +19 -12
- 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 +0 -192
- package/dist/chunk-VFPLTKCU.mjs.map +0 -1
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
import {
|
|
21
21
|
DEFAULT_MSDF_TEXT_PARAM_SCHEMA,
|
|
22
22
|
DEFAULT_SPRITE_PARAM_SCHEMA,
|
|
23
|
-
DEFAULT_STANDARD_PBR_PARAM_SCHEMA,
|
|
24
23
|
DEFAULT_UNLIT_PARAM_SCHEMA,
|
|
24
|
+
STANDARD_PIPELINE_PARAM_SCHEMA,
|
|
25
25
|
} from '@forgeax/engine-shader';
|
|
26
26
|
import type {
|
|
27
27
|
Handle,
|
|
@@ -38,10 +38,16 @@ import { VideoUploadUnsupportedError } from '../errors/render';
|
|
|
38
38
|
import {
|
|
39
39
|
assembleMaterialWithSkylightEntries,
|
|
40
40
|
type SkylightBindGroupResources,
|
|
41
|
+
type TextureInjectionResource,
|
|
41
42
|
type TransmissionBindGroupResources,
|
|
42
43
|
} from '../ibl/skylight-bind-group';
|
|
44
|
+
import type { IblBindingEntryInspection } from '../mesh-material-bindings';
|
|
43
45
|
import type { PipelineGroup2Contract } from '../pbr-pipeline';
|
|
44
|
-
import {
|
|
46
|
+
import {
|
|
47
|
+
isCanonicalStandardPbrMaterialShader,
|
|
48
|
+
isStandardPbrMaterialShader,
|
|
49
|
+
physicalTextureFields,
|
|
50
|
+
} from '../pbr-pipeline';
|
|
45
51
|
import { deriveTextureExtent } from '../render-data';
|
|
46
52
|
import type { MaterialSnapshot } from '../render-system-extract';
|
|
47
53
|
import type { RenderTargetTextureSource } from '../targets/contracts';
|
|
@@ -50,7 +56,12 @@ import {
|
|
|
50
56
|
resolveRenderTargetMaterialSource,
|
|
51
57
|
} from '../targets/material-source';
|
|
52
58
|
import type { StandardReflectionProbeBinding } from './frame-lighting';
|
|
53
|
-
import type {
|
|
59
|
+
import type {
|
|
60
|
+
BindGroupCounts,
|
|
61
|
+
MaterialBgAssemblyCacheEntry,
|
|
62
|
+
RenderFrameState,
|
|
63
|
+
} from './frame-snapshot';
|
|
64
|
+
import { getOpaqueResourceIdentity } from './frame-snapshot';
|
|
54
65
|
import { extractEntryResourceHandle, getOrCreatePerEntity } from './mesh-ssbo';
|
|
55
66
|
import {
|
|
56
67
|
type PipelineState,
|
|
@@ -232,6 +243,18 @@ function isImageError(error: unknown): error is ImageError {
|
|
|
232
243
|
return typeof code === 'string' && code.startsWith('image-');
|
|
233
244
|
}
|
|
234
245
|
|
|
246
|
+
function materialDiagnosticsEnabled(): boolean {
|
|
247
|
+
if (typeof globalThis !== 'object' || globalThis === null || !('process' in globalThis)) {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
const processValue = (
|
|
251
|
+
globalThis as {
|
|
252
|
+
readonly process?: { readonly env?: Record<string, string | undefined> };
|
|
253
|
+
}
|
|
254
|
+
).process;
|
|
255
|
+
return processValue?.env?.FORGEAX_MATERIAL_DIAGNOSTICS === '1';
|
|
256
|
+
}
|
|
257
|
+
|
|
235
258
|
export function residentTextureView(
|
|
236
259
|
world: World,
|
|
237
260
|
store: GpuResidencyCache,
|
|
@@ -240,7 +263,15 @@ export function residentTextureView(
|
|
|
240
263
|
worldId: World | number = world,
|
|
241
264
|
): TextureView | undefined {
|
|
242
265
|
const podRes = resolveAssetHandle<TextureAsset>(world, handle);
|
|
243
|
-
|
|
266
|
+
const diagnosticsEnabled = materialDiagnosticsEnabled();
|
|
267
|
+
if (!podRes.ok) {
|
|
268
|
+
if (diagnosticsEnabled) {
|
|
269
|
+
console.error(
|
|
270
|
+
`[render-material] texture resolve failed: ${JSON.stringify({ handle: handleSlot(handle), error: podRes.error })}`,
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
244
275
|
const residentRes = store.ensureResident(handle, podRes.value, worldId);
|
|
245
276
|
if (!residentRes.ok) {
|
|
246
277
|
// Preserve the concrete asset-capability boundary on the renderer error
|
|
@@ -249,9 +280,41 @@ export function residentTextureView(
|
|
|
249
280
|
if (residentRes.error instanceof RhiError || isImageError(residentRes.error)) {
|
|
250
281
|
runtime.errorRegistry.fire(residentRes.error);
|
|
251
282
|
}
|
|
283
|
+
if (diagnosticsEnabled) {
|
|
284
|
+
console.error(
|
|
285
|
+
`[render-material] texture residency failed: ${JSON.stringify({
|
|
286
|
+
handle: handleSlot(handle),
|
|
287
|
+
pod: {
|
|
288
|
+
kind: podRes.value.kind,
|
|
289
|
+
shape: podRes.value.shape,
|
|
290
|
+
format: podRes.value.format,
|
|
291
|
+
dataByteLength: podRes.value.data.byteLength,
|
|
292
|
+
mips: podRes.value.mips,
|
|
293
|
+
},
|
|
294
|
+
error: residentRes.error,
|
|
295
|
+
})}`,
|
|
296
|
+
);
|
|
297
|
+
}
|
|
252
298
|
return undefined;
|
|
253
299
|
}
|
|
254
|
-
|
|
300
|
+
const view = store.getTextureGpuView(handle, worldId);
|
|
301
|
+
if (diagnosticsEnabled) {
|
|
302
|
+
console.error(
|
|
303
|
+
`[render-material] texture residency ready: ${JSON.stringify({
|
|
304
|
+
handle: handleSlot(handle),
|
|
305
|
+
pod: {
|
|
306
|
+
kind: podRes.value.kind,
|
|
307
|
+
shape: podRes.value.shape,
|
|
308
|
+
format: podRes.value.format,
|
|
309
|
+
dataByteLength: podRes.value.data.byteLength,
|
|
310
|
+
mips: podRes.value.mips,
|
|
311
|
+
},
|
|
312
|
+
receipt: 'receipt' in residentRes.value ? residentRes.value.receipt : undefined,
|
|
313
|
+
viewReady: view !== undefined,
|
|
314
|
+
})}`,
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
return view;
|
|
255
318
|
}
|
|
256
319
|
|
|
257
320
|
function residentSampler(
|
|
@@ -398,7 +461,6 @@ export const BUILTIN_USER_REGION_TEXTURE_FIELDS: readonly string[] = [
|
|
|
398
461
|
'baseColorTexture',
|
|
399
462
|
'metallicRoughnessTexture',
|
|
400
463
|
'normalTexture',
|
|
401
|
-
'specularTintTexture',
|
|
402
464
|
'emissiveTexture',
|
|
403
465
|
'occlusionTexture',
|
|
404
466
|
'transmissionTexture',
|
|
@@ -406,21 +468,6 @@ export const BUILTIN_USER_REGION_TEXTURE_FIELDS: readonly string[] = [
|
|
|
406
468
|
];
|
|
407
469
|
|
|
408
470
|
const LEGACY_MATERIAL_TEXTURE_SCALE_OFFSET = 80;
|
|
409
|
-
// The Standard schema owns five transmission numeric fields between
|
|
410
|
-
// normalScale and the engine-owned coordinate records. Keep this fallback
|
|
411
|
-
// aligned with derive(DEFAULT_STANDARD_PBR_PARAM_SCHEMA): the first record is
|
|
412
|
-
// at byte 128, not the pre-transmission byte 96.
|
|
413
|
-
const STANDARD_PBR_TEXTURE_SCALE_OFFSET = 128;
|
|
414
|
-
const MATERIAL_TEXTURE_SCALE_FIELDS = [
|
|
415
|
-
'baseColorTexture',
|
|
416
|
-
'metallicRoughnessTexture',
|
|
417
|
-
'normalTexture',
|
|
418
|
-
'specularTintTexture',
|
|
419
|
-
'emissiveTexture',
|
|
420
|
-
'occlusionTexture',
|
|
421
|
-
'transmissionTexture',
|
|
422
|
-
'thicknessTexture',
|
|
423
|
-
] as const;
|
|
424
471
|
const LEGACY_MATERIAL_TEXTURE_SCALE_FIELDS = [
|
|
425
472
|
'baseColorTexture',
|
|
426
473
|
'metallicRoughnessTexture',
|
|
@@ -428,19 +475,20 @@ const LEGACY_MATERIAL_TEXTURE_SCALE_FIELDS = [
|
|
|
428
475
|
'emissiveTexture',
|
|
429
476
|
'occlusionTexture',
|
|
430
477
|
] as const;
|
|
431
|
-
const STANDARD_PBR_TEXTURE_COORDINATE_OFFSET = 128;
|
|
432
|
-
const STANDARD_PBR_TEXTURE_COORDINATE_STRIDE = 8;
|
|
433
478
|
const DEFAULT_LEGACY_TEXTURE_SCALES = new Float32Array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
|
|
434
|
-
const DEFAULT_STANDARD_TEXTURE_COORDINATES = new Float32Array([
|
|
435
|
-
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,
|
|
436
|
-
0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
|
|
437
|
-
]);
|
|
438
479
|
|
|
439
480
|
export interface StandardReflectionProbeMaterialProjection {
|
|
440
481
|
readonly probeIndex: number | undefined;
|
|
441
482
|
readonly fallbackToSkylight: boolean;
|
|
442
483
|
}
|
|
443
484
|
|
|
485
|
+
/** Keeps the fallback output as a same-pass, linear-HDR material projection. */
|
|
486
|
+
export function standardPbrFallbackDemand(
|
|
487
|
+
projection: StandardReflectionProbeMaterialProjection,
|
|
488
|
+
): boolean {
|
|
489
|
+
return projection.probeIndex !== undefined || projection.fallbackToSkylight;
|
|
490
|
+
}
|
|
491
|
+
|
|
444
492
|
/** Projects the selected scene row into the Standard material lane. */
|
|
445
493
|
export function projectReflectionProbeMaterialBinding(
|
|
446
494
|
binding: StandardReflectionProbeBinding,
|
|
@@ -529,13 +577,10 @@ export function applyMaterialTextureUvScales(
|
|
|
529
577
|
}
|
|
530
578
|
return;
|
|
531
579
|
}
|
|
532
|
-
//
|
|
533
|
-
//
|
|
534
|
-
//
|
|
535
|
-
const textureScaleOffset =
|
|
536
|
-
? STANDARD_PBR_TEXTURE_SCALE_OFFSET
|
|
537
|
-
: LEGACY_MATERIAL_TEXTURE_SCALE_OFFSET;
|
|
538
|
-
const isStandardPbr = textureScaleOffset === STANDARD_PBR_TEXTURE_SCALE_OFFSET;
|
|
580
|
+
// Unknown legacy material paths retain their historical packed scale tail.
|
|
581
|
+
// Every registered Standard/material-schema path returns above and is
|
|
582
|
+
// therefore fully schema-driven (including physical texture coordinates).
|
|
583
|
+
const textureScaleOffset = LEGACY_MATERIAL_TEXTURE_SCALE_OFFSET;
|
|
539
584
|
const hasTextureMetadata =
|
|
540
585
|
material.textureCoordinates !== undefined ||
|
|
541
586
|
material.textureHandles !== undefined ||
|
|
@@ -546,15 +591,10 @@ export function applyMaterialTextureUvScales(
|
|
|
546
591
|
material.emissiveTexture !== undefined ||
|
|
547
592
|
material.occlusionTexture !== undefined;
|
|
548
593
|
if (!hasTextureMetadata) {
|
|
549
|
-
f32.set(
|
|
550
|
-
isStandardPbr ? DEFAULT_STANDARD_TEXTURE_COORDINATES : DEFAULT_LEGACY_TEXTURE_SCALES,
|
|
551
|
-
textureScaleOffset / 4,
|
|
552
|
-
);
|
|
594
|
+
f32.set(DEFAULT_LEGACY_TEXTURE_SCALES, textureScaleOffset / 4);
|
|
553
595
|
return;
|
|
554
596
|
}
|
|
555
|
-
const fields =
|
|
556
|
-
? MATERIAL_TEXTURE_SCALE_FIELDS
|
|
557
|
-
: LEGACY_MATERIAL_TEXTURE_SCALE_FIELDS;
|
|
597
|
+
const fields = LEGACY_MATERIAL_TEXTURE_SCALE_FIELDS;
|
|
558
598
|
for (let index = 0; index < fields.length; index++) {
|
|
559
599
|
const field = fields[index];
|
|
560
600
|
if (field === undefined) continue;
|
|
@@ -563,39 +603,19 @@ export function applyMaterialTextureUvScales(
|
|
|
563
603
|
handle === undefined ? undefined : resolveAssetHandle<TextureAsset>(world, handle);
|
|
564
604
|
const texture = resolved?.ok === true ? resolved.value : undefined;
|
|
565
605
|
const [u, v] = materialTextureUvScale(texture);
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
const offset =
|
|
570
|
-
STANDARD_PBR_TEXTURE_COORDINATE_OFFSET / 4 + index * STANDARD_PBR_TEXTURE_COORDINATE_STRIDE;
|
|
571
|
-
f32[offset] = transform?.offset?.[0] ?? 0;
|
|
572
|
-
f32[offset + 1] = transform?.offset?.[1] ?? 0;
|
|
573
|
-
f32[offset + 2] = transform?.scale?.[0] ?? 1;
|
|
574
|
-
f32[offset + 3] = transform?.scale?.[1] ?? 1;
|
|
575
|
-
f32[offset + 4] = coordinates?.set ?? 0;
|
|
576
|
-
f32[offset + 5] = transform?.rotation ?? 0;
|
|
577
|
-
f32[offset + 6] = u;
|
|
578
|
-
f32[offset + 7] = v;
|
|
579
|
-
} else {
|
|
580
|
-
const offset = textureScaleOffset / 4 + index * 2;
|
|
581
|
-
f32[offset] = u;
|
|
582
|
-
f32[offset + 1] = v;
|
|
583
|
-
}
|
|
606
|
+
const offset = textureScaleOffset / 4 + index * 2;
|
|
607
|
+
f32[offset] = u;
|
|
608
|
+
f32[offset + 1] = v;
|
|
584
609
|
}
|
|
585
610
|
}
|
|
586
611
|
|
|
587
612
|
function materialCoordinateSchema(
|
|
588
613
|
material: MaterialSnapshot,
|
|
589
614
|
): readonly ParamSchemaEntry[] | undefined {
|
|
590
|
-
if (
|
|
591
|
-
isStandardPbrMaterialShader(material.materialShaderId) &&
|
|
592
|
-
material.paramSnapshot !== undefined
|
|
593
|
-
) {
|
|
594
|
-
return DEFAULT_STANDARD_PBR_PARAM_SCHEMA;
|
|
595
|
-
}
|
|
596
615
|
if (material.materialParamSchema !== undefined && material.materialParamSchema.length > 0) {
|
|
597
616
|
return material.materialParamSchema;
|
|
598
617
|
}
|
|
618
|
+
if (isStandardPbrMaterialShader(material.materialShaderId)) return STANDARD_PIPELINE_PARAM_SCHEMA;
|
|
599
619
|
switch (material.materialShaderId) {
|
|
600
620
|
case 'forgeax::default-unlit':
|
|
601
621
|
return DEFAULT_UNLIT_PARAM_SCHEMA;
|
|
@@ -645,6 +665,13 @@ export function defaultViewForUserRegionField(
|
|
|
645
665
|
}
|
|
646
666
|
if (field === 'normalTexture') return pipelineState.defaultNormalTextureView;
|
|
647
667
|
if (field === 'baseColorTexture') return pipelineState.fallbackTextureView;
|
|
668
|
+
if (field === 'anisotropyTexture') {
|
|
669
|
+
// The flat-normal fallback encodes a zero tangent direction and unit B
|
|
670
|
+
// strength; the shader's zero-vector guard selects its neutral (1, 0)
|
|
671
|
+
// axis. This keeps an absent anisotropy map neutral even on hosts that do
|
|
672
|
+
// not allocate the optional dedicated identity texture.
|
|
673
|
+
return pipelineState.defaultAnisotropyTextureView ?? pipelineState.defaultNormalTextureView;
|
|
674
|
+
}
|
|
648
675
|
return pipelineState.defaultWhiteTextureView;
|
|
649
676
|
}
|
|
650
677
|
|
|
@@ -662,7 +689,7 @@ export function defaultViewForUserRegionField(
|
|
|
662
689
|
* `renderableIndex` per RenderSystem lifetime via the `seenIndices` Set
|
|
663
690
|
* (the same warn-once anchor pattern used for missing-texture sprites).
|
|
664
691
|
*
|
|
665
|
-
* @param transformWorld The entity's resolved
|
|
692
|
+
* @param transformWorld The entity's resolved GlobalTransform.world mat4 (16 floats column-major).
|
|
666
693
|
* @param slices The four anchor distances `[left, top, right, bottom]`
|
|
667
694
|
* (sentinel `bottom < 0` for tile mode is consumed via abs()).
|
|
668
695
|
* @param renderableIndex The entity index into the validated renderables list.
|
|
@@ -691,17 +718,7 @@ export function detectNineSliceScaleTooSmall(
|
|
|
691
718
|
}
|
|
692
719
|
}
|
|
693
720
|
|
|
694
|
-
/**
|
|
695
|
-
* Build the 384-byte Material UBO payload for a PBR / unlit material entry
|
|
696
|
-
* (feat-20260527-sprite-nineslice M2 / w11; D-7 regression-net helper).
|
|
697
|
-
*
|
|
698
|
-
* Byte-for-byte equivalent to the legacy hard-coded PBR write path; each
|
|
699
|
-
* deviation is caught by `render-system-record-pbr-ubo-stable.test.ts`.
|
|
700
|
-
* The schema-driven paramSnapshot overlay (feat-20260523 M9-T05; AC-14)
|
|
701
|
-
* positions vec4 / f32 slots onto std140 [slot0 vec4, slot1 f32 metallic,
|
|
702
|
-
* slot1 f32 roughness] mirroring the engine-shipped default-standard-pbr
|
|
703
|
-
* Material struct.
|
|
704
|
-
*/
|
|
721
|
+
/** Build one max-sized, schema-driven Standard material UBO payload. */
|
|
705
722
|
export function buildPbrMaterialUboPayload(material: MaterialSnapshot): Uint8Array {
|
|
706
723
|
const buf = new Uint8Array(STANDARD_PBR_UBO_SIZE);
|
|
707
724
|
writePbrMaterialUboPayload(buf, material);
|
|
@@ -711,11 +728,10 @@ export function buildPbrMaterialUboPayload(material: MaterialSnapshot): Uint8Arr
|
|
|
711
728
|
/**
|
|
712
729
|
* Write the standard material payload into caller-owned storage.
|
|
713
730
|
*
|
|
714
|
-
* The allocating wrapper above remains the
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
*
|
|
718
|
-
* changing GPU-visible bytes.
|
|
731
|
+
* The allocating wrapper above remains the helper/test surface, while the
|
|
732
|
+
* frame recorder reuses one scratch slot for all materials. Field offsets are
|
|
733
|
+
* read from the material's admitted schema; no Standard field offset table is
|
|
734
|
+
* maintained in the record stage.
|
|
719
735
|
*/
|
|
720
736
|
export function writePbrMaterialUboPayload(
|
|
721
737
|
buf: Uint8Array | Float32Array,
|
|
@@ -728,114 +744,52 @@ export function writePbrMaterialUboPayload(
|
|
|
728
744
|
}
|
|
729
745
|
buf.fill(0);
|
|
730
746
|
const f32 = materialUboFloatView(buf);
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
// channelMap default = (B, G, R, _) per AGENTS.md + glTF 2.0
|
|
763
|
-
// KHR_materials_pbrSpecularGlossiness ARM packing -- now 4 independent
|
|
764
|
-
// f32 selectors; fragment casts each to u32 at the pick site.
|
|
765
|
-
f32[6] = 2; // metallicChannel <- B
|
|
766
|
-
f32[7] = 1; // roughnessChannel <- G
|
|
767
|
-
f32[8] = 0; // aoChannel <- R
|
|
768
|
-
f32[9] = 0; // extraChannel <- reserved
|
|
769
|
-
// emissive vec3 + emissiveIntensity (offset 48..63)
|
|
770
|
-
const em = material.emissive;
|
|
771
|
-
f32[12] = em?.[0] ?? 0;
|
|
772
|
-
f32[13] = em?.[1] ?? 0;
|
|
773
|
-
f32[14] = em?.[2] ?? 0;
|
|
774
|
-
f32[15] = material.emissiveIntensity ?? 0;
|
|
775
|
-
// occlusionStrength (offset 64)
|
|
776
|
-
f32[16] = material.occlusionStrength ?? 1;
|
|
777
|
-
// alphaCutoff (offset 68).
|
|
778
|
-
const alphaCutoff = material.paramSnapshot?.alphaCutoff;
|
|
779
|
-
f32[17] = typeof alphaCutoff === 'number' ? alphaCutoff : 0;
|
|
780
|
-
f32[18] = material.clearcoat ?? 0;
|
|
781
|
-
f32[19] = material.clearcoatRoughness ?? 0.5;
|
|
782
|
-
const specularTint = material.specularTint;
|
|
783
|
-
f32[20] = specularTint?.[0] ?? 1;
|
|
784
|
-
f32[21] = specularTint?.[1] ?? 1;
|
|
785
|
-
f32[22] = specularTint?.[2] ?? 1;
|
|
786
|
-
const snapshotNumber = (name: string, fallback: number): number => {
|
|
787
|
-
const value = material.paramSnapshot?.[name];
|
|
788
|
-
return typeof value === 'number' ? value : fallback;
|
|
789
|
-
};
|
|
790
|
-
const snapshotVec3 = (
|
|
791
|
-
name: string,
|
|
792
|
-
fallback: readonly [number, number, number],
|
|
793
|
-
): readonly [number, number, number] => {
|
|
794
|
-
const value = material.paramSnapshot?.[name];
|
|
795
|
-
return Array.isArray(value)
|
|
796
|
-
? [value[0] ?? fallback[0], value[1] ?? fallback[1], value[2] ?? fallback[2]]
|
|
797
|
-
: fallback;
|
|
747
|
+
const schema =
|
|
748
|
+
material.materialParamSchema === undefined || material.materialParamSchema.length === 0
|
|
749
|
+
? STANDARD_PIPELINE_PARAM_SCHEMA
|
|
750
|
+
: material.materialParamSchema;
|
|
751
|
+
const snapshot = material.paramSnapshot;
|
|
752
|
+
const fallback = (name: string, entry: (typeof schema)[number]): unknown => {
|
|
753
|
+
switch (name) {
|
|
754
|
+
case 'baseColor':
|
|
755
|
+
return [
|
|
756
|
+
material.baseColor[0] ?? 1,
|
|
757
|
+
material.baseColor[1] ?? 1,
|
|
758
|
+
material.baseColor[2] ?? 1,
|
|
759
|
+
1,
|
|
760
|
+
];
|
|
761
|
+
case 'metallic':
|
|
762
|
+
return material.metallic;
|
|
763
|
+
case 'roughness':
|
|
764
|
+
return material.roughness;
|
|
765
|
+
case 'specularColor':
|
|
766
|
+
return material.specularColor ?? [1, 1, 1];
|
|
767
|
+
case 'normalScale':
|
|
768
|
+
return material.normalScale ?? 1;
|
|
769
|
+
case 'emissive':
|
|
770
|
+
return material.emissive ?? [0, 0, 0];
|
|
771
|
+
case 'emissiveIntensity':
|
|
772
|
+
return material.emissiveIntensity ?? 0;
|
|
773
|
+
case 'occlusionStrength':
|
|
774
|
+
return material.occlusionStrength ?? 1;
|
|
775
|
+
default:
|
|
776
|
+
return entry.default;
|
|
777
|
+
}
|
|
798
778
|
};
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
// engine's stock PBR shader (charter P4 + R-H regression fence).
|
|
814
|
-
const paramSnap = material.paramSnapshot;
|
|
815
|
-
if (paramSnap !== undefined) {
|
|
816
|
-
const f32Snap = (name: string): number | undefined => {
|
|
817
|
-
const v = paramSnap[name];
|
|
818
|
-
return typeof v === 'number' ? v : undefined;
|
|
819
|
-
};
|
|
820
|
-
const colorSnap = (name: string): readonly number[] | undefined => {
|
|
821
|
-
const v = paramSnap[name];
|
|
822
|
-
return Array.isArray(v) && v.every((x) => typeof x === 'number')
|
|
823
|
-
? (v as readonly number[])
|
|
824
|
-
: undefined;
|
|
825
|
-
};
|
|
826
|
-
// Walk schema in declared order, fill positional UBO slots.
|
|
827
|
-
const materialShaderId = material.materialShaderId;
|
|
828
|
-
// Note: schema lookup is the caller's job (it owns the runtime ref);
|
|
829
|
-
// when the helper has no access to runtime, paramSnap is consumed
|
|
830
|
-
// positionally without a schema walk. The inline caller (recordFrame)
|
|
831
|
-
// still performs the schema-driven walk and writes the overlay before
|
|
832
|
-
// queueing this payload, so this helper is only the byte-stable
|
|
833
|
-
// baseline. To preserve byte-for-byte equivalence in the helper-only
|
|
834
|
-
// unit-test path, the overlay pass is skipped when the helper is
|
|
835
|
-
// called without an external schema reference.
|
|
836
|
-
void materialShaderId;
|
|
837
|
-
void f32Snap;
|
|
838
|
-
void colorSnap;
|
|
779
|
+
for (const entry of derivedParamSchema(schema).uboLayout.entries) {
|
|
780
|
+
const value =
|
|
781
|
+
snapshot?.[entry.name] ??
|
|
782
|
+
fallback(entry.name, schema.find((item) => item.name === entry.name) ?? entry);
|
|
783
|
+
const offset = entry.offset / 4;
|
|
784
|
+
const width = entry.size / 4;
|
|
785
|
+
if (typeof value === 'number') {
|
|
786
|
+
f32[offset] = value;
|
|
787
|
+
} else if (Array.isArray(value)) {
|
|
788
|
+
for (let index = 0; index < Math.min(width, value.length); index += 1) {
|
|
789
|
+
const component = value[index];
|
|
790
|
+
if (typeof component === 'number') f32[offset + index] = component;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
839
793
|
}
|
|
840
794
|
}
|
|
841
795
|
|
|
@@ -884,13 +838,7 @@ export function applyParamSnapshotToUbo(
|
|
|
884
838
|
if (paramSchema === undefined) return;
|
|
885
839
|
if (paramSnapshot === undefined) return;
|
|
886
840
|
const f32 = materialUboFloatView(payload);
|
|
887
|
-
const
|
|
888
|
-
Object.hasOwn(paramSnapshot, 'transmission') &&
|
|
889
|
-
Object.hasOwn(paramSnapshot, 'ior') &&
|
|
890
|
-
Object.hasOwn(paramSnapshot, 'thickness')
|
|
891
|
-
? DEFAULT_STANDARD_PBR_PARAM_SCHEMA
|
|
892
|
-
: paramSchema;
|
|
893
|
-
const { uboLayout } = derivedParamSchema(effectiveSchema);
|
|
841
|
+
const { uboLayout } = derivedParamSchema(paramSchema);
|
|
894
842
|
for (const entry of uboLayout.entries) {
|
|
895
843
|
const value = paramSnapshot[entry.name];
|
|
896
844
|
if (value === undefined) continue;
|
|
@@ -955,6 +903,46 @@ export interface PerSubmeshMaterialBgDeps {
|
|
|
955
903
|
/** Active transmission backdrop; undefined/null means layout placeholder. */
|
|
956
904
|
readonly transmissionBackdropView?: TextureView | null;
|
|
957
905
|
readonly bindGroupCounts: BindGroupCounts;
|
|
906
|
+
readonly frameState: RenderFrameState;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
function recordIblMaterialBinding(
|
|
910
|
+
frameState: RenderFrameState,
|
|
911
|
+
materialBgl: BindGroupLayout,
|
|
912
|
+
bindGroup: BindGroup,
|
|
913
|
+
entries: readonly BindGroupEntry[],
|
|
914
|
+
iblStart: number,
|
|
915
|
+
cache: 'hit' | 'miss',
|
|
916
|
+
): void {
|
|
917
|
+
const receipt = frameState.iblBindingInspection;
|
|
918
|
+
if (receipt === undefined) return;
|
|
919
|
+
const skylightBindingStart = entries.findIndex((entry) => entry.binding === iblStart);
|
|
920
|
+
if (skylightBindingStart < 0) return;
|
|
921
|
+
const iblEntries = entries.slice(skylightBindingStart, skylightBindingStart + 7);
|
|
922
|
+
const projected: IblBindingEntryInspection[] = [];
|
|
923
|
+
for (const entry of iblEntries) {
|
|
924
|
+
if (entry.resource.kind === 'externalTexture') continue;
|
|
925
|
+
const value =
|
|
926
|
+
entry.resource.kind === 'buffer' ? entry.resource.value.buffer : entry.resource.value;
|
|
927
|
+
if (typeof value !== 'object' || value === null) continue;
|
|
928
|
+
projected.push({
|
|
929
|
+
binding: entry.binding,
|
|
930
|
+
kind: entry.resource.kind,
|
|
931
|
+
resourceIdentity: getOpaqueResourceIdentity(value as object),
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
frameState.iblBindingInspection = {
|
|
935
|
+
...receipt,
|
|
936
|
+
material: {
|
|
937
|
+
bindGroupIdentity: getOpaqueResourceIdentity(bindGroup as object),
|
|
938
|
+
materialBglIdentity: getOpaqueResourceIdentity(materialBgl as object),
|
|
939
|
+
cache,
|
|
940
|
+
skylightBindingStart: iblEntries[0]?.binding ?? 0,
|
|
941
|
+
entries: projected,
|
|
942
|
+
reflectionBindings: projected.map((entry) => entry.binding),
|
|
943
|
+
},
|
|
944
|
+
errors: [],
|
|
945
|
+
};
|
|
958
946
|
}
|
|
959
947
|
|
|
960
948
|
/** @internal Exported only so buffer-generation invalidation stays regression-tested. */
|
|
@@ -1002,6 +990,7 @@ export function buildPerSubmeshMaterialBg(
|
|
|
1002
990
|
materialBgAssemblyCache,
|
|
1003
991
|
transmissionBackdropView,
|
|
1004
992
|
bindGroupCounts,
|
|
993
|
+
frameState,
|
|
1005
994
|
} = deps;
|
|
1006
995
|
const effectiveSkylightResources =
|
|
1007
996
|
resolveReflectionProbeResources?.(materialWorld, entityKey) ?? skylightResources;
|
|
@@ -1010,10 +999,31 @@ export function buildPerSubmeshMaterialBg(
|
|
|
1010
999
|
smMaterialHandle === undefined ? undefined : `${materialWorld.identity}:${smMaterialHandle}`;
|
|
1011
1000
|
const smHasVideoFields = (submeshMaterial.videoTextureFields?.size ?? 0) > 0;
|
|
1012
1001
|
const smShaderId = submeshMaterial.materialShaderId;
|
|
1002
|
+
// The cooked shader schema owns the resource ABI. A material snapshot may
|
|
1003
|
+
// carry only the authored values (for example a clearcoat-only root omits
|
|
1004
|
+
// the standard emissive/occlusion maps), while the Standard template still
|
|
1005
|
+
// declares those slots and expects neutral fallbacks to be bound.
|
|
1006
|
+
const smSchema =
|
|
1007
|
+
(smShaderId !== undefined ? runtime.getParamSchema?.(smShaderId) : undefined) ??
|
|
1008
|
+
submeshMaterial.materialParamSchema;
|
|
1013
1009
|
const smPerShaderBgl =
|
|
1014
|
-
smShaderId !== undefined
|
|
1010
|
+
smShaderId !== undefined
|
|
1011
|
+
? runtime.getMaterialBindGroupLayout?.(smShaderId, smSchema)
|
|
1012
|
+
: undefined;
|
|
1015
1013
|
const smMaterialBgl = smPerShaderBgl ?? pipelineState.materialBindGroupLayout;
|
|
1014
|
+
const standardMaterial = isStandardPbrMaterialShader(smShaderId);
|
|
1015
|
+
const physicalFields =
|
|
1016
|
+
standardMaterial && smSchema !== undefined ? physicalTextureFields(smSchema) : [];
|
|
1017
|
+
// Standard's built-in shader owns the canonical seven-pair user region even
|
|
1018
|
+
// when the authored root only declares a subset. Physical maps are appended
|
|
1019
|
+
// after the reserved IBL/transmission tail, so compacting this list would
|
|
1020
|
+
// shift the shader's IBL bindings and invalidate the render pipeline.
|
|
1021
|
+
const smUserRegionFields =
|
|
1022
|
+
smPerShaderBgl === undefined || isCanonicalStandardPbrMaterialShader(smShaderId)
|
|
1023
|
+
? BUILTIN_USER_REGION_TEXTURE_FIELDS
|
|
1024
|
+
: userRegionTextureFieldOrder(smSchema).filter((field) => !physicalFields.includes(field));
|
|
1016
1025
|
const hasActiveTransmissionBackdrop = transmissionBackdropView != null;
|
|
1026
|
+
const diagnosticsEnabled = materialDiagnosticsEnabled();
|
|
1017
1027
|
if (smMaterialHandle !== undefined && !smHasVideoFields && !hasActiveTransmissionBackdrop) {
|
|
1018
1028
|
const cached =
|
|
1019
1029
|
materialCacheKey === undefined ? undefined : materialBgAssemblyCache.get(materialCacheKey);
|
|
@@ -1028,21 +1038,48 @@ export function buildPerSubmeshMaterialBg(
|
|
|
1028
1038
|
transmissionBackdropView,
|
|
1029
1039
|
)
|
|
1030
1040
|
) {
|
|
1041
|
+
if (diagnosticsEnabled) {
|
|
1042
|
+
recordIblMaterialBinding(
|
|
1043
|
+
frameState,
|
|
1044
|
+
smMaterialBgl,
|
|
1045
|
+
cached.bindGroup,
|
|
1046
|
+
[
|
|
1047
|
+
{
|
|
1048
|
+
binding: 1 + smUserRegionFields.length * 2,
|
|
1049
|
+
resource: { kind: 'textureView', value: skylightResources.irradianceView },
|
|
1050
|
+
},
|
|
1051
|
+
{
|
|
1052
|
+
binding: 2 + smUserRegionFields.length * 2,
|
|
1053
|
+
resource: { kind: 'sampler', value: skylightResources.irradianceSampler },
|
|
1054
|
+
},
|
|
1055
|
+
{
|
|
1056
|
+
binding: 3 + smUserRegionFields.length * 2,
|
|
1057
|
+
resource: { kind: 'textureView', value: skylightResources.prefilterView },
|
|
1058
|
+
},
|
|
1059
|
+
{
|
|
1060
|
+
binding: 4 + smUserRegionFields.length * 2,
|
|
1061
|
+
resource: { kind: 'sampler', value: skylightResources.prefilterSampler },
|
|
1062
|
+
},
|
|
1063
|
+
{
|
|
1064
|
+
binding: 5 + smUserRegionFields.length * 2,
|
|
1065
|
+
resource: { kind: 'textureView', value: skylightResources.brdfLutView },
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
binding: 6 + smUserRegionFields.length * 2,
|
|
1069
|
+
resource: { kind: 'sampler', value: skylightResources.brdfLutSampler },
|
|
1070
|
+
},
|
|
1071
|
+
{
|
|
1072
|
+
binding: 7 + smUserRegionFields.length * 2,
|
|
1073
|
+
resource: { kind: 'buffer', value: { buffer: skylightResources.intensityBuffer } },
|
|
1074
|
+
},
|
|
1075
|
+
],
|
|
1076
|
+
1 + smUserRegionFields.length * 2,
|
|
1077
|
+
'hit',
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1031
1080
|
return cached.bindGroup;
|
|
1032
1081
|
}
|
|
1033
1082
|
}
|
|
1034
|
-
const smSchema =
|
|
1035
|
-
submeshMaterial.materialParamSchema ??
|
|
1036
|
-
(smShaderId !== undefined ? runtime.getParamSchema?.(smShaderId) : undefined);
|
|
1037
|
-
// The shipped PBR shaders always own the eight texture pairs declared by the
|
|
1038
|
-
// standard shader artifact. The runtime PBR BGL exposes those pairs directly;
|
|
1039
|
-
// emissive and occlusion are not duplicated in an engine injection region.
|
|
1040
|
-
// Keep the record projection on the shader-owned layout so IBL starts at
|
|
1041
|
-
// binding 17 rather than colliding with transmissionSampler.
|
|
1042
|
-
const smUserRegionFields =
|
|
1043
|
-
smPerShaderBgl === undefined || isStandardPbrMaterialShader(smShaderId)
|
|
1044
|
-
? BUILTIN_USER_REGION_TEXTURE_FIELDS
|
|
1045
|
-
: userRegionTextureFieldOrder(smSchema);
|
|
1046
1083
|
let materialResourcesResident = true;
|
|
1047
1084
|
const smSamplerForField = (field: string | undefined): Sampler => {
|
|
1048
1085
|
const handle = field === undefined ? undefined : submeshMaterial.samplerHandles?.get(field);
|
|
@@ -1125,6 +1162,38 @@ export function buildPerSubmeshMaterialBg(
|
|
|
1125
1162
|
},
|
|
1126
1163
|
);
|
|
1127
1164
|
}
|
|
1165
|
+
// Physical Standard maps are deliberately appended after the stable IBL /
|
|
1166
|
+
// transmission tail. Keep their resource projection separate from the
|
|
1167
|
+
// user-region loop so the slot order is the same as
|
|
1168
|
+
// `appendTextureInjection(afterTransmission, physicalFields)` in the
|
|
1169
|
+
// layout owner.
|
|
1170
|
+
const physicalTextureInjections: TextureInjectionResource[] = [];
|
|
1171
|
+
for (let slot = 0; slot < physicalFields.length; slot += 1) {
|
|
1172
|
+
const field = physicalFields[slot];
|
|
1173
|
+
if (field === undefined) continue;
|
|
1174
|
+
let view = defaultViewForUserRegionField(field, pipelineState, smSchema);
|
|
1175
|
+
const targetSource = materialRenderTargetSourceForField(
|
|
1176
|
+
submeshMaterial,
|
|
1177
|
+
field,
|
|
1178
|
+
resolveRenderTargetTextureSource,
|
|
1179
|
+
);
|
|
1180
|
+
if (targetSource !== undefined) {
|
|
1181
|
+
if (targetSource.textureView !== undefined) view = targetSource.textureView;
|
|
1182
|
+
else materialResourcesResident = false;
|
|
1183
|
+
} else {
|
|
1184
|
+
const handle = submeshMaterial.textureHandles?.get(field);
|
|
1185
|
+
if (handle !== undefined) {
|
|
1186
|
+
const resident = residentTextureView(materialWorld, store, runtime, handle);
|
|
1187
|
+
if (resident !== undefined) view = resident;
|
|
1188
|
+
else materialResourcesResident = false;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
physicalTextureInjections.push({
|
|
1192
|
+
slot,
|
|
1193
|
+
sampler: smSamplerForField(field),
|
|
1194
|
+
view,
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1128
1197
|
// The backdrop is a full mip-chain view owned by the pipeline. Reuse the
|
|
1129
1198
|
// pipeline's existing filtering/clamp sampler for screen-space sampling;
|
|
1130
1199
|
// the material default sampler intentionally keeps repeat addressing for
|
|
@@ -1140,6 +1209,7 @@ export function buildPerSubmeshMaterialBg(
|
|
|
1140
1209
|
sampler: transmissionSampler,
|
|
1141
1210
|
...(transmissionBackdropView === undefined ? {} : { backdropView: transmissionBackdropView }),
|
|
1142
1211
|
} satisfies TransmissionBindGroupResources,
|
|
1212
|
+
physicalTextureInjections,
|
|
1143
1213
|
);
|
|
1144
1214
|
const createBindGroup = (): BindGroup => {
|
|
1145
1215
|
const result = runtime.device.createBindGroup({
|
|
@@ -1150,16 +1220,60 @@ export function buildPerSubmeshMaterialBg(
|
|
|
1150
1220
|
if (!result.ok) throw result.error;
|
|
1151
1221
|
return result.value;
|
|
1152
1222
|
};
|
|
1223
|
+
const materialCacheHandles = smMergedEntries.map((entry) => extractEntryResourceHandle(entry));
|
|
1224
|
+
if (
|
|
1225
|
+
diagnosticsEnabled &&
|
|
1226
|
+
submeshMaterial.textureHandles === undefined &&
|
|
1227
|
+
smMaterialHandle !== undefined
|
|
1228
|
+
) {
|
|
1229
|
+
console.error(
|
|
1230
|
+
`[render-material] scalar material cache handles: ${JSON.stringify({
|
|
1231
|
+
entityKey,
|
|
1232
|
+
materialHandle: smMaterialHandle,
|
|
1233
|
+
shader: smShaderId,
|
|
1234
|
+
paramSnapshot: submeshMaterial.paramSnapshot,
|
|
1235
|
+
handleTypes: materialCacheHandles.map((handle) => typeof handle),
|
|
1236
|
+
})}`,
|
|
1237
|
+
);
|
|
1238
|
+
}
|
|
1239
|
+
if (
|
|
1240
|
+
diagnosticsEnabled &&
|
|
1241
|
+
materialCacheHandles.some((handle) => typeof handle !== 'object' || handle === null)
|
|
1242
|
+
) {
|
|
1243
|
+
console.error(
|
|
1244
|
+
`[render-material] invalid material cache handle: ${JSON.stringify({
|
|
1245
|
+
entityKey,
|
|
1246
|
+
materialHandle: smMaterialHandle,
|
|
1247
|
+
shader: smShaderId,
|
|
1248
|
+
entries: smMergedEntries.map((entry, index) => ({
|
|
1249
|
+
index,
|
|
1250
|
+
binding: entry.binding,
|
|
1251
|
+
kind: entry.resource.kind,
|
|
1252
|
+
handleType: typeof materialCacheHandles[index],
|
|
1253
|
+
})),
|
|
1254
|
+
})}`,
|
|
1255
|
+
);
|
|
1256
|
+
}
|
|
1153
1257
|
const smBindGroup = hasActiveTransmissionBackdrop
|
|
1154
1258
|
? createBindGroup()
|
|
1155
1259
|
: getOrCreatePerEntity(
|
|
1156
1260
|
materialBgShared,
|
|
1157
1261
|
smShaderId ?? '',
|
|
1158
|
-
|
|
1262
|
+
materialCacheHandles,
|
|
1159
1263
|
'material-shared',
|
|
1160
1264
|
createBindGroup,
|
|
1161
1265
|
bindGroupCounts,
|
|
1162
1266
|
);
|
|
1267
|
+
if (diagnosticsEnabled) {
|
|
1268
|
+
recordIblMaterialBinding(
|
|
1269
|
+
frameState,
|
|
1270
|
+
smMaterialBgl,
|
|
1271
|
+
smBindGroup,
|
|
1272
|
+
smMergedEntries,
|
|
1273
|
+
smBaseEntries.length,
|
|
1274
|
+
'miss',
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1163
1277
|
if (
|
|
1164
1278
|
smMaterialHandle !== undefined &&
|
|
1165
1279
|
!smHasVideoFields &&
|