@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
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export const REFLECTION_PROBE_IBL_STAGES = ['raw', 'filtered', 'publish'] as const;
|
|
2
|
+
export type ReflectionProbeIblStage = (typeof REFLECTION_PROBE_IBL_STAGES)[number];
|
|
3
|
+
|
|
4
|
+
export interface IblKernelCache {
|
|
5
|
+
readonly generation: number;
|
|
6
|
+
readonly pipelineIdentity: object;
|
|
7
|
+
readonly samplerIdentity: object;
|
|
8
|
+
readonly brdfLutIdentity: object;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const kernelCaches = new Map<number, IblKernelCache>();
|
|
12
|
+
|
|
13
|
+
export function createIblKernelCache(generation: number): IblKernelCache {
|
|
14
|
+
const existing = kernelCaches.get(generation);
|
|
15
|
+
if (existing !== undefined) return existing;
|
|
16
|
+
const created: IblKernelCache = {
|
|
17
|
+
generation,
|
|
18
|
+
pipelineIdentity: {},
|
|
19
|
+
samplerIdentity: {},
|
|
20
|
+
brdfLutIdentity: {},
|
|
21
|
+
};
|
|
22
|
+
kernelCaches.set(generation, created);
|
|
23
|
+
return created;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ProbeIblOutput {
|
|
27
|
+
readonly entityKey: number;
|
|
28
|
+
readonly resolution: number;
|
|
29
|
+
readonly deviceGeneration: number;
|
|
30
|
+
readonly raw: object;
|
|
31
|
+
readonly filtered: object;
|
|
32
|
+
readonly rawGeneration: number;
|
|
33
|
+
readonly filteredGeneration: number;
|
|
34
|
+
readonly lkg: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ProbeIblUpdate extends ProbeIblOutput {
|
|
38
|
+
readonly stages: typeof REFLECTION_PROBE_IBL_STAGES;
|
|
39
|
+
readonly nextStage: ReflectionProbeIblStage;
|
|
40
|
+
readonly candidateGeneration: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function createProbeIblOutput(input: {
|
|
44
|
+
readonly entityKey: number;
|
|
45
|
+
readonly resolution: number;
|
|
46
|
+
readonly deviceGeneration: number;
|
|
47
|
+
}): ProbeIblOutput {
|
|
48
|
+
return {
|
|
49
|
+
...input,
|
|
50
|
+
raw: {},
|
|
51
|
+
filtered: {},
|
|
52
|
+
rawGeneration: 0,
|
|
53
|
+
filteredGeneration: 0,
|
|
54
|
+
lkg: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function beginProbeIblUpdate(output: ProbeIblOutput): ProbeIblUpdate {
|
|
59
|
+
return {
|
|
60
|
+
...output,
|
|
61
|
+
stages: REFLECTION_PROBE_IBL_STAGES,
|
|
62
|
+
nextStage: 'raw',
|
|
63
|
+
candidateGeneration: output.filteredGeneration + 1,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function publishProbeIblOutput(
|
|
68
|
+
update: ProbeIblUpdate,
|
|
69
|
+
result: { readonly stage: ReflectionProbeIblStage; readonly ok: boolean },
|
|
70
|
+
): ProbeIblOutput {
|
|
71
|
+
if (!result.ok || result.stage !== update.nextStage) return update;
|
|
72
|
+
if (result.stage === 'raw') {
|
|
73
|
+
return {
|
|
74
|
+
...update,
|
|
75
|
+
rawGeneration: update.candidateGeneration,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (result.stage === 'filtered') return update;
|
|
79
|
+
return {
|
|
80
|
+
...update,
|
|
81
|
+
filteredGeneration: update.candidateGeneration,
|
|
82
|
+
lkg: true,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function resetIblKernelCaches(): void {
|
|
87
|
+
kernelCaches.clear();
|
|
88
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,13 @@ export {
|
|
|
11
11
|
renderPipelineContribution,
|
|
12
12
|
samplerContribution,
|
|
13
13
|
} from './assets/asset-decoders';
|
|
14
|
+
// Runtime contract: leases, frame receipts, detached inspection, profile,
|
|
15
|
+
// lifecycle state, and the single renderer event stream.
|
|
16
|
+
export type {
|
|
17
|
+
CubeCameraFaceView,
|
|
18
|
+
CubeCameraFaceViewInput,
|
|
19
|
+
} from './capture/cube-views';
|
|
20
|
+
export { buildCubeCameraFaceViews } from './capture/cube-views';
|
|
14
21
|
export { Atmosphere } from './components/atmosphere';
|
|
15
22
|
// ECS render vocabulary and grouped closed values.
|
|
16
23
|
export type {
|
|
@@ -42,6 +49,18 @@ export {
|
|
|
42
49
|
TONEMAP_REINHARD,
|
|
43
50
|
TONEMAP_REINHARD_EXTENDED,
|
|
44
51
|
} from './components/camera';
|
|
52
|
+
export {
|
|
53
|
+
CUBE_CAMERA_FACE_ORDER,
|
|
54
|
+
CUBE_CAMERA_UPDATE_CONTINUOUS,
|
|
55
|
+
CUBE_CAMERA_UPDATE_ON_DEMAND,
|
|
56
|
+
CUBE_CAMERA_UPDATE_ONCE,
|
|
57
|
+
CubeCamera,
|
|
58
|
+
type CubeCameraData,
|
|
59
|
+
type CubeCameraFace,
|
|
60
|
+
type CubeCameraUpdateIntent,
|
|
61
|
+
cubeCameraUpdateIntentFromF32,
|
|
62
|
+
cubeCameraUpdateIntentToF32,
|
|
63
|
+
} from './components/cube-camera';
|
|
45
64
|
export * from './components/directional-light';
|
|
46
65
|
export { Fog } from './components/fog';
|
|
47
66
|
export { Instances, type InstancesData } from './components/instances';
|
|
@@ -59,6 +78,16 @@ export {
|
|
|
59
78
|
pointShapeFromU32,
|
|
60
79
|
} from './components/points';
|
|
61
80
|
export { PostProcessParams } from './components/post-process-params';
|
|
81
|
+
export {
|
|
82
|
+
REFLECTION_PROBE_UPDATE_CONTINUOUS,
|
|
83
|
+
REFLECTION_PROBE_UPDATE_ON_CHANGE,
|
|
84
|
+
REFLECTION_PROBE_UPDATE_ONCE,
|
|
85
|
+
ReflectionProbe,
|
|
86
|
+
type ReflectionProbeData,
|
|
87
|
+
type ReflectionProbeUpdateIntent,
|
|
88
|
+
reflectionProbeUpdateIntentFromF32,
|
|
89
|
+
reflectionProbeUpdateIntentToF32,
|
|
90
|
+
} from './components/reflection-probe';
|
|
62
91
|
export { SceneInstance } from './components/scene-instance';
|
|
63
92
|
export {
|
|
64
93
|
SKYBOX_MODE_CUBEMAP,
|
|
@@ -84,8 +113,14 @@ export type {
|
|
|
84
113
|
// Public structured operation failure union. Concrete error classes stay
|
|
85
114
|
// behind the Renderer Result/event boundary.
|
|
86
115
|
export type {
|
|
116
|
+
ReflectionProbeBudgetExceededDetail,
|
|
87
117
|
RenderError,
|
|
88
118
|
RenderErrorCode,
|
|
119
|
+
RenderIntentInvalidDetail,
|
|
120
|
+
RenderTargetCapabilityMissingDetail,
|
|
121
|
+
RenderTargetDescriptorInvalidDetail,
|
|
122
|
+
RenderTargetOperationFailedDetail,
|
|
123
|
+
RenderTargetStateInvalidDetail,
|
|
89
124
|
SceneDataUnavailableDetail,
|
|
90
125
|
SceneDataUnavailableReason,
|
|
91
126
|
} from './errors/render';
|
|
@@ -131,13 +166,43 @@ export type {
|
|
|
131
166
|
RenderFeatureStatus,
|
|
132
167
|
RenderFeatureWorldVisibilitySnapshot,
|
|
133
168
|
} from './features/types';
|
|
169
|
+
export {
|
|
170
|
+
beginProbeIblUpdate,
|
|
171
|
+
createIblKernelCache,
|
|
172
|
+
createProbeIblOutput,
|
|
173
|
+
type IblKernelCache,
|
|
174
|
+
type ProbeIblOutput,
|
|
175
|
+
type ProbeIblUpdate,
|
|
176
|
+
publishProbeIblOutput,
|
|
177
|
+
REFLECTION_PROBE_IBL_STAGES,
|
|
178
|
+
type ReflectionProbeIblStage,
|
|
179
|
+
resetIblKernelCaches,
|
|
180
|
+
} from './ibl/kernel-cache';
|
|
134
181
|
export type {
|
|
135
182
|
BloomInspection,
|
|
136
183
|
MotionBlurInspection,
|
|
137
184
|
MotionBlurInspectionStatus,
|
|
185
|
+
ReflectionProbeInspection,
|
|
186
|
+
ReflectionProbeSelectionInspection,
|
|
138
187
|
TransmissionInspection,
|
|
139
188
|
} from './inspection-types';
|
|
140
189
|
export { Materials, MaterialTransmissionContractError } from './materials';
|
|
190
|
+
export {
|
|
191
|
+
type MeshMaterialBindingObservation,
|
|
192
|
+
type MeshMaterialBindingPreparationFailure,
|
|
193
|
+
type MeshMaterialBindingReadiness,
|
|
194
|
+
type MeshMaterialBindingResidency,
|
|
195
|
+
type MeshMaterialBindingSamplerObservation,
|
|
196
|
+
type MeshMaterialBindingSummary,
|
|
197
|
+
type MeshMaterialBindingTextureObservation,
|
|
198
|
+
projectMeshMaterialBindingObservation,
|
|
199
|
+
summarizeMeshMaterialBindings,
|
|
200
|
+
} from './mesh-material-bindings';
|
|
201
|
+
export type {
|
|
202
|
+
StandardClusterTransportInspection,
|
|
203
|
+
StandardLightingInspection,
|
|
204
|
+
StandardNoLocalLightingInspection,
|
|
205
|
+
} from './pipeline/standard-lighting/inspection';
|
|
141
206
|
// The host-facing default is a stable profile value; implementation-only
|
|
142
207
|
// pipeline helpers remain behind the package boundary.
|
|
143
208
|
export {
|
|
@@ -146,6 +211,10 @@ export {
|
|
|
146
211
|
type StandardVolumetricFogQuality,
|
|
147
212
|
} from './pipeline/standard-profile';
|
|
148
213
|
export { renderComponentsPlugin } from './plugin';
|
|
214
|
+
export {
|
|
215
|
+
inspectPointShadow,
|
|
216
|
+
type PointShadowInspection,
|
|
217
|
+
} from './point-shadow-inspection';
|
|
149
218
|
export {
|
|
150
219
|
admitPointsLines,
|
|
151
220
|
type LinesStyleInput,
|
|
@@ -156,9 +225,67 @@ export {
|
|
|
156
225
|
type PointsStyleInput,
|
|
157
226
|
} from './points-lines/admission';
|
|
158
227
|
export type { PointsLinesInspection } from './points-lines/inspection';
|
|
228
|
+
/**
|
|
229
|
+
* Public bounded GPU pass facts. Use the single `gpuPassTiming` opt-in,
|
|
230
|
+
* `draw()` receipt, and `observe(receipt, { include: ['timings'] })` route.
|
|
231
|
+
* Branch on the closed statuses `complete`, `partial`, `unavailable`, and
|
|
232
|
+
* `failed`; each reason/error exposes `code`, `expected`, `hint`, and `detail`.
|
|
233
|
+
* `latestKnownGood` is separate from current status and completeness. These
|
|
234
|
+
* facts describe pass durations, never frame latency. The bounded contract is
|
|
235
|
+
* in `record/gpu-pass-timing/contract.ts`; benchmark acceptance is fail-closed
|
|
236
|
+
* in `bench/gpu-pass-timing/validator.ts`, and recovery follows the producer's
|
|
237
|
+
* structured hint rather than a second timing API.
|
|
238
|
+
*/
|
|
239
|
+
export type {
|
|
240
|
+
GpuPassTimingCapability,
|
|
241
|
+
GpuPassTimingEntry,
|
|
242
|
+
GpuPassTimingError,
|
|
243
|
+
GpuPassTimingErrorCode,
|
|
244
|
+
GpuPassTimingFrame,
|
|
245
|
+
GpuPassTimingMeasuredEntry,
|
|
246
|
+
GpuPassTimingMeasurementSource,
|
|
247
|
+
GpuPassTimingObservation,
|
|
248
|
+
GpuPassTimingOptions,
|
|
249
|
+
GpuPassTimingPassIdentity,
|
|
250
|
+
GpuPassTimingReason,
|
|
251
|
+
GpuPassTimingReasonCode,
|
|
252
|
+
GpuPassTimingRef,
|
|
253
|
+
GpuPassTimingUnmeasuredEntry,
|
|
254
|
+
} from './record/gpu-pass-timing/index.js';
|
|
159
255
|
// Runtime contract: leases, frame receipts, detached inspection, profile,
|
|
160
256
|
// lifecycle state, and the single renderer event stream.
|
|
257
|
+
export {
|
|
258
|
+
advanceProbeFilter,
|
|
259
|
+
boxProjectReflectionDirection,
|
|
260
|
+
commitProbeFilterStep,
|
|
261
|
+
createProbeFilterState,
|
|
262
|
+
type ProbeFilterState,
|
|
263
|
+
probeFilterIsSteady,
|
|
264
|
+
} from './reflection/filter';
|
|
265
|
+
export {
|
|
266
|
+
buildReflectionProbeTable,
|
|
267
|
+
type ReflectionProbeTable,
|
|
268
|
+
type ReflectionProbeTableRow,
|
|
269
|
+
reflectionProbeTableBytes,
|
|
270
|
+
} from './reflection/gpu-table';
|
|
271
|
+
export {
|
|
272
|
+
admitReflectionProbe,
|
|
273
|
+
DEFAULT_REFLECTION_PROBE_LIMITS,
|
|
274
|
+
estimateReflectionProbeBytes,
|
|
275
|
+
type ReflectionProbeAdmission,
|
|
276
|
+
type ReflectionProbeAdmissionLimits,
|
|
277
|
+
type ReflectionProbeFact,
|
|
278
|
+
type ReflectionProbeInput,
|
|
279
|
+
ReflectionProbeProjection,
|
|
280
|
+
type ReflectionProbeProjectionSnapshot,
|
|
281
|
+
type ReflectionProbeSelection,
|
|
282
|
+
type ReflectionProbeSelectionResult,
|
|
283
|
+
type SkylightSelection,
|
|
284
|
+
selectReflectionProbe,
|
|
285
|
+
validateReflectionProbeInput,
|
|
286
|
+
} from './reflection/projection';
|
|
161
287
|
export type {
|
|
288
|
+
CubeCameraSnapshot,
|
|
162
289
|
FrameCamera,
|
|
163
290
|
FrameEnvironment,
|
|
164
291
|
FrameObservationRequest,
|
|
@@ -179,6 +306,27 @@ export type {
|
|
|
179
306
|
TemporalInspectionInput,
|
|
180
307
|
TemporalInspectionStatus,
|
|
181
308
|
} from './renderer-inspect';
|
|
309
|
+
export {
|
|
310
|
+
SHADOW_ATLAS_DEFAULT_FACE_SIZE,
|
|
311
|
+
SHADOW_ATLAS_DEFAULT_LAYERS,
|
|
312
|
+
ShadowAtlas,
|
|
313
|
+
} from './shadow-atlas';
|
|
314
|
+
export type {
|
|
315
|
+
RenderTarget,
|
|
316
|
+
RenderTargetAdmissionLimits,
|
|
317
|
+
RenderTargetDepthFormat,
|
|
318
|
+
RenderTargetDescriptor,
|
|
319
|
+
RenderTargetFormat,
|
|
320
|
+
RenderTargetMipLevels,
|
|
321
|
+
RenderTargetReadbackData,
|
|
322
|
+
RenderTargetReadbackRequest,
|
|
323
|
+
RenderTargetReadbackTicket,
|
|
324
|
+
RenderTargetSampleCount,
|
|
325
|
+
RenderTargetShape,
|
|
326
|
+
RenderTargetTextureAspect,
|
|
327
|
+
RenderTargetTextureSource,
|
|
328
|
+
RenderTargetTextureSourceOptions,
|
|
329
|
+
} from './targets/contracts';
|
|
182
330
|
export type { TemporalInspection, TemporalResourceInspection } from './temporal/inspection';
|
|
183
331
|
export {
|
|
184
332
|
SCENE_DATA_TEMPORAL_V1_DESCRIPTOR,
|
package/src/inspection-types.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* extract/record dependency graph.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { DirectionalShadowFilterLabel } from './components/directional-shadow-filter';
|
|
7
8
|
import type { PointsLinesInspection } from './points-lines/inspection';
|
|
8
9
|
|
|
9
10
|
export type BloomGraphStatus = 'empty' | 'valid' | 'invalid';
|
|
@@ -65,6 +66,61 @@ export interface GpuDrivenProductionInspection {
|
|
|
65
66
|
readonly cpuFallbackDrawItems: number;
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
export type DirectionalShadowEffectiveProfile =
|
|
70
|
+
| 'off'
|
|
71
|
+
| DirectionalShadowFilterLabel
|
|
72
|
+
| 'rhi-null-structural';
|
|
73
|
+
|
|
74
|
+
export type DirectionalShadowProfile = 'off' | DirectionalShadowFilterLabel;
|
|
75
|
+
|
|
76
|
+
export interface DirectionalShadowInspectionError {
|
|
77
|
+
readonly code: string;
|
|
78
|
+
readonly expected: string;
|
|
79
|
+
readonly hint: string;
|
|
80
|
+
readonly detail?: unknown;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Bounded, detached Directional shadow facts for AI-readable inspection. */
|
|
84
|
+
export interface DirectionalShadowInspection {
|
|
85
|
+
readonly requested: DirectionalShadowProfile;
|
|
86
|
+
readonly effective: DirectionalShadowEffectiveProfile;
|
|
87
|
+
readonly status: 'accepted' | 'fallback' | 'rejected';
|
|
88
|
+
readonly fallbackReason?: 'webgl2-unsupported' | 'rhi-null-structural' | 'candidate-failed';
|
|
89
|
+
readonly lastKnownGood: boolean;
|
|
90
|
+
readonly pixelEvidence: 'available' | 'not-available';
|
|
91
|
+
readonly cascadeCount: number;
|
|
92
|
+
readonly mapSize: number;
|
|
93
|
+
readonly atlasBytes: number;
|
|
94
|
+
readonly writerPasses: number;
|
|
95
|
+
readonly blockerTaps: number;
|
|
96
|
+
readonly filterTapUpperBound: number;
|
|
97
|
+
readonly seamTapUpperBound: number;
|
|
98
|
+
readonly shadowAngularRadius: number | undefined;
|
|
99
|
+
readonly maxPenumbraTexels: number | undefined;
|
|
100
|
+
readonly deviceGeneration: number;
|
|
101
|
+
readonly graphGeneration: number;
|
|
102
|
+
readonly error?: DirectionalShadowInspectionError;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type ReflectionProbeSelectionInspection =
|
|
106
|
+
| { readonly kind: 'probe'; readonly worldId: number; readonly entityKey: number }
|
|
107
|
+
| { readonly kind: 'skylight' };
|
|
108
|
+
|
|
109
|
+
export interface ReflectionProbeInspection {
|
|
110
|
+
readonly selection: ReflectionProbeSelectionInspection;
|
|
111
|
+
readonly factCount: number;
|
|
112
|
+
readonly acceptedCount: number;
|
|
113
|
+
readonly activeCount: number;
|
|
114
|
+
readonly rawFacesCaptured: number;
|
|
115
|
+
readonly filteredStepsCompleted: number;
|
|
116
|
+
readonly filteredMipLevels: readonly number[];
|
|
117
|
+
readonly scheduledRawFaces: number;
|
|
118
|
+
readonly scheduledFilteredSteps: number;
|
|
119
|
+
readonly pipelineReady: boolean;
|
|
120
|
+
readonly pipelineWarmupAttempts: number;
|
|
121
|
+
readonly pipelineWarmupFailure?: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
68
124
|
/** Detached semantic descriptor for the Standard scene-temporal producer. */
|
|
69
125
|
export interface TemporalTargetInspection {
|
|
70
126
|
readonly identity: 'standard-scene-temporal';
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { box3, type Mat4Like, mat4 } from '@forgeax/engine-math';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Inputs owned by the render extract/persistent-scene boundary. Bounds are
|
|
5
|
+
* deliberately derived here instead of being added to the author-facing
|
|
6
|
+
* `Instances` component or written back to a Pack asset.
|
|
7
|
+
*/
|
|
8
|
+
export interface DerivedInstancesUnionBoundsInput {
|
|
9
|
+
readonly meshAabb: ArrayLike<number> | undefined;
|
|
10
|
+
readonly entityWorld: ArrayLike<number>;
|
|
11
|
+
readonly transforms: ArrayLike<number> | undefined;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Renderer-owned cache key. Each generation is supplied by the owner that can
|
|
16
|
+
* observe that mutation: mesh/AABB publication, entity world transform, and
|
|
17
|
+
* the packed instance matrix array respectively.
|
|
18
|
+
*/
|
|
19
|
+
export interface InstanceBoundsCacheKey {
|
|
20
|
+
/** Optional scene/world scope for composite scenes; omitted for standalone tests. */
|
|
21
|
+
readonly worldId?: number;
|
|
22
|
+
readonly entityKey: number;
|
|
23
|
+
readonly meshGeneration: number;
|
|
24
|
+
readonly transformGeneration: number;
|
|
25
|
+
readonly matrixGeneration: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type InstanceBoundsCacheInput = InstanceBoundsCacheKey & DerivedInstancesUnionBoundsInput;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Stable bitwise fingerprint for detached numeric facts used by the cache.
|
|
32
|
+
* Float32 bits are hashed rather than decimal text so a real matrix/AABB
|
|
33
|
+
* change invalidates the projection without keeping another mutable ledger.
|
|
34
|
+
*/
|
|
35
|
+
export function fingerprintNumericArray(values: ArrayLike<number>): number {
|
|
36
|
+
let hash = 0x811c9dc5;
|
|
37
|
+
const scalar = new Float32Array(1);
|
|
38
|
+
const bits = new Uint32Array(scalar.buffer);
|
|
39
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
40
|
+
scalar[0] = Number(values[index]);
|
|
41
|
+
hash = Math.imul(hash ^ (bits[0] ?? 0), 0x01000193) >>> 0;
|
|
42
|
+
}
|
|
43
|
+
return hash >>> 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function finiteAabb(aabb: ArrayLike<number> | undefined): aabb is ArrayLike<number> {
|
|
47
|
+
if (aabb === undefined || aabb.length < 6) return false;
|
|
48
|
+
const minX = aabb[0] as number;
|
|
49
|
+
const minY = aabb[1] as number;
|
|
50
|
+
const minZ = aabb[2] as number;
|
|
51
|
+
const maxX = aabb[3] as number;
|
|
52
|
+
const maxY = aabb[4] as number;
|
|
53
|
+
const maxZ = aabb[5] as number;
|
|
54
|
+
return (
|
|
55
|
+
Number.isFinite(minX) &&
|
|
56
|
+
Number.isFinite(minY) &&
|
|
57
|
+
Number.isFinite(minZ) &&
|
|
58
|
+
Number.isFinite(maxX) &&
|
|
59
|
+
Number.isFinite(maxY) &&
|
|
60
|
+
Number.isFinite(maxZ) &&
|
|
61
|
+
minX <= maxX &&
|
|
62
|
+
minY <= maxY &&
|
|
63
|
+
minZ <= maxZ
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function finiteMatrix(matrix: ArrayLike<number>): matrix is Mat4Like {
|
|
68
|
+
if (matrix.length < 16) return false;
|
|
69
|
+
for (let index = 0; index < 16; index += 1) {
|
|
70
|
+
if (!Number.isFinite(matrix[index] as number)) return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function includeBox(out: box3.Box3, candidate: box3.Box3Like): void {
|
|
76
|
+
for (const x of [candidate[0] as number, candidate[3] as number]) {
|
|
77
|
+
for (const y of [candidate[1] as number, candidate[4] as number]) {
|
|
78
|
+
for (const z of [candidate[2] as number, candidate[5] as number]) {
|
|
79
|
+
box3.expandByPoint(out, [x, y, z]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Derive the world-space AABB enclosing every instance of a mesh.
|
|
87
|
+
*
|
|
88
|
+
* `undefined` is a conservative signal: the caller must skip CPU culling
|
|
89
|
+
* when an input is missing, malformed, or empty. This prevents an empty
|
|
90
|
+
* `Instances` row from becoming a synthetic identity draw/bounds candidate.
|
|
91
|
+
*/
|
|
92
|
+
export function deriveInstancesUnionBounds(
|
|
93
|
+
input: DerivedInstancesUnionBoundsInput,
|
|
94
|
+
): Float32Array | undefined {
|
|
95
|
+
const { meshAabb, entityWorld, transforms } = input;
|
|
96
|
+
if (!finiteAabb(meshAabb) || !finiteMatrix(entityWorld) || transforms === undefined) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
if (transforms.length === 0 || transforms.length % 16 !== 0) return undefined;
|
|
100
|
+
|
|
101
|
+
const local = box3.create(
|
|
102
|
+
meshAabb[0] as number,
|
|
103
|
+
meshAabb[1] as number,
|
|
104
|
+
meshAabb[2] as number,
|
|
105
|
+
meshAabb[3] as number,
|
|
106
|
+
meshAabb[4] as number,
|
|
107
|
+
meshAabb[5] as number,
|
|
108
|
+
);
|
|
109
|
+
const union = box3.create();
|
|
110
|
+
const composed = mat4.create();
|
|
111
|
+
const transformed = box3.create();
|
|
112
|
+
for (let offset = 0; offset < transforms.length; offset += 16) {
|
|
113
|
+
const instance = new Float32Array(16);
|
|
114
|
+
for (let lane = 0; lane < 16; lane += 1) {
|
|
115
|
+
instance[lane] = transforms[offset + lane] as number;
|
|
116
|
+
}
|
|
117
|
+
if (!finiteMatrix(instance)) return undefined;
|
|
118
|
+
mat4.multiply(composed, entityWorld, instance);
|
|
119
|
+
box3.transformBox3(transformed, local, composed);
|
|
120
|
+
if (!finiteAabb(transformed)) return undefined;
|
|
121
|
+
includeBox(union, transformed);
|
|
122
|
+
}
|
|
123
|
+
return new Float32Array(union);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
interface InstanceBoundsCacheEntry extends InstanceBoundsCacheKey {
|
|
127
|
+
readonly bounds: Float32Array | undefined;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Small renderer-owned per-entity cache. A changed generation replaces the
|
|
132
|
+
* entry atomically; packed-id reuse is safe when its owner supplies a new
|
|
133
|
+
* generation (the normal RenderScene slot generation contract).
|
|
134
|
+
*/
|
|
135
|
+
export class InstanceBoundsCache {
|
|
136
|
+
private readonly entries = new Map<string, InstanceBoundsCacheEntry>();
|
|
137
|
+
|
|
138
|
+
private key(input: Pick<InstanceBoundsCacheKey, 'worldId' | 'entityKey'>): string {
|
|
139
|
+
return `${input.worldId === undefined ? '' : `${input.worldId}:`}${input.entityKey}`;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
get(input: InstanceBoundsCacheInput): Float32Array | undefined {
|
|
143
|
+
const previous = this.entries.get(this.key(input));
|
|
144
|
+
if (
|
|
145
|
+
previous !== undefined &&
|
|
146
|
+
previous.meshGeneration === input.meshGeneration &&
|
|
147
|
+
previous.transformGeneration === input.transformGeneration &&
|
|
148
|
+
previous.matrixGeneration === input.matrixGeneration
|
|
149
|
+
) {
|
|
150
|
+
return previous.bounds;
|
|
151
|
+
}
|
|
152
|
+
const bounds = deriveInstancesUnionBounds(input);
|
|
153
|
+
this.entries.set(this.key(input), {
|
|
154
|
+
...(input.worldId === undefined ? {} : { worldId: input.worldId }),
|
|
155
|
+
entityKey: input.entityKey,
|
|
156
|
+
meshGeneration: input.meshGeneration,
|
|
157
|
+
transformGeneration: input.transformGeneration,
|
|
158
|
+
matrixGeneration: input.matrixGeneration,
|
|
159
|
+
bounds,
|
|
160
|
+
});
|
|
161
|
+
return bounds;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
invalidate(entityKey?: number, worldId?: number): void {
|
|
165
|
+
if (entityKey === undefined) {
|
|
166
|
+
this.entries.clear();
|
|
167
|
+
} else {
|
|
168
|
+
this.entries.delete(this.key({ entityKey, ...(worldId === undefined ? {} : { worldId }) }));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -156,6 +156,15 @@ export const SPOT_LIGHT_STD430_BYTES = 80;
|
|
|
156
156
|
export const SPOT_LIGHT_SHADOW_TILE_SENTINEL = -1;
|
|
157
157
|
/** Sentinel for a projector-only SpotLight with no shadow atlas tile. */
|
|
158
158
|
export const SPOT_LIGHT_PROJECTOR_ONLY_SENTINEL = -2;
|
|
159
|
+
/**
|
|
160
|
+
* High-bit marker carried by the shared LightSlot identity lane when this
|
|
161
|
+
* SpotLight is the one projector selected for the frame. The lower 30 bits
|
|
162
|
+
* retain the shadow-atlas tile (0..3), or zero for projector-only lights, so
|
|
163
|
+
* one 64-byte slot carries both shadow and projector identity without growing
|
|
164
|
+
* the cluster UBO or inventing a second light list.
|
|
165
|
+
*/
|
|
166
|
+
export const SPOT_LIGHT_PROJECTOR_FLAG = 0x40000000;
|
|
167
|
+
export const SPOT_LIGHT_TILE_MASK = SPOT_LIGHT_PROJECTOR_FLAG - 1;
|
|
159
168
|
/** Byte size of the array header (count u32 + 12 B pad to 16 B stride). */
|
|
160
169
|
export const LIGHT_ARRAY_HEADER_BYTES = 16;
|
|
161
170
|
/** Maximum number of slots packed in the first-slice cap layout (D-S3). */
|
|
@@ -310,6 +319,7 @@ export interface PointShadowSlotInfo {
|
|
|
310
319
|
export function packLightSlot(
|
|
311
320
|
snap: PointLightSnapshot | SpotLightSnapshot,
|
|
312
321
|
shadow?: PointShadowSlotInfo,
|
|
322
|
+
projectorSelected?: boolean,
|
|
313
323
|
): Float32Array {
|
|
314
324
|
const out = new Float32Array(16);
|
|
315
325
|
// position (vec3<f32> + invRangeSquared at lane .w)
|
|
@@ -340,12 +350,17 @@ export function packLightSlot(
|
|
|
340
350
|
out[14] = shadow.near;
|
|
341
351
|
out[15] = shadow.far;
|
|
342
352
|
} else if (snap.kind === 'spot') {
|
|
343
|
-
|
|
344
|
-
|
|
353
|
+
// The optional argument is explicit at the record owner. Keeping the
|
|
354
|
+
// source-derived fallback preserves standalone packing fixtures while the
|
|
355
|
+
// production path marks only the accepted projector identity.
|
|
356
|
+
const hasProjector =
|
|
357
|
+
projectorSelected ?? (snap.projectorAsset !== undefined && snap.lightViewProj !== undefined);
|
|
358
|
+
const tile = snap.shadowAtlasTile >= 0 ? snap.shadowAtlasTile : 0;
|
|
359
|
+
i32[13] = hasProjector
|
|
360
|
+
? SPOT_LIGHT_PROJECTOR_FLAG | (tile & SPOT_LIGHT_TILE_MASK)
|
|
361
|
+
: snap.shadowAtlasTile >= 0
|
|
345
362
|
? snap.shadowAtlasTile
|
|
346
|
-
:
|
|
347
|
-
? SPOT_LIGHT_PROJECTOR_ONLY_SENTINEL
|
|
348
|
-
: SPOT_LIGHT_SHADOW_TILE_SENTINEL;
|
|
363
|
+
: SPOT_LIGHT_SHADOW_TILE_SENTINEL;
|
|
349
364
|
out[14] = snap.shadowIntensity ?? 1;
|
|
350
365
|
// HDRP has no separate 80-byte SpotLight payload. Reuse the otherwise
|
|
351
366
|
// unused spot `.w` lane so the cluster path consumes the same authored PCF
|