@forgeax/engine-render 0.1.20 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/assembly/device-feature-admission.d.ts +18 -0
- package/dist/assembly/device-feature-admission.d.ts.map +1 -0
- package/dist/assembly/directional-shadow-inspection.d.ts +38 -0
- package/dist/assembly/directional-shadow-inspection.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +21 -18
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/host-contract.d.ts +9 -0
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/render-target-host.d.ts +46 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -0
- package/dist/assets/render-asset-port.d.ts.map +1 -1
- package/dist/authoring.mjs +3 -0
- package/dist/authoring.mjs.map +1 -1
- package/dist/capture/cube-views.d.ts +21 -0
- package/dist/capture/cube-views.d.ts.map +1 -0
- package/dist/capture/scheduler.d.ts +54 -0
- package/dist/capture/scheduler.d.ts.map +1 -0
- package/dist/{chunk-4XINDLAY.mjs → chunk-5YADUCA7.mjs} +1552 -1361
- package/dist/chunk-5YADUCA7.mjs.map +1 -0
- package/dist/{chunk-TBQJOK2L.mjs → chunk-6OPXDQ2E.mjs} +364 -51
- package/dist/chunk-6OPXDQ2E.mjs.map +1 -0
- package/dist/{chunk-M2MP4ZOU.mjs → chunk-BXBQQKFQ.mjs} +3 -9
- package/dist/chunk-BXBQQKFQ.mjs.map +1 -0
- package/dist/{chunk-CDTWTHZR.mjs → chunk-FS2KNUQH.mjs} +548 -6
- package/dist/chunk-FS2KNUQH.mjs.map +1 -0
- package/dist/components/camera.d.ts +1 -0
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/cube-camera.d.ts +20 -0
- package/dist/components/cube-camera.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +11 -2
- package/dist/components/directional-light.d.ts.map +1 -1
- package/dist/components/directional-shadow-filter.d.ts +25 -0
- package/dist/components/directional-shadow-filter.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/reflection-probe.d.ts +17 -0
- package/dist/components/reflection-probe.d.ts.map +1 -0
- package/dist/construct-renderer.mjs +5826 -1003
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/environment/frame.d.ts.map +1 -1
- package/dist/environment/lifecycle.d.ts +5 -0
- package/dist/environment/lifecycle.d.ts.map +1 -1
- package/dist/errors/render.d.ts +141 -93
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/directional-shadow-projection.d.ts +23 -0
- package/dist/extract/directional-shadow-projection.d.ts.map +1 -0
- package/dist/extract/environment.d.ts +14 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/extract/visibility.d.ts.map +1 -1
- package/dist/features/fullscreen.d.ts.map +1 -1
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +10 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +13 -2
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +0 -1
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +19 -17
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +4 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/kernel-cache.d.ts +36 -0
- package/dist/ibl/kernel-cache.d.ts.map +1 -0
- package/dist/index.d.ts +28 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +51 -0
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances-derived-bounds.d.ts +50 -0
- package/dist/instances-derived-bounds.d.ts.map +1 -0
- package/dist/internal.mjs +1 -1
- package/dist/light-buffer-layout.d.ts +10 -1
- package/dist/light-buffer-layout.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +54 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +14 -4
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts +2 -1
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-lighting/errors.d.ts +4 -0
- package/dist/pipeline/standard-lighting/errors.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/graph.d.ts +24 -0
- package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts +38 -0
- package/dist/pipeline/standard-lighting/inspection.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/layout.d.ts +28 -0
- package/dist/pipeline/standard-lighting/layout.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts +33 -0
- package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/membership.d.ts +14 -0
- package/dist/pipeline/standard-lighting/membership.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts +16 -0
- package/dist/pipeline/standard-lighting/prepare.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/topology.d.ts +45 -0
- package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -0
- package/dist/pipeline/standard-lighting/transport.d.ts +36 -0
- package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts +4 -13
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline/standard-profile.d.ts +5 -26
- package/dist/pipeline/standard-profile.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +40 -7
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/point-shadow-inspection.d.ts +21 -0
- package/dist/point-shadow-inspection.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +27 -32
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +28 -14
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts +5 -0
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +10 -4
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-pass-timing/contract.d.ts +96 -0
- package/dist/record/gpu-pass-timing/contract.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/errors.d.ts +18 -0
- package/dist/record/gpu-pass-timing/errors.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/index.d.ts +8 -0
- package/dist/record/gpu-pass-timing/index.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/parser.d.ts +11 -0
- package/dist/record/gpu-pass-timing/parser.d.ts.map +1 -0
- package/dist/record/gpu-pass-timing/session.d.ts +43 -0
- package/dist/record/gpu-pass-timing/session.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +8 -3
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +22 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +2 -0
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +43 -2
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +72 -4
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +7 -4
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/reflection/filter.d.ts +22 -0
- package/dist/reflection/filter.d.ts.map +1 -0
- package/dist/reflection/gpu-table.d.ts +25 -0
- package/dist/reflection/gpu-table.d.ts.map +1 -0
- package/dist/reflection/projection.d.ts +91 -0
- package/dist/reflection/projection.d.ts.map +1 -0
- package/dist/render-contract.d.ts +49 -7
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +1 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +42 -2
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +58 -17
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +17 -2
- package/dist/render-system.d.ts.map +1 -1
- package/dist/renderer.d.ts +43 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/scene/render-scene.d.ts +14 -0
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/shadow-atlas.d.ts +3 -3
- package/dist/shadow-atlas.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +3 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/targets/contracts.d.ts +66 -0
- package/dist/targets/contracts.d.ts.map +1 -0
- package/dist/targets/graph-projection.d.ts +29 -0
- package/dist/targets/graph-projection.d.ts.map +1 -0
- package/dist/targets/material-source.d.ts +34 -0
- package/dist/targets/material-source.d.ts.map +1 -0
- package/dist/targets/owner.d.ts +32 -0
- package/dist/targets/owner.d.ts.map +1 -0
- package/dist/targets/physical.d.ts +18 -0
- package/dist/targets/physical.d.ts.map +1 -0
- package/dist/targets/readback.d.ts +39 -0
- package/dist/targets/readback.d.ts.map +1 -0
- package/dist/temporal/index.mjs +3 -3
- package/dist/typed-render-graph-primitives.d.ts +1 -1
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +1 -1
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +2 -2
- package/dist/volume/passes.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/__tests__/bloom-exact-zero.unit.test.ts +48 -19
- package/src/__tests__/bloom-lifecycle.integration.test.ts +41 -13
- package/src/__tests__/camera-target-consumption.unit.test.ts +53 -0
- package/src/__tests__/cluster-binner.unit.test.ts +35 -0
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +7 -2
- package/src/__tests__/cube-camera-scheduler.unit.test.ts +70 -0
- package/src/__tests__/cube-camera-single-submit.perf.test.ts +75 -0
- package/src/__tests__/cube-camera-view-matrices.unit.test.ts +41 -0
- package/src/__tests__/cube-camera-vocabulary.unit.test.ts +47 -0
- package/src/__tests__/cube-camera.integration.test.ts +42 -0
- package/src/__tests__/device-feature-admission.unit.test.ts +73 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +3 -3
- package/src/__tests__/docs-gate-green.unit.test.ts +38 -0
- package/src/__tests__/factory-contract.integration.test.ts +255 -29
- package/src/__tests__/fog-component.unit.test.ts +67 -0
- package/src/__tests__/fog.integration.test.ts +86 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +37 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +10 -9
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +17 -1
- package/src/__tests__/gpu-driven-production.integration.test.ts +16 -17
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +12 -4
- package/src/__tests__/gpu-pass-timing-browser-runner.ts +281 -0
- package/src/__tests__/gpu-pass-timing-coexistence.integration.test.ts +80 -0
- package/src/__tests__/gpu-pass-timing-contract.unit.test.ts +243 -0
- package/src/__tests__/gpu-pass-timing-exact-zero.unit.test.ts +131 -0
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +230 -0
- package/src/__tests__/gpu-pass-timing-observation.unit.test.ts +233 -0
- package/src/__tests__/gpu-pass-timing-session.unit.test.ts +438 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +26 -0
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +125 -0
- package/src/__tests__/hdrp-group2-visibility.unit.test.ts +24 -0
- package/src/__tests__/instances-culling.integration.test.ts +94 -0
- package/src/__tests__/instances-derived-bounds.unit.test.ts +118 -0
- package/src/__tests__/material-observation.integration.test.ts +101 -0
- package/src/__tests__/pbr-view-layout.unit.test.ts +16 -0
- package/src/__tests__/point-shadow-inspection.unit.test.ts +60 -0
- package/src/__tests__/public-surface.test-d.ts +10 -0
- package/src/__tests__/reflection-probe-authoring.unit.test.ts +71 -0
- package/src/__tests__/reflection-probe-filter.unit.test.ts +54 -0
- package/src/__tests__/reflection-probe-ibl-topology.unit.test.ts +45 -0
- package/src/__tests__/reflection-probe-pass-encode.integration.test.ts +101 -0
- package/src/__tests__/reflection-probe-performance.perf.test.ts +60 -0
- package/src/__tests__/reflection-probe-recovery.integration.test.ts +55 -0
- package/src/__tests__/reflection-probe-selection.unit.test.ts +46 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +18 -3
- package/src/__tests__/render-feature-docs.unit.test.ts +1 -1
- package/src/__tests__/render-target-admission.unit.test.ts +80 -0
- package/src/__tests__/render-target-graph-projection.unit.test.ts +102 -0
- package/src/__tests__/render-target-inspection.unit.test.ts +52 -0
- package/src/__tests__/render-target-material-source.test-d.ts +30 -0
- package/src/__tests__/render-target-material-source.unit.test.ts +97 -0
- package/src/__tests__/render-target-owner-placement.unit.test.ts +203 -0
- package/src/__tests__/render-target-owner.unit.test.ts +122 -0
- package/src/__tests__/render-target-probe-soak.perf.test.ts +94 -0
- package/src/__tests__/render-target-public-schema.json +107 -0
- package/src/__tests__/render-target-public-schema.unit.test.ts +91 -0
- package/src/__tests__/render-target-public-surface.test-d.ts +83 -0
- package/src/__tests__/render-target-readback.integration.test.ts +90 -0
- package/src/__tests__/render-target-recovery.integration.test.ts +85 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +48 -0
- package/src/__tests__/renderer-lifecycle.integration.test.ts +14 -0
- package/src/__tests__/shader-stage-surface.unit.test.ts +19 -4
- package/src/__tests__/skin-motion-regression.unit.test.ts +132 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +11 -2
- package/src/__tests__/standard-cluster-capability.integration.test.ts +63 -0
- package/src/__tests__/standard-cluster-transport.unit.test.ts +121 -0
- package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +232 -0
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +8 -5
- package/src/__tests__/standard-lighting-inspection.integration.test.ts +138 -0
- package/src/__tests__/standard-lighting-ssot.unit.test.ts +18 -0
- package/src/__tests__/standard-lighting-write.unit.test.ts +377 -0
- package/src/__tests__/standard-lighting.integration.test.ts +67 -0
- package/src/__tests__/standard-pipeline.dawn.test.ts +206 -5
- package/src/__tests__/standard-pipeline.integration.test.ts +181 -150
- package/src/__tests__/standard-probe-binding.unit.test.ts +25 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +23 -38
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +395 -14
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +2 -2
- package/src/__tests__/visibility-resolver.unit.test.ts +15 -0
- package/src/assembly/device-feature-admission.ts +73 -0
- package/src/assembly/directional-shadow-inspection.ts +122 -0
- package/src/assembly/factory.ts +877 -286
- package/src/assembly/host-contract.ts +25 -0
- package/src/assembly/render-target-host.ts +847 -0
- package/src/assets/asset-decoders.ts +1 -1
- package/src/assets/render-asset-port.ts +7 -1
- package/src/capture/cube-views.ts +69 -0
- package/src/capture/scheduler.ts +265 -0
- package/src/components/__tests__/schema-contract.unit.test.ts +12 -0
- package/src/components/__tests__/schema-parity.unit.test.ts +9 -0
- package/src/components/camera.ts +4 -0
- package/src/components/cube-camera.ts +52 -0
- package/src/components/directional-light.ts +22 -2
- package/src/components/directional-shadow-filter.ts +57 -0
- package/src/components/index.ts +2 -0
- package/src/components/light-helpers.ts +81 -7
- package/src/components/reflection-probe.ts +49 -0
- package/src/environment/frame.ts +6 -24
- package/src/environment/lifecycle.ts +12 -0
- package/src/errors/render.ts +286 -142
- package/src/extract/directional-shadow-projection.ts +61 -0
- package/src/extract/environment.ts +57 -0
- package/src/extract/visibility.ts +25 -1
- package/src/features/fullscreen.ts +3 -0
- package/src/features/targets.ts +4 -1
- package/src/features/types.ts +10 -0
- package/src/fullscreen-post-process-pass.ts +43 -2
- package/src/gpu-driven/batch-topology.ts +1 -0
- package/src/gpu-driven/production-raster.ts +1 -3
- package/src/gpu-scene.ts +8 -1
- package/src/hdrp-buffers.ts +165 -59
- package/src/ibl/IblPipelineCache.ts +11 -0
- package/src/ibl/kernel-cache.ts +88 -0
- package/src/index.ts +148 -0
- package/src/inspection-types.ts +56 -0
- package/src/instances-derived-bounds.ts +171 -0
- package/src/light-buffer-layout.ts +20 -5
- package/src/mesh-material-bindings.ts +132 -0
- package/src/pbr-pipeline.ts +106 -17
- package/src/pipeline/standard-forward-lane.ts +46 -16
- package/src/pipeline/standard-lighting/errors.ts +6 -0
- package/src/pipeline/standard-lighting/graph.ts +157 -0
- package/src/pipeline/standard-lighting/inspection.ts +88 -0
- package/src/pipeline/standard-lighting/layout.ts +31 -0
- package/src/pipeline/standard-lighting/light-frame.ts +34 -0
- package/src/pipeline/standard-lighting/membership.ts +43 -0
- package/src/pipeline/standard-lighting/prepare.ts +37 -0
- package/src/pipeline/standard-lighting/topology.ts +120 -0
- package/src/pipeline/standard-lighting/transport.ts +77 -0
- package/src/pipeline/standard-pipeline.ts +122 -193
- package/src/pipeline/standard-post.ts +26 -7
- package/src/pipeline/standard-profile.ts +17 -47
- package/src/pipeline-spec.ts +84 -21
- package/src/point-shadow-inspection.ts +55 -0
- package/src/record/__tests__/temporal-payload.unit.test.ts +42 -1
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +73 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +40 -0
- package/src/record/frame-lighting.ts +367 -427
- package/src/record/frame-snapshot.ts +35 -27
- package/src/record/frame-targets.ts +17 -0
- package/src/record/frame.ts +261 -74
- package/src/record/gpu-pass-timing/contract.ts +180 -0
- package/src/record/gpu-pass-timing/errors.ts +34 -0
- package/src/record/gpu-pass-timing/index.ts +37 -0
- package/src/record/gpu-pass-timing/parser.ts +97 -0
- package/src/record/gpu-pass-timing/session.ts +938 -0
- package/src/record/gpu-timing.ts +21 -12
- package/src/record/main-pass-geometry.ts +120 -80
- package/src/record/main-pass-material.ts +95 -9
- package/src/record/main-pass-sprite-draws.ts +54 -25
- package/src/record/main-pass.ts +71 -15
- package/src/record/render-context.ts +72 -0
- package/src/record/shadow-pass.ts +17 -28
- package/src/record/skybox-post-pass.ts +20 -4
- package/src/record/typed-frame-graph.ts +893 -44
- package/src/record/view-ubo.ts +63 -28
- package/src/reflection/filter.ts +81 -0
- package/src/reflection/gpu-table.ts +44 -0
- package/src/reflection/projection.ts +281 -0
- package/src/render-contract.ts +76 -5
- package/src/render-graph-primitives.ts +9 -4
- package/src/render-pipeline.ts +117 -2
- package/src/render-system-extract.ts +557 -100
- package/src/render-system.ts +1095 -66
- package/src/renderer.ts +222 -0
- package/src/scene/render-scene.ts +115 -9
- package/src/shadow-atlas.ts +5 -5
- package/src/ssao-buffers.ts +9 -2
- package/src/targets/contracts.ts +182 -0
- package/src/targets/graph-projection.ts +169 -0
- package/src/targets/material-source.ts +143 -0
- package/src/targets/owner.ts +214 -0
- package/src/targets/physical.ts +18 -0
- package/src/targets/readback.ts +153 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +59 -20
- package/src/typed-render-graph-primitives.ts +5 -3
- package/src/typed-shadow-passes.ts +46 -40
- package/src/volume/passes.ts +15 -9
- package/dist/chunk-4XINDLAY.mjs.map +0 -1
- package/dist/chunk-CDTWTHZR.mjs.map +0 -1
- package/dist/chunk-M2MP4ZOU.mjs.map +0 -1
- package/dist/chunk-TBQJOK2L.mjs.map +0 -1
package/src/record/frame.ts
CHANGED
|
@@ -21,8 +21,14 @@ import {
|
|
|
21
21
|
} from '@forgeax/engine-rhi';
|
|
22
22
|
import type { MaterialRenderState, MeshAsset } from '@forgeax/engine-types';
|
|
23
23
|
import { handleSlot, toShared } from '@forgeax/engine-types';
|
|
24
|
+
import { CUBE_CAMERA_FACE_ORDER } from '../components/cube-camera';
|
|
25
|
+
import type { DirectionalShadowQuality } from '../components/directional-shadow-filter';
|
|
24
26
|
import type { MeshGpuHandles } from '../device/gpu-residency';
|
|
25
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
ObservationUnavailableError,
|
|
29
|
+
type ObservationUnavailableReason,
|
|
30
|
+
RendererOperationError,
|
|
31
|
+
} from '../errors/render';
|
|
26
32
|
import type { FogFrame } from '../extract/environment';
|
|
27
33
|
import type { GpuDrivenProduction, PreparedGpuDrivenFrame } from '../gpu-driven/production-raster';
|
|
28
34
|
import { GpuBuffer } from '../gpu-resource';
|
|
@@ -32,8 +38,12 @@ import {
|
|
|
32
38
|
GPU_BUFFER_USAGE_VERTEX,
|
|
33
39
|
} from '../gpu-usage';
|
|
34
40
|
import { disposeTransientInstanceBuffers } from '../instance-buffer-cache';
|
|
41
|
+
import { inspectStandardLighting } from '../pipeline/standard-lighting/inspection';
|
|
42
|
+
import { standardLightingTopologySignature } from '../pipeline/standard-lighting/topology';
|
|
43
|
+
import { inspectPointShadow } from '../point-shadow-inspection';
|
|
35
44
|
import type {
|
|
36
45
|
CameraSnapshot,
|
|
46
|
+
CubeCameraSnapshot,
|
|
37
47
|
RenderRecordPhase,
|
|
38
48
|
SpotLightProjectorFrameContext,
|
|
39
49
|
VolumetricFogFrameContext,
|
|
@@ -48,6 +58,7 @@ import type {
|
|
|
48
58
|
SkylightSnapshot,
|
|
49
59
|
} from '../render-system-extract';
|
|
50
60
|
import type { PersistentGpuDrivenState } from '../scene/render-scene';
|
|
61
|
+
import { SHADOW_ATLAS_DEFAULT_LAYERS } from '../shadow-atlas';
|
|
51
62
|
import {
|
|
52
63
|
getTransparentSortConfig,
|
|
53
64
|
TRANSPARENT_SORT_MODE_LAYER_Y,
|
|
@@ -63,7 +74,6 @@ import {
|
|
|
63
74
|
resolveSkyboxActive,
|
|
64
75
|
warnZeroLightStandard,
|
|
65
76
|
writeHdrpClusterAndSsaoBuffers,
|
|
66
|
-
writePointSpotLightBuffers,
|
|
67
77
|
writeShadowParamsBuffer,
|
|
68
78
|
} from './frame-lighting';
|
|
69
79
|
import {
|
|
@@ -223,12 +233,18 @@ import { computeSplitLdrSprite } from './main-pass-sprite-draws';
|
|
|
223
233
|
import { cleanPerEntityCache, ensureMeshSsboCapacity, uploadMeshSsboBatch } from './mesh-ssbo';
|
|
224
234
|
import { writeShadowCasterUniforms } from './shadow-pass';
|
|
225
235
|
import {
|
|
236
|
+
type CubeCaptureGraphState,
|
|
226
237
|
ensureCompiledFrameGraph,
|
|
227
238
|
executeCompiledFrameGraph,
|
|
228
239
|
type RenderFeatureGraphCandidate,
|
|
229
240
|
settleVolumetricFogGraphCandidate,
|
|
230
241
|
} from './typed-frame-graph';
|
|
231
|
-
import {
|
|
242
|
+
import {
|
|
243
|
+
CUBE_CAPTURE_VIEW_SLOT_BASE,
|
|
244
|
+
VIEW_UNIFORM_SLOT_STRIDE,
|
|
245
|
+
writePointsLinesViewUbo,
|
|
246
|
+
writeViewUbo,
|
|
247
|
+
} from './view-ubo';
|
|
232
248
|
|
|
233
249
|
/**
|
|
234
250
|
* A frame-local material table. Repeated snapshot objects share one UBO slot;
|
|
@@ -301,6 +317,67 @@ export function materialSlotCountForPrefix(
|
|
|
301
317
|
|
|
302
318
|
export type RecordProfileRunner = <T>(phase: RenderRecordPhase, action: () => T) => T;
|
|
303
319
|
|
|
320
|
+
export interface CubeCaptureFrameInput {
|
|
321
|
+
readonly snapshots: readonly CubeCameraSnapshot[];
|
|
322
|
+
readonly scheduler: import('../capture/scheduler').CubeCaptureScheduler;
|
|
323
|
+
readonly state: CubeCaptureGraphState;
|
|
324
|
+
readonly reflectionProbes?: import('./render-context').ReflectionProbeRecordState;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function prepareCubeCapture(
|
|
328
|
+
internals: RenderSystemInternals,
|
|
329
|
+
input: CubeCaptureFrameInput | undefined,
|
|
330
|
+
displayCamera: CameraSnapshot,
|
|
331
|
+
): readonly import('./typed-frame-graph').CubeCaptureGraphWork[] {
|
|
332
|
+
if (input === undefined) return [];
|
|
333
|
+
if (input.reflectionProbes === undefined) delete input.state.reflectionProbes;
|
|
334
|
+
else input.state.reflectionProbes = input.reflectionProbes.graph;
|
|
335
|
+
input.scheduler.beginFrame();
|
|
336
|
+
for (const snapshot of input.snapshots) {
|
|
337
|
+
const inspection = input.scheduler.inspect(snapshot.target);
|
|
338
|
+
if (inspection.candidateGeneration !== undefined) continue;
|
|
339
|
+
const requested = input.scheduler.request({
|
|
340
|
+
target: snapshot.target,
|
|
341
|
+
position: snapshot.position,
|
|
342
|
+
near: snapshot.near,
|
|
343
|
+
far: snapshot.far,
|
|
344
|
+
updateIntent: snapshot.updateIntent,
|
|
345
|
+
requestVersion: snapshot.requestVersion,
|
|
346
|
+
faceBudget: snapshot.faceBudget,
|
|
347
|
+
});
|
|
348
|
+
if (!requested.ok) internals.errorRegistry.fire(requested.error);
|
|
349
|
+
}
|
|
350
|
+
const work = input.scheduler.nextWork();
|
|
351
|
+
const physicalWork: import('./typed-frame-graph').CubeCaptureGraphWork[] = [];
|
|
352
|
+
for (const item of work) {
|
|
353
|
+
const physical = internals.getRenderTargetPhysical?.(item.target);
|
|
354
|
+
if (physical === undefined) continue;
|
|
355
|
+
const faceIndex = CUBE_CAMERA_FACE_ORDER.indexOf(item.face);
|
|
356
|
+
if (faceIndex < 0) continue;
|
|
357
|
+
const faceWorld = mat4.create();
|
|
358
|
+
mat4.invert(faceWorld, item.view);
|
|
359
|
+
physicalWork.push({
|
|
360
|
+
target: item.target,
|
|
361
|
+
faceIndex,
|
|
362
|
+
physical,
|
|
363
|
+
faceCamera: {
|
|
364
|
+
...displayCamera,
|
|
365
|
+
position: vec3.create(item.position[0] ?? 0, item.position[1] ?? 0, item.position[2] ?? 0),
|
|
366
|
+
world: faceWorld,
|
|
367
|
+
fov: Math.PI / 2,
|
|
368
|
+
aspect: 1,
|
|
369
|
+
near: item.near,
|
|
370
|
+
far: item.far,
|
|
371
|
+
projection: 'perspective',
|
|
372
|
+
},
|
|
373
|
+
viewBindGroupDynamicOffset:
|
|
374
|
+
(CUBE_CAPTURE_VIEW_SLOT_BASE + physicalWork.length) * VIEW_UNIFORM_SLOT_STRIDE,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
input.state.work = physicalWork;
|
|
378
|
+
return physicalWork;
|
|
379
|
+
}
|
|
380
|
+
|
|
304
381
|
const EMPTY_ENTITY_KEYS: ReadonlySet<number> = new Set<number>();
|
|
305
382
|
|
|
306
383
|
function runRecordProfilePhase<T>(
|
|
@@ -739,6 +816,8 @@ function prepareSpotLightProjectorFrame(
|
|
|
739
816
|
texture: resident.value.texture.handle,
|
|
740
817
|
view: resident.value.view,
|
|
741
818
|
sampler: sampler.value,
|
|
819
|
+
spotIndex: lights.spot.indexOf(source),
|
|
820
|
+
lightSlotIndex: lights.point.length + lights.spot.indexOf(source),
|
|
742
821
|
};
|
|
743
822
|
}
|
|
744
823
|
|
|
@@ -1036,11 +1115,12 @@ export function recordFrame(
|
|
|
1036
1115
|
gpuDriven?: {
|
|
1037
1116
|
readonly owner: GpuDrivenProduction;
|
|
1038
1117
|
readonly scene: PersistentGpuDrivenState | undefined;
|
|
1039
|
-
readonly onCoverage: (ownsAll: boolean) => void;
|
|
1118
|
+
readonly onCoverage: (ownsAll: boolean, clusteredLighting: boolean) => void;
|
|
1040
1119
|
},
|
|
1041
1120
|
renderReadLeases?: readonly RenderReadLease[],
|
|
1042
1121
|
featureGraphCandidate?: RenderFeatureGraphCandidate,
|
|
1043
1122
|
pointsLinesOwner?: import('./render-context').PointsLinesRecordOwner,
|
|
1123
|
+
cubeCapture?: CubeCaptureFrameInput,
|
|
1044
1124
|
environmentSignature = '',
|
|
1045
1125
|
fogSignature = '',
|
|
1046
1126
|
environmentReady = true,
|
|
@@ -1097,6 +1177,23 @@ export function recordFrame(
|
|
|
1097
1177
|
if (!camera) return false;
|
|
1098
1178
|
const pipelineState = internals.getPipelineState();
|
|
1099
1179
|
if (pipelineState === null) return false;
|
|
1180
|
+
if (pipelineState.device !== internals.device) {
|
|
1181
|
+
internals.errorRegistry.fire(
|
|
1182
|
+
new RendererOperationError('device-operation-failed', {
|
|
1183
|
+
operation: 'draw',
|
|
1184
|
+
cause: {
|
|
1185
|
+
code: 'pipeline-device-mismatch',
|
|
1186
|
+
expected: 'pipelineState.device === runtime.device',
|
|
1187
|
+
hint: 'discard stale pipeline state before recording the next frame',
|
|
1188
|
+
detail: {
|
|
1189
|
+
expected: 'pipelineState.device === runtime.device',
|
|
1190
|
+
hint: 'discard stale pipeline state before recording the next frame',
|
|
1191
|
+
},
|
|
1192
|
+
},
|
|
1193
|
+
}),
|
|
1194
|
+
);
|
|
1195
|
+
return false;
|
|
1196
|
+
}
|
|
1100
1197
|
frameState.currentFrameObservationSource = undefined;
|
|
1101
1198
|
frameState.currentDirectionalShadowView = null;
|
|
1102
1199
|
frameState.currentSpotShadowView = null;
|
|
@@ -1104,7 +1201,7 @@ export function recordFrame(
|
|
|
1104
1201
|
// Record-stage fold operator linear scan (groups transparent-sort entries
|
|
1105
1202
|
// into fold buckets + records the fold-eligible count metric). Extracted to
|
|
1106
1203
|
// computeFoldBuckets (M3/w18).
|
|
1107
|
-
const
|
|
1204
|
+
const lightingPreparation = runRecordProfilePhase(profilePhase, 'record/scene-state', () => {
|
|
1108
1205
|
const foldBuckets = runRecordProfilePhase(
|
|
1109
1206
|
profilePhase,
|
|
1110
1207
|
'record/scene-state/fold-buckets',
|
|
@@ -1115,11 +1212,11 @@ export function recordFrame(
|
|
|
1115
1212
|
// ensure + ExtractedLights three-arm destructure (directional fallback,
|
|
1116
1213
|
// point/spot arrays, totalLightCount). Extracted to prepareFrameLighting
|
|
1117
1214
|
// (M3/w18) so recordFrame stays a skeleton.
|
|
1118
|
-
const
|
|
1119
|
-
|
|
1120
|
-
'record/scene-state/lighting-prep',
|
|
1121
|
-
() => prepareFrameLighting(internals, frameState, lights),
|
|
1215
|
+
const lighting = runRecordProfilePhase(profilePhase, 'record/scene-state/lighting-prep', () =>
|
|
1216
|
+
prepareFrameLighting(internals, frameState, lights, camera, pipelineState),
|
|
1122
1217
|
);
|
|
1218
|
+
if (!lighting.ok) return lighting;
|
|
1219
|
+
const { light, totalLightCount, standard } = lighting.value;
|
|
1123
1220
|
|
|
1124
1221
|
runRecordProfilePhase(profilePhase, 'record/scene-state/ambient-resolution', () => {
|
|
1125
1222
|
// feat-20260520-skylight-ibl-cubemap M4 / t27 (AC-10 + F-4 nit):
|
|
@@ -1166,31 +1263,17 @@ export function recordFrame(
|
|
|
1166
1263
|
}
|
|
1167
1264
|
});
|
|
1168
1265
|
|
|
1169
|
-
// feat-20260608-cluster-lighting M5 / w21 + M6 / w23: HDRP per-frame CPU
|
|
1170
|
-
// cluster binning + light-data / cluster-grid / SSAO buffer uploads. Runs
|
|
1171
|
-
// only when the HDRP pipeline is active and there is at least one punctual
|
|
1172
|
-
// light. Extracted to a sub-function (M3/w18) so recordFrame stays a
|
|
1173
|
-
// skeleton; fail-soft error semantics are preserved verbatim.
|
|
1174
|
-
runRecordProfilePhase(profilePhase, 'record/scene-state/hdrp-cluster', () => {
|
|
1175
|
-
writeHdrpClusterAndSsaoBuffers(
|
|
1176
|
-
internals,
|
|
1177
|
-
frameState,
|
|
1178
|
-
camera,
|
|
1179
|
-
pointLights,
|
|
1180
|
-
spotLights,
|
|
1181
|
-
profilePhase,
|
|
1182
|
-
pipelineState.hdrpClusterMembershipPipeline !== null &&
|
|
1183
|
-
internals.device.caps?.compute === true,
|
|
1184
|
-
pipelineState.hdrpClusterMembershipBindGroupLayout,
|
|
1185
|
-
);
|
|
1186
|
-
});
|
|
1187
|
-
|
|
1188
1266
|
// Zero-light standard-material once-warn (no Skylight + 0 direct light +
|
|
1189
1267
|
// >=1 lit material -> black). Extracted to warnZeroLightStandard (M3/w18).
|
|
1190
1268
|
warnZeroLightStandard(frameState, renderables, skylight, totalLightCount);
|
|
1191
1269
|
|
|
1192
|
-
return { foldBuckets, light };
|
|
1270
|
+
return { ok: true as const, value: { foldBuckets, light, standard } };
|
|
1193
1271
|
});
|
|
1272
|
+
if (!lightingPreparation.ok) {
|
|
1273
|
+
internals.errorRegistry.fire(lightingPreparation.error);
|
|
1274
|
+
return false;
|
|
1275
|
+
}
|
|
1276
|
+
const { foldBuckets, light, standard } = lightingPreparation.value;
|
|
1194
1277
|
|
|
1195
1278
|
// Case E (this commit): 0 renderables = legitimate scene (LO §1.1
|
|
1196
1279
|
// hello-window minimum semantic). Mirrors the Case C softening for
|
|
@@ -1282,7 +1365,6 @@ export function recordFrame(
|
|
|
1282
1365
|
meshes: pipelineState.meshes,
|
|
1283
1366
|
viewBindGroupLayout: pipelineState.viewBindGroupLayout,
|
|
1284
1367
|
meshResidencyEpoch: internals.gpuStore.meshResidencyEpoch,
|
|
1285
|
-
hdrp: frameState.isHdrpActive,
|
|
1286
1368
|
});
|
|
1287
1369
|
if (prepared.ok) preparedGpuDriven = prepared.value;
|
|
1288
1370
|
else if (prepared.error.code !== 'rhi-not-available')
|
|
@@ -1296,7 +1378,36 @@ export function recordFrame(
|
|
|
1296
1378
|
lights.pointShadow.length > 0 ||
|
|
1297
1379
|
lights.spot.some((spot) => spot.castShadow);
|
|
1298
1380
|
const gpuOwnsAllPrimaryRaster = preparedGpuDriven?.ownsAllRenderables === true;
|
|
1299
|
-
gpuDriven?.onCoverage(
|
|
1381
|
+
gpuDriven?.onCoverage(
|
|
1382
|
+
gpuOwnsAllPrimaryRaster && !cpuShadowCastersActive,
|
|
1383
|
+
standard.kind === 'clustered',
|
|
1384
|
+
);
|
|
1385
|
+
|
|
1386
|
+
const cubeCaptureWork = prepareCubeCapture(internals, cubeCapture, camera);
|
|
1387
|
+
|
|
1388
|
+
// Validate renderables before graph admission. Besides producing the draw
|
|
1389
|
+
// plan, this is the owner of per-frame cache eviction; running it before a
|
|
1390
|
+
// graph candidate can fail guarantees despawned instance buffers are
|
|
1391
|
+
// released even when the frame cannot be submitted.
|
|
1392
|
+
const gpuOwnedEntityKeys = preparedGpuDriven?.entityKeys ?? EMPTY_ENTITY_KEYS;
|
|
1393
|
+
const validated = runRecordProfilePhase(profilePhase, 'record/validation', () =>
|
|
1394
|
+
gpuOwnsAllPrimaryRaster && !cpuShadowCastersActive && cubeCaptureWork.length === 0
|
|
1395
|
+
? []
|
|
1396
|
+
: validateRenderables(
|
|
1397
|
+
internals,
|
|
1398
|
+
world,
|
|
1399
|
+
worlds,
|
|
1400
|
+
pipelineState,
|
|
1401
|
+
frameState,
|
|
1402
|
+
renderables,
|
|
1403
|
+
transparentDispatch,
|
|
1404
|
+
cpuShadowCastersActive || cubeCaptureWork.length > 0
|
|
1405
|
+
? EMPTY_ENTITY_KEYS
|
|
1406
|
+
: gpuOwnedEntityKeys,
|
|
1407
|
+
),
|
|
1408
|
+
);
|
|
1409
|
+
gpuDriven?.owner.recordCpuValidation(validated, gpuOwnedEntityKeys);
|
|
1410
|
+
cleanPerFrameCaches(internals, frameState, validated, gpuOwnedEntityKeys);
|
|
1300
1411
|
|
|
1301
1412
|
const preflightGraph = runRecordProfilePhase(profilePhase, 'record/render-graph', () =>
|
|
1302
1413
|
ensureCompiledFrameGraph(
|
|
@@ -1310,14 +1421,60 @@ export function recordFrame(
|
|
|
1310
1421
|
graphShadowMapSize,
|
|
1311
1422
|
preparedGpuDriven,
|
|
1312
1423
|
featureGraphCandidate,
|
|
1424
|
+
cubeCapture?.state,
|
|
1313
1425
|
cameras.length === 0,
|
|
1314
1426
|
transmissionDemand,
|
|
1315
1427
|
graphVolumetricFog,
|
|
1316
1428
|
volumeTopologyCandidate,
|
|
1429
|
+
standard,
|
|
1317
1430
|
),
|
|
1318
1431
|
);
|
|
1319
1432
|
if (preflightGraph === null) return false;
|
|
1320
1433
|
|
|
1434
|
+
// The compiled graph is the acceptance boundary for the prepared
|
|
1435
|
+
// Standard lighting declaration. Upload the same declaration only after
|
|
1436
|
+
// that graph is current; a failed candidate therefore cannot leave an old
|
|
1437
|
+
// graph consuming a new buffer generation.
|
|
1438
|
+
if (frameState.standardLightingGraphSignature !== standardLightingTopologySignature(standard)) {
|
|
1439
|
+
internals.errorRegistry.fire(
|
|
1440
|
+
new RendererOperationError('device-operation-failed', {
|
|
1441
|
+
operation: 'draw',
|
|
1442
|
+
cause: {
|
|
1443
|
+
code: 'standard-graph-generation-mismatch',
|
|
1444
|
+
expected: 'compiled graph and prepared Standard lighting share one topology signature',
|
|
1445
|
+
hint: 'retry the frame after the Standard graph candidate is accepted',
|
|
1446
|
+
detail: {
|
|
1447
|
+
expected: standardLightingTopologySignature(standard),
|
|
1448
|
+
actual: frameState.standardLightingGraphSignature,
|
|
1449
|
+
},
|
|
1450
|
+
},
|
|
1451
|
+
}),
|
|
1452
|
+
);
|
|
1453
|
+
return false;
|
|
1454
|
+
}
|
|
1455
|
+
if (standard.kind === 'clustered') {
|
|
1456
|
+
const clusterWrite = runRecordProfilePhase(
|
|
1457
|
+
profilePhase,
|
|
1458
|
+
'record/scene-state/hdrp-cluster',
|
|
1459
|
+
() =>
|
|
1460
|
+
writeHdrpClusterAndSsaoBuffers(
|
|
1461
|
+
internals,
|
|
1462
|
+
frameState,
|
|
1463
|
+
camera,
|
|
1464
|
+
standard.prepared,
|
|
1465
|
+
standard.transport,
|
|
1466
|
+
profilePhase,
|
|
1467
|
+
pipelineState.hdrpClusterMembershipPipeline !== null,
|
|
1468
|
+
pipelineState.hdrpClusterMembershipBindGroupLayout,
|
|
1469
|
+
preparedSpotLightProjector?.lightSlotIndex,
|
|
1470
|
+
),
|
|
1471
|
+
);
|
|
1472
|
+
if (!clusterWrite.ok) {
|
|
1473
|
+
internals.errorRegistry.fire(clusterWrite.error);
|
|
1474
|
+
return false;
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1321
1478
|
// Acquire the swap-chain texture + colour view + target dimensions (with
|
|
1322
1479
|
// one reconfigure-and-retry on surface-outdated). Extracted to
|
|
1323
1480
|
// acquireSwapChainTarget (M3/w18); returns null on unrecoverable failure
|
|
@@ -1501,41 +1658,6 @@ export function recordFrame(
|
|
|
1501
1658
|
const geometryColorResolveView: TextureView | null = null;
|
|
1502
1659
|
const ldrSpriteColorView: TextureView | null = null;
|
|
1503
1660
|
|
|
1504
|
-
// Validate renderable handles + collect render plan. Empty `renderables`
|
|
1505
|
-
// input or all-unregistered handles both produce `validatedOrdered.length === 0`,
|
|
1506
|
-
// which is the Case E (clear-pass-only) path.
|
|
1507
|
-
//
|
|
1508
|
-
// feat-20260520-2d-sprite-layer-mvp M-3 / w25 (@new-surface): per-entry
|
|
1509
|
-
// `renderableIndex` tracks the position into the original renderables[]
|
|
1510
|
-
// array so the bucket-aware reordering below can correlate
|
|
1511
|
-
// transparent-sort output (TransparentEntry.renderableIndex) back to
|
|
1512
|
-
// the validated row.
|
|
1513
|
-
// bug-20260527-renderstate-pipeline-dispatch-gap D-4:
|
|
1514
|
-
// build a renderableIndex -> renderState map from dispatch entries
|
|
1515
|
-
// so each ValidatedRenderable carries its per-material renderState
|
|
1516
|
-
// override without an O(n^2) back-scan in the draw loop.
|
|
1517
|
-
const gpuOwnedEntityKeys = preparedGpuDriven?.entityKeys ?? EMPTY_ENTITY_KEYS;
|
|
1518
|
-
const validated = runRecordProfilePhase(profilePhase, 'record/validation', () =>
|
|
1519
|
-
gpuOwnsAllPrimaryRaster && !cpuShadowCastersActive
|
|
1520
|
-
? []
|
|
1521
|
-
: validateRenderables(
|
|
1522
|
-
internals,
|
|
1523
|
-
world,
|
|
1524
|
-
worlds,
|
|
1525
|
-
pipelineState,
|
|
1526
|
-
frameState,
|
|
1527
|
-
renderables,
|
|
1528
|
-
transparentDispatch,
|
|
1529
|
-
cpuShadowCastersActive ? EMPTY_ENTITY_KEYS : gpuOwnedEntityKeys,
|
|
1530
|
-
),
|
|
1531
|
-
);
|
|
1532
|
-
gpuDriven?.owner.recordCpuValidation(validated, gpuOwnedEntityKeys);
|
|
1533
|
-
|
|
1534
|
-
// Per-frame cache clean-up: drop per-entity BG cache entries + instance
|
|
1535
|
-
// buffers whose entityKey is absent from the current validated set (despawn
|
|
1536
|
-
// eviction). Extracted to cleanPerFrameCaches (M3/w18).
|
|
1537
|
-
cleanPerFrameCaches(internals, frameState, validated, gpuOwnedEntityKeys);
|
|
1538
|
-
|
|
1539
1661
|
// Dispatch-ordered render plan: reorder validated renderables to dispatch
|
|
1540
1662
|
// order, run the mesh-SSBO capacity gate (graceful truncation), and build
|
|
1541
1663
|
// the fold dispatch plan. Extracted to buildDispatchPlan (M3/w18).
|
|
@@ -1607,6 +1729,7 @@ export function recordFrame(
|
|
|
1607
1729
|
frameState.spotShadowSnapshots,
|
|
1608
1730
|
fog,
|
|
1609
1731
|
temporalView,
|
|
1732
|
+
preparedSpotLightProjector?.spotIndex,
|
|
1610
1733
|
);
|
|
1611
1734
|
if (pipelineState.pointsLinesViewBuffer !== undefined) {
|
|
1612
1735
|
writePointsLinesViewUbo(
|
|
@@ -1623,11 +1746,6 @@ export function recordFrame(
|
|
|
1623
1746
|
lights,
|
|
1624
1747
|
);
|
|
1625
1748
|
|
|
1626
|
-
// Per-frame full rewrite of the PointLight + SpotLight std430 storage
|
|
1627
|
-
// buffers (header + first-slice cap N=4 slots). Extracted to
|
|
1628
|
-
// writePointSpotLightBuffers (M3/w18).
|
|
1629
|
-
writePointSpotLightBuffers(internals, pipelineState, lights);
|
|
1630
|
-
|
|
1631
1749
|
// Per-renderable entity_world upload (batched): all N mat4+normalMatrix
|
|
1632
1750
|
// slots assembled into a single contiguous scratch buffer, then flushed
|
|
1633
1751
|
// as one writeBuffer call. Extracted to mesh-ssbo.ts (M3/w21) so its
|
|
@@ -1676,10 +1794,40 @@ export function recordFrame(
|
|
|
1676
1794
|
validated.length > 0 || preparedGpuDriven !== undefined,
|
|
1677
1795
|
bindGroupCounts,
|
|
1678
1796
|
undefined,
|
|
1679
|
-
|
|
1797
|
+
true,
|
|
1798
|
+
standard,
|
|
1680
1799
|
),
|
|
1681
1800
|
);
|
|
1682
1801
|
|
|
1802
|
+
for (const capture of cubeCaptureWork) {
|
|
1803
|
+
writeViewUbo(
|
|
1804
|
+
internals.device.queue,
|
|
1805
|
+
pipelineState.viewUniformBuffer,
|
|
1806
|
+
capture.faceCamera,
|
|
1807
|
+
light,
|
|
1808
|
+
lights,
|
|
1809
|
+
frameState.spotShadowSnapshots,
|
|
1810
|
+
capture.viewBindGroupDynamicOffset,
|
|
1811
|
+
undefined,
|
|
1812
|
+
preparedSpotLightProjector?.spotIndex,
|
|
1813
|
+
);
|
|
1814
|
+
}
|
|
1815
|
+
for (const probe of cubeCapture?.reflectionProbes?.graph.work ?? []) {
|
|
1816
|
+
if (probe.faceCamera === undefined || probe.viewBindGroupDynamicOffset === undefined)
|
|
1817
|
+
continue;
|
|
1818
|
+
writeViewUbo(
|
|
1819
|
+
internals.device.queue,
|
|
1820
|
+
pipelineState.viewUniformBuffer,
|
|
1821
|
+
probe.faceCamera,
|
|
1822
|
+
light,
|
|
1823
|
+
lights,
|
|
1824
|
+
frameState.spotShadowSnapshots,
|
|
1825
|
+
probe.viewBindGroupDynamicOffset,
|
|
1826
|
+
undefined,
|
|
1827
|
+
preparedSpotLightProjector?.spotIndex,
|
|
1828
|
+
);
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1683
1831
|
// ── feat-20260529-rendergraph-pass-abstraction M4 / w13b ───────────
|
|
1684
1832
|
// The compiled typed graph is the sole per-frame pass owner.
|
|
1685
1833
|
//
|
|
@@ -1755,16 +1903,21 @@ export function recordFrame(
|
|
|
1755
1903
|
dispatch: transparentDispatch,
|
|
1756
1904
|
hdrpClusterBindGroup,
|
|
1757
1905
|
hdrpClusterMembershipBindGroup,
|
|
1906
|
+
standardLighting: standard,
|
|
1758
1907
|
foldDispatchPlan,
|
|
1759
1908
|
materialSlotIndices,
|
|
1760
1909
|
materialSlots,
|
|
1761
1910
|
materialSlotOwners,
|
|
1762
1911
|
materialSlotCount,
|
|
1912
|
+
...(cubeCapture?.reflectionProbes === undefined
|
|
1913
|
+
? {}
|
|
1914
|
+
: { reflectionProbes: cubeCapture.reflectionProbes }),
|
|
1763
1915
|
pointsLines: pointsLinesOwner,
|
|
1764
1916
|
materialBgAssemblyCache: frameState.materialBgAssemblyCache,
|
|
1765
1917
|
directionalShadowCacheReuse: directionalShadowCache.reuse,
|
|
1766
1918
|
...(profilePhase !== undefined ? { profilePhase } : {}),
|
|
1767
1919
|
};
|
|
1920
|
+
let completion: Promise<unknown> | undefined;
|
|
1768
1921
|
const stagedTemporalFrame = {
|
|
1769
1922
|
frameId: frameState.frameNumber,
|
|
1770
1923
|
currentViewProjection: new Float32Array(currentViewProjection),
|
|
@@ -1788,9 +1941,18 @@ export function recordFrame(
|
|
|
1788
1941
|
profilePhase === undefined
|
|
1789
1942
|
? undefined
|
|
1790
1943
|
: (pass, encode) => profilePhase(graphExecutionPhase(pass.name), encode),
|
|
1944
|
+
cubeCaptureWork.length === 0 ? undefined : cubeCaptureWork.map((work) => work.faceIndex),
|
|
1945
|
+
(done) => {
|
|
1946
|
+
completion = done;
|
|
1947
|
+
},
|
|
1791
1948
|
timingCapture,
|
|
1792
1949
|
),
|
|
1793
1950
|
);
|
|
1951
|
+
if (cubeCapture !== undefined && cubeCaptureWork.length > 0) {
|
|
1952
|
+
const completed = cubeCapture.scheduler.completeSubmission(submitted, completion);
|
|
1953
|
+
if (!completed.ok) internals.errorRegistry.fire(completed.error);
|
|
1954
|
+
}
|
|
1955
|
+
cubeCapture?.reflectionProbes?.completeSubmission(submitted, completion);
|
|
1794
1956
|
if (submitted && !directionalShadowCache.reuse) {
|
|
1795
1957
|
frameState.directionalShadowCache = frameState.directionalShadowCacheRecorded
|
|
1796
1958
|
? directionalShadowCache.next
|
|
@@ -1837,6 +1999,11 @@ export function recordFrame(
|
|
|
1837
1999
|
frameState.volumetricFogAccepted = volumetricFog;
|
|
1838
2000
|
frameState.volumetricFogAcceptedContext = preparedVolumetricFog;
|
|
1839
2001
|
}
|
|
2002
|
+
frameState.standardLightingInspection = inspectStandardLighting(standard);
|
|
2003
|
+
frameState.pointShadowInspection = inspectPointShadow(
|
|
2004
|
+
lights.pointShadow,
|
|
2005
|
+
SHADOW_ATLAS_DEFAULT_LAYERS,
|
|
2006
|
+
);
|
|
1840
2007
|
}
|
|
1841
2008
|
return submitted;
|
|
1842
2009
|
} finally {
|
|
@@ -1857,9 +2024,9 @@ export function recordFrame(
|
|
|
1857
2024
|
);
|
|
1858
2025
|
}
|
|
1859
2026
|
frameState.frameNumber += 1;
|
|
1860
|
-
// feat-20260608-cluster-lighting M5 / w22: clear
|
|
2027
|
+
// feat-20260608-cluster-lighting M5 / w22: clear Standard once-per-frame fired
|
|
1861
2028
|
// set so the next frame re-fires if the condition persists.
|
|
1862
|
-
frameState.
|
|
2029
|
+
frameState.standardOncePerFrameFired.clear();
|
|
1863
2030
|
}
|
|
1864
2031
|
}
|
|
1865
2032
|
|
|
@@ -1927,6 +2094,20 @@ function sameLightViewProj(
|
|
|
1927
2094
|
return true;
|
|
1928
2095
|
}
|
|
1929
2096
|
|
|
2097
|
+
function sameDirectionalShadowQuality(
|
|
2098
|
+
previous: DirectionalShadowQuality,
|
|
2099
|
+
next: DirectionalShadowQuality,
|
|
2100
|
+
): boolean {
|
|
2101
|
+
if (previous.kind !== next.kind) return false;
|
|
2102
|
+
if (previous.kind === 'pcf' && next.kind === 'pcf') return previous.kernel === next.kernel;
|
|
2103
|
+
if (previous.kind !== 'pcss' || next.kind !== 'pcss') return false;
|
|
2104
|
+
return (
|
|
2105
|
+
previous.preset === next.preset &&
|
|
2106
|
+
previous.angularRadiusRadians === next.angularRadiusRadians &&
|
|
2107
|
+
previous.maxPenumbraTexels === next.maxPenumbraTexels
|
|
2108
|
+
);
|
|
2109
|
+
}
|
|
2110
|
+
|
|
1930
2111
|
function prepareDirectionalShadowCache(
|
|
1931
2112
|
internals: RenderSystemInternals,
|
|
1932
2113
|
frameState: RenderFrameState,
|
|
@@ -1946,6 +2127,7 @@ function prepareDirectionalShadowCache(
|
|
|
1946
2127
|
cascadeCount === undefined ||
|
|
1947
2128
|
cascadeCount <= 0 ||
|
|
1948
2129
|
lightViewProj === undefined ||
|
|
2130
|
+
lights.directionalShadowQuality === undefined ||
|
|
1949
2131
|
validatedOrdered.length === 0
|
|
1950
2132
|
) {
|
|
1951
2133
|
return { reuse: false, next: null };
|
|
@@ -1958,6 +2140,10 @@ function prepareDirectionalShadowCache(
|
|
|
1958
2140
|
cached !== null &&
|
|
1959
2141
|
cached.shadowMapSize === shadowMapSize &&
|
|
1960
2142
|
cached.cascadeCount === cascadeCount &&
|
|
2143
|
+
sameDirectionalShadowQuality(
|
|
2144
|
+
cached.directionalShadowQuality,
|
|
2145
|
+
lights.directionalShadowQuality,
|
|
2146
|
+
) &&
|
|
1961
2147
|
cached.pipelineHandle === frameState.installedPipelineHandle &&
|
|
1962
2148
|
cached.graphTopologyKey === frameState.compiledFrameGraphTopologyKey &&
|
|
1963
2149
|
cached.assetCatalogEpoch === assetCatalogEpoch &&
|
|
@@ -1986,6 +2172,7 @@ function prepareDirectionalShadowCache(
|
|
|
1986
2172
|
graphTopologyKey: frameState.compiledFrameGraphTopologyKey,
|
|
1987
2173
|
shadowMapSize,
|
|
1988
2174
|
cascadeCount,
|
|
2175
|
+
directionalShadowQuality: lights.directionalShadowQuality,
|
|
1989
2176
|
lightViewProj: lightViewProj.map((matrix) => new Float32Array(matrix)),
|
|
1990
2177
|
meshResidencyEpoch,
|
|
1991
2178
|
},
|