@forgeax/engine-render 0.1.20 → 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 +365 -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 +18 -0
- package/dist/assembly/device-feature-admission.d.ts.map +1 -0
- package/dist/assembly/directional-shadow-inspection.d.ts +38 -0
- package/dist/assembly/directional-shadow-inspection.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +30 -19
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +19 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/render-target-host.d.ts +46 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -0
- package/dist/assets/render-asset-port.d.ts.map +1 -1
- package/dist/authoring.mjs +4 -1
- package/dist/authoring.mjs.map +1 -1
- package/dist/capture/cube-views.d.ts +21 -0
- package/dist/capture/cube-views.d.ts.map +1 -0
- package/dist/capture/scheduler.d.ts +54 -0
- package/dist/capture/scheduler.d.ts.map +1 -0
- package/dist/{chunk-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-CDTWTHZR.mjs → chunk-FF7K3FSO.mjs} +474 -168
- 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-TBQJOK2L.mjs → chunk-QODA5UKU.mjs} +321 -269
- 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-4XINDLAY.mjs → chunk-ZUWKAZ2I.mjs} +1963 -2178
- 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/camera.d.ts +1 -0
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/cube-camera.d.ts +20 -0
- package/dist/components/cube-camera.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +11 -2
- package/dist/components/directional-light.d.ts.map +1 -1
- package/dist/components/directional-shadow-filter.d.ts +25 -0
- package/dist/components/directional-shadow-filter.d.ts.map +1 -0
- package/dist/components/index.d.ts +5 -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/reflection-probe.d.ts +17 -0
- package/dist/components/reflection-probe.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 +14836 -9620
- 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/frame.d.ts.map +1 -1
- package/dist/environment/lifecycle.d.ts +5 -0
- package/dist/environment/lifecycle.d.ts.map +1 -1
- package/dist/errors/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 +166 -93
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/directional-shadow-projection.d.ts +23 -0
- package/dist/extract/directional-shadow-projection.d.ts.map +1 -0
- package/dist/extract/environment.d.ts +14 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/extract/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/fullscreen.d.ts.map +1 -1
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +10 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +13 -2
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +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 +97 -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 +21 -19
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +4 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/kernel-cache.d.ts +36 -0
- package/dist/ibl/kernel-cache.d.ts.map +1 -0
- package/dist/index.d.ts +39 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +91 -6
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +214 -1
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +50 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -0
- package/dist/internal.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 -140
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/materials.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +54 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +38 -14
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts +2 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/errors.d.ts +4 -0
- package/dist/pipeline/standard-lighting/errors.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/graph.d.ts +24 -0
- package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts +38 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/layout.d.ts +28 -0
- package/dist/pipeline/standard-lighting/layout.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts +33 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/membership.d.ts +14 -0
- package/dist/pipeline/standard-lighting/membership.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts +16 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/topology.d.ts +45 -0
- package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/transport.d.ts +36 -0
- package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts +4 -13
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +5 -26
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +2 -0
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +40 -7
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/point-shadow-inspection.d.ts +21 -0
- package/dist/point-shadow-inspection.d.ts.map +1 -0
- package/dist/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 +33 -36
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +78 -24
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts +5 -0
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +16 -6
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-pass-timing/contract.d.ts +96 -0
- package/dist/record/gpu-pass-timing/contract.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/errors.d.ts +18 -0
- package/dist/record/gpu-pass-timing/errors.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/index.d.ts +8 -0
- package/dist/record/gpu-pass-timing/index.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/parser.d.ts +11 -0
- package/dist/record/gpu-pass-timing/parser.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/session.d.ts +43 -0
- package/dist/record/gpu-pass-timing/session.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +20 -3
- 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 +25 -2
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +2 -0
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +98 -6
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +119 -4
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +7 -5
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/reflection/filter.d.ts +22 -0
- package/dist/reflection/filter.d.ts.map +1 -0
- package/dist/reflection/gpu-table.d.ts +25 -0
- package/dist/reflection/gpu-table.d.ts.map +1 -0
- package/dist/reflection/inspection.d.ts +10 -0
- package/dist/reflection/inspection.d.ts.map +1 -0
- package/dist/reflection/projection.d.ts +140 -0
- package/dist/reflection/projection.d.ts.map +1 -0
- 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 +62 -14
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +49 -2
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +160 -31
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +28 -2
- package/dist/render-system.d.ts.map +1 -1
- package/dist/renderer.d.ts +43 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/scene/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 +117 -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/shadow-atlas.d.ts +3 -3
- package/dist/shadow-atlas.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +3 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/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/targets/contracts.d.ts +66 -0
- package/dist/targets/contracts.d.ts.map +1 -0
- package/dist/targets/graph-projection.d.ts +29 -0
- package/dist/targets/graph-projection.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +34 -0
- package/dist/targets/material-source.d.ts.map +1 -0
- package/dist/targets/owner.d.ts +32 -0
- package/dist/targets/owner.d.ts.map +1 -0
- package/dist/targets/physical.d.ts +18 -0
- package/dist/targets/physical.d.ts.map +1 -0
- package/dist/targets/readback.d.ts +39 -0
- package/dist/targets/readback.d.ts.map +1 -0
- package/dist/temporal/frame-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 +5 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +1 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +9 -5
- package/dist/volume/passes.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/__tests__/bloom-exact-zero.unit.test.ts +48 -19
- package/src/__tests__/bloom-lifecycle.integration.test.ts +41 -13
- package/src/__tests__/camera-target-consumption.unit.test.ts +53 -0
- package/src/__tests__/cluster-binner.unit.test.ts +35 -0
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +12 -2
- package/src/__tests__/cube-camera-scheduler.unit.test.ts +70 -0
- package/src/__tests__/cube-camera-single-submit.perf.test.ts +75 -0
- package/src/__tests__/cube-camera-view-matrices.unit.test.ts +41 -0
- package/src/__tests__/cube-camera-vocabulary.unit.test.ts +47 -0
- package/src/__tests__/cube-camera.integration.test.ts +42 -0
- package/src/__tests__/detached-inspection.integration.test.ts +6 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +85 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +62 -6
- package/src/__tests__/docs-gate-green.unit.test.ts +38 -0
- 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 +288 -29
- package/src/__tests__/fog-component.unit.test.ts +67 -0
- package/src/__tests__/fog.integration.test.ts +86 -0
- package/src/__tests__/frame-observation.contract.test.ts +15 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +37 -0
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +10 -8
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +18 -1
- package/src/__tests__/gpu-driven-production.integration.test.ts +579 -17
- 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 +101 -6
- 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-pass-timing-browser-runner.ts +281 -0
- package/src/__tests__/gpu-pass-timing-coexistence.integration.test.ts +80 -0
- package/src/__tests__/gpu-pass-timing-contract.unit.test.ts +243 -0
- package/src/__tests__/gpu-pass-timing-exact-zero.unit.test.ts +131 -0
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +230 -0
- package/src/__tests__/gpu-pass-timing-observation.unit.test.ts +233 -0
- package/src/__tests__/gpu-pass-timing-session.unit.test.ts +438 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +26 -0
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +125 -0
- package/src/__tests__/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__/hdrp-group2-visibility.unit.test.ts +24 -0
- package/src/__tests__/instances-culling.integration.test.ts +94 -0
- package/src/__tests__/instances-derived-bounds.unit.test.ts +118 -0
- package/src/__tests__/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__/material-observation.integration.test.ts +101 -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__/pbr-view-layout.unit.test.ts +16 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +60 -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__/public-surface.test-d.ts +10 -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-authoring.unit.test.ts +71 -0
- package/src/__tests__/reflection-probe-filter.unit.test.ts +54 -0
- package/src/__tests__/reflection-probe-ibl-topology.unit.test.ts +45 -0
- package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
- package/src/__tests__/reflection-probe-pass-encode.integration.test.ts +101 -0
- package/src/__tests__/reflection-probe-performance.perf.test.ts +60 -0
- package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
- package/src/__tests__/reflection-probe-recovery.integration.test.ts +55 -0
- package/src/__tests__/reflection-probe-selection.unit.test.ts +46 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +19 -3
- 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__/render-target-admission.unit.test.ts +80 -0
- package/src/__tests__/render-target-graph-projection.unit.test.ts +102 -0
- package/src/__tests__/render-target-inspection.unit.test.ts +52 -0
- package/src/__tests__/render-target-material-source.test-d.ts +30 -0
- package/src/__tests__/render-target-material-source.unit.test.ts +97 -0
- package/src/__tests__/render-target-owner-placement.unit.test.ts +203 -0
- package/src/__tests__/render-target-owner.unit.test.ts +122 -0
- package/src/__tests__/render-target-probe-soak.perf.test.ts +94 -0
- package/src/__tests__/render-target-public-schema.json +107 -0
- package/src/__tests__/render-target-public-schema.unit.test.ts +91 -0
- package/src/__tests__/render-target-public-surface.test-d.ts +83 -0
- package/src/__tests__/render-target-readback.integration.test.ts +90 -0
- package/src/__tests__/render-target-recovery.integration.test.ts +85 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +124 -0
- package/src/__tests__/renderer-lifecycle.integration.test.ts +14 -0
- package/src/__tests__/shader-stage-surface.unit.test.ts +19 -4
- package/src/__tests__/skin-motion-regression.unit.test.ts +154 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +13 -4
- 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-capability.integration.test.ts +63 -0
- package/src/__tests__/standard-cluster-transport.unit.test.ts +121 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +299 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +15 -5
- package/src/__tests__/standard-lighting-inspection.integration.test.ts +138 -0
- package/src/__tests__/standard-lighting-ssot.unit.test.ts +18 -0
- package/src/__tests__/standard-lighting-write.unit.test.ts +441 -0
- package/src/__tests__/standard-lighting.integration.test.ts +67 -0
- package/src/__tests__/standard-pipeline.dawn.test.ts +206 -5
- package/src/__tests__/standard-pipeline.integration.test.ts +181 -150
- package/src/__tests__/standard-probe-binding.unit.test.ts +25 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +23 -38
- package/src/__tests__/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__/typed-pipeline-topology.unit.test.ts +395 -14
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +2 -2
- 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__/visibility-resolver.unit.test.ts +15 -0
- 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 +80 -0
- package/src/assembly/directional-shadow-inspection.ts +122 -0
- package/src/assembly/factory.ts +1411 -366
- package/src/assembly/host-contract.ts +35 -0
- package/src/assembly/render-target-host.ts +847 -0
- package/src/assets/asset-decoders.ts +1 -1
- package/src/assets/render-asset-port.ts +7 -1
- package/src/capture/cube-views.ts +69 -0
- package/src/capture/scheduler.ts +265 -0
- package/src/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/__tests__/schema-contract.unit.test.ts +12 -0
- package/src/components/__tests__/schema-parity.unit.test.ts +9 -0
- package/src/components/camera.ts +4 -0
- package/src/components/cube-camera.ts +52 -0
- package/src/components/directional-light.ts +22 -2
- package/src/components/directional-shadow-filter.ts +57 -0
- package/src/components/index.ts +5 -0
- package/src/components/light-helpers.ts +133 -8
- package/src/components/light-probe.ts +13 -0
- package/src/components/rect-area-light.ts +15 -0
- package/src/components/reflection-probe.ts +49 -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/frame.ts +6 -24
- package/src/environment/lifecycle.ts +20 -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 +341 -143
- package/src/extract/camera.ts +3 -3
- package/src/extract/directional-shadow-projection.ts +61 -0
- package/src/extract/environment.ts +57 -0
- package/src/extract/gpu-driven.ts +108 -0
- package/src/extract/visibility.ts +2 -1
- package/src/features/fullscreen.ts +3 -0
- package/src/features/targets.ts +4 -1
- package/src/features/types.ts +10 -0
- package/src/fullscreen-post-process-pass.ts +43 -2
- package/src/gpu-driven/batch-topology.ts +207 -28
- package/src/gpu-driven/prepared-draw.ts +208 -0
- package/src/gpu-driven/production-raster.ts +953 -43
- package/src/gpu-driven/view-gpu.ts +411 -29
- package/src/gpu-scene-schema.ts +13 -0
- package/src/gpu-scene.ts +140 -64
- package/src/gpu-usage.ts +0 -1
- package/src/hdrp-buffers.ts +169 -63
- package/src/ibl/IblPipelineCache.ts +11 -0
- package/src/ibl/kernel-cache.ts +88 -0
- package/src/index.ts +222 -0
- package/src/inspection-types.ts +276 -1
- package/src/instances-derived-bounds.ts +171 -0
- package/src/internal.ts +38 -0
- package/src/light-buffer-layout.ts +155 -310
- package/src/materials.ts +16 -2
- package/src/mesh-material-bindings.ts +132 -0
- package/src/pbr-pipeline.ts +255 -60
- package/src/pipeline/standard-forward-lane.ts +93 -16
- package/src/pipeline/standard-lighting/errors.ts +6 -0
- package/src/pipeline/standard-lighting/graph.ts +158 -0
- package/src/pipeline/standard-lighting/inspection.ts +88 -0
- package/src/pipeline/standard-lighting/layout.ts +31 -0
- package/src/pipeline/standard-lighting/light-frame.ts +35 -0
- package/src/pipeline/standard-lighting/membership.ts +43 -0
- package/src/pipeline/standard-lighting/prepare.ts +37 -0
- package/src/pipeline/standard-lighting/topology.ts +120 -0
- package/src/pipeline/standard-lighting/transport.ts +78 -0
- package/src/pipeline/standard-pipeline.ts +124 -193
- package/src/pipeline/standard-post.ts +26 -7
- package/src/pipeline/standard-profile.ts +17 -47
- package/src/pipeline-builder.ts +5 -2
- package/src/pipeline-spec.ts +95 -21
- package/src/plugin.ts +4 -0
- package/src/point-shadow-inspection.ts +55 -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 +64 -1
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +73 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +20 -1
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +40 -0
- package/src/record/frame-lighting.ts +591 -452
- package/src/record/frame-snapshot.ts +92 -39
- package/src/record/frame-targets.ts +17 -0
- package/src/record/frame.ts +662 -158
- package/src/record/gpu-pass-timing/contract.ts +180 -0
- package/src/record/gpu-pass-timing/errors.ts +34 -0
- package/src/record/gpu-pass-timing/index.ts +37 -0
- package/src/record/gpu-pass-timing/parser.ts +97 -0
- package/src/record/gpu-pass-timing/session.ts +938 -0
- package/src/record/gpu-timing.ts +112 -39
- package/src/record/helpers.ts +0 -58
- package/src/record/main-pass-geometry.ts +324 -119
- package/src/record/main-pass-material.ts +103 -10
- package/src/record/main-pass-sprite-draws.ts +99 -103
- package/src/record/main-pass.ts +71 -15
- package/src/record/mesh-ssbo.ts +47 -36
- package/src/record/render-context.ts +136 -3
- package/src/record/shadow-pass.ts +83 -68
- package/src/record/skybox-post-pass.ts +20 -4
- package/src/record/typed-frame-graph.ts +1034 -43
- package/src/record/view-ubo.ts +72 -47
- package/src/reflection/filter.ts +81 -0
- package/src/reflection/gpu-table.ts +44 -0
- package/src/reflection/inspection.ts +67 -0
- package/src/reflection/projection.ts +476 -0
- package/src/reflection/record-owner.ts +1283 -0
- package/src/render-contract.ts +93 -10
- package/src/render-graph-primitives.ts +9 -4
- package/src/render-pipeline.ts +122 -2
- package/src/render-system-extract.ts +1041 -225
- package/src/render-system.ts +1310 -85
- package/src/renderer.ts +222 -0
- 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 +942 -171
- 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/shadow-atlas.ts +5 -5
- package/src/ssao-buffers.ts +9 -2
- 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/targets/contracts.ts +182 -0
- package/src/targets/graph-projection.ts +169 -0
- package/src/targets/material-source.ts +143 -0
- package/src/targets/owner.ts +214 -0
- package/src/targets/physical.ts +18 -0
- package/src/targets/readback.ts +153 -0
- package/src/temporal/frame-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/transmission/__tests__/standard-transmission.dawn.test.ts +59 -20
- package/src/typed-render-graph-primitives.ts +53 -3
- package/src/typed-shadow-passes.ts +46 -40
- package/src/volume/passes.ts +61 -58
- package/dist/.tsbuildinfo +0 -1
- package/dist/chunk-4XINDLAY.mjs.map +0 -1
- package/dist/chunk-CDTWTHZR.mjs.map +0 -1
- package/dist/chunk-M2MP4ZOU.mjs +0 -73
- package/dist/chunk-M2MP4ZOU.mjs.map +0 -1
- package/dist/chunk-PCHBPYML.mjs.map +0 -1
- package/dist/chunk-TBQJOK2L.mjs.map +0 -1
- package/dist/chunk-VFPLTKCU.mjs.map +0 -1
|
@@ -17,19 +17,36 @@ import {
|
|
|
17
17
|
GPU_BUFFER_USAGE_STORAGE,
|
|
18
18
|
GPU_BUFFER_USAGE_UNIFORM,
|
|
19
19
|
} from '../gpu-usage';
|
|
20
|
+
import { createHdrpSkinUnifiedBindGroup, getOrCreateHdrpBuffers } from '../hdrp-buffers';
|
|
20
21
|
import type { InstanceBufferCacheEntry } from '../instance-buffer-cache';
|
|
21
22
|
import { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';
|
|
22
|
-
import {
|
|
23
|
-
|
|
23
|
+
import {
|
|
24
|
+
createPbrSkinMeshBindGroupEntries,
|
|
25
|
+
isStandardPbrMaterialShader,
|
|
26
|
+
pbrSkinMeshDynamicOffsets,
|
|
27
|
+
SKIN_MATERIAL_SHADER_ID,
|
|
28
|
+
} from '../pbr-pipeline';
|
|
29
|
+
import {
|
|
30
|
+
renderStateHash,
|
|
31
|
+
standardStorageVariantSet,
|
|
32
|
+
standardTopologyVariantSet,
|
|
33
|
+
variantSetFromVertexLayoutProjection,
|
|
34
|
+
} from '../pipeline-spec';
|
|
24
35
|
import type { PointsLinesRecordPlan } from '../points-lines/record';
|
|
25
36
|
import { POINTS_LINES_MATERIAL_SHADER_ID } from '../points-lines/record';
|
|
26
37
|
import type { RenderRecordPhase } from '../render-contract';
|
|
27
38
|
import type { MaterialSnapshot } from '../render-system-extract';
|
|
39
|
+
import {
|
|
40
|
+
PROBE_BLEND_RECORD_BYTE_SIZE,
|
|
41
|
+
PROBE_BLEND_RECORD_STRIDE,
|
|
42
|
+
probeBlendRecordOffset,
|
|
43
|
+
} from '../scene/probe-blend-record';
|
|
28
44
|
import { worldEntityKey } from './frame-snapshot';
|
|
29
45
|
import {
|
|
30
46
|
geometryRenderStateForTopology,
|
|
31
47
|
isEntityFullyTransparent,
|
|
32
48
|
selectGeometryPipeline,
|
|
49
|
+
selectMaterialGroup2,
|
|
33
50
|
} from './main-pass-material';
|
|
34
51
|
import {
|
|
35
52
|
getOrCreateFromChain,
|
|
@@ -40,19 +57,22 @@ import {
|
|
|
40
57
|
MESH_UBO_FULL_ARRAY_BYTES,
|
|
41
58
|
packInstanceStorageBuffer,
|
|
42
59
|
} from './mesh-ssbo';
|
|
43
|
-
import type { _InternalRenderPipelineContext } from './render-context';
|
|
60
|
+
import type { _InternalRenderPipelineContext, MaterialShaderPipelineEntry } from './render-context';
|
|
44
61
|
import { MATERIAL_PER_ENTITY_STRIDE } from './render-context';
|
|
45
62
|
import { POINTS_LINES_VIEW_SLOT_STRIDE, writePointsLinesViewUbo } from './view-ubo';
|
|
46
63
|
|
|
47
64
|
type GeometryInstanceDraw = {
|
|
48
65
|
readonly instanceBuffer: Buffer;
|
|
49
66
|
readonly instanceBindGroup: BindGroup;
|
|
67
|
+
/** -1 means the no-probe layout and therefore no dynamic offset. */
|
|
68
|
+
readonly probeOffset: number;
|
|
50
69
|
readonly instanceCount: number;
|
|
51
70
|
};
|
|
52
71
|
|
|
53
72
|
type GeometryBindingState = {
|
|
54
73
|
pipeline: RenderPipeline | null;
|
|
55
74
|
instancesBuffer: Buffer | null;
|
|
75
|
+
probeOffset: number;
|
|
56
76
|
};
|
|
57
77
|
|
|
58
78
|
type MaterialPipelineLookup = {
|
|
@@ -66,7 +86,8 @@ type MaterialPipelineLookup = {
|
|
|
66
86
|
readonly layoutProjection: import('@forgeax/engine-geometry').VertexLayoutProjection;
|
|
67
87
|
readonly sampleCount: number;
|
|
68
88
|
readonly colorFormatOverride: GPUTextureFormat | undefined;
|
|
69
|
-
readonly
|
|
89
|
+
readonly additionalColorFormats: readonly GPUTextureFormat[] | undefined;
|
|
90
|
+
readonly handle: MaterialShaderPipelineEntry | null;
|
|
70
91
|
};
|
|
71
92
|
|
|
72
93
|
type GeometryRecordProfileSegment = 'material-bind-groups' | 'pipeline-selection' | 'draw-submit';
|
|
@@ -127,9 +148,17 @@ function submitSubmeshDraws(
|
|
|
127
148
|
state.pipeline = pipeline;
|
|
128
149
|
}
|
|
129
150
|
for (const instanceDraw of instanceDraws) {
|
|
130
|
-
if (
|
|
131
|
-
|
|
151
|
+
if (
|
|
152
|
+
instanceDraw.instanceBuffer !== state.instancesBuffer ||
|
|
153
|
+
instanceDraw.probeOffset !== state.probeOffset
|
|
154
|
+
) {
|
|
155
|
+
if (instanceDraw.probeOffset < 0) {
|
|
156
|
+
pass.setBindGroup(3, instanceDraw.instanceBindGroup);
|
|
157
|
+
} else {
|
|
158
|
+
pass.setBindGroup(3, instanceDraw.instanceBindGroup, [instanceDraw.probeOffset]);
|
|
159
|
+
}
|
|
132
160
|
state.instancesBuffer = instanceDraw.instanceBuffer;
|
|
161
|
+
state.probeOffset = instanceDraw.probeOffset;
|
|
133
162
|
}
|
|
134
163
|
if (indexed) {
|
|
135
164
|
pass.drawIndexed(indexCount, instanceDraw.instanceCount, indexOffset, 0, 0);
|
|
@@ -197,8 +226,13 @@ export function recordGeometryDraws(
|
|
|
197
226
|
validatedOrdered,
|
|
198
227
|
splitLdrSprite,
|
|
199
228
|
viewBindGroup,
|
|
229
|
+
viewBindGroupDynamicOffset = 0,
|
|
200
230
|
} = c;
|
|
201
231
|
const colorFormatOverride = c.transparentColorFormat as GPUTextureFormat | undefined;
|
|
232
|
+
// The prepared Standard topology is the frame authority. A bind-group
|
|
233
|
+
// identity is only a resource result; using it to infer the shader lane
|
|
234
|
+
// would silently fall back to URP when the clustered resource is missing.
|
|
235
|
+
const clusteredLighting = c.standardLighting?.kind === 'clustered';
|
|
202
236
|
// A no-tone frame may still render into the graph-owned rgba16float target
|
|
203
237
|
// (the linear-LDR route). Shader variants must follow the attachment's
|
|
204
238
|
// numeric domain rather than the camera's tone-map switch, otherwise the
|
|
@@ -210,19 +244,20 @@ export function recordGeometryDraws(
|
|
|
210
244
|
const bindingState: GeometryBindingState = {
|
|
211
245
|
pipeline: null,
|
|
212
246
|
instancesBuffer: null,
|
|
247
|
+
probeOffset: -1,
|
|
213
248
|
};
|
|
214
249
|
const identityInstanceBuffer = pipelineState.identityInstanceBuffer;
|
|
215
250
|
const identityInstanceDraws: readonly GeometryInstanceDraw[] = [
|
|
216
251
|
{
|
|
217
252
|
instanceBuffer: identityInstanceBuffer,
|
|
218
|
-
instanceBindGroup: resolveGeometryInstancesBindGroup(c, identityInstanceBuffer),
|
|
253
|
+
instanceBindGroup: resolveGeometryInstancesBindGroup(c, identityInstanceBuffer, undefined),
|
|
254
|
+
probeOffset: -1,
|
|
219
255
|
instanceCount: 1,
|
|
220
256
|
},
|
|
221
257
|
];
|
|
222
258
|
const profilePhase = c.profilePhase;
|
|
223
259
|
const materialGroup1DynamicOffsets = new Uint32Array(1);
|
|
224
260
|
const meshGroup2DynamicOffsets = [0];
|
|
225
|
-
const skinGroup2DynamicOffsets = [0, 0];
|
|
226
261
|
let lastStencilReference: number | null = null;
|
|
227
262
|
// feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (D-7):
|
|
228
263
|
// sprite PSO selection no longer maintains a dedicated tag — the
|
|
@@ -238,6 +273,9 @@ export function recordGeometryDraws(
|
|
|
238
273
|
// renderer's authoritative cache still owns lifetime/invalidation, while
|
|
239
274
|
// this frame-local table removes the hot call/lookup overhead.
|
|
240
275
|
const materialPipelineLookupCache = new Map<string, Map<string, MaterialPipelineLookup[]>>();
|
|
276
|
+
const recordOcclusionCandidate = (draw: () => void): void => {
|
|
277
|
+
draw();
|
|
278
|
+
};
|
|
241
279
|
const resolveMaterialPipeline = (
|
|
242
280
|
materialShaderId: string,
|
|
243
281
|
renderState: MaterialSnapshot['renderState'],
|
|
@@ -246,7 +284,20 @@ export function recordGeometryDraws(
|
|
|
246
284
|
variantSet: string | undefined,
|
|
247
285
|
colorFormat: GPUTextureFormat | undefined,
|
|
248
286
|
layoutProjection: import('@forgeax/engine-geometry').VertexLayoutProjection,
|
|
249
|
-
):
|
|
287
|
+
): MaterialShaderPipelineEntry | null => {
|
|
288
|
+
// The fallback MRT is an extension of the built-in Standard PBR output
|
|
289
|
+
// contract only. The render pass may carry a second attachment whenever
|
|
290
|
+
// another renderable needs S_fallback, but shaders such as unlit, sprite,
|
|
291
|
+
// and the skin PBR variant still expose only @location(0). Passing that
|
|
292
|
+
// attachment into their PSO would make WebGPU reject the pipeline before
|
|
293
|
+
// the first draw ("Color target has no corresponding fragment stage
|
|
294
|
+
// output"). Keep the graph attachment shared while deriving pipeline
|
|
295
|
+
// targets from the shader's actual output contract.
|
|
296
|
+
const reflectionFallbackFormats =
|
|
297
|
+
materialShaderId === 'forgeax::default-standard-pbr' &&
|
|
298
|
+
c.reflectionFallbackColorFormat !== undefined
|
|
299
|
+
? [c.reflectionFallbackColorFormat]
|
|
300
|
+
: undefined;
|
|
250
301
|
const renderStateKey = renderStateHash(renderState);
|
|
251
302
|
const shaderLookupCache = materialPipelineLookupCache.get(materialShaderId);
|
|
252
303
|
const cachedLookups = shaderLookupCache?.get(renderStateKey);
|
|
@@ -261,7 +312,8 @@ export function recordGeometryDraws(
|
|
|
261
312
|
cached.passKind === passKind &&
|
|
262
313
|
cached.layoutProjection.digest === layoutProjection.digest &&
|
|
263
314
|
cached.sampleCount === sampleCount &&
|
|
264
|
-
cached.colorFormatOverride === colorFormat
|
|
315
|
+
cached.colorFormatOverride === colorFormat &&
|
|
316
|
+
cached.additionalColorFormats?.join(',') === reflectionFallbackFormats?.join(',')
|
|
265
317
|
) {
|
|
266
318
|
return cached.handle;
|
|
267
319
|
}
|
|
@@ -277,14 +329,20 @@ export function recordGeometryDraws(
|
|
|
277
329
|
return null;
|
|
278
330
|
}
|
|
279
331
|
const resolvedVariantSet = resolvedVariantSetResult.value;
|
|
332
|
+
const fallbackVariantSet =
|
|
333
|
+
materialShaderId !== 'forgeax::default-standard-pbr'
|
|
334
|
+
? resolvedVariantSet
|
|
335
|
+
: c.reflectionFallbackColorFormat !== undefined && resolvedVariantSet === ''
|
|
336
|
+
? ''
|
|
337
|
+
: `${resolvedVariantSet === undefined || resolvedVariantSet === '' ? '' : `${resolvedVariantSet}+`}REFLECTION_FALLBACK_AVAILABLE=${c.reflectionFallbackColorFormat !== undefined}`;
|
|
280
338
|
const resolvePipeline = () =>
|
|
281
|
-
runtime.
|
|
339
|
+
runtime.getMaterialShaderPipelineEntry?.(
|
|
282
340
|
materialShaderId,
|
|
283
341
|
isHdrTarget,
|
|
284
342
|
renderState,
|
|
285
343
|
topology,
|
|
286
344
|
indexFormat,
|
|
287
|
-
|
|
345
|
+
fallbackVariantSet,
|
|
288
346
|
passKind,
|
|
289
347
|
undefined,
|
|
290
348
|
sampleCount,
|
|
@@ -293,6 +351,9 @@ export function recordGeometryDraws(
|
|
|
293
351
|
undefined,
|
|
294
352
|
undefined,
|
|
295
353
|
layoutProjection,
|
|
354
|
+
undefined,
|
|
355
|
+
undefined,
|
|
356
|
+
reflectionFallbackFormats,
|
|
296
357
|
) ?? null;
|
|
297
358
|
const handle =
|
|
298
359
|
profilePhase === undefined
|
|
@@ -317,6 +378,7 @@ export function recordGeometryDraws(
|
|
|
317
378
|
layoutProjection,
|
|
318
379
|
sampleCount,
|
|
319
380
|
colorFormatOverride: colorFormat,
|
|
381
|
+
additionalColorFormats: reflectionFallbackFormats,
|
|
320
382
|
handle,
|
|
321
383
|
};
|
|
322
384
|
if (shaderLookupCache === undefined) {
|
|
@@ -340,13 +402,18 @@ export function recordGeometryDraws(
|
|
|
340
402
|
// Points/Lines share the Standard geometry pass. Their retained source
|
|
341
403
|
// is prepared once by the renderer owner, while this loop remains the
|
|
342
404
|
// sole pass/draw submission owner and preserves the authored topology.
|
|
343
|
-
const pointsLinesSubmission = c.pointsLines?.prepare(entry,
|
|
405
|
+
const pointsLinesSubmission = c.pointsLines?.prepare(entry, clusteredLighting);
|
|
344
406
|
if (entry.source.pointsLines !== undefined && pointsLinesSubmission?.plan.drawCount !== 1)
|
|
345
407
|
continue;
|
|
346
408
|
|
|
347
409
|
if (
|
|
348
410
|
passKind === 'forward' &&
|
|
349
|
-
c.gpuDrivenEntityKeys.has(
|
|
411
|
+
c.gpuDrivenEntityKeys.has(
|
|
412
|
+
worldEntityKey(
|
|
413
|
+
c.gpuDrivenWorldKeys?.[entry.source.worldId] ?? entry.source.worldId,
|
|
414
|
+
entry.source.entityKey,
|
|
415
|
+
),
|
|
416
|
+
)
|
|
350
417
|
) {
|
|
351
418
|
continue;
|
|
352
419
|
}
|
|
@@ -399,7 +466,7 @@ export function recordGeometryDraws(
|
|
|
399
466
|
entry.source.entityKey,
|
|
400
467
|
entry.world ?? c.world,
|
|
401
468
|
);
|
|
402
|
-
const
|
|
469
|
+
const pointsLinesPipelineEntry = resolveMaterialPipeline(
|
|
403
470
|
POINTS_LINES_MATERIAL_SHADER_ID,
|
|
404
471
|
{
|
|
405
472
|
...pointsLinesMaterial.renderState,
|
|
@@ -411,7 +478,8 @@ export function recordGeometryDraws(
|
|
|
411
478
|
colorFormatOverride,
|
|
412
479
|
pointsLinesSubmission.layoutProjection,
|
|
413
480
|
);
|
|
414
|
-
if (
|
|
481
|
+
if (pointsLinesPipelineEntry === null) continue;
|
|
482
|
+
const pointsLinesPipeline = pointsLinesPipelineEntry.pipeline;
|
|
415
483
|
if (pipelineState.pointsLinesViewBuffer === undefined) continue;
|
|
416
484
|
writePointsLinesViewUbo(
|
|
417
485
|
runtime.device.queue,
|
|
@@ -426,9 +494,9 @@ export function recordGeometryDraws(
|
|
|
426
494
|
pass.setBindGroup(
|
|
427
495
|
0,
|
|
428
496
|
viewBindGroup as BindGroup,
|
|
429
|
-
new Uint32Array([i * POINTS_LINES_VIEW_SLOT_STRIDE]),
|
|
497
|
+
new Uint32Array([0, i * POINTS_LINES_VIEW_SLOT_STRIDE]),
|
|
430
498
|
0,
|
|
431
|
-
|
|
499
|
+
2,
|
|
432
500
|
);
|
|
433
501
|
pass.setPipeline(pointsLinesPipeline);
|
|
434
502
|
pass.setVertexBuffer(0, pointsLinesSubmission.vertexBuffer);
|
|
@@ -438,13 +506,12 @@ export function recordGeometryDraws(
|
|
|
438
506
|
const pointsLinesMeshGroup = meshBindGroup ?? meshGroup2;
|
|
439
507
|
if (pointsLinesMeshGroup === null) continue;
|
|
440
508
|
pass.setBindGroup(2, pointsLinesMeshGroup, meshGroup2DynamicOffsets);
|
|
441
|
-
|
|
442
|
-
3,
|
|
509
|
+
const pointsLinesInstancesBg =
|
|
443
510
|
identityInstanceDraws[0]?.instanceBindGroup ??
|
|
444
|
-
|
|
445
|
-
);
|
|
446
|
-
recordPointsLinesDraw(pass, pointsLinesSubmission.plan);
|
|
447
|
-
pass.setBindGroup(0, viewBindGroup as BindGroup, [0]);
|
|
511
|
+
resolveGeometryInstancesBindGroup(c, identityInstanceBuffer, undefined);
|
|
512
|
+
pass.setBindGroup(3, pointsLinesInstancesBg);
|
|
513
|
+
recordOcclusionCandidate(() => recordPointsLinesDraw(pass, pointsLinesSubmission.plan));
|
|
514
|
+
pass.setBindGroup(0, viewBindGroup as BindGroup, [viewBindGroupDynamicOffset, 0]);
|
|
448
515
|
continue;
|
|
449
516
|
}
|
|
450
517
|
|
|
@@ -471,14 +538,15 @@ export function recordGeometryDraws(
|
|
|
471
538
|
// length instead.
|
|
472
539
|
if (pipelineTag === 'unlit') dispatchCounts.unlit += 1;
|
|
473
540
|
|
|
474
|
-
const instanceDraws = resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws);
|
|
541
|
+
const instanceDraws = resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws, false);
|
|
475
542
|
if (instanceDraws === null) continue;
|
|
476
543
|
|
|
477
|
-
// feat-20260611 R2 / M8 / w28 (IS-14): skin entries need a
|
|
544
|
+
// feat-20260611 R2 / M8 / w28 (IS-14): skin entries need a 3-binding
|
|
478
545
|
// group(2) BG matching `pbr-skin-pl` (binding 0 mesh-array UBO +
|
|
479
|
-
// binding 1 palette UBO
|
|
546
|
+
// binding 1 current palette UBO + binding 2 previous palette UBO).
|
|
547
|
+
// Building this here -- not in the
|
|
480
548
|
// `meshBindGroup` factory above -- because the binding-shape
|
|
481
|
-
// (1-entry vs
|
|
549
|
+
// (1-entry vs 3-entry) is per-entry, not per-frame. URP / HDRP
|
|
482
550
|
// entries keep using `meshGroup2` (1-entry mesh-array or HDRP
|
|
483
551
|
// unified). The skin-variant cache key includes both buffer
|
|
484
552
|
// identities so a future allocator-driven palette buffer rotation
|
|
@@ -489,7 +557,7 @@ export function recordGeometryDraws(
|
|
|
489
557
|
// BGL-build failure), AND (b) the skin PSO cache returns a non-null
|
|
490
558
|
// pipeline for this entry. Without (b), the per-submesh selector
|
|
491
559
|
// below falls back to URP `standardPipeline` (`pbr-pl` layout,
|
|
492
|
-
// 1-entry mesh-array BGL); binding the
|
|
560
|
+
// 1-entry mesh-array BGL); binding the 3-entry skin BG against
|
|
493
561
|
// that pipeline reproduces the exact `pbr-mesh-array-bgl ... does
|
|
494
562
|
// not match layout pbr-skin-mesh-array-bgl` device error R1
|
|
495
563
|
// captured. Mirrors the uniform null skip-draw pattern (M6-T1).
|
|
@@ -501,6 +569,8 @@ export function recordGeometryDraws(
|
|
|
501
569
|
meshGroup2DynamicOffsets[0] = i * MESH_PER_ENTITY_STRIDE;
|
|
502
570
|
let group2DynamicOffsets: readonly number[] = meshGroup2DynamicOffsets;
|
|
503
571
|
const isSkinEntry = entry.source.skin !== undefined;
|
|
572
|
+
const probeBlendRecordAvailable =
|
|
573
|
+
runtime.device.caps.storageBuffer && entry.source.probeBlendRecord !== undefined;
|
|
504
574
|
// feat-20260612-skin-palette-per-frame-upload M1 / m1-3 + M6: the
|
|
505
575
|
// record stage reads the GPU buffer reference through
|
|
506
576
|
// `entry.source.skin.buffer` (per-slice carrier set at extract time
|
|
@@ -517,28 +587,41 @@ export function recordGeometryDraws(
|
|
|
517
587
|
// and walks 0, 1536, 3072, ... on the storage path.
|
|
518
588
|
const skinAllocator = pipelineState.skinPaletteAllocator;
|
|
519
589
|
const skinSlice = entry.source.skin;
|
|
590
|
+
const clusteredSkin = clusteredLighting;
|
|
591
|
+
const skinMeshBindGroupLayout = clusteredSkin
|
|
592
|
+
? pipelineState.hdrpSkinMeshBindGroupLayout
|
|
593
|
+
: pipelineState.pbrSkinMeshBindGroupLayout;
|
|
594
|
+
const hdrpSkinBuffers =
|
|
595
|
+
isSkinEntry && clusteredSkin
|
|
596
|
+
? getOrCreateHdrpBuffers(runtime, frameState.installedPipelineConfig?.clusterGrid)
|
|
597
|
+
: null;
|
|
520
598
|
const skinResources =
|
|
521
599
|
isSkinEntry &&
|
|
522
|
-
|
|
600
|
+
skinMeshBindGroupLayout !== null &&
|
|
523
601
|
skinAllocator !== null &&
|
|
524
|
-
skinSlice !== undefined
|
|
602
|
+
skinSlice !== undefined &&
|
|
603
|
+
(!clusteredSkin || hdrpSkinBuffers !== null)
|
|
525
604
|
? {
|
|
526
|
-
meshArrayBgl:
|
|
605
|
+
meshArrayBgl: skinMeshBindGroupLayout,
|
|
527
606
|
paletteBuffer: skinSlice.buffer,
|
|
528
607
|
paletteBindingWindowBytes: skinAllocator.bindingWindowBytes,
|
|
608
|
+
hdrpBuffers: hdrpSkinBuffers,
|
|
529
609
|
}
|
|
530
610
|
: null;
|
|
531
611
|
// Probe the skin PSO cache up front so we can decide whether to swap
|
|
532
|
-
// to the
|
|
612
|
+
// to the skin BG. The same probe + selector is repeated in
|
|
533
613
|
// the per-submesh loop below (the loop's variantSet derivation is
|
|
534
614
|
// identical -- skin shader registers a single all-true variant so
|
|
535
615
|
// the canonical empty-key rule applies on HDRP and the URP key is
|
|
536
616
|
// the explicit expanded form, mirroring the standard PBR path).
|
|
537
617
|
const skinVariantSetResult = variantSetFromVertexLayoutProjection(
|
|
538
618
|
entry.mesh.layoutProjection,
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
619
|
+
standardTopologyVariantSet(
|
|
620
|
+
c.standardLighting,
|
|
621
|
+
runtime.device.caps.storageBuffer,
|
|
622
|
+
entry.mesh.layoutProjection.attributes.some((attribute) => attribute.key === 'color'),
|
|
623
|
+
probeBlendRecordAvailable,
|
|
624
|
+
),
|
|
542
625
|
);
|
|
543
626
|
if (!skinVariantSetResult.ok) runtime.errorRegistry.fire(skinVariantSetResult.error);
|
|
544
627
|
const skinVariantSet = skinVariantSetResult.ok ? skinVariantSetResult.value : undefined;
|
|
@@ -559,6 +642,9 @@ export function recordGeometryDraws(
|
|
|
559
642
|
undefined,
|
|
560
643
|
undefined,
|
|
561
644
|
entry.mesh.layoutProjection,
|
|
645
|
+
undefined,
|
|
646
|
+
undefined,
|
|
647
|
+
undefined,
|
|
562
648
|
) ?? null)
|
|
563
649
|
: null;
|
|
564
650
|
if (skinResources !== null && skinPsoProbe !== null) {
|
|
@@ -579,45 +665,47 @@ export function recordGeometryDraws(
|
|
|
579
665
|
const skinMissesBefore = bindGroupCounts.createBindGroup;
|
|
580
666
|
const skinBindGroup: BindGroup = getOrCreateFromChain(
|
|
581
667
|
frameState.meshBindGroupCache,
|
|
582
|
-
[
|
|
668
|
+
[
|
|
669
|
+
pipelineState.meshStorageBuffer.buffer,
|
|
670
|
+
skinResources.paletteBuffer,
|
|
671
|
+
...(skinResources.hdrpBuffers === null
|
|
672
|
+
? []
|
|
673
|
+
: [
|
|
674
|
+
skinResources.hdrpBuffers.lightDataBuffer,
|
|
675
|
+
skinResources.hdrpBuffers.clusterGridBuffer,
|
|
676
|
+
skinResources.hdrpBuffers.lightIndexListBuffer,
|
|
677
|
+
skinResources.hdrpBuffers.clusterUniformBuffer,
|
|
678
|
+
]),
|
|
679
|
+
],
|
|
583
680
|
'pbr-skin-mesh',
|
|
584
681
|
() => {
|
|
682
|
+
if (skinResources.hdrpBuffers !== null) {
|
|
683
|
+
const result = createHdrpSkinUnifiedBindGroup(
|
|
684
|
+
runtime,
|
|
685
|
+
skinResources.hdrpBuffers,
|
|
686
|
+
skinResources.meshArrayBgl,
|
|
687
|
+
pipelineState.meshStorageBuffer.buffer,
|
|
688
|
+
skinResources.paletteBuffer,
|
|
689
|
+
skinResources.paletteBindingWindowBytes,
|
|
690
|
+
);
|
|
691
|
+
if (result === null) {
|
|
692
|
+
throw new RhiError({
|
|
693
|
+
code: 'webgpu-runtime-error',
|
|
694
|
+
expected: 'HDRP clustered skin BindGroup creation succeeds',
|
|
695
|
+
hint: 'inspect prior errorRegistry events for createBindGroup failure detail',
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
return result;
|
|
699
|
+
}
|
|
585
700
|
const result = runtime.device.createBindGroup({
|
|
586
701
|
label: 'pbr-skin-mesh-bg',
|
|
587
702
|
layout: skinResources.meshArrayBgl,
|
|
588
|
-
entries:
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
buffer: pipelineState.meshStorageBuffer.buffer,
|
|
595
|
-
offset: 0,
|
|
596
|
-
size: meshBindSize,
|
|
597
|
-
},
|
|
598
|
-
},
|
|
599
|
-
},
|
|
600
|
-
{
|
|
601
|
-
binding: 1,
|
|
602
|
-
resource: {
|
|
603
|
-
kind: 'buffer',
|
|
604
|
-
value: {
|
|
605
|
-
buffer: skinResources.paletteBuffer,
|
|
606
|
-
offset: 0,
|
|
607
|
-
// M6 SSOT: static BG entry size (= MAX_JOINTS * 64 =
|
|
608
|
-
// 16320 B) sourced from the allocator. The per-draw
|
|
609
|
-
// window slides via `group2DynamicOffsets[1]`
|
|
610
|
-
// (= entry.source.skin.byteOffset) so this size
|
|
611
|
-
// stays at the worst case across all skin entries
|
|
612
|
-
// -- one BG covers every skinned draw in the frame
|
|
613
|
-
// (m3-1b miss=1 + hit=N-1 contract). The allocator
|
|
614
|
-
// guarantees `buffer.size >= byteOffset + this size`
|
|
615
|
-
// so dynOffset[1] passes WebGPU validation.
|
|
616
|
-
size: skinResources.paletteBindingWindowBytes,
|
|
617
|
-
},
|
|
618
|
-
},
|
|
619
|
-
},
|
|
620
|
-
],
|
|
703
|
+
entries: createPbrSkinMeshBindGroupEntries(
|
|
704
|
+
pipelineState.meshStorageBuffer.buffer,
|
|
705
|
+
meshBindSize,
|
|
706
|
+
skinResources.paletteBuffer,
|
|
707
|
+
skinResources.paletteBindingWindowBytes,
|
|
708
|
+
),
|
|
621
709
|
});
|
|
622
710
|
if (!result.ok) throw result.error;
|
|
623
711
|
return result.value;
|
|
@@ -634,9 +722,10 @@ export function recordGeometryDraws(
|
|
|
634
722
|
// Replaces the prior PR #353 hard-coded `0` second slot -- every
|
|
635
723
|
// skin entry now points the palette window at its own slice while
|
|
636
724
|
// sharing the worst-case BG entry size above.
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
725
|
+
group2DynamicOffsets = pbrSkinMeshDynamicOffsets(
|
|
726
|
+
i * MESH_PER_ENTITY_STRIDE,
|
|
727
|
+
entry.source.skin?.byteOffset ?? 0,
|
|
728
|
+
);
|
|
640
729
|
} else if (isSkinEntry) {
|
|
641
730
|
// Skin entry but skin PSO not ready (cache miss / async build pending,
|
|
642
731
|
// or skin pipeline layout failed at boot). Skip the draw rather than
|
|
@@ -762,6 +851,8 @@ export function recordGeometryDraws(
|
|
|
762
851
|
entry.source.skin !== undefined
|
|
763
852
|
? SKIN_MATERIAL_SHADER_ID
|
|
764
853
|
: submeshMaterial.materialShaderId;
|
|
854
|
+
const probeBlendAvailable =
|
|
855
|
+
probeBlendRecordAvailable && isStandardPbrMaterialShader(smMaterialShaderId);
|
|
765
856
|
const isSpriteShader =
|
|
766
857
|
smMaterialShaderId === 'forgeax::sprite' || smMaterialShaderId === 'forgeax::sprite-lit';
|
|
767
858
|
// Preserve the dedicated sprite-pass state when the linear-LDR graph
|
|
@@ -778,6 +869,8 @@ export function recordGeometryDraws(
|
|
|
778
869
|
: geometryRenderStateForTopology(smTopology, submeshMaterial.renderState);
|
|
779
870
|
const pipelineRenderState = geometryRenderStateForPass(basePipelineRenderState, passKind);
|
|
780
871
|
let smPipelineHandle: typeof pipelineState.unlitPipeline;
|
|
872
|
+
let materialGroup2Contract: 'mesh' | 'skin' | 'cluster' | 'skin-cluster' | undefined;
|
|
873
|
+
let materialPipelineEntry: MaterialShaderPipelineEntry | null = null;
|
|
781
874
|
if (smMaterialShaderId === undefined || smMaterialShaderId === 'forgeax::default-unlit') {
|
|
782
875
|
const unlitShaderId = smMaterialShaderId ?? 'forgeax::default-unlit';
|
|
783
876
|
const unlitProjectionVariantResult = variantSetFromVertexLayoutProjection(
|
|
@@ -789,9 +882,10 @@ export function recordGeometryDraws(
|
|
|
789
882
|
continue;
|
|
790
883
|
}
|
|
791
884
|
const unlitHasColor = unlitProjectionVariantResult.value === 'VERTEX_COLOR_AVAILABLE=true';
|
|
792
|
-
const unlitVariantSet =
|
|
793
|
-
|
|
794
|
-
|
|
885
|
+
const unlitVariantSet = standardStorageVariantSet(
|
|
886
|
+
runtime.device.caps.storageBuffer,
|
|
887
|
+
unlitHasColor,
|
|
888
|
+
);
|
|
795
889
|
const unlitRsp = resolveMaterialPipeline(
|
|
796
890
|
unlitShaderId,
|
|
797
891
|
pipelineRenderState,
|
|
@@ -801,8 +895,9 @@ export function recordGeometryDraws(
|
|
|
801
895
|
colorFormatOverride,
|
|
802
896
|
entry.mesh.layoutProjection,
|
|
803
897
|
);
|
|
898
|
+
materialPipelineEntry = unlitRsp;
|
|
804
899
|
smPipelineHandle =
|
|
805
|
-
unlitRsp ??
|
|
900
|
+
unlitRsp?.pipeline ??
|
|
806
901
|
(colorFormatOverride === undefined
|
|
807
902
|
? selectGeometryPipeline(pipelineState, isHdrTarget, msaaActive)
|
|
808
903
|
: null);
|
|
@@ -829,11 +924,12 @@ export function recordGeometryDraws(
|
|
|
829
924
|
// VERTEX_COLOR_AVAILABLE=false axis, so retain the two capability
|
|
830
925
|
// axes explicitly or the selector would silently choose the URP
|
|
831
926
|
// group(2) layout for an HDRP cluster bind group.
|
|
832
|
-
const capabilityVariantSet =
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
927
|
+
const capabilityVariantSet = standardTopologyVariantSet(
|
|
928
|
+
c.standardLighting,
|
|
929
|
+
runtime.device.caps.storageBuffer,
|
|
930
|
+
hasVertexColor,
|
|
931
|
+
probeBlendAvailable,
|
|
932
|
+
);
|
|
837
933
|
// Sprite's base request must retain the boot-selected artifact. Only
|
|
838
934
|
// SpriteInstances uses the explicit empty key for the
|
|
839
935
|
// PER_INSTANCE_REGION=true variant; synthesizing the generic PBR
|
|
@@ -848,19 +944,12 @@ export function recordGeometryDraws(
|
|
|
848
944
|
: capabilityVariantSet === ''
|
|
849
945
|
? entry.variantSet
|
|
850
946
|
: `${capabilityVariantSet}+${entry.variantSet}`;
|
|
851
|
-
const projectionVariantSetResult = isSpriteShader
|
|
852
|
-
? ({ ok: true, value: variantSet } as const)
|
|
853
|
-
: variantSetFromVertexLayoutProjection(entry.mesh.layoutProjection, variantSet);
|
|
854
|
-
if (!projectionVariantSetResult.ok) {
|
|
855
|
-
runtime.errorRegistry.fire(projectionVariantSetResult.error);
|
|
856
|
-
continue;
|
|
857
|
-
}
|
|
858
947
|
const cachedPipeline = resolveMaterialPipeline(
|
|
859
948
|
smMaterialShaderId,
|
|
860
949
|
pipelineRenderState,
|
|
861
950
|
smTopology,
|
|
862
951
|
entry.mesh.indexFormat,
|
|
863
|
-
|
|
952
|
+
variantSet,
|
|
864
953
|
colorFormatOverride,
|
|
865
954
|
entry.mesh.layoutProjection,
|
|
866
955
|
);
|
|
@@ -877,7 +966,8 @@ export function recordGeometryDraws(
|
|
|
877
966
|
// build resolves. The pre-loop skin-PSO probe still skips the
|
|
878
967
|
// entire entry on first-submesh probe miss; this site only
|
|
879
968
|
// fires on per-submesh topology variance miss.
|
|
880
|
-
|
|
969
|
+
materialPipelineEntry = cachedPipeline;
|
|
970
|
+
smPipelineHandle = cachedPipeline?.pipeline ?? null;
|
|
881
971
|
} else {
|
|
882
972
|
smPipelineHandle = selectGeometryPipeline(pipelineState, isHdrTarget, msaaActive);
|
|
883
973
|
}
|
|
@@ -885,37 +975,38 @@ export function recordGeometryDraws(
|
|
|
885
975
|
if (smPipelineHandle === null) {
|
|
886
976
|
continue;
|
|
887
977
|
}
|
|
978
|
+
// The probe record is an ABI extension of the built-in Standard PBR
|
|
979
|
+
// shaders only. RenderScene may retain a record on every projected
|
|
980
|
+
// renderable, but unlit/custom shaders still use the one-binding
|
|
981
|
+
// instances BGL and must never receive the probe bind group. Resolve
|
|
982
|
+
// this per submesh so mixed-material meshes cannot cross the layouts.
|
|
983
|
+
const instanceDraws = resolveGeometryInstanceBuffer(
|
|
984
|
+
c,
|
|
985
|
+
entry,
|
|
986
|
+
identityInstanceDraws,
|
|
987
|
+
probeBlendAvailable,
|
|
988
|
+
);
|
|
989
|
+
if (instanceDraws === null) continue;
|
|
888
990
|
// Standard clustered PBR variants declare the unified cluster/SSAO
|
|
889
991
|
// group(2) layout. Unlit and other URP-layout materials must bind the
|
|
890
992
|
// ordinary mesh group instead; choosing one group for the whole pass
|
|
891
993
|
// makes Dawn reject an otherwise valid unlit pipeline and invalidates
|
|
892
994
|
// the command buffer before it reaches the surface.
|
|
893
|
-
const usesStandardClusterBindings = smMaterialShaderId === 'forgeax::default-standard-pbr';
|
|
894
995
|
if (!isSkinEntry) {
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
996
|
+
materialGroup2Contract = materialPipelineEntry?.group2Contract;
|
|
997
|
+
if (materialGroup2Contract === undefined) continue;
|
|
998
|
+
const selectedGroup = selectMaterialGroup2(
|
|
999
|
+
meshGroup2,
|
|
1000
|
+
meshBindGroup,
|
|
1001
|
+
materialGroup2Contract,
|
|
1002
|
+
);
|
|
1003
|
+
if (selectedGroup === null) continue;
|
|
1004
|
+
group2BindGroup = selectedGroup;
|
|
903
1005
|
}
|
|
904
1006
|
pass.setBindGroup(2, group2BindGroup, group2DynamicOffsets);
|
|
905
1007
|
|
|
906
1008
|
if (profilePhase === undefined) {
|
|
907
|
-
|
|
908
|
-
pass,
|
|
909
|
-
bindingState,
|
|
910
|
-
smPipelineHandle,
|
|
911
|
-
instanceDraws,
|
|
912
|
-
entry.mesh.indexed,
|
|
913
|
-
sm.indexCount,
|
|
914
|
-
sm.vertexCount,
|
|
915
|
-
sm.indexOffset,
|
|
916
|
-
);
|
|
917
|
-
} else {
|
|
918
|
-
profileGeometrySegment(c, passKind, 'draw-submit', () =>
|
|
1009
|
+
recordOcclusionCandidate(() =>
|
|
919
1010
|
submitSubmeshDraws(
|
|
920
1011
|
pass,
|
|
921
1012
|
bindingState,
|
|
@@ -927,6 +1018,21 @@ export function recordGeometryDraws(
|
|
|
927
1018
|
sm.indexOffset,
|
|
928
1019
|
),
|
|
929
1020
|
);
|
|
1021
|
+
} else {
|
|
1022
|
+
profileGeometrySegment(c, passKind, 'draw-submit', () =>
|
|
1023
|
+
recordOcclusionCandidate(() =>
|
|
1024
|
+
submitSubmeshDraws(
|
|
1025
|
+
pass,
|
|
1026
|
+
bindingState,
|
|
1027
|
+
smPipelineHandle,
|
|
1028
|
+
instanceDraws,
|
|
1029
|
+
entry.mesh.indexed,
|
|
1030
|
+
sm.indexCount,
|
|
1031
|
+
sm.vertexCount,
|
|
1032
|
+
sm.indexOffset,
|
|
1033
|
+
),
|
|
1034
|
+
),
|
|
1035
|
+
);
|
|
930
1036
|
}
|
|
931
1037
|
}
|
|
932
1038
|
}
|
|
@@ -941,10 +1047,38 @@ function resolveGeometryInstanceBuffer(
|
|
|
941
1047
|
c: _InternalRenderPipelineContext,
|
|
942
1048
|
entry: _InternalRenderPipelineContext['validatedOrdered'][number],
|
|
943
1049
|
identityInstanceDraws: readonly GeometryInstanceDraw[],
|
|
1050
|
+
useProbeBlend: boolean,
|
|
944
1051
|
): readonly GeometryInstanceDraw[] | null {
|
|
945
1052
|
const { runtime, pipelineState, frameState } = c;
|
|
946
1053
|
const inst = entry.source.instances;
|
|
947
|
-
|
|
1054
|
+
const probeBinding =
|
|
1055
|
+
!useProbeBlend ||
|
|
1056
|
+
!runtime.device.caps.storageBuffer ||
|
|
1057
|
+
entry.source.probeBlendRecord === undefined
|
|
1058
|
+
? undefined
|
|
1059
|
+
: resolveProbeBlendBuffer(
|
|
1060
|
+
c,
|
|
1061
|
+
entry.source.probeBlendRecord,
|
|
1062
|
+
worldEntityKey(entry.source.worldId, entry.source.entityKey),
|
|
1063
|
+
);
|
|
1064
|
+
if (inst === undefined) {
|
|
1065
|
+
const identity = identityInstanceDraws[0];
|
|
1066
|
+
if (identity === undefined) return null;
|
|
1067
|
+
return [
|
|
1068
|
+
{
|
|
1069
|
+
...identity,
|
|
1070
|
+
instanceBindGroup: resolveGeometryInstancesBindGroup(
|
|
1071
|
+
c,
|
|
1072
|
+
pipelineState.identityInstanceBuffer,
|
|
1073
|
+
probeBinding?.buffer,
|
|
1074
|
+
),
|
|
1075
|
+
probeOffset: probeBinding?.offset ?? -1,
|
|
1076
|
+
},
|
|
1077
|
+
];
|
|
1078
|
+
}
|
|
1079
|
+
// A present, empty Instances array means zero draws. Do not fall back to
|
|
1080
|
+
// the shared identity buffer, which would silently render one instance.
|
|
1081
|
+
if (inst.instanceCount === 0) return [];
|
|
948
1082
|
let instanceBuffer: Buffer = pipelineState.identityInstanceBuffer;
|
|
949
1083
|
let instanceCount = 1;
|
|
950
1084
|
{
|
|
@@ -982,7 +1116,12 @@ function resolveGeometryInstanceBuffer(
|
|
|
982
1116
|
}
|
|
983
1117
|
draws.push({
|
|
984
1118
|
instanceBuffer: buffer.handle,
|
|
985
|
-
instanceBindGroup: resolveGeometryInstancesBindGroup(
|
|
1119
|
+
instanceBindGroup: resolveGeometryInstancesBindGroup(
|
|
1120
|
+
c,
|
|
1121
|
+
buffer.handle,
|
|
1122
|
+
probeBinding?.buffer,
|
|
1123
|
+
),
|
|
1124
|
+
probeOffset: probeBinding?.offset ?? -1,
|
|
986
1125
|
instanceCount: count,
|
|
987
1126
|
});
|
|
988
1127
|
}
|
|
@@ -1074,25 +1213,80 @@ function resolveGeometryInstanceBuffer(
|
|
|
1074
1213
|
return [
|
|
1075
1214
|
{
|
|
1076
1215
|
instanceBuffer,
|
|
1077
|
-
instanceBindGroup: resolveGeometryInstancesBindGroup(c, instanceBuffer),
|
|
1216
|
+
instanceBindGroup: resolveGeometryInstancesBindGroup(c, instanceBuffer, probeBinding?.buffer),
|
|
1217
|
+
probeOffset: probeBinding?.offset ?? -1,
|
|
1078
1218
|
instanceCount,
|
|
1079
1219
|
},
|
|
1080
1220
|
];
|
|
1081
1221
|
}
|
|
1082
1222
|
|
|
1083
|
-
function
|
|
1223
|
+
export function resolveProbeBlendBuffer(
|
|
1224
|
+
c: _InternalRenderPipelineContext,
|
|
1225
|
+
record: import('../scene/probe-blend-record').ProbeBlendRecord | undefined,
|
|
1226
|
+
entityKey?: number,
|
|
1227
|
+
): { readonly buffer: Buffer; readonly offset: number } {
|
|
1228
|
+
const { runtime, frameState } = c;
|
|
1229
|
+
const usage = runtime.device.caps.storageBuffer
|
|
1230
|
+
? GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST
|
|
1231
|
+
: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST;
|
|
1232
|
+
if (record === undefined) throw new Error('probe blend record is required for probe allocation');
|
|
1233
|
+
if (entityKey === undefined) throw new Error('probe blend record requires an entity key');
|
|
1234
|
+
const offset = probeBlendRecordOffset(record.objectKey);
|
|
1235
|
+
const requiredCapacity = record.objectKey + 2;
|
|
1236
|
+
let buffer = frameState.probeBlendRecordBuffer;
|
|
1237
|
+
if (buffer === undefined || frameState.probeBlendRecordBufferCapacity < requiredCapacity) {
|
|
1238
|
+
const created = runtime.device.createBuffer({
|
|
1239
|
+
label: 'probe-blend-records',
|
|
1240
|
+
size: requiredCapacity * PROBE_BLEND_RECORD_STRIDE,
|
|
1241
|
+
usage,
|
|
1242
|
+
mappedAtCreation: false,
|
|
1243
|
+
});
|
|
1244
|
+
if (!created.ok) throw created.error;
|
|
1245
|
+
buffer = new GpuBuffer(runtime.device, created.value);
|
|
1246
|
+
frameState.probeBlendRecordBuffer = buffer;
|
|
1247
|
+
frameState.probeBlendRecordBufferCapacity = requiredCapacity;
|
|
1248
|
+
// The cache is tied to the previous backing allocation. A new buffer has
|
|
1249
|
+
// no valid record contents, so every later object must upload its full
|
|
1250
|
+
// 160B payload even when generation/bytes match the old allocation.
|
|
1251
|
+
frameState.probeBlendBuffers.clear();
|
|
1252
|
+
}
|
|
1253
|
+
const cached = frameState.probeBlendBuffers.get(entityKey);
|
|
1254
|
+
const unchanged =
|
|
1255
|
+
cached !== undefined &&
|
|
1256
|
+
cached.generation === record.generation &&
|
|
1257
|
+
cached.bytes.length === record.bytes.length &&
|
|
1258
|
+
cached.bytes.every((value, index) => value === record.bytes[index]);
|
|
1259
|
+
if (!unchanged) {
|
|
1260
|
+
const uploaded = runtime.device.queue.writeBuffer(buffer.handle, offset, record.bytes);
|
|
1261
|
+
if (!uploaded.ok) throw uploaded.error;
|
|
1262
|
+
// Publish the generation only after the complete 160B queue write succeeds.
|
|
1263
|
+
frameState.probeBlendBuffers.set(entityKey, {
|
|
1264
|
+
generation: record.generation,
|
|
1265
|
+
bytes: new Uint8Array(record.bytes),
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
return { buffer: buffer.handle, offset };
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
export function resolveGeometryInstancesBindGroup(
|
|
1084
1272
|
c: _InternalRenderPipelineContext,
|
|
1085
1273
|
instanceBuffer: Buffer,
|
|
1274
|
+
probeBuffer?: Buffer,
|
|
1086
1275
|
): BindGroup {
|
|
1087
1276
|
const { runtime, pipelineState, frameState, bindGroupCounts } = c;
|
|
1277
|
+
const layout =
|
|
1278
|
+
probeBuffer === undefined
|
|
1279
|
+
? pipelineState.instancesBindGroupLayout
|
|
1280
|
+
: pipelineState.probeInstancesBindGroupLayout;
|
|
1281
|
+
if (layout === undefined) throw new Error('probe instances bind-group layout is unavailable');
|
|
1088
1282
|
return getOrCreateFromChain(
|
|
1089
1283
|
frameState.instancesBgShared,
|
|
1090
|
-
[
|
|
1091
|
-
'instances',
|
|
1284
|
+
probeBuffer === undefined ? [layout, instanceBuffer] : [layout, instanceBuffer, probeBuffer],
|
|
1285
|
+
probeBuffer === undefined ? 'instances-no-probe' : 'instances-probe',
|
|
1092
1286
|
() => {
|
|
1093
1287
|
const result = runtime.device.createBindGroup({
|
|
1094
1288
|
label: 'pbr-instances-bg',
|
|
1095
|
-
layout
|
|
1289
|
+
layout,
|
|
1096
1290
|
entries: [
|
|
1097
1291
|
{
|
|
1098
1292
|
binding: 0,
|
|
@@ -1101,6 +1295,17 @@ function resolveGeometryInstancesBindGroup(
|
|
|
1101
1295
|
value: { buffer: instanceBuffer },
|
|
1102
1296
|
},
|
|
1103
1297
|
},
|
|
1298
|
+
...(probeBuffer === undefined
|
|
1299
|
+
? []
|
|
1300
|
+
: [
|
|
1301
|
+
{
|
|
1302
|
+
binding: 1,
|
|
1303
|
+
resource: {
|
|
1304
|
+
kind: 'buffer' as const,
|
|
1305
|
+
value: { buffer: probeBuffer, offset: 0, size: PROBE_BLEND_RECORD_BYTE_SIZE },
|
|
1306
|
+
},
|
|
1307
|
+
},
|
|
1308
|
+
]),
|
|
1104
1309
|
],
|
|
1105
1310
|
});
|
|
1106
1311
|
if (!result.ok) throw result.error;
|