@forgeax/engine-render 0.1.4 → 0.1.6
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 +130 -641
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts +2 -0
- package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts +2 -0
- package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts.map +1 -0
- package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts +2 -0
- package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts.map +1 -1
- package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts +6 -0
- package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts.map +1 -1
- package/dist/{gpu-driven/view-reference.d.ts → __tests__/gpu-driven-view-reference.d.ts} +4 -4
- package/dist/__tests__/gpu-driven-view-reference.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts.map +1 -1
- package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts +2 -0
- package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts.map +1 -0
- package/dist/__tests__/morph-feature-plan.unit.test.d.ts +2 -0
- package/dist/__tests__/morph-feature-plan.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-plan.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-plan.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-plan.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-plan.unit.test.d.ts.map +1 -0
- package/dist/__tests__/ssao-config.unit.test.d.ts +2 -0
- package/dist/__tests__/ssao-config.unit.test.d.ts.map +1 -0
- package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts +2 -0
- package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts.map +1 -0
- package/dist/__tests__/standard-descriptors.test-d.d.ts +2 -0
- package/dist/__tests__/standard-descriptors.test-d.d.ts.map +1 -0
- package/dist/__tests__/standard-pipeline.dawn.test.d.ts +2 -0
- package/dist/__tests__/standard-pipeline.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/standard-pipeline.integration.test.d.ts +2 -0
- package/dist/__tests__/standard-pipeline.integration.test.d.ts.map +1 -0
- package/dist/__tests__/standard-profile-oracle.unit.test.d.ts +2 -0
- package/dist/__tests__/standard-profile-oracle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts.map +1 -0
- package/dist/{renderer/backend-selection.d.ts → assembly/backend-contract.d.ts} +15 -4
- package/dist/assembly/backend-contract.d.ts.map +1 -0
- package/dist/assembly/factory.d.ts +207 -0
- package/dist/assembly/factory.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +84 -0
- package/dist/assembly/host-contract.d.ts.map +1 -0
- package/dist/{renderer → assembly}/material/assembly.d.ts +0 -1
- package/dist/{renderer → assembly}/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/pipeline-projection.d.ts +30 -0
- package/dist/assembly/material/pipeline-projection.d.ts.map +1 -0
- package/dist/authoring.d.ts +10 -11
- package/dist/authoring.d.ts.map +1 -1
- package/dist/authoring.mjs +25 -3
- package/dist/authoring.mjs.map +1 -1
- package/dist/chunk-CQXZC5XI.mjs +182 -0
- package/dist/chunk-CQXZC5XI.mjs.map +1 -0
- package/dist/chunk-QC4VW3XJ.mjs +79 -0
- package/dist/chunk-QC4VW3XJ.mjs.map +1 -0
- package/dist/chunk-SCRSAK5B.mjs +480 -0
- package/dist/chunk-SCRSAK5B.mjs.map +1 -0
- package/dist/components/__tests__/schema-contract.unit.test.d.ts +2 -0
- package/dist/components/__tests__/schema-contract.unit.test.d.ts.map +1 -0
- package/dist/components/glyph-text.d.ts +1 -1
- package/dist/components/glyph-text.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/instances.d.ts +1 -1
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/components/light-helpers.d.ts +1 -1
- package/dist/components/light-helpers.d.ts.map +1 -1
- package/dist/components/mesh-filter.d.ts +7 -7
- package/dist/components/mesh-filter.d.ts.map +1 -1
- package/dist/components/scene-instance.d.ts +11 -11
- package/dist/components/skybox-background.d.ts +56 -0
- package/dist/components/skybox-background.d.ts.map +1 -0
- package/dist/components/skylight.d.ts +55 -0
- package/dist/components/skylight.d.ts.map +1 -0
- package/dist/components/sprite-animation.d.ts +2 -3
- package/dist/components/sprite-animation.d.ts.map +1 -1
- package/dist/components/sprite-instances.d.ts +1 -1
- package/dist/components/sprite-playback-mode.d.ts +6 -1
- package/dist/components/sprite-playback-mode.d.ts.map +1 -1
- package/dist/components/sprite-region-override.d.ts +2 -3
- package/dist/components/sprite-region-override.d.ts.map +1 -1
- package/dist/components/tile-layer.d.ts +5 -0
- package/dist/components/tile-layer.d.ts.map +1 -1
- package/dist/construct-renderer.d.ts +18 -1
- package/dist/construct-renderer.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +27008 -4
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/debug-draw-glue.d.ts +2 -53
- package/dist/debug-draw-glue.d.ts.map +1 -1
- package/dist/device/device-scope.d.ts +83 -0
- package/dist/device/device-scope.d.ts.map +1 -0
- package/dist/{gpu-resource-store.d.ts → device/gpu-residency.d.ts} +91 -48
- package/dist/device/gpu-residency.d.ts.map +1 -0
- package/dist/device/resource-types.d.ts +8 -0
- package/dist/device/resource-types.d.ts.map +1 -0
- package/dist/engine-metrics.d.ts +2 -2
- package/dist/engine-metrics.d.ts.map +1 -1
- package/dist/errors/recover.d.ts +28 -1
- package/dist/errors/recover.d.ts.map +1 -1
- package/dist/errors/render.d.ts +249 -258
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/features/fullscreen.d.ts +19 -0
- package/dist/features/fullscreen.d.ts.map +1 -0
- package/dist/features/host.d.ts +32 -26
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/morph/morph-feature.d.ts +39 -5
- package/dist/features/morph/morph-feature.d.ts.map +1 -1
- package/dist/features/plan.d.ts +182 -0
- package/dist/features/plan.d.ts.map +1 -0
- package/dist/features/prepared-gpu-work.d.ts +21 -17
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/prepared-graphics-store.d.ts +2 -1
- package/dist/features/prepared-graphics-store.d.ts.map +1 -1
- package/dist/features/prepared-graphics.d.ts +11 -21
- package/dist/features/prepared-graphics.d.ts.map +1 -1
- package/dist/features/render-graph-compute.d.ts +2 -2
- package/dist/features/render-graph-compute.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +4 -7
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +2 -2
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/render-graph-resources.d.ts +6 -6
- package/dist/features/render-graph-resources.d.ts.map +1 -1
- package/dist/features/targets.d.ts +5 -5
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +11 -190
- package/dist/features/types.d.ts.map +1 -1
- package/dist/features/vocabulary.d.ts +14 -0
- package/dist/features/vocabulary.d.ts.map +1 -0
- package/dist/fullscreen-post-process-pass.d.ts +4 -25
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/glyph-text-layout-system.d.ts +3 -2
- package/dist/glyph-text-layout-system.d.ts.map +1 -1
- package/dist/gpu-driven/batch-topology.d.ts +6 -75
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts +13 -112
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/view-gpu.d.ts +10 -66
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-resource.d.ts +3 -3
- package/dist/gpu-scene-schema.d.ts +1 -94
- package/dist/gpu-scene-schema.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +7 -33
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +3 -53
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/IblPipelineCache.d.ts +74 -180
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +1 -1
- package/dist/index.d.ts +13 -43
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +165 -3
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +69 -0
- package/dist/inspection-types.d.ts.map +1 -0
- package/dist/instance-buffer-cache.d.ts +1 -4
- package/dist/instance-buffer-cache.d.ts.map +1 -1
- package/dist/internal.d.ts +1 -73
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +1 -43
- package/dist/internal.mjs.map +1 -1
- package/dist/lifecycle.d.ts +36 -2
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/materials.d.ts +0 -3
- package/dist/materials.d.ts.map +1 -1
- package/dist/mesh-material-bindings.d.ts +0 -1
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +75 -29
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-forward-lane.d.ts +5 -0
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -0
- package/dist/pipeline/standard-pipeline.d.ts +31 -0
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -0
- package/dist/pipeline/standard-profile.d.ts +40 -0
- package/dist/pipeline/standard-profile.d.ts.map +1 -0
- package/dist/pipeline-builder.d.ts +3 -3
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec-types.d.ts +24 -0
- package/dist/pipeline-spec-types.d.ts.map +1 -0
- package/dist/pipeline-spec.d.ts +16 -155
- package/dist/pipeline-spec.d.ts.map +1 -1
- package/dist/plugin.d.ts +1 -14
- package/dist/plugin.d.ts.map +1 -1
- package/dist/post-process-errors.d.ts +18 -18
- package/dist/post-process-errors.d.ts.map +1 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts +2 -5
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts +2 -0
- package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +7 -73
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +44 -44
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts +5 -38
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +64 -52
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/helpers.d.ts +3 -2
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +5 -4
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +90 -59
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +28 -3
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +1 -1
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +276 -3
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +235 -0
- package/dist/record/render-context.d.ts.map +1 -0
- package/dist/record/shadow-pass.d.ts +15 -88
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +29 -7
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +3 -3
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/render-contract.d.ts +416 -0
- package/dist/render-contract.d.ts.map +1 -0
- package/dist/render-data.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +14 -362
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +25 -64
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +107 -338
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +21 -713
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene-types.d.ts +58 -0
- package/dist/scene/render-scene-types.d.ts.map +1 -0
- package/dist/scene/render-scene.d.ts +105 -0
- package/dist/scene/render-scene.d.ts.map +1 -0
- package/dist/scene-instances/post-spawn-resolve-joints.d.ts +2 -5
- package/dist/scene-instances/post-spawn-resolve-joints.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +22 -3
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/systems/skin-palette-allocator.d.ts +2 -4
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/systems/skin-palette-types.d.ts +14 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -0
- package/dist/systems/transparent-sort-config.d.ts +23 -2
- package/dist/systems/transparent-sort-config.d.ts.map +1 -1
- package/dist/tilemap-chunk-extract-system.d.ts +4 -3
- package/dist/tilemap-chunk-extract-system.d.ts.map +1 -1
- package/dist/typed-render-graph-primitives.d.ts +2 -4
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/typed-shadow-passes.d.ts +3 -3
- package/dist/typed-shadow-passes.d.ts.map +1 -1
- package/package.json +23 -23
- package/src/__tests__/backend-selection-rhi-capture.test-d.ts +1 -1
- package/src/__tests__/callback-inference.test-d.ts +6 -3
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +7 -4
- package/src/__tests__/construct-renderer-identity.unit.test.ts +15 -2
- package/src/__tests__/device-scope-lifecycle.unit.test.ts +151 -0
- package/src/__tests__/device-scope-stale-matrix.unit.test.ts +42 -0
- package/src/__tests__/direct-extract-consumer-contract.test-d.ts +8 -19
- package/src/__tests__/direct-light-snapshot.unit.test.ts +3 -13
- package/src/__tests__/factory-contract.integration.test.ts +158 -209
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +1 -4
- package/src/__tests__/frame-observation.contract.test.ts +17 -8
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +32 -0
- package/src/__tests__/glyph-text-layout-recovery.unit.test.ts +6 -11
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +9 -16
- package/src/__tests__/gpu-driven-production.integration.test.ts +32 -205
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +4 -7
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +87 -8
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +170 -8
- package/src/{gpu-driven/view-reference.ts → __tests__/gpu-driven-view-reference.ts} +4 -3
- package/src/__tests__/gpu-driven-view.browser.test.ts +12 -1
- package/src/__tests__/gpu-driven-view.dawn.test.ts +12 -1
- package/src/__tests__/gpu-driven-view.unit.test.ts +11 -267
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +3 -3
- package/src/__tests__/gpu-scene-render-graph-gpu.ts +2 -3
- package/src/__tests__/gpu-scene.dawn.test.ts +2 -6
- package/src/__tests__/gpu-scene.unit.test.ts +10 -24
- package/src/__tests__/ibl/face-uniforms.unit.test.ts +46 -0
- package/src/__tests__/infinite-grid-no-vertex-probe.unit.test.ts +34 -66
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +14 -5
- package/src/__tests__/light-buffer-layout.unit.test.ts +4 -49
- package/src/__tests__/material-cooked-projection.unit.test.ts +2 -51
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +10 -15
- package/src/__tests__/material-static-dynamic-route.unit.test.ts +4 -23
- package/src/__tests__/material-stride-surface.unit.test.ts +2 -2
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +7 -8
- package/src/__tests__/morph-culling-reentry.dawn.test.ts +29 -38
- package/src/__tests__/morph-feature-gpu-work.integration.test.ts +45 -43
- package/src/__tests__/morph-feature-plan.unit.test.ts +53 -0
- package/src/__tests__/morph-visual-evidence.integration.test.ts +47 -33
- package/src/__tests__/nineslice-handle-surface.unit.test.ts +11 -6
- package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -13
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +6 -81
- package/src/__tests__/prepared-graphics-generation.unit.test.ts +3 -17
- package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +6 -74
- package/src/__tests__/prepared-graphics-resolver.unit.test.ts +1 -3
- package/src/__tests__/prepared-graphics-snapshot.unit.test.ts +2 -2
- package/src/__tests__/profiler-default-off.test.ts +1 -1
- package/src/__tests__/profiler-phase-catalog.test.ts +2 -2
- package/src/__tests__/profiler-phase-integration.test.ts +5 -13
- package/src/__tests__/profiler-phase-token.test.ts +3 -8
- package/src/__tests__/public-surface.test-d.ts +65 -3
- package/src/__tests__/recover-error-policy-owner.unit.test.ts +1 -21
- package/src/__tests__/render-error-code-owner.test-d.ts +18 -23
- package/src/__tests__/render-error-detail-ssot.test-d.ts +0 -95
- package/src/__tests__/render-error-exhaustive.test-d.ts +8 -1
- package/src/__tests__/render-feature-assembly.test-d.ts +8 -16
- package/src/__tests__/render-feature-context.test-d.ts +16 -40
- package/src/__tests__/render-feature-contract.test-d.ts +9 -18
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +6 -8
- package/src/__tests__/render-feature-docs.unit.test.ts +8 -7
- package/src/__tests__/render-feature-gpu-work.integration.test.ts +14 -75
- package/src/__tests__/render-feature-plan.test-d.ts +161 -0
- package/src/__tests__/render-feature-plan.unit.test.ts +170 -0
- package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +8 -19
- package/src/__tests__/render-feature-prepared-errors.test-d.ts +3 -6
- package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +10 -71
- package/src/__tests__/render-feature-prepared-graphics-isolation.unit.test.ts +11 -61
- package/src/__tests__/render-feature-prepared-graphics-negative.test-d.ts +20 -43
- package/src/__tests__/render-feature-prepared-graphics.test-d.ts +56 -78
- package/src/__tests__/render-feature-public-surface.test-d.ts +6 -24
- package/src/__tests__/render-feature-retry.unit.test.ts +7 -48
- package/src/__tests__/render-feature-scheduling.unit.test.ts +15 -27
- package/src/__tests__/render-feature-stage-failed-policy-owner.unit.test.ts +0 -9
- package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +19 -109
- package/src/__tests__/render-feature-visibility-context.test-d.ts +1 -6
- package/src/__tests__/render-feature-visibility-context.unit.test.ts +1 -2
- package/src/__tests__/render-feature-zero-work.unit.test.ts +14 -20
- package/src/__tests__/render-scene-projection.unit.test.ts +73 -111
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +44 -95
- package/src/__tests__/renderer-lifecycle.integration.test.ts +49 -1
- package/src/__tests__/shader-stage-surface.unit.test.ts +14 -9
- package/src/__tests__/ssao-config.unit.test.ts +36 -0
- package/src/__tests__/ssao-kernel-surface.unit.test.ts +4 -5
- package/src/__tests__/standard-clustered-pipeline.unit.test.ts +28 -0
- package/src/__tests__/standard-descriptors.test-d.ts +22 -0
- package/src/__tests__/standard-pipeline.dawn.test.ts +61 -0
- package/src/__tests__/standard-pipeline.integration.test.ts +124 -0
- package/src/__tests__/standard-profile-oracle.unit.test.ts +62 -0
- package/src/__tests__/surface-configuration.unit.test.ts +1 -2
- package/src/__tests__/texture-usage-surface.unit.test.ts +3 -6
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +40 -206
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +1 -11
- package/src/__tests__/urp-pipeline.unit.test.ts +2 -2
- package/src/__tests__/vertex-color-pipeline.unit.test.ts +10 -2
- package/src/__tests__/vertex-layout-consumer.unit.test.ts +1 -1
- package/src/__tests__/visibility-diagnostics.integration.test.ts +7 -11
- package/src/__tests__/visibility-extract.integration.test.ts +20 -11
- package/src/__tests__/visibility-extract.perf.test.ts +66 -32
- package/src/__tests__/visibility-feature-dedup.integration.test.ts +2 -4
- package/src/__tests__/visibility-hidden-report.unit.test.ts +1 -2
- package/src/__tests__/visibility-instances.integration.test.ts +7 -11
- package/src/__tests__/visibility-multi-world.integration.test.ts +38 -6
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +18 -41
- package/src/__tests__/visibility-public-surface.test-d.ts +10 -9
- package/src/__tests__/visibility-resolver.unit.test.ts +2 -1
- package/src/__tests__/visibility-resource-short-circuit.unit.test.ts +80 -0
- package/src/__tests__/visibility-snapshot-contract.unit.test.ts +2 -1
- package/src/__tests__/vocabulary.unit.test.ts +1 -1
- package/src/assembly/backend-contract.ts +57 -0
- package/src/{renderer/renderer-factory.ts → assembly/factory.ts} +1663 -2690
- package/src/assembly/host-contract.ts +101 -0
- package/src/{renderer → assembly}/material/assembly.ts +0 -2
- package/src/assembly/material/pipeline-projection.ts +63 -0
- package/src/authoring.ts +14 -22
- package/src/components/__tests__/schema-contract.unit.test.ts +10 -0
- package/src/components/glyph-text.ts +3 -2
- package/src/components/index.ts +7 -9
- package/src/components/instances.ts +4 -5
- package/src/components/light-helpers.ts +1 -1
- package/src/components/mesh-filter.ts +11 -10
- package/src/components/post-process-params.ts +3 -3
- package/src/components/scene-instance.ts +12 -12
- package/src/components/skybox-background.ts +103 -0
- package/src/components/{environment.ts → skylight.ts} +2 -110
- package/src/components/sprite-animation.ts +3 -4
- package/src/components/sprite-instances.ts +2 -2
- package/src/components/sprite-playback-mode.ts +7 -1
- package/src/components/sprite-region-override.ts +2 -3
- package/src/components/tile-layer.ts +8 -2
- package/src/construct-renderer.ts +67 -4
- package/src/debug-draw-glue.ts +8 -129
- package/src/device/device-scope.ts +306 -0
- package/src/{gpu-resource-store.ts → device/gpu-residency.ts} +540 -639
- package/src/device/resource-types.ts +20 -0
- package/src/engine-metrics.ts +12 -19
- package/src/errors/recover.ts +45 -3
- package/src/errors/render.ts +357 -460
- package/src/features/fullscreen.ts +46 -0
- package/src/features/host.ts +575 -309
- package/src/features/morph/morph-feature.ts +195 -105
- package/src/features/plan.ts +447 -0
- package/src/features/prepared-gpu-work.ts +72 -15
- package/src/features/prepared-graphics-store.ts +20 -6
- package/src/features/prepared-graphics.ts +12 -71
- package/src/features/render-graph-compute.ts +14 -5
- package/src/features/render-graph-contribution.ts +43 -63
- package/src/features/render-graph-raster.ts +11 -6
- package/src/features/render-graph-resources.ts +25 -23
- package/src/features/targets.ts +8 -21
- package/src/features/types.ts +39 -227
- package/src/features/vocabulary.ts +24 -0
- package/src/fullscreen-post-process-pass.ts +14 -57
- package/src/glyph-text-layout-system.ts +70 -96
- package/src/gpu-driven/batch-topology.ts +24 -202
- package/src/gpu-driven/production-raster.ts +93 -1108
- package/src/gpu-driven/view-gpu.ts +46 -192
- package/src/gpu-resource.ts +4 -4
- package/src/gpu-scene-schema.ts +11 -99
- package/src/gpu-scene.ts +231 -364
- package/src/hdrp-buffers.ts +12 -221
- package/src/ibl/IblPipelineCache.ts +471 -711
- package/src/ibl/skylight-bind-group.ts +4 -4
- package/src/index.ts +58 -217
- package/src/inspection-types.ts +76 -0
- package/src/instance-buffer-cache.ts +1 -29
- package/src/internal.ts +6 -85
- package/src/lifecycle.ts +64 -19
- package/src/materials.ts +7 -29
- package/src/mesh-material-bindings.ts +0 -1
- package/src/pbr-pipeline.ts +434 -53
- package/src/{urp-pipeline.ts → pipeline/standard-forward-lane.ts} +38 -149
- package/src/{hdrp-pipeline.ts → pipeline/standard-pipeline.ts} +221 -191
- package/src/pipeline/standard-profile.ts +65 -0
- package/src/pipeline-builder.ts +60 -64
- package/src/pipeline-spec-types.ts +28 -0
- package/src/pipeline-spec.ts +72 -609
- package/src/plugin.ts +3 -75
- package/src/post-process-errors.ts +31 -33
- package/src/prepare/prepared-graphics-resolver.ts +5 -4
- package/src/record/__tests__/material-slot-plan.unit.test.ts +1 -33
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +41 -0
- package/src/record/__tests__/video-texture-view.unit.test.ts +1 -1
- package/src/record/frame-lighting.ts +74 -195
- package/src/record/frame-snapshot.ts +45 -60
- package/src/record/frame-targets.ts +8 -243
- package/src/record/frame.ts +509 -796
- package/src/record/helpers.ts +6 -11
- package/src/record/main-pass-geometry.ts +106 -147
- package/src/record/main-pass-material.ts +517 -190
- package/src/record/main-pass-sprite-draws.ts +198 -117
- package/src/record/main-pass.ts +162 -143
- package/src/record/mesh-ssbo.ts +517 -38
- package/src/record/render-context.ts +364 -0
- package/src/record/shadow-pass.ts +138 -1838
- package/src/record/skybox-post-pass.ts +12 -14
- package/src/record/typed-frame-graph.ts +215 -254
- package/src/record/view-ubo.ts +6 -37
- package/src/render-contract.ts +571 -0
- package/src/render-data.ts +3 -3
- package/src/render-graph-primitives.ts +76 -851
- package/src/render-pipeline.ts +104 -188
- package/src/render-system-extract.ts +1048 -1729
- package/src/render-system.ts +330 -1957
- package/src/scene/render-scene-types.ts +64 -0
- package/src/scene/render-scene.ts +1032 -0
- package/src/scene-instances/post-spawn-resolve-joints.ts +4 -7
- package/src/ssao-buffers.ts +167 -8
- package/src/systems/skin-palette-allocator.ts +21 -64
- package/src/systems/skin-palette-types.ts +14 -0
- package/src/systems/transparent-sort-config.ts +25 -3
- package/src/tilemap-chunk-extract-system.ts +53 -70
- package/src/typed-render-graph-primitives.ts +35 -24
- package/src/typed-shadow-passes.ts +26 -56
- package/dist/__tests__/analytic-sky-contract.test.d.ts +0 -2
- package/dist/__tests__/analytic-sky-contract.test.d.ts.map +0 -1
- package/dist/__tests__/analytic-sky-falsify.test.d.ts +0 -2
- package/dist/__tests__/analytic-sky-falsify.test.d.ts.map +0 -1
- package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts +0 -2
- package/dist/__tests__/assets-runtime-handoff.integration.test.d.ts.map +0 -1
- package/dist/__tests__/backend-selection.integration.test.d.ts +0 -2
- package/dist/__tests__/backend-selection.integration.test.d.ts.map +0 -1
- package/dist/__tests__/camera-temporal.test-d.d.ts +0 -2
- package/dist/__tests__/camera-temporal.test-d.d.ts.map +0 -1
- package/dist/__tests__/camera-temporal.test.d.ts +0 -2
- package/dist/__tests__/camera-temporal.test.d.ts.map +0 -1
- package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts +0 -2
- package/dist/__tests__/directional-shadow-probe-atlas-layout.unit.test.d.ts.map +0 -1
- package/dist/__tests__/environment-inspection.test.d.ts +0 -2
- package/dist/__tests__/environment-inspection.test.d.ts.map +0 -1
- package/dist/__tests__/fog-ai-user.fixture.d.ts +0 -2
- package/dist/__tests__/fog-ai-user.fixture.d.ts.map +0 -1
- package/dist/__tests__/fog-custom-render-feature.fixture.d.ts +0 -16
- package/dist/__tests__/fog-custom-render-feature.fixture.d.ts.map +0 -1
- package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-custom-render-feature.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-inspection.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-inspection.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-owner-state.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-owner-state.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-pipeline-topology.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-public-surface.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-public-surface.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-ray-contract.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-ray-contract.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-source-absence.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-source-absence.integration.test.d.ts.map +0 -1
- package/dist/__tests__/fog-temporal.integration.test.d.ts +0 -2
- package/dist/__tests__/fog-temporal.integration.test.d.ts.map +0 -1
- package/dist/__tests__/frame-chain.unit.test.d.ts +0 -2
- package/dist/__tests__/frame-chain.unit.test.d.ts.map +0 -1
- package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts +0 -2
- package/dist/__tests__/gpu-scene-field-type-owner.test-d.d.ts.map +0 -1
- package/dist/__tests__/hdrp-pipeline.unit.test.d.ts +0 -2
- package/dist/__tests__/hdrp-pipeline.unit.test.d.ts.map +0 -1
- package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts +0 -2
- package/dist/__tests__/ibl/ibl-fallback.unit.test.d.ts.map +0 -1
- package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts +0 -2
- package/dist/__tests__/material-derived-error-stop-draw.integration.test.d.ts.map +0 -1
- package/dist/__tests__/material-derived-payload.integration.test.d.ts +0 -2
- package/dist/__tests__/material-derived-payload.integration.test.d.ts.map +0 -1
- package/dist/__tests__/materials.unit.test.d.ts +0 -2
- package/dist/__tests__/materials.unit.test.d.ts.map +0 -1
- package/dist/__tests__/param-schema-projection-census.unit.test.d.ts +0 -2
- package/dist/__tests__/param-schema-projection-census.unit.test.d.ts.map +0 -1
- package/dist/__tests__/persistent-render-scene.unit.test.d.ts +0 -2
- package/dist/__tests__/persistent-render-scene.unit.test.d.ts.map +0 -1
- package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts +0 -2
- package/dist/__tests__/pipeline-error-policy-owner.unit.test.d.ts.map +0 -1
- package/dist/__tests__/pipeline-pass-trace.test.d.ts +0 -2
- package/dist/__tests__/pipeline-pass-trace.test.d.ts.map +0 -1
- package/dist/__tests__/pipeline-stage-owner.test-d.d.ts +0 -2
- package/dist/__tests__/pipeline-stage-owner.test-d.d.ts.map +0 -1
- package/dist/__tests__/plugin.test.d.ts +0 -2
- package/dist/__tests__/plugin.test.d.ts.map +0 -1
- package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts +0 -2
- package/dist/__tests__/prepared-graphics-backend-matrix.unit.test.d.ts.map +0 -1
- package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts +0 -2
- package/dist/__tests__/prepared-graphics-resolver-recording.unit.test.d.ts.map +0 -1
- package/dist/__tests__/public-pipeline-id.test-d.d.ts +0 -2
- package/dist/__tests__/public-pipeline-id.test-d.d.ts.map +0 -1
- package/dist/__tests__/render-dispatch-membership.unit.test.d.ts +0 -2
- package/dist/__tests__/render-dispatch-membership.unit.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-construction.unit.test.d.ts +0 -2
- package/dist/__tests__/render-feature-construction.unit.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts +0 -2
- package/dist/__tests__/render-feature-error-code-owner.test-d.d.ts.map +0 -1
- package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts +0 -2
- package/dist/__tests__/render-feature-gpu-buffer-usage-owner.test-d.d.ts.map +0 -1
- package/dist/__tests__/render-feature-graph.integration.test.d.ts +0 -2
- package/dist/__tests__/render-feature-graph.integration.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts +0 -2
- package/dist/__tests__/render-feature-graphics-staging.unit.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-order.unit.test.d.ts +0 -2
- package/dist/__tests__/render-feature-order.unit.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts +0 -2
- package/dist/__tests__/render-feature-prepared-graphics-recording.unit.test.d.ts.map +0 -1
- package/dist/__tests__/render-feature-staging.unit.test.d.ts +0 -2
- package/dist/__tests__/render-feature-staging.unit.test.d.ts.map +0 -1
- package/dist/__tests__/renderer-render-scene-public.test-d.d.ts +0 -2
- package/dist/__tests__/renderer-render-scene-public.test-d.d.ts.map +0 -1
- package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts +0 -2
- package/dist/__tests__/scene-temporal-coverage.unit.test.d.ts.map +0 -1
- package/dist/__tests__/sun-snapshot-consumers.test.d.ts +0 -2
- package/dist/__tests__/sun-snapshot-consumers.test.d.ts.map +0 -1
- package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts +0 -2
- package/dist/__tests__/surface-backend-kind-owner.test-d.d.ts.map +0 -1
- package/dist/__tests__/taa-history-store.unit.test.d.ts +0 -2
- package/dist/__tests__/taa-history-store.unit.test.d.ts.map +0 -1
- package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts +0 -2
- package/dist/__tests__/temporal-frame-transaction.integration.test.d.ts.map +0 -1
- package/dist/__tests__/temporal-inspection.unit.test.d.ts +0 -2
- package/dist/__tests__/temporal-inspection.unit.test.d.ts.map +0 -1
- package/dist/assets/__tests__/asset-decoders.unit.test.d.ts +0 -2
- package/dist/assets/__tests__/asset-decoders.unit.test.d.ts.map +0 -1
- package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts +0 -2
- package/dist/assets/__tests__/mipmap-generator.unit.test.d.ts.map +0 -1
- package/dist/assets/__tests__/render-asset-port.unit.test.d.ts +0 -2
- package/dist/assets/__tests__/render-asset-port.unit.test.d.ts.map +0 -1
- package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts +0 -2
- package/dist/assets/__tests__/resolve-render-asset.unit.test.d.ts.map +0 -1
- package/dist/chunk-DJIMFYX6.mjs +0 -1439
- package/dist/chunk-DJIMFYX6.mjs.map +0 -1
- package/dist/chunk-F2SIOCRM.mjs +0 -7423
- package/dist/chunk-F2SIOCRM.mjs.map +0 -1
- package/dist/chunk-JMSB7AR4.mjs +0 -3
- package/dist/chunk-JMSB7AR4.mjs.map +0 -1
- package/dist/chunk-KHI6K4C6.mjs +0 -659
- package/dist/chunk-KHI6K4C6.mjs.map +0 -1
- package/dist/chunk-PORZOL2V.mjs +0 -569
- package/dist/chunk-PORZOL2V.mjs.map +0 -1
- package/dist/chunk-UOJGMDGP.mjs +0 -29913
- package/dist/chunk-UOJGMDGP.mjs.map +0 -1
- package/dist/components/__tests__/atmosphere-red.test.d.ts +0 -2
- package/dist/components/__tests__/atmosphere-red.test.d.ts.map +0 -1
- package/dist/components/__tests__/atmosphere.test.d.ts +0 -2
- package/dist/components/__tests__/atmosphere.test.d.ts.map +0 -1
- package/dist/components/__tests__/fog.test-d.d.ts +0 -2
- package/dist/components/__tests__/fog.test-d.d.ts.map +0 -1
- package/dist/components/__tests__/fog.test.d.ts +0 -2
- package/dist/components/__tests__/fog.test.d.ts.map +0 -1
- package/dist/components/atmosphere.d.ts +0 -18
- package/dist/components/atmosphere.d.ts.map +0 -1
- package/dist/components/environment.d.ts +0 -115
- package/dist/components/environment.d.ts.map +0 -1
- package/dist/deferred-lighting.d.ts +0 -13
- package/dist/deferred-lighting.d.ts.map +0 -1
- package/dist/dynamic-texture-store.d.ts +0 -42
- package/dist/dynamic-texture-store.d.ts.map +0 -1
- package/dist/environment/__tests__/failure-injection.test.d.ts +0 -2
- package/dist/environment/__tests__/failure-injection.test.d.ts.map +0 -1
- package/dist/environment/__tests__/generation-red.test.d.ts +0 -2
- package/dist/environment/__tests__/generation-red.test.d.ts.map +0 -1
- package/dist/environment/__tests__/generation.test.d.ts +0 -2
- package/dist/environment/__tests__/generation.test.d.ts.map +0 -1
- package/dist/environment/__tests__/graph-transaction.test.d.ts +0 -2
- package/dist/environment/__tests__/graph-transaction.test.d.ts.map +0 -1
- package/dist/environment/__tests__/inspection-red.test.d.ts +0 -2
- package/dist/environment/__tests__/inspection-red.test.d.ts.map +0 -1
- package/dist/environment/__tests__/lifecycle-evidence.test.d.ts +0 -2
- package/dist/environment/__tests__/lifecycle-evidence.test.d.ts.map +0 -1
- package/dist/environment/__tests__/pipeline-topology.test.d.ts +0 -2
- package/dist/environment/__tests__/pipeline-topology.test.d.ts.map +0 -1
- package/dist/environment/__tests__/readiness.test.d.ts +0 -2
- package/dist/environment/__tests__/readiness.test.d.ts.map +0 -1
- package/dist/environment/__tests__/recovery.test.d.ts +0 -2
- package/dist/environment/__tests__/recovery.test.d.ts.map +0 -1
- package/dist/environment/__tests__/resize-dispose.test.d.ts +0 -2
- package/dist/environment/__tests__/resize-dispose.test.d.ts.map +0 -1
- package/dist/environment/__tests__/signature-red.test.d.ts +0 -2
- package/dist/environment/__tests__/signature-red.test.d.ts.map +0 -1
- package/dist/environment/__tests__/signature.test.d.ts +0 -2
- package/dist/environment/__tests__/signature.test.d.ts.map +0 -1
- package/dist/environment/descriptors.d.ts +0 -2
- package/dist/environment/descriptors.d.ts.map +0 -1
- package/dist/environment/extracted-environment.d.ts +0 -53
- package/dist/environment/extracted-environment.d.ts.map +0 -1
- package/dist/environment/generation.d.ts +0 -62
- package/dist/environment/generation.d.ts.map +0 -1
- package/dist/environment/gpu-bundle.d.ts +0 -23
- package/dist/environment/gpu-bundle.d.ts.map +0 -1
- package/dist/environment/graph.d.ts +0 -108
- package/dist/environment/graph.d.ts.map +0 -1
- package/dist/environment/inspection.d.ts +0 -48
- package/dist/environment/inspection.d.ts.map +0 -1
- package/dist/environment/lifecycle.d.ts +0 -22
- package/dist/environment/lifecycle.d.ts.map +0 -1
- package/dist/environment/readiness.d.ts +0 -29
- package/dist/environment/readiness.d.ts.map +0 -1
- package/dist/environment/signature.d.ts +0 -70
- package/dist/environment/signature.d.ts.map +0 -1
- package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts +0 -2
- package/dist/extract/__tests__/directional-csm-domain.unit.test.d.ts.map +0 -1
- package/dist/extract/__tests__/environment-source.test.d.ts +0 -2
- package/dist/extract/__tests__/environment-source.test.d.ts.map +0 -1
- package/dist/extract/__tests__/schema-readers.unit.test.d.ts +0 -2
- package/dist/extract/__tests__/schema-readers.unit.test.d.ts.map +0 -1
- package/dist/extract/directional-csm.d.ts +0 -129
- package/dist/extract/directional-csm.d.ts.map +0 -1
- package/dist/extract/index.d.ts +0 -5
- package/dist/extract/index.d.ts.map +0 -1
- package/dist/extract/material-interface.d.ts +0 -56
- package/dist/extract/material-interface.d.ts.map +0 -1
- package/dist/extract/schema-readers.d.ts +0 -20
- package/dist/extract/schema-readers.d.ts.map +0 -1
- package/dist/features/graph-contribution.d.ts +0 -64
- package/dist/features/graph-contribution.d.ts.map +0 -1
- package/dist/features/index.d.ts +0 -21
- package/dist/features/index.d.ts.map +0 -1
- package/dist/features/morph/index.d.ts +0 -3
- package/dist/features/morph/index.d.ts.map +0 -1
- package/dist/features/morph/morph-bounds.d.ts +0 -42
- package/dist/features/morph/morph-bounds.d.ts.map +0 -1
- package/dist/features/scene-temporal.d.ts +0 -45
- package/dist/features/scene-temporal.d.ts.map +0 -1
- package/dist/features/taa-resolve.d.ts +0 -21
- package/dist/features/taa-resolve.d.ts.map +0 -1
- package/dist/frame-chain.d.ts +0 -14
- package/dist/frame-chain.d.ts.map +0 -1
- package/dist/gpu-driven/view-reference.d.ts.map +0 -1
- package/dist/gpu-resource-store.d.ts.map +0 -1
- package/dist/hdrp-cluster-membership.d.ts +0 -2
- package/dist/hdrp-cluster-membership.d.ts.map +0 -1
- package/dist/hdrp-pipeline.d.ts +0 -36
- package/dist/hdrp-pipeline.d.ts.map +0 -1
- package/dist/ibl/cubemap-projection.d.ts +0 -23
- package/dist/ibl/cubemap-projection.d.ts.map +0 -1
- package/dist/ibl/face-uniforms.d.ts +0 -65
- package/dist/ibl/face-uniforms.d.ts.map +0 -1
- package/dist/mesh-update-errors.d.ts +0 -71
- package/dist/mesh-update-errors.d.ts.map +0 -1
- package/dist/mipmap-generator.d.ts +0 -39
- package/dist/mipmap-generator.d.ts.map +0 -1
- package/dist/param-schema-projection-census.d.ts +0 -18
- package/dist/param-schema-projection-census.d.ts.map +0 -1
- package/dist/persistent-render-scene.d.ts +0 -158
- package/dist/persistent-render-scene.d.ts.map +0 -1
- package/dist/pipeline/index.d.ts +0 -11
- package/dist/pipeline/index.d.ts.map +0 -1
- package/dist/pipeline-errors.d.ts +0 -110
- package/dist/pipeline-errors.d.ts.map +0 -1
- package/dist/prepare/__tests__/schema-readers.unit.test.d.ts +0 -2
- package/dist/prepare/__tests__/schema-readers.unit.test.d.ts.map +0 -1
- package/dist/prepare/index.d.ts +0 -4
- package/dist/prepare/index.d.ts.map +0 -1
- package/dist/prepare/schema-readers.d.ts +0 -11
- package/dist/prepare/schema-readers.d.ts.map +0 -1
- package/dist/record/__tests__/environment-record.test.d.ts +0 -2
- package/dist/record/__tests__/environment-record.test.d.ts.map +0 -1
- package/dist/record/__tests__/frame-targets.unit.test.d.ts +0 -2
- package/dist/record/__tests__/frame-targets.unit.test.d.ts.map +0 -1
- package/dist/record/__tests__/membership-timing.unit.test.d.ts +0 -2
- package/dist/record/__tests__/membership-timing.unit.test.d.ts.map +0 -1
- package/dist/record/__tests__/render-submission.integration.test.d.ts +0 -2
- package/dist/record/__tests__/render-submission.integration.test.d.ts.map +0 -1
- package/dist/record/__tests__/render-submission.perf.test.d.ts +0 -2
- package/dist/record/__tests__/render-submission.perf.test.d.ts.map +0 -1
- package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts +0 -2
- package/dist/record/__tests__/shadow-submit-mode.unit.test.d.ts.map +0 -1
- package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts +0 -2
- package/dist/record/__tests__/view-ubo-layout.unit.test.d.ts.map +0 -1
- package/dist/record/frame-observation.d.ts +0 -38
- package/dist/record/frame-observation.d.ts.map +0 -1
- package/dist/record/index.d.ts +0 -15
- package/dist/record/index.d.ts.map +0 -1
- package/dist/record/main-pass-skin.d.ts +0 -46
- package/dist/record/main-pass-skin.d.ts.map +0 -1
- package/dist/record/main-pass-sprite.d.ts +0 -69
- package/dist/record/main-pass-sprite.d.ts.map +0 -1
- package/dist/record/material-payload.d.ts +0 -43
- package/dist/record/material-payload.d.ts.map +0 -1
- package/dist/record/material-slot-plan.d.ts +0 -26
- package/dist/record/material-slot-plan.d.ts.map +0 -1
- package/dist/record/membership-timing.d.ts +0 -232
- package/dist/record/membership-timing.d.ts.map +0 -1
- package/dist/record/shadow-caster-uniform.d.ts +0 -8
- package/dist/record/shadow-caster-uniform.d.ts.map +0 -1
- package/dist/record/shadow-submit-mode.d.ts +0 -66
- package/dist/record/shadow-submit-mode.d.ts.map +0 -1
- package/dist/render-dispatch-membership.d.ts +0 -47
- package/dist/render-dispatch-membership.d.ts.map +0 -1
- package/dist/render-pipeline-context.d.ts +0 -289
- package/dist/render-pipeline-context.d.ts.map +0 -1
- package/dist/render-pipeline-target.d.ts +0 -16
- package/dist/render-pipeline-target.d.ts.map +0 -1
- package/dist/render-scene-projection.d.ts +0 -174
- package/dist/render-scene-projection.d.ts.map +0 -1
- package/dist/render-system-fold.d.ts +0 -266
- package/dist/render-system-fold.d.ts.map +0 -1
- package/dist/renderer/asset-service.d.ts +0 -10
- package/dist/renderer/asset-service.d.ts.map +0 -1
- package/dist/renderer/backend-selection.d.ts.map +0 -1
- package/dist/renderer/environment-classify.d.ts +0 -6
- package/dist/renderer/environment-classify.d.ts.map +0 -1
- package/dist/renderer/environment-error.d.ts +0 -13
- package/dist/renderer/environment-error.d.ts.map +0 -1
- package/dist/renderer/material/pipeline-projection.d.ts +0 -91
- package/dist/renderer/material/pipeline-projection.d.ts.map +0 -1
- package/dist/renderer/renderer-factory.d.ts +0 -289
- package/dist/renderer/renderer-factory.d.ts.map +0 -1
- package/dist/renderer.d.ts +0 -771
- package/dist/renderer.d.ts.map +0 -1
- package/dist/scene-utils/collect-subtree.d.ts +0 -11
- package/dist/scene-utils/collect-subtree.d.ts.map +0 -1
- package/dist/ssao-data.d.ts +0 -34
- package/dist/ssao-data.d.ts.map +0 -1
- package/dist/surface-format.d.ts +0 -10
- package/dist/surface-format.d.ts.map +0 -1
- package/dist/taa-history-store.d.ts +0 -88
- package/dist/taa-history-store.d.ts.map +0 -1
- package/dist/temporal-coverage.d.ts +0 -35
- package/dist/temporal-coverage.d.ts.map +0 -1
- package/dist/temporal-frame-transaction.d.ts +0 -92
- package/dist/temporal-frame-transaction.d.ts.map +0 -1
- package/dist/temporal-inspection.d.ts +0 -57
- package/dist/temporal-inspection.d.ts.map +0 -1
- package/dist/temporal-view.d.ts +0 -43
- package/dist/temporal-view.d.ts.map +0 -1
- package/dist/tilemap/resolve-tileset-runtime.d.ts +0 -23
- package/dist/tilemap/resolve-tileset-runtime.d.ts.map +0 -1
- package/dist/urp-pipeline.d.ts +0 -4
- package/dist/urp-pipeline.d.ts.map +0 -1
- package/src/__tests__/analytic-sky-contract.test.ts +0 -27
- package/src/__tests__/analytic-sky-falsify-carriers.mjs +0 -43
- package/src/__tests__/analytic-sky-falsify.test.ts +0 -94
- package/src/__tests__/assets-runtime-handoff.integration.test.ts +0 -36
- package/src/__tests__/backend-selection.integration.test.ts +0 -11
- package/src/__tests__/camera-temporal.test-d.ts +0 -8
- package/src/__tests__/camera-temporal.test.ts +0 -188
- package/src/__tests__/directional-shadow-probe-atlas-layout.unit.test.ts +0 -18
- package/src/__tests__/environment-inspection.test.ts +0 -45
- package/src/__tests__/fog-ai-user.fixture.ts +0 -350
- package/src/__tests__/fog-custom-render-feature.fixture.ts +0 -33
- package/src/__tests__/fog-custom-render-feature.integration.test.ts +0 -76
- package/src/__tests__/fog-inspection.integration.test.ts +0 -127
- package/src/__tests__/fog-owner-state.integration.test.ts +0 -112
- package/src/__tests__/fog-pipeline-topology.integration.test.ts +0 -93
- package/src/__tests__/fog-public-surface.integration.test.ts +0 -60
- package/src/__tests__/fog-ray-contract.integration.test.ts +0 -73
- package/src/__tests__/fog-source-absence.integration.test.ts +0 -51
- package/src/__tests__/fog-temporal.integration.test.ts +0 -115
- package/src/__tests__/frame-chain.unit.test.ts +0 -26
- package/src/__tests__/gpu-scene-field-type-owner.test-d.ts +0 -27
- package/src/__tests__/hdrp-pipeline.unit.test.ts +0 -100
- package/src/__tests__/ibl/ibl-fallback.unit.test.ts +0 -23
- package/src/__tests__/material-derived-error-stop-draw.integration.test.ts +0 -69
- package/src/__tests__/material-derived-payload.integration.test.ts +0 -164
- package/src/__tests__/materials.unit.test.ts +0 -25
- package/src/__tests__/param-schema-projection-census.unit.test.ts +0 -40
- package/src/__tests__/persistent-render-scene.unit.test.ts +0 -1311
- package/src/__tests__/pipeline-error-policy-owner.unit.test.ts +0 -167
- package/src/__tests__/pipeline-pass-trace.test.ts +0 -92
- package/src/__tests__/pipeline-stage-owner.test-d.ts +0 -13
- package/src/__tests__/plugin.test.ts +0 -25
- package/src/__tests__/prepared-graphics-backend-matrix.unit.test.ts +0 -129
- package/src/__tests__/prepared-graphics-resolver-recording.unit.test.ts +0 -180
- package/src/__tests__/public-pipeline-id.test-d.ts +0 -6
- package/src/__tests__/render-dispatch-membership.unit.test.ts +0 -117
- package/src/__tests__/render-feature-construction.unit.test.ts +0 -124
- package/src/__tests__/render-feature-error-code-owner.test-d.ts +0 -27
- package/src/__tests__/render-feature-gpu-buffer-usage-owner.test-d.ts +0 -46
- package/src/__tests__/render-feature-graph.integration.test.ts +0 -205
- package/src/__tests__/render-feature-graphics-staging.unit.test.ts +0 -200
- package/src/__tests__/render-feature-order.unit.test.ts +0 -66
- package/src/__tests__/render-feature-prepared-graphics-recording.unit.test.ts +0 -107
- package/src/__tests__/render-feature-staging.unit.test.ts +0 -94
- package/src/__tests__/renderer-render-scene-public.test-d.ts +0 -27
- package/src/__tests__/scene-temporal-coverage.unit.test.ts +0 -259
- package/src/__tests__/sun-snapshot-consumers.test.ts +0 -35
- package/src/__tests__/surface-backend-kind-owner.test-d.ts +0 -42
- package/src/__tests__/taa-history-store.unit.test.ts +0 -196
- package/src/__tests__/temporal-frame-transaction.integration.test.ts +0 -537
- package/src/__tests__/temporal-inspection.unit.test.ts +0 -138
- package/src/assets/__tests__/asset-decoders.unit.test.ts +0 -92
- package/src/assets/__tests__/mipmap-generator.unit.test.ts +0 -52
- package/src/assets/__tests__/render-asset-port.unit.test.ts +0 -54
- package/src/assets/__tests__/resolve-render-asset.unit.test.ts +0 -47
- package/src/components/__tests__/atmosphere-red.test.ts +0 -51
- package/src/components/__tests__/atmosphere.test.ts +0 -79
- package/src/components/__tests__/fog.test-d.ts +0 -49
- package/src/components/__tests__/fog.test.ts +0 -60
- package/src/components/atmosphere.ts +0 -64
- package/src/deferred-lighting.ts +0 -92
- package/src/dynamic-texture-store.ts +0 -111
- package/src/environment/README.md +0 -76
- package/src/environment/__tests__/failure-injection.test.ts +0 -50
- package/src/environment/__tests__/generation-red.test.ts +0 -64
- package/src/environment/__tests__/generation.test.ts +0 -37
- package/src/environment/__tests__/graph-transaction.test.ts +0 -85
- package/src/environment/__tests__/inspection-red.test.ts +0 -53
- package/src/environment/__tests__/lifecycle-evidence.test.ts +0 -40
- package/src/environment/__tests__/pipeline-topology.test.ts +0 -33
- package/src/environment/__tests__/readiness.test.ts +0 -42
- package/src/environment/__tests__/recovery.test.ts +0 -62
- package/src/environment/__tests__/resize-dispose.test.ts +0 -30
- package/src/environment/__tests__/signature-red.test.ts +0 -45
- package/src/environment/__tests__/signature.test.ts +0 -60
- package/src/environment/descriptors.ts +0 -7
- package/src/environment/extracted-environment.ts +0 -239
- package/src/environment/generation.ts +0 -158
- package/src/environment/gpu-bundle.ts +0 -144
- package/src/environment/graph.ts +0 -588
- package/src/environment/inspection.ts +0 -107
- package/src/environment/lifecycle.ts +0 -124
- package/src/environment/readiness.ts +0 -76
- package/src/environment/signature.ts +0 -185
- package/src/extract/__tests__/directional-csm-domain.unit.test.ts +0 -391
- package/src/extract/__tests__/environment-source.test.ts +0 -105
- package/src/extract/__tests__/schema-readers.unit.test.ts +0 -16
- package/src/extract/directional-csm.ts +0 -959
- package/src/extract/index.ts +0 -10
- package/src/extract/material-interface.ts +0 -604
- package/src/extract/schema-readers.ts +0 -27
- package/src/features/graph-contribution.ts +0 -577
- package/src/features/index.ts +0 -100
- package/src/features/morph/index.ts +0 -24
- package/src/features/morph/morph-bounds.ts +0 -123
- package/src/features/scene-temporal.ts +0 -274
- package/src/features/taa-resolve.ts +0 -244
- package/src/frame-chain.ts +0 -21
- package/src/hdrp-cluster-membership.ts +0 -70
- package/src/ibl/cubemap-projection.ts +0 -60
- package/src/ibl/face-uniforms.ts +0 -150
- package/src/mesh-update-errors.ts +0 -113
- package/src/mipmap-generator.ts +0 -244
- package/src/param-schema-projection-census.ts +0 -73
- package/src/persistent-render-scene.ts +0 -1752
- package/src/pipeline/index.ts +0 -40
- package/src/pipeline-errors.ts +0 -172
- package/src/prepare/__tests__/schema-readers.unit.test.ts +0 -16
- package/src/prepare/index.ts +0 -8
- package/src/prepare/schema-readers.ts +0 -20
- package/src/record/__tests__/environment-record.test.ts +0 -35
- package/src/record/__tests__/frame-targets.unit.test.ts +0 -54
- package/src/record/__tests__/membership-timing.unit.test.ts +0 -524
- package/src/record/__tests__/render-submission.integration.test.ts +0 -76
- package/src/record/__tests__/render-submission.perf.test.ts +0 -141
- package/src/record/__tests__/shadow-submit-mode.unit.test.ts +0 -88
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +0 -101
- package/src/record/frame-observation.ts +0 -122
- package/src/record/index.ts +0 -15
- package/src/record/main-pass-skin.ts +0 -51
- package/src/record/main-pass-sprite.ts +0 -166
- package/src/record/material-payload.ts +0 -292
- package/src/record/material-slot-plan.ts +0 -68
- package/src/record/membership-timing.ts +0 -1012
- package/src/record/shadow-caster-uniform.ts +0 -37
- package/src/record/shadow-submit-mode.ts +0 -277
- package/src/render-dispatch-membership.ts +0 -155
- package/src/render-pipeline-context.ts +0 -332
- package/src/render-pipeline-target.ts +0 -96
- package/src/render-scene-projection.ts +0 -1738
- package/src/render-system-fold.ts +0 -531
- package/src/renderer/asset-service.ts +0 -32
- package/src/renderer/backend-selection.ts +0 -121
- package/src/renderer/environment-classify.ts +0 -30
- package/src/renderer/environment-error.ts +0 -19
- package/src/renderer/material/pipeline-projection.ts +0 -140
- package/src/renderer.ts +0 -940
- package/src/scene-utils/collect-subtree.ts +0 -40
- package/src/ssao-data.ts +0 -106
- package/src/surface-format.ts +0 -37
- package/src/taa-history-store.ts +0 -429
- package/src/temporal-coverage.ts +0 -106
- package/src/temporal-frame-transaction.ts +0 -301
- package/src/temporal-inspection.ts +0 -194
- package/src/temporal-view.ts +0 -174
- package/src/tilemap/resolve-tileset-runtime.ts +0 -72
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
// IblPipelineCache.ts --
|
|
1
|
+
// IblPipelineCache.ts -- DeviceScope-generation cache for IBL precompute.
|
|
2
2
|
//
|
|
3
3
|
// Plan-strategy D-1/D-7: cache for 4 GPU passes (equirect->cube /
|
|
4
4
|
// irradiance / prefilter / BRDF LUT). M2 provides the cache skeleton;
|
|
5
5
|
// M3 (t18/t20) wires real shader math from ibl.wgsl.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
7
|
+
// The cache is keyed by the renderer-owned DeviceScope generation. Raw device
|
|
8
|
+
// handles are inputs to pipeline creation, never cache or lifecycle owners.
|
|
9
9
|
//
|
|
10
10
|
// Public surface (M3):
|
|
11
|
-
// - getOrCreateIblCache(
|
|
11
|
+
// - getOrCreateIblCache(scope): get or initialize the generation cache
|
|
12
12
|
// - iblCacheSize(): introspection hook
|
|
13
|
-
// - hasIblCache(
|
|
13
|
+
// - hasIblCache(scope): introspection hook
|
|
14
14
|
// - setIblWgslSource(source): set the ibl.wgsl WGSL source string
|
|
15
15
|
// - createIblShaderModules(device, factory): create shader modules from ibl.wgsl
|
|
16
|
-
// - createIblPipelines(device, factory, modules): create 4 render pipelines
|
|
16
|
+
// - createIblPipelines(scope, device, factory, modules): create 4 render pipelines
|
|
17
17
|
// - runIblPrecompute(opts): execute 4 GPU precompute passes (M3 t20)
|
|
18
18
|
//
|
|
19
19
|
// M3 t20: pipeline slots are filled with real render pipelines loaded from
|
|
@@ -21,86 +21,111 @@
|
|
|
21
21
|
// executed in the standard order (equirect->cube -> irradiance -> prefilter
|
|
22
22
|
// -> BRDF LUT), with counters set post-execution per AC-04/05/06.
|
|
23
23
|
|
|
24
|
-
// ───
|
|
24
|
+
// ─── RHI-owned handles ───────────────────────────────────────────────────────
|
|
25
25
|
|
|
26
|
+
import {
|
|
27
|
+
type BindGroup,
|
|
28
|
+
type BindGroupLayout,
|
|
29
|
+
type Buffer,
|
|
30
|
+
type CommandBuffer,
|
|
31
|
+
err,
|
|
32
|
+
ok,
|
|
33
|
+
type RenderPipeline,
|
|
34
|
+
type Result,
|
|
35
|
+
type RhiCommandEncoder,
|
|
36
|
+
type RhiDevice,
|
|
37
|
+
type RhiError,
|
|
38
|
+
type RhiRenderPassEncoder,
|
|
39
|
+
type Sampler,
|
|
40
|
+
type ShaderModule,
|
|
41
|
+
type Texture,
|
|
42
|
+
type TextureFormat,
|
|
43
|
+
type TextureView,
|
|
44
|
+
} from '@forgeax/engine-rhi';
|
|
45
|
+
import type { DeviceScope } from '../device/device-scope';
|
|
26
46
|
import { GPU_SHADER_STAGE_FRAGMENT, GPU_SHADER_STAGE_VERTEX } from '../gpu-stage';
|
|
27
47
|
import {
|
|
28
48
|
GPU_TEXTURE_USAGE_COPY_DST,
|
|
29
49
|
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
30
50
|
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING,
|
|
31
51
|
} from '../gpu-texture-usage';
|
|
32
|
-
import { cubemapCaptureProjection } from './cubemap-projection';
|
|
33
52
|
|
|
34
53
|
/**
|
|
35
54
|
* Shader module factory (async, injected via configureGpuDevice).
|
|
36
55
|
* Mirrors `MipmapShaderModuleFactory` from mipmap-generator.
|
|
37
56
|
*/
|
|
57
|
+
/**
|
|
58
|
+
* IBL is assembled by the renderer's device owner, so it consumes the full
|
|
59
|
+
* opaque RHI device rather than a structurally-compatible raw/shim split.
|
|
60
|
+
* Keeping the owner as RhiDevice makes the backend boundary explicit: raw
|
|
61
|
+
* GPU handles can only exist inside an RHI implementation or a test readback.
|
|
62
|
+
*/
|
|
63
|
+
export type IblRhiOwner = RhiDevice;
|
|
64
|
+
|
|
38
65
|
export type IblShaderModuleFactory = (
|
|
39
|
-
device:
|
|
66
|
+
device: IblRhiOwner,
|
|
40
67
|
desc: { code: string; label?: string },
|
|
41
|
-
) => Promise<
|
|
68
|
+
) => Promise<Result<ShaderModule, RhiError>>;
|
|
69
|
+
|
|
70
|
+
export interface IblPipelineSet {
|
|
71
|
+
readonly equirectToCubePipeline: RenderPipeline;
|
|
72
|
+
readonly irradiancePipeline: RenderPipeline;
|
|
73
|
+
readonly prefilterPipeline: RenderPipeline;
|
|
74
|
+
readonly brdfLutPipeline: RenderPipeline;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface IblPipelineError {
|
|
78
|
+
readonly code: 'ibl-pipeline-create-failed' | 'ibl-shader-module-missing';
|
|
79
|
+
readonly expected: string;
|
|
80
|
+
readonly hint: string;
|
|
81
|
+
readonly detail: { readonly stage: string; readonly rhiCode?: RhiError['code'] };
|
|
82
|
+
}
|
|
42
83
|
|
|
43
84
|
/**
|
|
44
|
-
* Per-
|
|
85
|
+
* Per-DeviceScope-generation IBL pipeline cache instance.
|
|
45
86
|
*
|
|
46
87
|
* M3.5 (round-2 t52): the 4 pipeline slots are mutable so createIblPipelines
|
|
47
88
|
* can fill them after construction. The 4 textures + their views are also
|
|
48
89
|
* cached here so runIblPrecompute targets are stable across calls
|
|
49
90
|
* (idempotent).
|
|
50
91
|
*/
|
|
51
|
-
export interface
|
|
92
|
+
export interface IblPipelineCache {
|
|
52
93
|
/** Color format shared by all precompute outputs for this device. */
|
|
53
|
-
outputFormat?:
|
|
94
|
+
outputFormat?: TextureFormat;
|
|
54
95
|
/** Equirectangular-to-cubemap pipeline. */
|
|
55
|
-
|
|
56
|
-
equirectToCubePipeline?: any;
|
|
96
|
+
equirectToCubePipeline?: RenderPipeline;
|
|
57
97
|
/** Diffuse irradiance convolution pipeline. */
|
|
58
|
-
|
|
59
|
-
irradiancePipeline?: any;
|
|
98
|
+
irradiancePipeline?: RenderPipeline;
|
|
60
99
|
/** Specular prefilter pipeline. */
|
|
61
|
-
|
|
62
|
-
prefilterPipeline?: any;
|
|
100
|
+
prefilterPipeline?: RenderPipeline;
|
|
63
101
|
/** BRDF integration LUT pipeline. */
|
|
64
|
-
|
|
65
|
-
brdfLutPipeline?: any;
|
|
102
|
+
brdfLutPipeline?: RenderPipeline;
|
|
66
103
|
|
|
67
104
|
/** Face uniforms BGL (shared across equirect/irradiance/prefilter, D-9). */
|
|
68
|
-
|
|
69
|
-
faceUniformsBgl?: any;
|
|
105
|
+
faceUniformsBgl?: BindGroupLayout;
|
|
70
106
|
/** group(1) BGL for the equirect-to-cube pass (texture_2d + sampler). */
|
|
71
|
-
|
|
72
|
-
equirectGroup1Bgl?: any;
|
|
107
|
+
equirectGroup1Bgl?: BindGroupLayout;
|
|
73
108
|
/** group(1) BGL for irradiance + prefilter (texture_cube + sampler). */
|
|
74
|
-
|
|
75
|
-
cubeGroup1Bgl?: any;
|
|
109
|
+
cubeGroup1Bgl?: BindGroupLayout;
|
|
76
110
|
/** group(0) BGL for prefilter (face + prefilter uniforms). */
|
|
77
|
-
|
|
78
|
-
prefilterGroup0Bgl?: any;
|
|
111
|
+
prefilterGroup0Bgl?: BindGroupLayout;
|
|
79
112
|
|
|
80
113
|
/** Irradiance cubemap texture (32x32; outputFormat, cube). */
|
|
81
|
-
|
|
82
|
-
irradianceTexture?: any;
|
|
114
|
+
irradianceTexture?: Texture;
|
|
83
115
|
/** Irradiance cubemap view (dimension:cube). */
|
|
84
|
-
|
|
85
|
-
irradianceView?: any;
|
|
116
|
+
irradianceView?: TextureView;
|
|
86
117
|
/** Per-face 2D views for irradiance (render-attachment use). */
|
|
87
|
-
|
|
88
|
-
irradianceFaceViews?: ReadonlyArray<any>;
|
|
118
|
+
irradianceFaceViews?: ReadonlyArray<TextureView>;
|
|
89
119
|
/** Specular prefilter cubemap (128x128, 5 mip levels). */
|
|
90
|
-
|
|
91
|
-
prefilterTexture?: any;
|
|
120
|
+
prefilterTexture?: Texture;
|
|
92
121
|
/** Prefilter cubemap view (dimension:cube, all mips). */
|
|
93
|
-
|
|
94
|
-
prefilterView?: any;
|
|
122
|
+
prefilterView?: TextureView;
|
|
95
123
|
/** Per-face 2D views per mip for prefilter (5 mips x 6 faces). */
|
|
96
|
-
|
|
97
|
-
prefilterFaceViewsByMip?: ReadonlyArray<ReadonlyArray<any>>;
|
|
124
|
+
prefilterFaceViewsByMip?: ReadonlyArray<ReadonlyArray<TextureView>>;
|
|
98
125
|
/** BRDF LUT (256x256; outputFormat). */
|
|
99
|
-
|
|
100
|
-
brdfLutTexture?: any;
|
|
126
|
+
brdfLutTexture?: Texture;
|
|
101
127
|
/** BRDF LUT view. */
|
|
102
|
-
|
|
103
|
-
brdfLutView?: any;
|
|
128
|
+
brdfLutView?: TextureView;
|
|
104
129
|
|
|
105
130
|
/** Counter: times irradiance pass has executed. AC-04: == 1 after first cook. */
|
|
106
131
|
irradianceBakeCount: number;
|
|
@@ -111,101 +136,41 @@ export interface IblPipelineCachePerDevice {
|
|
|
111
136
|
}
|
|
112
137
|
|
|
113
138
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
139
|
+
* Cache ownership follows the renderer's DeviceScope generation. A cache is
|
|
140
|
+
* never recovered by looking up an opaque device handle, so every pipeline and
|
|
141
|
+
* side texture is born under the same lifecycle owner as the rest of the
|
|
142
|
+
* renderer resources.
|
|
116
143
|
*/
|
|
117
|
-
const
|
|
144
|
+
const scopeCaches: WeakMap<DeviceScope, IblPipelineCache> = new WeakMap();
|
|
118
145
|
|
|
119
146
|
/**
|
|
120
|
-
* Get or create the
|
|
147
|
+
* Get or create the current-generation IBL pipeline cache.
|
|
121
148
|
*/
|
|
122
|
-
export function getOrCreateIblCache(
|
|
123
|
-
const existing =
|
|
149
|
+
export function getOrCreateIblCache(scope: DeviceScope): IblPipelineCache {
|
|
150
|
+
const existing = scopeCaches.get(scope);
|
|
124
151
|
if (existing !== undefined) return existing;
|
|
125
152
|
|
|
126
|
-
const cache:
|
|
153
|
+
const cache: IblPipelineCache = {
|
|
127
154
|
irradianceBakeCount: 0,
|
|
128
155
|
prefilterBakeCount: 0,
|
|
129
156
|
brdfLutBakeCount: 0,
|
|
130
157
|
};
|
|
131
|
-
|
|
158
|
+
scopeCaches.set(scope, cache);
|
|
132
159
|
return cache;
|
|
133
160
|
}
|
|
134
161
|
|
|
135
162
|
/**
|
|
136
|
-
*
|
|
137
|
-
*/
|
|
138
|
-
export function iblCacheSize(): number {
|
|
139
|
-
// WeakMap doesn't expose size; approximate by iteration.
|
|
140
|
-
let count = 0;
|
|
141
|
-
try {
|
|
142
|
-
// biome-ignore lint/suspicious/noExplicitAny: WeakMap iteration hack
|
|
143
|
-
for (const _ of deviceCache as any) {
|
|
144
|
-
count++;
|
|
145
|
-
}
|
|
146
|
-
} catch {
|
|
147
|
-
// WeakMap is not iterable; this is expected.
|
|
148
|
-
}
|
|
149
|
-
return count;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Check whether a device has an active cache entry (introspection for tests).
|
|
154
|
-
*/
|
|
155
|
-
export function hasIblCache(device: object): boolean {
|
|
156
|
-
return deviceCache.has(device);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Clear the per-device cache entry for the given device, if any.
|
|
161
|
-
*
|
|
162
|
-
* feat-20260612-rhi-destroy-renderer-dispose-gpu-lifecycle / M5: called from
|
|
163
|
-
* `Renderer.dispose()` step 4 (plan-strategy D-2 6-step walk) so the IBL
|
|
164
|
-
* pipelines / textures attached to a torn-down device do not survive in the
|
|
165
|
-
* runtime cache. The underlying GPU pipeline / texture handles are not
|
|
166
|
-
* separately destroyed here -- they were created on the same RhiDevice the
|
|
167
|
-
* dispose chain is about to release at step 5 (`context.unconfigure`); the
|
|
168
|
-
* spec contract is that releasing the device tears down its child pipelines
|
|
169
|
-
* implicitly. Clearing the WeakMap entry simply lets GC reclaim the JS-side
|
|
170
|
-
* cache record.
|
|
171
|
-
*
|
|
172
|
-
* Idempotent (architecture-principles §6): a second call after the entry
|
|
173
|
-
* was deleted is a no-op.
|
|
174
|
-
*/
|
|
175
|
-
export function clearIblCacheForDevice(device: object): void {
|
|
176
|
-
deviceCache.delete(device);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// ─── IBL WGSL source management ──────────────────────────────────────────────
|
|
180
|
-
|
|
181
|
-
let iblWgslSourceCache: string | undefined;
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Set the ibl.wgsl source string. Called once by the consumer
|
|
185
|
-
* (e.g., AssetRegistry) when the shader module source is loaded.
|
|
163
|
+
* Check whether a DeviceScope generation has an active cache entry.
|
|
186
164
|
*/
|
|
187
|
-
export function
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Get the cached ibl.wgsl source string.
|
|
193
|
-
* Throws if not yet loaded.
|
|
194
|
-
*/
|
|
195
|
-
export function getIblWgslSource(): string {
|
|
196
|
-
if (iblWgslSourceCache === undefined) {
|
|
197
|
-
throw new Error(
|
|
198
|
-
'ibl.wgsl source not loaded -- call setIblWgslSource before using IBL pipelines',
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
return iblWgslSourceCache;
|
|
165
|
+
export function hasIblCache(scope: DeviceScope): boolean {
|
|
166
|
+
return scopeCaches.has(scope);
|
|
202
167
|
}
|
|
203
168
|
|
|
204
169
|
// ─── M3.5 composed ibl-* shader source registry ─────────────────────────────
|
|
205
170
|
//
|
|
206
171
|
// 4 composed WGSL strings -- one per render pipeline. Each string is the
|
|
207
172
|
// output of @forgeax/engine-naga composeShader after merging ibl_shared +
|
|
208
|
-
// the per-pass module. Built by
|
|
173
|
+
// the per-pass module. Built by ShaderCatalog / vite-plugin-shader at
|
|
209
174
|
// build-time so the runtime cache never reaches into engine-naga
|
|
210
175
|
// (AGENTS.md grep gate forbids).
|
|
211
176
|
|
|
@@ -225,22 +190,12 @@ let iblComposedShadersCache: IblComposedShaders | undefined;
|
|
|
225
190
|
/**
|
|
226
191
|
* Inject the composed ibl-* shader sources used by createIblPipelines.
|
|
227
192
|
* Called once by the engine bootstrap (createRenderer step "shader-load")
|
|
228
|
-
* with the 4 composed entries from
|
|
193
|
+
* with the 4 composed entries from ShaderCatalog.
|
|
229
194
|
*/
|
|
230
195
|
export function setIblComposedShaders(sources: IblComposedShaders): void {
|
|
231
196
|
iblComposedShadersCache = sources;
|
|
232
197
|
}
|
|
233
198
|
|
|
234
|
-
/**
|
|
235
|
-
* Retrieve the cached composed shader bundle.
|
|
236
|
-
* Returns undefined when the runtime is operating without a real shader
|
|
237
|
-
* source (mock device unit tests that exercise pipeline dispatch surface
|
|
238
|
-
* only).
|
|
239
|
-
*/
|
|
240
|
-
export function getIblComposedShaders(): IblComposedShaders | undefined {
|
|
241
|
-
return iblComposedShadersCache;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
199
|
// ─── Standard cube vertices for cubemap face rendering ───────────────────────
|
|
245
200
|
// 36 vertices (6 faces * 2 triangles * 3 vertices), vec3<f32> format.
|
|
246
201
|
// Unit cube [-1, 1]^3 centered at origin.
|
|
@@ -296,6 +251,18 @@ function buildCaptureViewProjs(): Float32Array[] {
|
|
|
296
251
|
});
|
|
297
252
|
}
|
|
298
253
|
|
|
254
|
+
function cubemapCaptureProjection(fovy: number, near: number, far: number): Float32Array {
|
|
255
|
+
const f = 1.0 / Math.tan(fovy / 2);
|
|
256
|
+
const nf = 1.0 / (near - far);
|
|
257
|
+
// biome-ignore format: manual column-major mat4
|
|
258
|
+
return new Float32Array([
|
|
259
|
+
f, 0, 0, 0,
|
|
260
|
+
0, -f, 0, 0,
|
|
261
|
+
0, 0, (far + near) * nf, -1,
|
|
262
|
+
0, 0, 2 * far * near * nf, 0,
|
|
263
|
+
]);
|
|
264
|
+
}
|
|
265
|
+
|
|
299
266
|
function lookAtMatrix(
|
|
300
267
|
eye: readonly number[],
|
|
301
268
|
target: readonly number[],
|
|
@@ -379,43 +346,6 @@ export const PREFILTER_SIZE = 128;
|
|
|
379
346
|
export const PREFILTER_MIP_LEVELS = 5;
|
|
380
347
|
export const BRDF_LUT_SIZE = 256;
|
|
381
348
|
|
|
382
|
-
/**
|
|
383
|
-
* Minimal device shape used by createIblPipelines + runIblPrecompute. The
|
|
384
|
-
* surface is intentionally narrow so unit-level mock devices can exercise
|
|
385
|
-
* the dispatch path without standing up the full RHI shim.
|
|
386
|
-
*/
|
|
387
|
-
export interface IblPipelineDevice {
|
|
388
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
389
|
-
createBindGroupLayout(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
|
|
390
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
391
|
-
createPipelineLayout(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
|
|
392
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
393
|
-
createRenderPipeline(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
|
|
394
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
395
|
-
createBuffer(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
|
|
396
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
397
|
-
createTexture(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
|
|
398
|
-
createTextureView(
|
|
399
|
-
// biome-ignore lint/suspicious/noExplicitAny: opaque GPU texture
|
|
400
|
-
texture: any,
|
|
401
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
402
|
-
desc: any,
|
|
403
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
404
|
-
): { ok: true; value: any } | { ok: false; error: unknown };
|
|
405
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
406
|
-
createSampler(desc?: any): { ok: true; value: any } | { ok: false; error: unknown };
|
|
407
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
408
|
-
createBindGroup(desc: any): { ok: true; value: any } | { ok: false; error: unknown };
|
|
409
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
410
|
-
createCommandEncoder(desc?: any): { ok: true; value: any } | { ok: false; error: unknown };
|
|
411
|
-
readonly queue: {
|
|
412
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
413
|
-
submit(buffers: ReadonlyArray<any>): unknown;
|
|
414
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim shapes
|
|
415
|
-
writeBuffer?: (...args: any[]) => unknown;
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
|
|
419
349
|
/**
|
|
420
350
|
* Create 4 independent GPURenderPipelines + their shared / per-pass bind
|
|
421
351
|
* group layouts. Pipeline slots are stored on the per-device cache and
|
|
@@ -427,37 +357,24 @@ export interface IblPipelineDevice {
|
|
|
427
357
|
* irradiance + prefilter, none for brdf-lut.
|
|
428
358
|
*/
|
|
429
359
|
export async function createIblPipelines(
|
|
430
|
-
|
|
360
|
+
scope: DeviceScope,
|
|
361
|
+
device: IblRhiOwner,
|
|
431
362
|
factory: IblShaderModuleFactory,
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
)
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
448
|
-
| { ok: false; error: unknown }
|
|
449
|
-
> {
|
|
450
|
-
const cache = getOrCreateIblCache(device);
|
|
451
|
-
if (cache.equirectToCubePipeline !== undefined) {
|
|
452
|
-
return {
|
|
453
|
-
ok: true,
|
|
454
|
-
value: {
|
|
455
|
-
equirectToCubePipeline: cache.equirectToCubePipeline,
|
|
456
|
-
irradiancePipeline: cache.irradiancePipeline,
|
|
457
|
-
prefilterPipeline: cache.prefilterPipeline,
|
|
458
|
-
brdfLutPipeline: cache.brdfLutPipeline,
|
|
459
|
-
},
|
|
460
|
-
};
|
|
363
|
+
cubeOutputFormat: TextureFormat = 'rgba16float',
|
|
364
|
+
): Promise<Result<IblPipelineSet, RhiError | IblPipelineError>> {
|
|
365
|
+
const cache = getOrCreateIblCache(scope);
|
|
366
|
+
if (
|
|
367
|
+
cache.equirectToCubePipeline !== undefined &&
|
|
368
|
+
cache.irradiancePipeline !== undefined &&
|
|
369
|
+
cache.prefilterPipeline !== undefined &&
|
|
370
|
+
cache.brdfLutPipeline !== undefined
|
|
371
|
+
) {
|
|
372
|
+
return ok({
|
|
373
|
+
equirectToCubePipeline: cache.equirectToCubePipeline,
|
|
374
|
+
irradiancePipeline: cache.irradiancePipeline,
|
|
375
|
+
prefilterPipeline: cache.prefilterPipeline,
|
|
376
|
+
brdfLutPipeline: cache.brdfLutPipeline,
|
|
377
|
+
});
|
|
461
378
|
}
|
|
462
379
|
// Keep the output format on the per-device cache so the four pipelines and
|
|
463
380
|
// their lazily-created side textures cannot drift. WebGL2 may need the
|
|
@@ -476,16 +393,6 @@ export async function createIblPipelines(
|
|
|
476
393
|
brdfLut: fallbackCode,
|
|
477
394
|
};
|
|
478
395
|
|
|
479
|
-
// M5-amend Bug 1: normalise shim/raw return shapes. See runIblPrecompute
|
|
480
|
-
// for full rationale -- same helper applied across both functions so
|
|
481
|
-
// dawn-node (raw GPUDevice) + browser (rhi-shim) both succeed.
|
|
482
|
-
// biome-ignore lint/suspicious/noExplicitAny: union of shim/raw return shapes
|
|
483
|
-
const unwrap = (r: any): any => {
|
|
484
|
-
if (r === null || r === undefined) return undefined;
|
|
485
|
-
if (typeof r === 'object' && 'ok' in r) return r.ok ? r.value : undefined;
|
|
486
|
-
return r;
|
|
487
|
-
};
|
|
488
|
-
|
|
489
396
|
const modules = await Promise.all([
|
|
490
397
|
factory(device, { code: src.equirectToCube, label: 'ibl-equirect-to-cube' }),
|
|
491
398
|
factory(device, { code: src.irradiance, label: 'ibl-irradiance' }),
|
|
@@ -493,183 +400,175 @@ export async function createIblPipelines(
|
|
|
493
400
|
factory(device, { code: src.brdfLut, label: 'ibl-brdf-lut' }),
|
|
494
401
|
]);
|
|
495
402
|
for (const m of modules) {
|
|
496
|
-
if (!m.ok) return
|
|
403
|
+
if (!m.ok) return err(m.error);
|
|
404
|
+
}
|
|
405
|
+
const shaderModules = modules.flatMap((module) => (module.ok ? [module.value] : []));
|
|
406
|
+
if (shaderModules.length !== 4) {
|
|
407
|
+
return err(iblPipelineError('shader-modules', 'ibl-shader-module-missing'));
|
|
408
|
+
}
|
|
409
|
+
const [mEq, mIr, mPr, mBr] = shaderModules;
|
|
410
|
+
if (mEq === undefined || mIr === undefined || mPr === undefined || mBr === undefined) {
|
|
411
|
+
return err(iblPipelineError('shader-modules', 'ibl-shader-module-missing'));
|
|
497
412
|
}
|
|
498
|
-
// biome-ignore lint/style/noNonNullAssertion: checked above
|
|
499
|
-
const [mEq, mIr, mPr, mBr] = modules.map((m) => m.value!) as [unknown, unknown, unknown, unknown];
|
|
500
413
|
|
|
501
414
|
// D-9: faceUniforms BGL shared across 3 pipelines (equirect / irradiance /
|
|
502
415
|
// prefilter). The prefilter additionally needs binding(1) for prefUniforms;
|
|
503
416
|
// we keep a separate BGL for the prefilter group(0) to honour the WGSL
|
|
504
417
|
// declaration in ibl-prefilter.wgsl.
|
|
505
|
-
const faceBgl =
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
visibility: GPU_SHADER_STAGE_FRAGMENT,
|
|
558
|
-
sampler: { type: 'filtering' },
|
|
559
|
-
},
|
|
560
|
-
],
|
|
561
|
-
}),
|
|
562
|
-
);
|
|
563
|
-
if (cubeGroup1 === undefined) return { ok: false, error: 'ibl-cube-group1-bgl' };
|
|
564
|
-
cache.cubeGroup1Bgl = cubeGroup1;
|
|
418
|
+
const faceBgl = device.createBindGroupLayout({
|
|
419
|
+
label: 'ibl-face-uniforms-bgl',
|
|
420
|
+
entries: [{ binding: 0, visibility: GPU_SHADER_STAGE_VERTEX, buffer: { type: 'uniform' } }],
|
|
421
|
+
});
|
|
422
|
+
if (!faceBgl.ok) return err(faceBgl.error);
|
|
423
|
+
cache.faceUniformsBgl = faceBgl.value;
|
|
424
|
+
|
|
425
|
+
const prefilterGroup0 = device.createBindGroupLayout({
|
|
426
|
+
label: 'ibl-prefilter-group0-bgl',
|
|
427
|
+
entries: [
|
|
428
|
+
{ binding: 0, visibility: GPU_SHADER_STAGE_VERTEX, buffer: { type: 'uniform' } },
|
|
429
|
+
{ binding: 1, visibility: GPU_SHADER_STAGE_FRAGMENT, buffer: { type: 'uniform' } },
|
|
430
|
+
],
|
|
431
|
+
});
|
|
432
|
+
if (!prefilterGroup0.ok) return err(prefilterGroup0.error);
|
|
433
|
+
cache.prefilterGroup0Bgl = prefilterGroup0.value;
|
|
434
|
+
|
|
435
|
+
const equirectGroup1 = device.createBindGroupLayout({
|
|
436
|
+
label: 'ibl-equirect-group1-bgl',
|
|
437
|
+
entries: [
|
|
438
|
+
{
|
|
439
|
+
binding: 0,
|
|
440
|
+
visibility: GPU_SHADER_STAGE_FRAGMENT,
|
|
441
|
+
texture: { sampleType: 'float', viewDimension: '2d' },
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
binding: 1,
|
|
445
|
+
visibility: GPU_SHADER_STAGE_FRAGMENT,
|
|
446
|
+
sampler: { type: 'filtering' },
|
|
447
|
+
},
|
|
448
|
+
],
|
|
449
|
+
});
|
|
450
|
+
if (!equirectGroup1.ok) return err(equirectGroup1.error);
|
|
451
|
+
cache.equirectGroup1Bgl = equirectGroup1.value;
|
|
452
|
+
|
|
453
|
+
const cubeGroup1 = device.createBindGroupLayout({
|
|
454
|
+
label: 'ibl-cube-group1-bgl',
|
|
455
|
+
entries: [
|
|
456
|
+
{
|
|
457
|
+
binding: 0,
|
|
458
|
+
visibility: GPU_SHADER_STAGE_FRAGMENT,
|
|
459
|
+
texture: { sampleType: 'float', viewDimension: 'cube' },
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
binding: 1,
|
|
463
|
+
visibility: GPU_SHADER_STAGE_FRAGMENT,
|
|
464
|
+
sampler: { type: 'filtering' },
|
|
465
|
+
},
|
|
466
|
+
],
|
|
467
|
+
});
|
|
468
|
+
if (!cubeGroup1.ok) return err(cubeGroup1.error);
|
|
469
|
+
cache.cubeGroup1Bgl = cubeGroup1.value;
|
|
565
470
|
|
|
566
471
|
// Pipeline layouts.
|
|
567
|
-
const equirectLayout =
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
);
|
|
587
|
-
if (prefilterLayout === undefined) return { ok: false, error: 'ibl-prefilter-pipeline-layout' };
|
|
588
|
-
const brdfLutLayout = unwrap(
|
|
589
|
-
device.createPipelineLayout({
|
|
590
|
-
label: 'ibl-brdf-lut-pipeline-layout',
|
|
591
|
-
bindGroupLayouts: [],
|
|
592
|
-
}),
|
|
593
|
-
);
|
|
594
|
-
if (brdfLutLayout === undefined) return { ok: false, error: 'ibl-brdf-lut-pipeline-layout' };
|
|
472
|
+
const equirectLayout = device.createPipelineLayout({
|
|
473
|
+
label: 'ibl-equirect-pipeline-layout',
|
|
474
|
+
bindGroupLayouts: [faceBgl.value, equirectGroup1.value],
|
|
475
|
+
});
|
|
476
|
+
if (!equirectLayout.ok) return err(equirectLayout.error);
|
|
477
|
+
const irradianceLayout = device.createPipelineLayout({
|
|
478
|
+
label: 'ibl-irradiance-pipeline-layout',
|
|
479
|
+
bindGroupLayouts: [faceBgl.value, cubeGroup1.value],
|
|
480
|
+
});
|
|
481
|
+
if (!irradianceLayout.ok) return err(irradianceLayout.error);
|
|
482
|
+
const prefilterLayout = device.createPipelineLayout({
|
|
483
|
+
label: 'ibl-prefilter-pipeline-layout',
|
|
484
|
+
bindGroupLayouts: [prefilterGroup0.value, cubeGroup1.value],
|
|
485
|
+
});
|
|
486
|
+
if (!prefilterLayout.ok) return err(prefilterLayout.error);
|
|
487
|
+
const brdfLutLayout = device.createPipelineLayout({
|
|
488
|
+
label: 'ibl-brdf-lut-pipeline-layout',
|
|
489
|
+
bindGroupLayouts: [],
|
|
490
|
+
});
|
|
491
|
+
if (!brdfLutLayout.ok) return err(brdfLutLayout.error);
|
|
595
492
|
|
|
596
493
|
const vertexLayout3F = {
|
|
597
494
|
arrayStride: 12,
|
|
598
495
|
attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x3' as const }],
|
|
599
496
|
};
|
|
600
497
|
|
|
601
|
-
const pipeEquirect =
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
498
|
+
const pipeEquirect = device.createRenderPipeline({
|
|
499
|
+
label: 'ibl-equirect-to-cube-pipeline',
|
|
500
|
+
layout: equirectLayout.value,
|
|
501
|
+
vertex: { module: mEq, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },
|
|
502
|
+
fragment: {
|
|
503
|
+
module: mEq,
|
|
504
|
+
entryPoint: 'equirectToCube_fs',
|
|
505
|
+
targets: [{ format: cubeOutputFormat }],
|
|
506
|
+
},
|
|
507
|
+
primitive: { topology: 'triangle-list', cullMode: 'none' },
|
|
508
|
+
});
|
|
509
|
+
if (!pipeEquirect.ok) return err(pipeEquirect.error);
|
|
510
|
+
cache.equirectToCubePipeline = pipeEquirect.value;
|
|
511
|
+
|
|
512
|
+
const pipeIrradiance = device.createRenderPipeline({
|
|
513
|
+
label: 'ibl-irradiance-pipeline',
|
|
514
|
+
layout: irradianceLayout.value,
|
|
515
|
+
vertex: { module: mIr, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },
|
|
516
|
+
fragment: {
|
|
517
|
+
module: mIr,
|
|
518
|
+
entryPoint: 'irradianceConvolve_fs',
|
|
519
|
+
targets: [{ format: cubeOutputFormat }],
|
|
520
|
+
},
|
|
521
|
+
primitive: { topology: 'triangle-list', cullMode: 'none' },
|
|
522
|
+
});
|
|
523
|
+
if (!pipeIrradiance.ok) return err(pipeIrradiance.error);
|
|
524
|
+
cache.irradiancePipeline = pipeIrradiance.value;
|
|
525
|
+
|
|
526
|
+
const pipePrefilter = device.createRenderPipeline({
|
|
527
|
+
label: 'ibl-prefilter-pipeline',
|
|
528
|
+
layout: prefilterLayout.value,
|
|
529
|
+
vertex: { module: mPr, entryPoint: 'cubemap_vs', buffers: [vertexLayout3F] },
|
|
530
|
+
fragment: {
|
|
531
|
+
module: mPr,
|
|
532
|
+
entryPoint: 'prefilterEnv_fs',
|
|
533
|
+
targets: [{ format: cubeOutputFormat }],
|
|
534
|
+
},
|
|
535
|
+
primitive: { topology: 'triangle-list', cullMode: 'none' },
|
|
536
|
+
});
|
|
537
|
+
if (!pipePrefilter.ok) return err(pipePrefilter.error);
|
|
538
|
+
cache.prefilterPipeline = pipePrefilter.value;
|
|
539
|
+
|
|
540
|
+
const pipeBrdfLut = device.createRenderPipeline({
|
|
541
|
+
label: 'ibl-brdf-lut-pipeline',
|
|
542
|
+
layout: brdfLutLayout.value,
|
|
543
|
+
vertex: { module: mBr, entryPoint: 'fullscreen_vs', buffers: [] },
|
|
544
|
+
fragment: {
|
|
545
|
+
module: mBr,
|
|
546
|
+
entryPoint: 'brdfLutBake_fs',
|
|
547
|
+
targets: [{ format: cubeOutputFormat }],
|
|
548
|
+
},
|
|
549
|
+
primitive: { topology: 'triangle-list', cullMode: 'none' },
|
|
550
|
+
});
|
|
551
|
+
if (!pipeBrdfLut.ok) return err(pipeBrdfLut.error);
|
|
552
|
+
cache.brdfLutPipeline = pipeBrdfLut.value;
|
|
553
|
+
|
|
554
|
+
return ok({
|
|
555
|
+
equirectToCubePipeline: pipeEquirect.value,
|
|
556
|
+
irradiancePipeline: pipeIrradiance.value,
|
|
557
|
+
prefilterPipeline: pipePrefilter.value,
|
|
558
|
+
brdfLutPipeline: pipeBrdfLut.value,
|
|
559
|
+
});
|
|
560
|
+
}
|
|
664
561
|
|
|
562
|
+
function iblPipelineError(
|
|
563
|
+
stage: string,
|
|
564
|
+
code: IblPipelineError['code'],
|
|
565
|
+
cause?: RhiError,
|
|
566
|
+
): IblPipelineError {
|
|
665
567
|
return {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
prefilterPipeline: cache.prefilterPipeline,
|
|
671
|
-
brdfLutPipeline: cache.brdfLutPipeline,
|
|
672
|
-
},
|
|
568
|
+
code,
|
|
569
|
+
expected: `${stage} completed through the RHI Result contract`,
|
|
570
|
+
hint: `inspect the ${stage} RHI error before retrying IBL pipeline creation`,
|
|
571
|
+
detail: { stage, ...(cause === undefined ? {} : { rhiCode: cause.code }) },
|
|
673
572
|
};
|
|
674
573
|
}
|
|
675
574
|
|
|
@@ -677,28 +576,28 @@ export async function createIblPipelines(
|
|
|
677
576
|
|
|
678
577
|
/**
|
|
679
578
|
* Options consumed by runIblPrecompute. The caller (the internal
|
|
680
|
-
*
|
|
579
|
+
* GpuResidencyCache equirect-to-cubemap projection) provides the equirect input
|
|
681
580
|
* + cubemap target GPU resources; the face-uniform / prefilter-uniform buffers
|
|
682
581
|
* come from the t55 helpers.
|
|
683
582
|
*/
|
|
684
583
|
export interface RunIblPrecomputeOptions {
|
|
685
|
-
readonly
|
|
686
|
-
|
|
687
|
-
readonly equirectGpuTex:
|
|
688
|
-
|
|
689
|
-
readonly
|
|
690
|
-
|
|
691
|
-
readonly
|
|
692
|
-
|
|
693
|
-
readonly
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
readonly
|
|
700
|
-
|
|
701
|
-
readonly
|
|
584
|
+
readonly scope: DeviceScope;
|
|
585
|
+
readonly device: IblRhiOwner;
|
|
586
|
+
readonly equirectGpuTex: Texture;
|
|
587
|
+
readonly equirectView: TextureView;
|
|
588
|
+
readonly cubeGpuTex: Texture;
|
|
589
|
+
readonly cubeView: TextureView;
|
|
590
|
+
readonly cubeFaceViews: ReadonlyArray<TextureView>;
|
|
591
|
+
readonly faceUniformsBuffer: Buffer;
|
|
592
|
+
readonly prefilterUniformsBuffer: Buffer;
|
|
593
|
+
readonly cubeVertexBuffer: Buffer;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
export interface IblPrecomputeError {
|
|
597
|
+
readonly code: 'ibl-precompute-not-dispatched';
|
|
598
|
+
readonly expected: string;
|
|
599
|
+
readonly hint: string;
|
|
600
|
+
readonly detail?: { readonly stage: string; readonly rhiCode?: RhiError['code'] };
|
|
702
601
|
}
|
|
703
602
|
|
|
704
603
|
/**
|
|
@@ -712,107 +611,28 @@ export interface RunIblPrecomputeOptions {
|
|
|
712
611
|
* round-1 "counter += 1 as dispatch proxy" anti-pattern.
|
|
713
612
|
*
|
|
714
613
|
* Returns Result.err with code='ibl-precompute-not-dispatched' when the
|
|
715
|
-
* underlying device lacks queue.submit or
|
|
614
|
+
* underlying device lacks queue.submit or one of the 4 pipelines was not
|
|
716
615
|
* created (createIblPipelines must run first).
|
|
717
616
|
*/
|
|
718
617
|
export function runIblPrecompute(
|
|
719
618
|
opts: RunIblPrecomputeOptions,
|
|
720
|
-
):
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
const { device } = opts;
|
|
724
|
-
const cache = getOrCreateIblCache(device);
|
|
619
|
+
): Result<{ submitted: boolean }, IblPrecomputeError> {
|
|
620
|
+
const { device, scope } = opts;
|
|
621
|
+
const cache = getOrCreateIblCache(scope);
|
|
725
622
|
const outputFormat = cache.outputFormat ?? 'rgba16float';
|
|
726
623
|
|
|
727
|
-
// M5-amend Bug 1: support both rhi-shim path (Result<T, RhiError>) and raw
|
|
728
|
-
// GPUDevice path (returns value directly). The shim returns
|
|
729
|
-
// `{ok, value}`; raw devices return the GPU resource handle directly.
|
|
730
|
-
// Same root cause + remedy as the mesh-upload raw-device fix at
|
|
731
|
-
// uploadMeshById. Without this normalisation, every `device.createXxx(...)`
|
|
732
|
-
// call inside this function bails on `!res.ok` (== !undefined == true)
|
|
733
|
-
// when invoked from dawn-node / native bindings, silently skipping the
|
|
734
|
-
// entire dispatch chain.
|
|
735
|
-
// biome-ignore lint/suspicious/noExplicitAny: union of shim/raw return shapes
|
|
736
|
-
const unwrap = (r: any): any => {
|
|
737
|
-
if (r === null || r === undefined) return undefined;
|
|
738
|
-
if (typeof r === 'object' && 'ok' in r) return r.ok ? r.value : undefined;
|
|
739
|
-
return r;
|
|
740
|
-
};
|
|
741
|
-
|
|
742
|
-
// M5-amend Bug 1: detect raw GPUDevice vs rhi-shim. The shim's
|
|
743
|
-
// `createBindGroup` accepts the forgeax tagged-union resource shape
|
|
744
|
-
// (`{kind: 'buffer', value: {buffer, offset, size}}` etc.); raw
|
|
745
|
-
// GPUDevice strictly requires WebGPU spec shape (`{buffer, offset,
|
|
746
|
-
// size}` directly as `resource` for buffer bindings, raw view/sampler
|
|
747
|
-
// handles directly for the other kinds). Probe by creating a no-op
|
|
748
|
-
// empty BGL: shim wraps in `{ok, value}`; raw returns the BGL handle
|
|
749
|
-
// directly. We discard the probe result; the cache already has BGLs.
|
|
750
|
-
// biome-ignore lint/suspicious/noExplicitAny: probe call
|
|
751
|
-
const probe: any = device.createBindGroupLayout({
|
|
752
|
-
label: 'ibl-shape-probe',
|
|
753
|
-
entries: [],
|
|
754
|
-
});
|
|
755
|
-
const isRawDevice =
|
|
756
|
-
probe === null || probe === undefined || typeof probe !== 'object' || !('ok' in probe);
|
|
757
|
-
|
|
758
|
-
// biome-ignore lint/suspicious/noExplicitAny: spec buffer-binding shape
|
|
759
|
-
type SpecBgEntry = { binding: number; resource: any };
|
|
760
|
-
// biome-ignore lint/suspicious/noExplicitAny: forgeax tagged-union resource
|
|
761
|
-
const toSpecResource = (r: any): any => {
|
|
762
|
-
if (r === null || r === undefined) return r;
|
|
763
|
-
if (typeof r !== 'object' || !('kind' in r)) return r;
|
|
764
|
-
if (r.kind === 'sampler') return r.value;
|
|
765
|
-
if (r.kind === 'textureView') return r.value;
|
|
766
|
-
if (r.kind === 'externalTexture') return r.value;
|
|
767
|
-
if (r.kind === 'buffer') {
|
|
768
|
-
const v = r.value;
|
|
769
|
-
if (v !== null && typeof v === 'object' && 'buffer' in v) return v;
|
|
770
|
-
// legacy shape -- shouldn't occur after Bug 1 fix but tolerate
|
|
771
|
-
return { buffer: v };
|
|
772
|
-
}
|
|
773
|
-
return r;
|
|
774
|
-
};
|
|
775
|
-
// biome-ignore lint/suspicious/noExplicitAny: descriptor builder
|
|
776
|
-
const buildBgDesc = (desc: any): any => {
|
|
777
|
-
if (!isRawDevice) return desc;
|
|
778
|
-
const entries: SpecBgEntry[] = (
|
|
779
|
-
desc.entries as ReadonlyArray<{ binding: number; resource: unknown }>
|
|
780
|
-
).map((e) => ({
|
|
781
|
-
binding: e.binding,
|
|
782
|
-
resource: toSpecResource(e.resource),
|
|
783
|
-
}));
|
|
784
|
-
const out: { label?: string; layout: unknown; entries: SpecBgEntry[] } = {
|
|
785
|
-
layout: desc.layout,
|
|
786
|
-
entries,
|
|
787
|
-
};
|
|
788
|
-
if ('label' in desc && desc.label !== undefined) out.label = desc.label;
|
|
789
|
-
return out;
|
|
790
|
-
};
|
|
791
|
-
|
|
792
624
|
if (
|
|
793
625
|
cache.equirectToCubePipeline === undefined ||
|
|
794
626
|
cache.irradiancePipeline === undefined ||
|
|
795
627
|
cache.prefilterPipeline === undefined ||
|
|
796
628
|
cache.brdfLutPipeline === undefined
|
|
797
629
|
) {
|
|
798
|
-
return {
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
},
|
|
805
|
-
};
|
|
806
|
-
}
|
|
807
|
-
if (typeof device.queue?.submit !== 'function') {
|
|
808
|
-
return {
|
|
809
|
-
ok: false,
|
|
810
|
-
error: {
|
|
811
|
-
code: 'ibl-precompute-not-dispatched',
|
|
812
|
-
expected: 'device.queue.submit callable',
|
|
813
|
-
hint: 'check IblPipelineCache.runIblPrecompute is called inside the GpuResourceStore equirect-to-cubemap projection; counters must not increment before queue.submit',
|
|
814
|
-
},
|
|
815
|
-
};
|
|
630
|
+
return err({
|
|
631
|
+
code: 'ibl-precompute-not-dispatched',
|
|
632
|
+
expected: '4 IBL pipelines created via createIblPipelines',
|
|
633
|
+
hint: 'check IblPipelineCache.createIblPipelines was called before runIblPrecompute; counters must not increment before queue.submit',
|
|
634
|
+
detail: { stage: 'pipeline-cache' },
|
|
635
|
+
});
|
|
816
636
|
}
|
|
817
637
|
|
|
818
638
|
// Allocate side textures (irradiance / prefilter / brdf-lut) lazily.
|
|
@@ -821,31 +641,8 @@ export function runIblPrecompute(
|
|
|
821
641
|
// requires the TextureUsage::CopySrc bit on the source. Without it
|
|
822
642
|
// Dawn fails-fast "usage doesn't include CopySrc".
|
|
823
643
|
|
|
824
|
-
// M5-amend Bug 1: helper that normalises shim/raw texture-view creation.
|
|
825
|
-
// Raw GPUDevice exposes `gpuTexture.createView(desc)` on the texture
|
|
826
|
-
// object itself; the rhi-shim exposes `device.createTextureView(tex, desc)`
|
|
827
|
-
// and returns Result<T>.
|
|
828
|
-
// biome-ignore lint/suspicious/noExplicitAny: shim/raw device split
|
|
829
|
-
const makeView = (texture: any, desc: any): any => {
|
|
830
|
-
// biome-ignore lint/suspicious/noExplicitAny: device shim shape
|
|
831
|
-
const dev = device as any;
|
|
832
|
-
if (typeof dev.createTextureView === 'function') {
|
|
833
|
-
const r = dev.createTextureView(texture, desc);
|
|
834
|
-
const u = unwrap(r);
|
|
835
|
-
if (u !== undefined) return u;
|
|
836
|
-
}
|
|
837
|
-
if (texture !== null && texture !== undefined && typeof texture.createView === 'function') {
|
|
838
|
-
try {
|
|
839
|
-
return texture.createView(desc);
|
|
840
|
-
} catch {
|
|
841
|
-
return undefined;
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
return undefined;
|
|
845
|
-
};
|
|
846
|
-
|
|
847
644
|
if (cache.irradianceTexture === undefined) {
|
|
848
|
-
const
|
|
645
|
+
const textureResult = device.createTexture({
|
|
849
646
|
label: 'ibl-irradiance-cube',
|
|
850
647
|
size: { width: IRRADIANCE_SIZE, height: IRRADIANCE_SIZE, depthOrArrayLayers: 6 },
|
|
851
648
|
mipLevelCount: 1,
|
|
@@ -857,34 +654,33 @@ export function runIblPrecompute(
|
|
|
857
654
|
GPU_TEXTURE_USAGE_COPY_DST |
|
|
858
655
|
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
859
656
|
viewFormats: [],
|
|
657
|
+
textureBindingViewDimension: undefined,
|
|
860
658
|
});
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
const cubeView = makeView(tVal, {
|
|
659
|
+
if (!textureResult.ok) return err(badAlloc('irradiance-texture', textureResult.error));
|
|
660
|
+
cache.irradianceTexture = textureResult.value;
|
|
661
|
+
const cubeViewResult = device.createTextureView(textureResult.value, {
|
|
865
662
|
label: 'ibl-irradiance-cube-view',
|
|
866
663
|
dimension: 'cube',
|
|
867
664
|
arrayLayerCount: 6,
|
|
868
665
|
});
|
|
869
|
-
if (
|
|
870
|
-
cache.irradianceView =
|
|
871
|
-
|
|
872
|
-
const faceViews: any[] = [];
|
|
666
|
+
if (!cubeViewResult.ok) return err(badAlloc('irradiance-view', cubeViewResult.error));
|
|
667
|
+
cache.irradianceView = cubeViewResult.value;
|
|
668
|
+
const faceViews: TextureView[] = [];
|
|
873
669
|
for (let f = 0; f < 6; f++) {
|
|
874
|
-
const
|
|
670
|
+
const viewResult = device.createTextureView(textureResult.value, {
|
|
875
671
|
label: `ibl-irradiance-face-${f}`,
|
|
876
672
|
dimension: '2d',
|
|
877
673
|
baseArrayLayer: f,
|
|
878
674
|
arrayLayerCount: 1,
|
|
879
675
|
});
|
|
880
|
-
if (
|
|
881
|
-
faceViews.push(
|
|
676
|
+
if (!viewResult.ok) return err(badAlloc('irradiance-face-view', viewResult.error));
|
|
677
|
+
faceViews.push(viewResult.value);
|
|
882
678
|
}
|
|
883
679
|
cache.irradianceFaceViews = faceViews;
|
|
884
680
|
}
|
|
885
681
|
|
|
886
682
|
if (cache.prefilterTexture === undefined) {
|
|
887
|
-
const
|
|
683
|
+
const textureResult = device.createTexture({
|
|
888
684
|
label: 'ibl-prefilter-cube',
|
|
889
685
|
size: { width: PREFILTER_SIZE, height: PREFILTER_SIZE, depthOrArrayLayers: 6 },
|
|
890
686
|
mipLevelCount: PREFILTER_MIP_LEVELS,
|
|
@@ -896,26 +692,24 @@ export function runIblPrecompute(
|
|
|
896
692
|
GPU_TEXTURE_USAGE_COPY_DST |
|
|
897
693
|
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
898
694
|
viewFormats: [],
|
|
695
|
+
textureBindingViewDimension: undefined,
|
|
899
696
|
});
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
const cubeView = makeView(tVal, {
|
|
697
|
+
if (!textureResult.ok) return err(badAlloc('prefilter-texture', textureResult.error));
|
|
698
|
+
cache.prefilterTexture = textureResult.value;
|
|
699
|
+
const cubeViewResult = device.createTextureView(textureResult.value, {
|
|
904
700
|
label: 'ibl-prefilter-cube-view',
|
|
905
701
|
dimension: 'cube',
|
|
906
702
|
arrayLayerCount: 6,
|
|
907
703
|
baseMipLevel: 0,
|
|
908
704
|
mipLevelCount: PREFILTER_MIP_LEVELS,
|
|
909
705
|
});
|
|
910
|
-
if (
|
|
911
|
-
cache.prefilterView =
|
|
912
|
-
|
|
913
|
-
const mipViews: any[][] = [];
|
|
706
|
+
if (!cubeViewResult.ok) return err(badAlloc('prefilter-view', cubeViewResult.error));
|
|
707
|
+
cache.prefilterView = cubeViewResult.value;
|
|
708
|
+
const mipViews: TextureView[][] = [];
|
|
914
709
|
for (let m = 0; m < PREFILTER_MIP_LEVELS; m++) {
|
|
915
|
-
|
|
916
|
-
const faces: any[] = [];
|
|
710
|
+
const faces: TextureView[] = [];
|
|
917
711
|
for (let f = 0; f < 6; f++) {
|
|
918
|
-
const
|
|
712
|
+
const viewResult = device.createTextureView(textureResult.value, {
|
|
919
713
|
label: `ibl-prefilter-mip${m}-face${f}`,
|
|
920
714
|
dimension: '2d',
|
|
921
715
|
baseMipLevel: m,
|
|
@@ -923,8 +717,8 @@ export function runIblPrecompute(
|
|
|
923
717
|
baseArrayLayer: f,
|
|
924
718
|
arrayLayerCount: 1,
|
|
925
719
|
});
|
|
926
|
-
if (
|
|
927
|
-
faces.push(
|
|
720
|
+
if (!viewResult.ok) return err(badAlloc('prefilter-face-view', viewResult.error));
|
|
721
|
+
faces.push(viewResult.value);
|
|
928
722
|
}
|
|
929
723
|
mipViews.push(faces);
|
|
930
724
|
}
|
|
@@ -932,7 +726,7 @@ export function runIblPrecompute(
|
|
|
932
726
|
}
|
|
933
727
|
|
|
934
728
|
if (cache.brdfLutTexture === undefined) {
|
|
935
|
-
const
|
|
729
|
+
const textureResult = device.createTexture({
|
|
936
730
|
label: 'ibl-brdf-lut',
|
|
937
731
|
size: { width: BRDF_LUT_SIZE, height: BRDF_LUT_SIZE, depthOrArrayLayers: 1 },
|
|
938
732
|
mipLevelCount: 1,
|
|
@@ -944,22 +738,22 @@ export function runIblPrecompute(
|
|
|
944
738
|
GPU_TEXTURE_USAGE_COPY_DST |
|
|
945
739
|
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
946
740
|
viewFormats: [],
|
|
741
|
+
textureBindingViewDimension: undefined,
|
|
947
742
|
});
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
const v = makeView(tVal, {
|
|
743
|
+
if (!textureResult.ok) return err(badAlloc('brdf-lut-texture', textureResult.error));
|
|
744
|
+
cache.brdfLutTexture = textureResult.value;
|
|
745
|
+
const viewResult = device.createTextureView(textureResult.value, {
|
|
952
746
|
label: 'ibl-brdf-lut-view',
|
|
953
747
|
dimension: '2d',
|
|
954
748
|
});
|
|
955
|
-
if (
|
|
956
|
-
cache.brdfLutView =
|
|
749
|
+
if (!viewResult.ok) return err(badAlloc('brdf-lut-view', viewResult.error));
|
|
750
|
+
cache.brdfLutView = viewResult.value;
|
|
957
751
|
}
|
|
958
752
|
|
|
959
753
|
// Shared sampler (filtering, linear-linear).
|
|
960
754
|
// U=repeat because equirect wraps horizontally (atan2 seam at ±π);
|
|
961
755
|
// V=clamp because equirect poles are clamped vertically.
|
|
962
|
-
const
|
|
756
|
+
const samplerResult = device.createSampler({
|
|
963
757
|
label: 'ibl-precompute-sampler',
|
|
964
758
|
magFilter: 'linear',
|
|
965
759
|
minFilter: 'linear',
|
|
@@ -968,51 +762,74 @@ export function runIblPrecompute(
|
|
|
968
762
|
addressModeV: 'clamp-to-edge',
|
|
969
763
|
addressModeW: 'clamp-to-edge',
|
|
970
764
|
});
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
const
|
|
975
|
-
|
|
976
|
-
|
|
765
|
+
if (!samplerResult.ok) return err(badAlloc('sampler', samplerResult.error));
|
|
766
|
+
const sampler: Sampler = samplerResult.value;
|
|
767
|
+
|
|
768
|
+
const encoderResult = device.createCommandEncoder({ label: 'ibl-precompute-encoder' });
|
|
769
|
+
if (!encoderResult.ok) return err(badAlloc('encoder', encoderResult.error));
|
|
770
|
+
const encoder: RhiCommandEncoder = encoderResult.value;
|
|
771
|
+
|
|
772
|
+
const faceUniformsBgl = cache.faceUniformsBgl;
|
|
773
|
+
const equirectGroup1Bgl = cache.equirectGroup1Bgl;
|
|
774
|
+
const cubeGroup1Bgl = cache.cubeGroup1Bgl;
|
|
775
|
+
const prefilterGroup0Bgl = cache.prefilterGroup0Bgl;
|
|
776
|
+
const equirectPipeline = cache.equirectToCubePipeline;
|
|
777
|
+
const irradiancePipeline = cache.irradiancePipeline;
|
|
778
|
+
const prefilterPipeline = cache.prefilterPipeline;
|
|
779
|
+
const brdfLutPipeline = cache.brdfLutPipeline;
|
|
780
|
+
const irrFaceViews = cache.irradianceFaceViews;
|
|
781
|
+
const prefMipViews = cache.prefilterFaceViewsByMip;
|
|
782
|
+
const brdfLutView = cache.brdfLutView;
|
|
783
|
+
if (
|
|
784
|
+
faceUniformsBgl === undefined ||
|
|
785
|
+
equirectGroup1Bgl === undefined ||
|
|
786
|
+
cubeGroup1Bgl === undefined ||
|
|
787
|
+
prefilterGroup0Bgl === undefined ||
|
|
788
|
+
equirectPipeline === undefined ||
|
|
789
|
+
irradiancePipeline === undefined ||
|
|
790
|
+
prefilterPipeline === undefined ||
|
|
791
|
+
brdfLutPipeline === undefined ||
|
|
792
|
+
irrFaceViews === undefined ||
|
|
793
|
+
prefMipViews === undefined ||
|
|
794
|
+
brdfLutView === undefined
|
|
795
|
+
) {
|
|
796
|
+
return err(badAlloc('ibl-cache-resources'));
|
|
797
|
+
}
|
|
977
798
|
|
|
978
799
|
// Bind group: equirect group(1).
|
|
979
|
-
const
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
),
|
|
990
|
-
);
|
|
991
|
-
if (equirectBg === undefined) return { ok: false, error: badAlloc('equirect-bg') };
|
|
800
|
+
const equirectBgResult = device.createBindGroup({
|
|
801
|
+
label: 'ibl-equirect-bg',
|
|
802
|
+
layout: equirectGroup1Bgl,
|
|
803
|
+
entries: [
|
|
804
|
+
{ binding: 0, resource: { kind: 'textureView', value: opts.equirectView } },
|
|
805
|
+
{ binding: 1, resource: { kind: 'sampler', value: sampler } },
|
|
806
|
+
],
|
|
807
|
+
});
|
|
808
|
+
if (!equirectBgResult.ok) return err(badAlloc('equirect-bg', equirectBgResult.error));
|
|
809
|
+
const equirectBg: BindGroup = equirectBgResult.value;
|
|
992
810
|
|
|
993
811
|
// Bind group: cube group(1) for irradiance + prefilter.
|
|
994
|
-
const
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
),
|
|
1005
|
-
);
|
|
1006
|
-
if (cubeBg === undefined) return { ok: false, error: badAlloc('cube-bg') };
|
|
812
|
+
const cubeBgResult = device.createBindGroup({
|
|
813
|
+
label: 'ibl-cube-bg',
|
|
814
|
+
layout: cubeGroup1Bgl,
|
|
815
|
+
entries: [
|
|
816
|
+
{ binding: 0, resource: { kind: 'textureView', value: opts.cubeView } },
|
|
817
|
+
{ binding: 1, resource: { kind: 'sampler', value: sampler } },
|
|
818
|
+
],
|
|
819
|
+
});
|
|
820
|
+
if (!cubeBgResult.ok) return err(badAlloc('cube-bg', cubeBgResult.error));
|
|
821
|
+
const cubeBg: BindGroup = cubeBgResult.value;
|
|
1007
822
|
|
|
1008
823
|
// (a) equirect-to-cube: 6 face draws.
|
|
1009
824
|
const cubeFaceViews = opts.cubeFaceViews;
|
|
1010
825
|
for (let face = 0; face < 6; face++) {
|
|
1011
|
-
const
|
|
826
|
+
const cubeFaceView = cubeFaceViews[face];
|
|
827
|
+
if (cubeFaceView === undefined) return err(badAlloc('cube-face-view'));
|
|
828
|
+
const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
|
|
1012
829
|
label: 'ibl-equirect-to-cube',
|
|
1013
830
|
colorAttachments: [
|
|
1014
831
|
{
|
|
1015
|
-
view:
|
|
832
|
+
view: cubeFaceView,
|
|
1016
833
|
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
1017
834
|
loadOp: 'clear',
|
|
1018
835
|
storeOp: 'store',
|
|
@@ -1020,30 +837,26 @@ export function runIblPrecompute(
|
|
|
1020
837
|
],
|
|
1021
838
|
});
|
|
1022
839
|
// Face uniform: dynamic offset = face * 256.
|
|
1023
|
-
const
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
offset: face * 256,
|
|
1036
|
-
size: 64,
|
|
1037
|
-
},
|
|
1038
|
-
},
|
|
840
|
+
const faceBgResult = device.createBindGroup({
|
|
841
|
+
label: `ibl-face-bg-${face}`,
|
|
842
|
+
layout: faceUniformsBgl,
|
|
843
|
+
entries: [
|
|
844
|
+
{
|
|
845
|
+
binding: 0,
|
|
846
|
+
resource: {
|
|
847
|
+
kind: 'buffer',
|
|
848
|
+
value: {
|
|
849
|
+
buffer: opts.faceUniformsBuffer,
|
|
850
|
+
offset: face * 256,
|
|
851
|
+
size: 64,
|
|
1039
852
|
},
|
|
1040
|
-
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
);
|
|
1044
|
-
if (
|
|
1045
|
-
pass.setPipeline(
|
|
1046
|
-
pass.setBindGroup(0,
|
|
853
|
+
},
|
|
854
|
+
},
|
|
855
|
+
],
|
|
856
|
+
});
|
|
857
|
+
if (!faceBgResult.ok) return err(badAlloc('face-bg', faceBgResult.error));
|
|
858
|
+
pass.setPipeline(equirectPipeline);
|
|
859
|
+
pass.setBindGroup(0, faceBgResult.value);
|
|
1047
860
|
pass.setBindGroup(1, equirectBg);
|
|
1048
861
|
pass.setVertexBuffer(0, opts.cubeVertexBuffer);
|
|
1049
862
|
pass.draw(6, 1, face * 6, 0);
|
|
@@ -1051,43 +864,40 @@ export function runIblPrecompute(
|
|
|
1051
864
|
}
|
|
1052
865
|
|
|
1053
866
|
// (b) irradiance convolve: 6 face draws.
|
|
1054
|
-
const irrFaceViews = cache.irradianceFaceViews ?? [];
|
|
1055
867
|
for (let face = 0; face < 6; face++) {
|
|
1056
|
-
const
|
|
868
|
+
const irrFaceView = irrFaceViews[face];
|
|
869
|
+
if (irrFaceView === undefined) return err(badAlloc('irradiance-face-view'));
|
|
870
|
+
const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
|
|
1057
871
|
label: 'ibl-irradiance',
|
|
1058
872
|
colorAttachments: [
|
|
1059
873
|
{
|
|
1060
|
-
view:
|
|
874
|
+
view: irrFaceView,
|
|
1061
875
|
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
1062
876
|
loadOp: 'clear',
|
|
1063
877
|
storeOp: 'store',
|
|
1064
878
|
},
|
|
1065
879
|
],
|
|
1066
880
|
});
|
|
1067
|
-
const
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
offset: face * 256,
|
|
1080
|
-
size: 64,
|
|
1081
|
-
},
|
|
1082
|
-
},
|
|
881
|
+
const faceBgResult = device.createBindGroup({
|
|
882
|
+
label: `ibl-irr-face-bg-${face}`,
|
|
883
|
+
layout: faceUniformsBgl,
|
|
884
|
+
entries: [
|
|
885
|
+
{
|
|
886
|
+
binding: 0,
|
|
887
|
+
resource: {
|
|
888
|
+
kind: 'buffer',
|
|
889
|
+
value: {
|
|
890
|
+
buffer: opts.faceUniformsBuffer,
|
|
891
|
+
offset: face * 256,
|
|
892
|
+
size: 64,
|
|
1083
893
|
},
|
|
1084
|
-
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
);
|
|
1088
|
-
if (
|
|
1089
|
-
pass.setPipeline(
|
|
1090
|
-
pass.setBindGroup(0,
|
|
894
|
+
},
|
|
895
|
+
},
|
|
896
|
+
],
|
|
897
|
+
});
|
|
898
|
+
if (!faceBgResult.ok) return err(badAlloc('irr-face-bg', faceBgResult.error));
|
|
899
|
+
pass.setPipeline(irradiancePipeline);
|
|
900
|
+
pass.setBindGroup(0, faceBgResult.value);
|
|
1091
901
|
pass.setBindGroup(1, cubeBg);
|
|
1092
902
|
pass.setVertexBuffer(0, opts.cubeVertexBuffer);
|
|
1093
903
|
pass.draw(6, 1, face * 6, 0);
|
|
@@ -1095,57 +905,55 @@ export function runIblPrecompute(
|
|
|
1095
905
|
}
|
|
1096
906
|
|
|
1097
907
|
// (c) prefilter env: 5 mips x 6 faces = 30 sub-passes.
|
|
1098
|
-
const prefMipViews = cache.prefilterFaceViewsByMip ?? [];
|
|
1099
908
|
for (let mip = 0; mip < PREFILTER_MIP_LEVELS; mip++) {
|
|
1100
|
-
const mipFaceViews = prefMipViews[mip]
|
|
909
|
+
const mipFaceViews = prefMipViews[mip];
|
|
910
|
+
if (mipFaceViews === undefined) return err(badAlloc('prefilter-mip-views'));
|
|
1101
911
|
for (let face = 0; face < 6; face++) {
|
|
1102
912
|
const subIdx = mip * 6 + face;
|
|
1103
|
-
const
|
|
913
|
+
const mipFaceView = mipFaceViews[face];
|
|
914
|
+
if (mipFaceView === undefined) return err(badAlloc('prefilter-face-view'));
|
|
915
|
+
const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
|
|
1104
916
|
label: 'ibl-prefilter',
|
|
1105
917
|
colorAttachments: [
|
|
1106
918
|
{
|
|
1107
|
-
view:
|
|
919
|
+
view: mipFaceView,
|
|
1108
920
|
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
1109
921
|
loadOp: 'clear',
|
|
1110
922
|
storeOp: 'store',
|
|
1111
923
|
},
|
|
1112
924
|
],
|
|
1113
925
|
});
|
|
1114
|
-
const
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
offset: face * 256,
|
|
1127
|
-
size: 64,
|
|
1128
|
-
},
|
|
1129
|
-
},
|
|
926
|
+
const bgResult = device.createBindGroup({
|
|
927
|
+
label: `ibl-pref-bg-${subIdx}`,
|
|
928
|
+
layout: prefilterGroup0Bgl,
|
|
929
|
+
entries: [
|
|
930
|
+
{
|
|
931
|
+
binding: 0,
|
|
932
|
+
resource: {
|
|
933
|
+
kind: 'buffer',
|
|
934
|
+
value: {
|
|
935
|
+
buffer: opts.faceUniformsBuffer,
|
|
936
|
+
offset: face * 256,
|
|
937
|
+
size: 64,
|
|
1130
938
|
},
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
939
|
+
},
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
binding: 1,
|
|
943
|
+
resource: {
|
|
944
|
+
kind: 'buffer',
|
|
945
|
+
value: {
|
|
946
|
+
buffer: opts.prefilterUniformsBuffer,
|
|
947
|
+
offset: subIdx * 256,
|
|
948
|
+
size: 16,
|
|
1141
949
|
},
|
|
1142
|
-
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
);
|
|
1146
|
-
if (
|
|
1147
|
-
pass.setPipeline(
|
|
1148
|
-
pass.setBindGroup(0,
|
|
950
|
+
},
|
|
951
|
+
},
|
|
952
|
+
],
|
|
953
|
+
});
|
|
954
|
+
if (!bgResult.ok) return err(badAlloc('pref-bg', bgResult.error));
|
|
955
|
+
pass.setPipeline(prefilterPipeline);
|
|
956
|
+
pass.setBindGroup(0, bgResult.value);
|
|
1149
957
|
pass.setBindGroup(1, cubeBg);
|
|
1150
958
|
pass.setVertexBuffer(0, opts.cubeVertexBuffer);
|
|
1151
959
|
pass.draw(6, 1, face * 6, 0);
|
|
@@ -1155,18 +963,18 @@ export function runIblPrecompute(
|
|
|
1155
963
|
|
|
1156
964
|
// (d) brdf-lut: fullscreen triangle.
|
|
1157
965
|
{
|
|
1158
|
-
const pass = encoder.beginRenderPass({
|
|
966
|
+
const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
|
|
1159
967
|
label: 'ibl-brdf-lut',
|
|
1160
968
|
colorAttachments: [
|
|
1161
969
|
{
|
|
1162
|
-
view:
|
|
970
|
+
view: brdfLutView,
|
|
1163
971
|
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
1164
972
|
loadOp: 'clear',
|
|
1165
973
|
storeOp: 'store',
|
|
1166
974
|
},
|
|
1167
975
|
],
|
|
1168
976
|
});
|
|
1169
|
-
pass.setPipeline(
|
|
977
|
+
pass.setPipeline(brdfLutPipeline);
|
|
1170
978
|
pass.draw(3, 1, 0, 0);
|
|
1171
979
|
pass.end();
|
|
1172
980
|
}
|
|
@@ -1174,73 +982,25 @@ export function runIblPrecompute(
|
|
|
1174
982
|
// Finish + submit. Counter increments are STRICTLY after submit; if
|
|
1175
983
|
// submit throws or fails, counters stay at 0 (AC-20 critical invariant).
|
|
1176
984
|
const finishRes = encoder.finish();
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
finishRes !== undefined &&
|
|
1182
|
-
typeof finishRes === 'object' &&
|
|
1183
|
-
'ok' in finishRes
|
|
1184
|
-
) {
|
|
1185
|
-
if (!finishRes.ok) return { ok: false, error: badAlloc('finish') };
|
|
1186
|
-
cmdBuffer = finishRes.value;
|
|
1187
|
-
} else {
|
|
1188
|
-
cmdBuffer = finishRes;
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
// Submit -- may throw on mock devices in failure-injection tests, or
|
|
1192
|
-
// return a structured Result.err on the rhi shim path. AC-20 critical:
|
|
1193
|
-
// counters are incremented ONLY if submit returns cleanly (no throw +
|
|
1194
|
-
// no .ok === false).
|
|
1195
|
-
let submitOk = true;
|
|
1196
|
-
let submitError: unknown;
|
|
1197
|
-
try {
|
|
1198
|
-
// biome-ignore lint/suspicious/noExplicitAny: submit returns Result|undefined
|
|
1199
|
-
const submitRes = device.queue.submit([cmdBuffer]) as any;
|
|
1200
|
-
if (
|
|
1201
|
-
submitRes !== null &&
|
|
1202
|
-
submitRes !== undefined &&
|
|
1203
|
-
typeof submitRes === 'object' &&
|
|
1204
|
-
'ok' in submitRes &&
|
|
1205
|
-
submitRes.ok === false
|
|
1206
|
-
) {
|
|
1207
|
-
submitOk = false;
|
|
1208
|
-
submitError = submitRes.error;
|
|
1209
|
-
}
|
|
1210
|
-
} catch (e) {
|
|
1211
|
-
submitOk = false;
|
|
1212
|
-
submitError = e;
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
if (!submitOk) {
|
|
1216
|
-
return {
|
|
1217
|
-
ok: false,
|
|
1218
|
-
error: {
|
|
1219
|
-
code: 'ibl-precompute-not-dispatched',
|
|
1220
|
-
expected: 'device.queue.submit returned successfully',
|
|
1221
|
-
hint: `queue.submit failed: ${String(submitError)}; counters must not increment before queue.submit`,
|
|
1222
|
-
},
|
|
1223
|
-
};
|
|
1224
|
-
}
|
|
985
|
+
if (!finishRes.ok) return err(badAlloc('finish', finishRes.error));
|
|
986
|
+
const cmdBuffer: CommandBuffer = finishRes.value;
|
|
987
|
+
const submitRes = device.queue.submit([cmdBuffer]);
|
|
988
|
+
if (!submitRes.ok) return err(badAlloc('queue.submit', submitRes.error));
|
|
1225
989
|
|
|
1226
990
|
// POST-SUBMIT counter increments (AC-20).
|
|
1227
991
|
cache.irradianceBakeCount += 1;
|
|
1228
992
|
cache.prefilterBakeCount += 1;
|
|
1229
993
|
cache.brdfLutBakeCount += 1;
|
|
1230
994
|
|
|
1231
|
-
return
|
|
995
|
+
return ok({ submitted: true });
|
|
1232
996
|
}
|
|
1233
997
|
|
|
1234
998
|
// Local helper -- structured error payload shared across allocation paths.
|
|
1235
|
-
function badAlloc(stage: string
|
|
999
|
+
function badAlloc(stage: string, cause?: RhiError): IblPrecomputeError {
|
|
1236
1000
|
return {
|
|
1237
1001
|
code: 'ibl-precompute-not-dispatched',
|
|
1238
1002
|
expected: `${stage} allocated successfully`,
|
|
1239
|
-
hint: `check
|
|
1003
|
+
hint: `check the RHI Result for ${stage}; counters must not increment before queue.submit`,
|
|
1004
|
+
...(cause === undefined ? {} : { detail: { stage, rhiCode: cause.code } }),
|
|
1240
1005
|
};
|
|
1241
1006
|
}
|
|
1242
|
-
|
|
1243
|
-
// biome-ignore lint/suspicious/noExplicitAny: opaque BGL return
|
|
1244
|
-
function prefilterGroup0LayoutOf(cache: IblPipelineCachePerDevice): any {
|
|
1245
|
-
return cache.prefilterGroup0Bgl;
|
|
1246
|
-
}
|