@forgeax/engine-render 0.0.0-dev.8d955ade1c79
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/LICENSE +202 -0
- package/README.md +647 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/__tests__/authoring-path.unit.test.d.ts +2 -0
- package/dist/__tests__/authoring-path.unit.test.d.ts.map +1 -0
- package/dist/__tests__/backend-selection-rhi-capture.test-d.d.ts +2 -0
- package/dist/__tests__/backend-selection-rhi-capture.test-d.d.ts.map +1 -0
- package/dist/__tests__/callback-inference.test-d.d.ts +2 -0
- package/dist/__tests__/callback-inference.test-d.d.ts.map +1 -0
- package/dist/__tests__/cluster-binner.test.d.ts +2 -0
- package/dist/__tests__/cluster-binner.test.d.ts.map +1 -0
- package/dist/__tests__/cluster-grid-default-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/cluster-grid-default-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/construct-renderer-identity.unit.test.d.ts +2 -0
- package/dist/__tests__/construct-renderer-identity.unit.test.d.ts.map +1 -0
- 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__/direct-extract-consumer-contract.test-d.d.ts +2 -0
- package/dist/__tests__/direct-extract-consumer-contract.test-d.d.ts.map +1 -0
- package/dist/__tests__/direct-light-snapshot.unit.test.d.ts +2 -0
- package/dist/__tests__/direct-light-snapshot.unit.test.d.ts.map +1 -0
- package/dist/__tests__/factory-contract.integration.test.d.ts +2 -0
- package/dist/__tests__/factory-contract.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fallback-row-stride-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/fallback-row-stride-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/frame-observation.contract.test.d.ts +2 -0
- package/dist/__tests__/frame-observation.contract.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__/glyph-text-layout-recovery.unit.test.d.ts +2 -0
- package/dist/__tests__/glyph-text-layout-recovery.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts +6 -0
- package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster.browser.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-indirect-raster.browser.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-indirect-raster.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-indirect-raster.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-production.integration.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-production.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-scaling.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-scaling.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts +18 -0
- package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view-graph.integration.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view-graph.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view-reference.d.ts +15 -0
- package/dist/__tests__/gpu-driven-view-reference.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view.browser.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view.browser.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-driven-view.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-driven-view.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-resource-store-stride.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-resource-store-stride.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts +7 -0
- package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph.browser.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene-render-graph.browser.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-render-graph.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene-render-graph.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene-schema.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene-schema.unit.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene.dawn.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/gpu-scene.unit.test.d.ts +2 -0
- package/dist/__tests__/gpu-scene.unit.test.d.ts.map +1 -0
- 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__/infinite-grid-no-vertex-probe.unit.test.d.ts +2 -0
- package/dist/__tests__/infinite-grid-no-vertex-probe.unit.test.d.ts.map +1 -0
- package/dist/__tests__/injection-kind-owner.test-d.d.ts +2 -0
- package/dist/__tests__/injection-kind-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/ktx2-basis-gpu-consumer.dawn.test.d.ts +2 -0
- package/dist/__tests__/ktx2-basis-gpu-consumer.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/light-buffer-layout.unit.test.d.ts +2 -0
- package/dist/__tests__/light-buffer-layout.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-contract-inventory.unit.test.d.ts +2 -0
- package/dist/__tests__/material-contract-inventory.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-cooked-projection.unit.test.d.ts +2 -0
- package/dist/__tests__/material-cooked-projection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-snapshot-mutation.integration.test.d.ts +2 -0
- package/dist/__tests__/material-snapshot-mutation.integration.test.d.ts.map +1 -0
- package/dist/__tests__/material-static-dynamic-route.unit.test.d.ts +2 -0
- package/dist/__tests__/material-static-dynamic-route.unit.test.d.ts.map +1 -0
- package/dist/__tests__/material-stride-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/material-stride-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-buffer-usage-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-buffer-usage-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-material-bindings.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-material-bindings.unit.test.d.ts.map +1 -0
- package/dist/__tests__/mesh-stride-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/mesh-stride-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/morph-culling-reentry.dawn.test.d.ts +2 -0
- package/dist/__tests__/morph-culling-reentry.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/morph-feature-gpu-work.integration.test.d.ts +2 -0
- package/dist/__tests__/morph-feature-gpu-work.integration.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__/morph-visual-evidence.integration.test.d.ts +2 -0
- package/dist/__tests__/morph-visual-evidence.integration.test.d.ts.map +1 -0
- package/dist/__tests__/nineslice-handle-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/nineslice-handle-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/post-process-error-policy-owner.unit.test.d.ts +2 -0
- package/dist/__tests__/post-process-error-policy-owner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-buffer-kind-owner.test-d.d.ts +2 -0
- package/dist/__tests__/prepared-buffer-kind-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-capability.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-capability.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-generation.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-generation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-lifecycle.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-lifecycle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-pipeline-warmup.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-pipeline-warmup.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-resolver.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-resolver.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-snapshot.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-snapshot.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-store.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-store.unit.test.d.ts.map +1 -0
- package/dist/__tests__/prepared-graphics-validation.unit.test.d.ts +2 -0
- package/dist/__tests__/prepared-graphics-validation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-default-off.test.d.ts +2 -0
- package/dist/__tests__/profiler-default-off.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-phase-catalog.test.d.ts +2 -0
- package/dist/__tests__/profiler-phase-catalog.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-phase-integration.test.d.ts +2 -0
- package/dist/__tests__/profiler-phase-integration.test.d.ts.map +1 -0
- package/dist/__tests__/profiler-phase-token.test.d.ts +2 -0
- package/dist/__tests__/profiler-phase-token.test.d.ts.map +1 -0
- package/dist/__tests__/public-surface.test-d.d.ts +2 -0
- package/dist/__tests__/public-surface.test-d.d.ts.map +1 -0
- package/dist/__tests__/recover-error-policy-owner.unit.test.d.ts +2 -0
- package/dist/__tests__/recover-error-policy-owner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-error-code-owner.test-d.d.ts +2 -0
- package/dist/__tests__/render-error-code-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-error-detail-ssot.test-d.d.ts +2 -0
- package/dist/__tests__/render-error-detail-ssot.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts +2 -0
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-assembly.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-assembly.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-context.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-context.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-contract.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-contract.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-diagnostics.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-diagnostics.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-docs.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-docs.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-errors.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-errors.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-gpu-work.integration.test.d.ts +2 -0
- package/dist/__tests__/render-feature-gpu-work.integration.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__/render-feature-prepared-diagnostics.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-diagnostics.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-errors.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-errors.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics-docs.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics-docs.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics-isolation.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics-isolation.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics-negative.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics-negative.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-prepared-graphics.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-prepared-graphics.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-public-surface.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-public-surface.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-retry.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-retry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-scheduling.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-scheduling.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-stage-failed-policy-owner.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-stage-failed-policy-owner.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-stage-fault-recovery.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-stage-fault-recovery.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-visibility-context.test-d.d.ts +2 -0
- package/dist/__tests__/render-feature-visibility-context.test-d.d.ts.map +1 -0
- package/dist/__tests__/render-feature-visibility-context.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-visibility-context.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-feature-zero-work.unit.test.d.ts +2 -0
- package/dist/__tests__/render-feature-zero-work.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-compute-raster-gpu.d.ts +7 -0
- package/dist/__tests__/render-graph-compute-raster-gpu.d.ts.map +1 -0
- package/dist/__tests__/render-graph-compute-raster.browser.test.d.ts +2 -0
- package/dist/__tests__/render-graph-compute-raster.browser.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-compute-raster.dawn.test.d.ts +2 -0
- package/dist/__tests__/render-graph-compute-raster.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-hzb-gpu.d.ts +7 -0
- package/dist/__tests__/render-graph-hzb-gpu.d.ts.map +1 -0
- package/dist/__tests__/render-graph-hzb.browser.test.d.ts +2 -0
- package/dist/__tests__/render-graph-hzb.browser.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-hzb.dawn.test.d.ts +2 -0
- package/dist/__tests__/render-graph-hzb.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-primitives.unit.test.d.ts +2 -0
- package/dist/__tests__/render-graph-primitives.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-storage-indirect-gpu.d.ts +12 -0
- package/dist/__tests__/render-graph-storage-indirect-gpu.d.ts.map +1 -0
- package/dist/__tests__/render-graph-storage-indirect.browser.test.d.ts +2 -0
- package/dist/__tests__/render-graph-storage-indirect.browser.test.d.ts.map +1 -0
- package/dist/__tests__/render-graph-storage-indirect.dawn.test.d.ts +2 -0
- package/dist/__tests__/render-graph-storage-indirect.dawn.test.d.ts.map +1 -0
- package/dist/__tests__/render-scene-projection.unit.test.d.ts +2 -0
- package/dist/__tests__/render-scene-projection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/renderer-factory-material-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/renderer-factory-material-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/renderer-lifecycle.integration.test.d.ts +2 -0
- package/dist/__tests__/renderer-lifecycle.integration.test.d.ts.map +1 -0
- package/dist/__tests__/rhi-backend-package-boundary.unit.test.d.ts +2 -0
- package/dist/__tests__/rhi-backend-package-boundary.unit.test.d.ts.map +1 -0
- package/dist/__tests__/scriptable-pack-consumer.test-d.d.ts +2 -0
- package/dist/__tests__/scriptable-pack-consumer.test-d.d.ts.map +1 -0
- package/dist/__tests__/shader-stage-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/shader-stage-surface.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__/ssao-kernel-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/ssao-kernel-surface.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__/surface-configuration.unit.test.d.ts +2 -0
- package/dist/__tests__/surface-configuration.unit.test.d.ts.map +1 -0
- package/dist/__tests__/texture-usage-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/texture-usage-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/typed-pipeline-topology.unit.test.d.ts +2 -0
- package/dist/__tests__/typed-pipeline-topology.unit.test.d.ts.map +1 -0
- package/dist/__tests__/urp-pipeline-targets.unit.test.d.ts +2 -0
- package/dist/__tests__/urp-pipeline-targets.unit.test.d.ts.map +1 -0
- package/dist/__tests__/urp-pipeline.unit.test.d.ts +2 -0
- package/dist/__tests__/urp-pipeline.unit.test.d.ts.map +1 -0
- package/dist/__tests__/vertex-color-pipeline.unit.test.d.ts +2 -0
- package/dist/__tests__/vertex-color-pipeline.unit.test.d.ts.map +1 -0
- package/dist/__tests__/vertex-layout-consumer.unit.test.d.ts +2 -0
- package/dist/__tests__/vertex-layout-consumer.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-diagnostics.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-diagnostics.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-extract.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-extract.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-extract.perf.test.d.ts +2 -0
- package/dist/__tests__/visibility-extract.perf.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-feature-dedup.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-feature-dedup.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-hidden-report.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-hidden-report.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-instances.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-instances.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-multi-world.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-multi-world.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-producer-matrix.integration.test.d.ts +2 -0
- package/dist/__tests__/visibility-producer-matrix.integration.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-producer-matrix.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-producer-matrix.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-public-surface.test-d.d.ts +2 -0
- package/dist/__tests__/visibility-public-surface.test-d.d.ts.map +1 -0
- package/dist/__tests__/visibility-resolver.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-resolver.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/__tests__/visibility-snapshot-contract.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-snapshot-contract.unit.test.d.ts.map +1 -0
- package/dist/__tests__/vocabulary.unit.test.d.ts +2 -0
- package/dist/__tests__/vocabulary.unit.test.d.ts.map +1 -0
- package/dist/assembly/backend-contract.d.ts +37 -0
- 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/assembly/material/assembly.d.ts +21 -0
- package/dist/assembly/material/assembly.d.ts.map +1 -0
- package/dist/assembly/material/pipeline-projection.d.ts +30 -0
- package/dist/assembly/material/pipeline-projection.d.ts.map +1 -0
- package/dist/assets/asset-decoders.d.ts +5 -0
- package/dist/assets/asset-decoders.d.ts.map +1 -0
- package/dist/assets/render-asset-port.d.ts +17 -0
- package/dist/assets/render-asset-port.d.ts.map +1 -0
- package/dist/assets/resolve-render-asset.d.ts +6 -0
- package/dist/assets/resolve-render-asset.d.ts.map +1 -0
- package/dist/authoring.d.ts +12 -0
- package/dist/authoring.d.ts.map +1 -0
- package/dist/authoring.mjs +27 -0
- package/dist/authoring.mjs.map +1 -0
- package/dist/chunk-CQXZC5XI.mjs +182 -0
- package/dist/chunk-CQXZC5XI.mjs.map +1 -0
- package/dist/chunk-HCOGPHKS.mjs +93 -0
- package/dist/chunk-HCOGPHKS.mjs.map +1 -0
- package/dist/chunk-YEJIUW7D.mjs +1152 -0
- package/dist/chunk-YEJIUW7D.mjs.map +1 -0
- package/dist/cluster-binner.d.ts +152 -0
- package/dist/cluster-binner.d.ts.map +1 -0
- package/dist/components/__tests__/points-lines-admission.unit.test.d.ts +2 -0
- package/dist/components/__tests__/points-lines-admission.unit.test.d.ts.map +1 -0
- package/dist/components/__tests__/points-lines-schema.unit.test.d.ts +2 -0
- package/dist/components/__tests__/points-lines-schema.unit.test.d.ts.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/__tests__/schema-parity.unit.test.d.ts +2 -0
- package/dist/components/__tests__/schema-parity.unit.test.d.ts.map +1 -0
- package/dist/components/__tests__/visibility-schema.unit.test.d.ts +2 -0
- package/dist/components/__tests__/visibility-schema.unit.test.d.ts.map +1 -0
- package/dist/components/camera.d.ts +311 -0
- package/dist/components/camera.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +76 -0
- package/dist/components/directional-light.d.ts.map +1 -0
- package/dist/components/glyph-text.d.ts +26 -0
- package/dist/components/glyph-text.d.ts.map +1 -0
- package/dist/components/index.d.ts +24 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/instances.d.ts +41 -0
- package/dist/components/instances.d.ts.map +1 -0
- package/dist/components/layer.d.ts +34 -0
- package/dist/components/layer.d.ts.map +1 -0
- package/dist/components/light-helpers.d.ts +53 -0
- package/dist/components/light-helpers.d.ts.map +1 -0
- package/dist/components/lines.d.ts +5 -0
- package/dist/components/lines.d.ts.map +1 -0
- package/dist/components/mesh-filter.d.ts +24 -0
- package/dist/components/mesh-filter.d.ts.map +1 -0
- package/dist/components/mesh-renderer.d.ts +33 -0
- package/dist/components/mesh-renderer.d.ts.map +1 -0
- package/dist/components/point-light-shadow.d.ts +27 -0
- package/dist/components/point-light-shadow.d.ts.map +1 -0
- package/dist/components/point-light.d.ts +35 -0
- package/dist/components/point-light.d.ts.map +1 -0
- package/dist/components/points.d.ts +15 -0
- package/dist/components/points.d.ts.map +1 -0
- package/dist/components/post-process-params.d.ts +5 -0
- package/dist/components/post-process-params.d.ts.map +1 -0
- package/dist/components/scene-instance.d.ts +140 -0
- package/dist/components/scene-instance.d.ts.map +1 -0
- 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/sort-key.d.ts +44 -0
- package/dist/components/sort-key.d.ts.map +1 -0
- package/dist/components/spot-light.d.ts +81 -0
- package/dist/components/spot-light.d.ts.map +1 -0
- package/dist/components/sprite-animation.d.ts +74 -0
- package/dist/components/sprite-animation.d.ts.map +1 -0
- package/dist/components/sprite-instances.d.ts +51 -0
- package/dist/components/sprite-instances.d.ts.map +1 -0
- package/dist/components/sprite-playback-mode.d.ts +42 -0
- package/dist/components/sprite-playback-mode.d.ts.map +1 -0
- package/dist/components/sprite-region-override.d.ts +46 -0
- package/dist/components/sprite-region-override.d.ts.map +1 -0
- package/dist/components/tile-layer.d.ts +106 -0
- package/dist/components/tile-layer.d.ts.map +1 -0
- package/dist/components/tilemap.d.ts +25 -0
- package/dist/components/tilemap.d.ts.map +1 -0
- package/dist/components/visibility.d.ts +22 -0
- package/dist/components/visibility.d.ts.map +1 -0
- package/dist/construct-renderer.d.ts +19 -0
- package/dist/construct-renderer.d.ts.map +1 -0
- package/dist/construct-renderer.mjs +27462 -0
- package/dist/construct-renderer.mjs.map +1 -0
- package/dist/debug-draw-glue.d.ts +5 -0
- package/dist/debug-draw-glue.d.ts.map +1 -0
- package/dist/device/device-scope.d.ts +83 -0
- package/dist/device/device-scope.d.ts.map +1 -0
- package/dist/device/gpu-residency.d.ts +337 -0
- 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 +23 -0
- package/dist/engine-metrics.d.ts.map +1 -0
- package/dist/errors/ecs-validation.d.ts +3 -0
- package/dist/errors/ecs-validation.d.ts.map +1 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/recover.d.ts +105 -0
- package/dist/errors/recover.d.ts.map +1 -0
- package/dist/errors/render.d.ts +705 -0
- package/dist/errors/render.d.ts.map +1 -0
- package/dist/extract/visibility.d.ts +26 -0
- package/dist/extract/visibility.d.ts.map +1 -0
- package/dist/features/fullscreen.d.ts +19 -0
- package/dist/features/fullscreen.d.ts.map +1 -0
- package/dist/features/host.d.ts +106 -0
- package/dist/features/host.d.ts.map +1 -0
- package/dist/features/morph/morph-feature.d.ts +79 -0
- package/dist/features/morph/morph-feature.d.ts.map +1 -0
- 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 +117 -0
- package/dist/features/prepared-gpu-work.d.ts.map +1 -0
- package/dist/features/prepared-graphics-store.d.ts +66 -0
- package/dist/features/prepared-graphics-store.d.ts.map +1 -0
- package/dist/features/prepared-graphics.d.ts +215 -0
- package/dist/features/prepared-graphics.d.ts.map +1 -0
- package/dist/features/render-graph-compute.d.ts +13 -0
- package/dist/features/render-graph-compute.d.ts.map +1 -0
- package/dist/features/render-graph-contribution.d.ts +12 -0
- package/dist/features/render-graph-contribution.d.ts.map +1 -0
- package/dist/features/render-graph-raster.d.ts +38 -0
- package/dist/features/render-graph-raster.d.ts.map +1 -0
- package/dist/features/render-graph-resources.d.ts +11 -0
- package/dist/features/render-graph-resources.d.ts.map +1 -0
- package/dist/features/targets.d.ts +32 -0
- package/dist/features/targets.d.ts.map +1 -0
- package/dist/features/types.d.ts +68 -0
- package/dist/features/types.d.ts.map +1 -0
- 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 +157 -0
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -0
- package/dist/glyph-text-layout-system.d.ts +19 -0
- package/dist/glyph-text-layout-system.d.ts.map +1 -0
- package/dist/gpu-driven/batch-topology.d.ts +55 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +51 -0
- package/dist/gpu-driven/production-raster.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +85 -0
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -0
- package/dist/gpu-resource.d.ts +73 -0
- package/dist/gpu-resource.d.ts.map +1 -0
- package/dist/gpu-scene-schema.d.ts +78 -0
- package/dist/gpu-scene-schema.d.ts.map +1 -0
- package/dist/gpu-scene.d.ts +55 -0
- package/dist/gpu-scene.d.ts.map +1 -0
- package/dist/gpu-stage.d.ts +4 -0
- package/dist/gpu-stage.d.ts.map +1 -0
- package/dist/gpu-texture-usage.d.ts +6 -0
- package/dist/gpu-texture-usage.d.ts.map +1 -0
- package/dist/gpu-usage.d.ts +9 -0
- package/dist/gpu-usage.d.ts.map +1 -0
- package/dist/hdrp-buffers.d.ts +163 -0
- package/dist/hdrp-buffers.d.ts.map +1 -0
- package/dist/ibl/IblPipelineCache.d.ts +168 -0
- package/dist/ibl/IblPipelineCache.d.ts.map +1 -0
- package/dist/ibl/skylight-bind-group.d.ts +130 -0
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +169 -0
- package/dist/index.mjs.map +1 -0
- package/dist/inspection-types.d.ts +72 -0
- package/dist/inspection-types.d.ts.map +1 -0
- package/dist/instance-buffer-cache.d.ts +56 -0
- package/dist/instance-buffer-cache.d.ts.map +1 -0
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.mjs +3 -0
- package/dist/internal.mjs.map +1 -0
- package/dist/lifecycle.d.ts +62 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/light-buffer-layout.d.ts +164 -0
- package/dist/light-buffer-layout.d.ts.map +1 -0
- package/dist/materials.d.ts +47 -0
- package/dist/materials.d.ts.map +1 -0
- package/dist/mesh-material-bindings.d.ts +43 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -0
- package/dist/pbr-pipeline.d.ts +301 -0
- package/dist/pbr-pipeline.d.ts.map +1 -0
- 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 +122 -0
- package/dist/pipeline-builder.d.ts.map +1 -0
- 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 +367 -0
- package/dist/pipeline-spec.d.ts.map +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/points-lines/__tests__/bounds.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/bounds.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/inspection.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/inspection.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/points-lines.bench.d.ts +2 -0
- package/dist/points-lines/__tests__/points-lines.bench.d.ts.map +1 -0
- package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/snapshot.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/snapshot.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts.map +1 -0
- package/dist/points-lines/admission.d.ts +36 -0
- package/dist/points-lines/admission.d.ts.map +1 -0
- package/dist/points-lines/bounds.d.ts +8 -0
- package/dist/points-lines/bounds.d.ts.map +1 -0
- package/dist/points-lines/expansion-cache.d.ts +28 -0
- package/dist/points-lines/expansion-cache.d.ts.map +1 -0
- package/dist/points-lines/inspection.d.ts +53 -0
- package/dist/points-lines/inspection.d.ts.map +1 -0
- package/dist/points-lines/prepare.d.ts +67 -0
- package/dist/points-lines/prepare.d.ts.map +1 -0
- package/dist/points-lines/record.d.ts +60 -0
- package/dist/points-lines/record.d.ts.map +1 -0
- package/dist/points-lines/snapshot.d.ts +49 -0
- package/dist/points-lines/snapshot.d.ts.map +1 -0
- package/dist/post-process-errors.d.ts +182 -0
- package/dist/post-process-errors.d.ts.map +1 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts +59 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -0
- package/dist/record/__tests__/material-bg-cache.unit.test.d.ts +2 -0
- package/dist/record/__tests__/material-bg-cache.unit.test.d.ts.map +1 -0
- package/dist/record/__tests__/material-slot-plan.unit.test.d.ts +2 -0
- package/dist/record/__tests__/material-slot-plan.unit.test.d.ts.map +1 -0
- 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/__tests__/video-texture-view.unit.test.d.ts +2 -0
- package/dist/record/__tests__/video-texture-view.unit.test.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +121 -0
- package/dist/record/frame-lighting.d.ts.map +1 -0
- package/dist/record/frame-snapshot.d.ts +429 -0
- package/dist/record/frame-snapshot.d.ts.map +1 -0
- package/dist/record/frame-targets.d.ts +20 -0
- package/dist/record/frame-targets.d.ts.map +1 -0
- package/dist/record/frame.d.ts +71 -0
- package/dist/record/frame.d.ts.map +1 -0
- package/dist/record/helpers.d.ts +102 -0
- package/dist/record/helpers.d.ts.map +1 -0
- package/dist/record/main-pass-geometry.d.ts +28 -0
- package/dist/record/main-pass-geometry.d.ts.map +1 -0
- package/dist/record/main-pass-material.d.ts +204 -0
- package/dist/record/main-pass-material.d.ts.map +1 -0
- package/dist/record/main-pass-sprite-draws.d.ts +43 -0
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -0
- package/dist/record/main-pass.d.ts +20 -0
- package/dist/record/main-pass.d.ts.map +1 -0
- package/dist/record/mesh-ssbo.d.ts +446 -0
- package/dist/record/mesh-ssbo.d.ts.map +1 -0
- package/dist/record/render-context.d.ts +252 -0
- package/dist/record/render-context.d.ts.map +1 -0
- package/dist/record/shadow-pass.d.ts +52 -0
- package/dist/record/shadow-pass.d.ts.map +1 -0
- package/dist/record/skybox-post-pass.d.ts +33 -0
- package/dist/record/skybox-post-pass.d.ts.map +1 -0
- package/dist/record/typed-frame-graph.d.ts +35 -0
- package/dist/record/typed-frame-graph.d.ts.map +1 -0
- package/dist/record/view-ubo.d.ts +45 -0
- package/dist/record/view-ubo.d.ts.map +1 -0
- package/dist/render-contract.d.ts +424 -0
- package/dist/render-contract.d.ts.map +1 -0
- package/dist/render-data.d.ts +143 -0
- package/dist/render-data.d.ts.map +1 -0
- package/dist/render-graph-primitives.d.ts +76 -0
- package/dist/render-graph-primitives.d.ts.map +1 -0
- package/dist/render-pipeline.d.ts +110 -0
- package/dist/render-pipeline.d.ts.map +1 -0
- package/dist/render-system-extract.d.ts +868 -0
- package/dist/render-system-extract.d.ts.map +1 -0
- package/dist/render-system.d.ts +125 -0
- package/dist/render-system.d.ts.map +1 -0
- package/dist/scene/render-scene-types.d.ts +61 -0
- package/dist/scene/render-scene-types.d.ts.map +1 -0
- package/dist/scene/render-scene.d.ts +112 -0
- package/dist/scene/render-scene.d.ts.map +1 -0
- package/dist/scene-instances/post-spawn-resolve-joints.d.ts +30 -0
- package/dist/scene-instances/post-spawn-resolve-joints.d.ts.map +1 -0
- package/dist/shadow-atlas.d.ts +117 -0
- package/dist/shadow-atlas.d.ts.map +1 -0
- package/dist/ssao-buffers.d.ts +50 -0
- package/dist/ssao-buffers.d.ts.map +1 -0
- package/dist/ssao-config.d.ts +28 -0
- package/dist/ssao-config.d.ts.map +1 -0
- package/dist/systems/active-camera.d.ts +53 -0
- package/dist/systems/active-camera.d.ts.map +1 -0
- package/dist/systems/pass-selector.d.ts +24 -0
- package/dist/systems/pass-selector.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts +49 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -0
- 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 +112 -0
- package/dist/systems/transparent-sort-config.d.ts.map +1 -0
- package/dist/tilemap-chunk-extract-system.d.ts +143 -0
- package/dist/tilemap-chunk-extract-system.d.ts.map +1 -0
- package/dist/typed-render-graph-primitives.d.ts +57 -0
- package/dist/typed-render-graph-primitives.d.ts.map +1 -0
- package/dist/typed-shadow-passes.d.ts +11 -0
- package/dist/typed-shadow-passes.d.ts.map +1 -0
- package/package.json +94 -0
- package/src/__tests__/authoring-path.unit.test.ts +23 -0
- package/src/__tests__/backend-selection-rhi-capture.test-d.ts +21 -0
- package/src/__tests__/callback-inference.test-d.ts +8 -0
- package/src/__tests__/cluster-binner.test.ts +272 -0
- package/src/__tests__/cluster-grid-default-surface.unit.test.ts +20 -0
- package/src/__tests__/construct-renderer-identity.unit.test.ts +23 -0
- 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 +23 -0
- package/src/__tests__/direct-light-snapshot.unit.test.ts +61 -0
- package/src/__tests__/factory-contract.integration.test.ts +280 -0
- package/src/__tests__/fallback-row-stride-surface.unit.test.ts +15 -0
- package/src/__tests__/frame-observation.contract.test.ts +112 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +32 -0
- package/src/__tests__/glyph-text-layout-recovery.unit.test.ts +167 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +350 -0
- package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +12 -0
- package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +16 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +436 -0
- package/src/__tests__/gpu-driven-scaling.unit.test.ts +87 -0
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +271 -0
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +290 -0
- package/src/__tests__/gpu-driven-view-reference.ts +111 -0
- package/src/__tests__/gpu-driven-view.browser.test.ts +30 -0
- package/src/__tests__/gpu-driven-view.dawn.test.ts +28 -0
- package/src/__tests__/gpu-driven-view.unit.test.ts +199 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +59 -0
- package/src/__tests__/gpu-scene-render-graph-gpu.ts +308 -0
- package/src/__tests__/gpu-scene-render-graph.browser.test.ts +19 -0
- package/src/__tests__/gpu-scene-render-graph.dawn.test.ts +19 -0
- package/src/__tests__/gpu-scene-schema.unit.test.ts +16 -0
- package/src/__tests__/gpu-scene.dawn.test.ts +205 -0
- package/src/__tests__/gpu-scene.unit.test.ts +147 -0
- package/src/__tests__/ibl/face-uniforms.unit.test.ts +46 -0
- package/src/__tests__/infinite-grid-no-vertex-probe.unit.test.ts +92 -0
- package/src/__tests__/injection-kind-owner.test-d.ts +14 -0
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +728 -0
- package/src/__tests__/light-buffer-layout.unit.test.ts +40 -0
- package/src/__tests__/material-contract-inventory.unit.test.ts +24 -0
- package/src/__tests__/material-cooked-projection.unit.test.ts +150 -0
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +53 -0
- package/src/__tests__/material-static-dynamic-route.unit.test.ts +94 -0
- package/src/__tests__/material-stride-surface.unit.test.ts +32 -0
- package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +106 -0
- package/src/__tests__/mesh-material-bindings.unit.test.ts +89 -0
- package/src/__tests__/mesh-stride-surface.unit.test.ts +16 -0
- package/src/__tests__/morph-culling-reentry.dawn.test.ts +157 -0
- package/src/__tests__/morph-feature-gpu-work.integration.test.ts +80 -0
- package/src/__tests__/morph-feature-plan.unit.test.ts +53 -0
- package/src/__tests__/morph-visual-evidence.integration.test.ts +80 -0
- package/src/__tests__/nineslice-handle-surface.unit.test.ts +19 -0
- package/src/__tests__/post-process-error-policy-owner.unit.test.ts +201 -0
- package/src/__tests__/prepared-buffer-kind-owner.test-d.ts +29 -0
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +65 -0
- package/src/__tests__/prepared-graphics-generation.unit.test.ts +161 -0
- package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +138 -0
- package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +29 -0
- package/src/__tests__/prepared-graphics-resolver.unit.test.ts +285 -0
- package/src/__tests__/prepared-graphics-snapshot.unit.test.ts +105 -0
- package/src/__tests__/prepared-graphics-store.unit.test.ts +154 -0
- package/src/__tests__/prepared-graphics-validation.unit.test.ts +176 -0
- package/src/__tests__/profiler-default-off.test.ts +22 -0
- package/src/__tests__/profiler-phase-catalog.test.ts +66 -0
- package/src/__tests__/profiler-phase-integration.test.ts +62 -0
- package/src/__tests__/profiler-phase-token.test.ts +79 -0
- package/src/__tests__/public-surface.test-d.ts +94 -0
- package/src/__tests__/recover-error-policy-owner.unit.test.ts +107 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +116 -0
- package/src/__tests__/render-error-detail-ssot.test-d.ts +139 -0
- package/src/__tests__/render-error-exhaustive.test-d.ts +110 -0
- package/src/__tests__/render-feature-assembly.test-d.ts +43 -0
- package/src/__tests__/render-feature-context.test-d.ts +57 -0
- package/src/__tests__/render-feature-contract.test-d.ts +49 -0
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +149 -0
- package/src/__tests__/render-feature-docs.unit.test.ts +89 -0
- package/src/__tests__/render-feature-errors.unit.test.ts +47 -0
- package/src/__tests__/render-feature-gpu-work.integration.test.ts +316 -0
- 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 +90 -0
- package/src/__tests__/render-feature-prepared-errors.test-d.ts +79 -0
- package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +80 -0
- package/src/__tests__/render-feature-prepared-graphics-isolation.unit.test.ts +72 -0
- package/src/__tests__/render-feature-prepared-graphics-negative.test-d.ts +36 -0
- package/src/__tests__/render-feature-prepared-graphics.test-d.ts +74 -0
- package/src/__tests__/render-feature-prepared-graphics.unit.test.ts +121 -0
- package/src/__tests__/render-feature-public-surface.test-d.ts +57 -0
- package/src/__tests__/render-feature-retry.unit.test.ts +87 -0
- package/src/__tests__/render-feature-scheduling.unit.test.ts +110 -0
- package/src/__tests__/render-feature-stage-failed-policy-owner.unit.test.ts +137 -0
- package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +146 -0
- package/src/__tests__/render-feature-visibility-context.test-d.ts +33 -0
- package/src/__tests__/render-feature-visibility-context.unit.test.ts +37 -0
- package/src/__tests__/render-feature-zero-work.unit.test.ts +76 -0
- package/src/__tests__/render-graph-compute-raster-gpu.ts +342 -0
- package/src/__tests__/render-graph-compute-raster.browser.test.ts +16 -0
- package/src/__tests__/render-graph-compute-raster.dawn.test.ts +22 -0
- package/src/__tests__/render-graph-hzb-gpu.ts +239 -0
- package/src/__tests__/render-graph-hzb.browser.test.ts +16 -0
- package/src/__tests__/render-graph-hzb.dawn.test.ts +23 -0
- package/src/__tests__/render-graph-primitives.unit.test.ts +22 -0
- package/src/__tests__/render-graph-storage-indirect-gpu.ts +162 -0
- package/src/__tests__/render-graph-storage-indirect.browser.test.ts +21 -0
- package/src/__tests__/render-graph-storage-indirect.dawn.test.ts +28 -0
- package/src/__tests__/render-scene-projection.unit.test.ts +168 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +121 -0
- package/src/__tests__/renderer-lifecycle.integration.test.ts +58 -0
- package/src/__tests__/rhi-backend-package-boundary.unit.test.ts +11 -0
- package/src/__tests__/scriptable-pack-consumer.test-d.ts +14 -0
- package/src/__tests__/shader-stage-surface.unit.test.ts +43 -0
- package/src/__tests__/ssao-config.unit.test.ts +36 -0
- package/src/__tests__/ssao-kernel-surface.unit.test.ts +14 -0
- 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 +91 -0
- package/src/__tests__/texture-usage-surface.unit.test.ts +58 -0
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +223 -0
- package/src/__tests__/urp-pipeline-targets.unit.test.ts +42 -0
- package/src/__tests__/urp-pipeline.unit.test.ts +14 -0
- package/src/__tests__/vertex-color-pipeline.unit.test.ts +132 -0
- package/src/__tests__/vertex-layout-consumer.unit.test.ts +25 -0
- package/src/__tests__/visibility-diagnostics.integration.test.ts +62 -0
- package/src/__tests__/visibility-extract.integration.test.ts +98 -0
- package/src/__tests__/visibility-extract.perf.test.ts +130 -0
- package/src/__tests__/visibility-feature-dedup.integration.test.ts +55 -0
- package/src/__tests__/visibility-hidden-report.unit.test.ts +36 -0
- package/src/__tests__/visibility-instances.integration.test.ts +46 -0
- package/src/__tests__/visibility-multi-world.integration.test.ts +86 -0
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +168 -0
- package/src/__tests__/visibility-producer-matrix.unit.test.ts +96 -0
- package/src/__tests__/visibility-public-surface.test-d.ts +27 -0
- package/src/__tests__/visibility-resolver.unit.test.ts +85 -0
- package/src/__tests__/visibility-resource-short-circuit.unit.test.ts +80 -0
- package/src/__tests__/visibility-snapshot-contract.unit.test.ts +60 -0
- package/src/__tests__/vocabulary.unit.test.ts +21 -0
- package/src/assembly/backend-contract.ts +57 -0
- package/src/assembly/factory.ts +8130 -0
- package/src/assembly/host-contract.ts +101 -0
- package/src/assembly/material/assembly.ts +48 -0
- package/src/assembly/material/pipeline-projection.ts +63 -0
- package/src/assets/asset-decoders.ts +158 -0
- package/src/assets/render-asset-port.ts +44 -0
- package/src/assets/resolve-render-asset.ts +13 -0
- package/src/authoring.ts +17 -0
- package/src/cluster-binner.ts +700 -0
- package/src/components/__tests__/points-lines-admission.unit.test.ts +219 -0
- package/src/components/__tests__/points-lines-schema.unit.test.ts +56 -0
- package/src/components/__tests__/schema-contract.unit.test.ts +10 -0
- package/src/components/__tests__/schema-parity.unit.test.ts +25 -0
- package/src/components/__tests__/visibility-schema.unit.test.ts +35 -0
- package/src/components/camera.ts +512 -0
- package/src/components/directional-light.ts +120 -0
- package/src/components/glyph-text.ts +64 -0
- package/src/components/index.ts +54 -0
- package/src/components/instances.ts +206 -0
- package/src/components/layer.ts +69 -0
- package/src/components/light-helpers.ts +188 -0
- package/src/components/lines.ts +18 -0
- package/src/components/mesh-filter.ts +60 -0
- package/src/components/mesh-renderer.ts +61 -0
- package/src/components/point-light-shadow.ts +43 -0
- package/src/components/point-light.ts +65 -0
- package/src/components/points.ts +40 -0
- package/src/components/post-process-params.ts +35 -0
- package/src/components/scene-instance.ts +193 -0
- package/src/components/skybox-background.ts +103 -0
- package/src/components/skylight.ts +97 -0
- package/src/components/sort-key.ts +75 -0
- package/src/components/spot-light.ts +124 -0
- package/src/components/sprite-animation.ts +168 -0
- package/src/components/sprite-instances.ts +179 -0
- package/src/components/sprite-playback-mode.ts +79 -0
- package/src/components/sprite-region-override.ts +105 -0
- package/src/components/tile-layer.ts +167 -0
- package/src/components/tilemap.ts +48 -0
- package/src/components/visibility.ts +53 -0
- package/src/construct-renderer.ts +67 -0
- package/src/debug-draw-glue.ts +48 -0
- package/src/device/device-scope.ts +306 -0
- package/src/device/gpu-residency.ts +1822 -0
- package/src/device/resource-types.ts +20 -0
- package/src/engine-metrics.ts +82 -0
- package/src/errors/ecs-validation.ts +16 -0
- package/src/errors/index.ts +3 -0
- package/src/errors/recover.ts +161 -0
- package/src/errors/render.ts +1284 -0
- package/src/extract/visibility.ts +120 -0
- package/src/features/fullscreen.ts +46 -0
- package/src/features/host.ts +1363 -0
- package/src/features/morph/morph-feature.ts +377 -0
- package/src/features/plan.ts +447 -0
- package/src/features/prepared-gpu-work.ts +959 -0
- package/src/features/prepared-graphics-store.ts +449 -0
- package/src/features/prepared-graphics.ts +420 -0
- package/src/features/render-graph-compute.ts +69 -0
- package/src/features/render-graph-contribution.ts +75 -0
- package/src/features/render-graph-raster.ts +332 -0
- package/src/features/render-graph-resources.ts +38 -0
- package/src/features/targets.ts +70 -0
- package/src/features/types.ts +103 -0
- package/src/features/vocabulary.ts +24 -0
- package/src/fullscreen-post-process-pass.ts +363 -0
- package/src/glyph-text-layout-system.ts +421 -0
- package/src/gpu-driven/batch-topology.ts +245 -0
- package/src/gpu-driven/production-raster.ts +695 -0
- package/src/gpu-driven/view-gpu.ts +703 -0
- package/src/gpu-resource.ts +159 -0
- package/src/gpu-scene-schema.ts +136 -0
- package/src/gpu-scene.ts +722 -0
- package/src/gpu-stage.ts +9 -0
- package/src/gpu-texture-usage.ts +12 -0
- package/src/gpu-usage.ts +14 -0
- package/src/hdrp-buffers.ts +480 -0
- package/src/ibl/IblPipelineCache.ts +1006 -0
- package/src/ibl/skylight-bind-group.ts +513 -0
- package/src/index.ts +129 -0
- package/src/inspection-types.ts +80 -0
- package/src/instance-buffer-cache.ts +95 -0
- package/src/internal.ts +9 -0
- package/src/lifecycle.ts +168 -0
- package/src/light-buffer-layout.ts +346 -0
- package/src/materials.ts +214 -0
- package/src/mesh-material-bindings.ts +103 -0
- package/src/pbr-pipeline.ts +1137 -0
- package/src/pipeline/standard-forward-lane.ts +229 -0
- package/src/pipeline/standard-pipeline.ts +555 -0
- package/src/pipeline/standard-profile.ts +65 -0
- package/src/pipeline-builder.ts +382 -0
- package/src/pipeline-spec-types.ts +28 -0
- package/src/pipeline-spec.ts +1231 -0
- package/src/plugin.ts +69 -0
- package/src/points-lines/__tests__/bounds.unit.test.ts +21 -0
- package/src/points-lines/__tests__/cache-recovery.unit.test.ts +157 -0
- package/src/points-lines/__tests__/inspection-lanes.integration.test.ts +146 -0
- package/src/points-lines/__tests__/inspection.unit.test.ts +173 -0
- package/src/points-lines/__tests__/lane-structural.integration.test.ts +122 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +400 -0
- package/src/points-lines/__tests__/raster-lane.integration.test.ts +44 -0
- package/src/points-lines/__tests__/snapshot.unit.test.ts +101 -0
- package/src/points-lines/__tests__/view-ubo.unit.test.ts +73 -0
- package/src/points-lines/admission.ts +238 -0
- package/src/points-lines/bounds.ts +23 -0
- package/src/points-lines/expansion-cache.ts +215 -0
- package/src/points-lines/inspection.ts +97 -0
- package/src/points-lines/prepare.ts +177 -0
- package/src/points-lines/record.ts +125 -0
- package/src/points-lines/snapshot.ts +130 -0
- package/src/post-process-errors.ts +302 -0
- package/src/prepare/prepared-graphics-resolver.ts +456 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +41 -0
- package/src/record/__tests__/material-slot-plan.unit.test.ts +44 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +41 -0
- package/src/record/__tests__/video-texture-view.unit.test.ts +90 -0
- package/src/record/frame-lighting.ts +1074 -0
- package/src/record/frame-snapshot.ts +500 -0
- package/src/record/frame-targets.ts +137 -0
- package/src/record/frame.ts +1598 -0
- package/src/record/helpers.ts +284 -0
- package/src/record/main-pass-geometry.ts +1065 -0
- package/src/record/main-pass-material.ts +1043 -0
- package/src/record/main-pass-sprite-draws.ts +1137 -0
- package/src/record/main-pass.ts +610 -0
- package/src/record/mesh-ssbo.ts +885 -0
- package/src/record/render-context.ts +384 -0
- package/src/record/shadow-pass.ts +698 -0
- package/src/record/skybox-post-pass.ts +593 -0
- package/src/record/typed-frame-graph.ts +461 -0
- package/src/record/view-ubo.ts +222 -0
- package/src/render-contract.ts +582 -0
- package/src/render-data.ts +385 -0
- package/src/render-graph-primitives.ts +811 -0
- package/src/render-pipeline.ts +259 -0
- package/src/render-system-extract.ts +4585 -0
- package/src/render-system.ts +1933 -0
- package/src/scene/render-scene-types.ts +67 -0
- package/src/scene/render-scene.ts +1087 -0
- package/src/scene-instances/post-spawn-resolve-joints.ts +165 -0
- package/src/shadow-atlas.ts +244 -0
- package/src/ssao-buffers.ts +334 -0
- package/src/ssao-config.ts +61 -0
- package/src/systems/active-camera.ts +116 -0
- package/src/systems/pass-selector.ts +49 -0
- package/src/systems/skin-palette-allocator.ts +251 -0
- package/src/systems/skin-palette-types.ts +14 -0
- package/src/systems/transparent-sort-config.ts +233 -0
- package/src/tilemap-chunk-extract-system.ts +1290 -0
- package/src/typed-render-graph-primitives.ts +541 -0
- package/src/typed-shadow-passes.ts +165 -0
|
@@ -0,0 +1,1006 @@
|
|
|
1
|
+
// IblPipelineCache.ts -- DeviceScope-generation cache for IBL precompute.
|
|
2
|
+
//
|
|
3
|
+
// Plan-strategy D-1/D-7: cache for 4 GPU passes (equirect->cube /
|
|
4
|
+
// irradiance / prefilter / BRDF LUT). M2 provides the cache skeleton;
|
|
5
|
+
// M3 (t18/t20) wires real shader math from ibl.wgsl.
|
|
6
|
+
//
|
|
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
|
+
//
|
|
10
|
+
// Public surface (M3):
|
|
11
|
+
// - getOrCreateIblCache(scope): get or initialize the generation cache
|
|
12
|
+
// - iblCacheSize(): introspection hook
|
|
13
|
+
// - hasIblCache(scope): introspection hook
|
|
14
|
+
// - setIblWgslSource(source): set the ibl.wgsl WGSL source string
|
|
15
|
+
// - createIblShaderModules(device, factory): create shader modules from ibl.wgsl
|
|
16
|
+
// - createIblPipelines(scope, device, factory, modules): create 4 render pipelines
|
|
17
|
+
// - runIblPrecompute(opts): execute 4 GPU precompute passes (M3 t20)
|
|
18
|
+
//
|
|
19
|
+
// M3 t20: pipeline slots are filled with real render pipelines loaded from
|
|
20
|
+
// ibl.wgsl, replacing the M2 stub undefined slots. The 4 GPU passes are
|
|
21
|
+
// executed in the standard order (equirect->cube -> irradiance -> prefilter
|
|
22
|
+
// -> BRDF LUT), with counters set post-execution per AC-04/05/06.
|
|
23
|
+
|
|
24
|
+
// ─── RHI-owned handles ───────────────────────────────────────────────────────
|
|
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';
|
|
46
|
+
import { GPU_SHADER_STAGE_FRAGMENT, GPU_SHADER_STAGE_VERTEX } from '../gpu-stage';
|
|
47
|
+
import {
|
|
48
|
+
GPU_TEXTURE_USAGE_COPY_DST,
|
|
49
|
+
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
50
|
+
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING,
|
|
51
|
+
} from '../gpu-texture-usage';
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Shader module factory (async, injected via configureGpuDevice).
|
|
55
|
+
* Mirrors `MipmapShaderModuleFactory` from mipmap-generator.
|
|
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
|
+
|
|
65
|
+
export type IblShaderModuleFactory = (
|
|
66
|
+
device: IblRhiOwner,
|
|
67
|
+
desc: { code: string; label?: string },
|
|
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
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Per-DeviceScope-generation IBL pipeline cache instance.
|
|
86
|
+
*
|
|
87
|
+
* M3.5 (round-2 t52): the 4 pipeline slots are mutable so createIblPipelines
|
|
88
|
+
* can fill them after construction. The 4 textures + their views are also
|
|
89
|
+
* cached here so runIblPrecompute targets are stable across calls
|
|
90
|
+
* (idempotent).
|
|
91
|
+
*/
|
|
92
|
+
export interface IblPipelineCache {
|
|
93
|
+
/** Color format shared by all precompute outputs for this device. */
|
|
94
|
+
outputFormat?: TextureFormat;
|
|
95
|
+
/** Equirectangular-to-cubemap pipeline. */
|
|
96
|
+
equirectToCubePipeline?: RenderPipeline;
|
|
97
|
+
/** Diffuse irradiance convolution pipeline. */
|
|
98
|
+
irradiancePipeline?: RenderPipeline;
|
|
99
|
+
/** Specular prefilter pipeline. */
|
|
100
|
+
prefilterPipeline?: RenderPipeline;
|
|
101
|
+
/** BRDF integration LUT pipeline. */
|
|
102
|
+
brdfLutPipeline?: RenderPipeline;
|
|
103
|
+
|
|
104
|
+
/** Face uniforms BGL (shared across equirect/irradiance/prefilter, D-9). */
|
|
105
|
+
faceUniformsBgl?: BindGroupLayout;
|
|
106
|
+
/** group(1) BGL for the equirect-to-cube pass (texture_2d + sampler). */
|
|
107
|
+
equirectGroup1Bgl?: BindGroupLayout;
|
|
108
|
+
/** group(1) BGL for irradiance + prefilter (texture_cube + sampler). */
|
|
109
|
+
cubeGroup1Bgl?: BindGroupLayout;
|
|
110
|
+
/** group(0) BGL for prefilter (face + prefilter uniforms). */
|
|
111
|
+
prefilterGroup0Bgl?: BindGroupLayout;
|
|
112
|
+
|
|
113
|
+
/** Irradiance cubemap texture (32x32; outputFormat, cube). */
|
|
114
|
+
irradianceTexture?: Texture;
|
|
115
|
+
/** Irradiance cubemap view (dimension:cube). */
|
|
116
|
+
irradianceView?: TextureView;
|
|
117
|
+
/** Per-face 2D views for irradiance (render-attachment use). */
|
|
118
|
+
irradianceFaceViews?: ReadonlyArray<TextureView>;
|
|
119
|
+
/** Specular prefilter cubemap (128x128, 5 mip levels). */
|
|
120
|
+
prefilterTexture?: Texture;
|
|
121
|
+
/** Prefilter cubemap view (dimension:cube, all mips). */
|
|
122
|
+
prefilterView?: TextureView;
|
|
123
|
+
/** Per-face 2D views per mip for prefilter (5 mips x 6 faces). */
|
|
124
|
+
prefilterFaceViewsByMip?: ReadonlyArray<ReadonlyArray<TextureView>>;
|
|
125
|
+
/** BRDF LUT (256x256; outputFormat). */
|
|
126
|
+
brdfLutTexture?: Texture;
|
|
127
|
+
/** BRDF LUT view. */
|
|
128
|
+
brdfLutView?: TextureView;
|
|
129
|
+
|
|
130
|
+
/** Counter: times irradiance pass has executed. AC-04: == 1 after first cook. */
|
|
131
|
+
irradianceBakeCount: number;
|
|
132
|
+
/** Counter: times prefilter pass has executed. AC-05: == 1 after first cook. */
|
|
133
|
+
prefilterBakeCount: number;
|
|
134
|
+
/** Counter: times BRDF LUT pass has executed. AC-06: == 1 after first cook. */
|
|
135
|
+
brdfLutBakeCount: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
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.
|
|
143
|
+
*/
|
|
144
|
+
const scopeCaches: WeakMap<DeviceScope, IblPipelineCache> = new WeakMap();
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Get or create the current-generation IBL pipeline cache.
|
|
148
|
+
*/
|
|
149
|
+
export function getOrCreateIblCache(scope: DeviceScope): IblPipelineCache {
|
|
150
|
+
const existing = scopeCaches.get(scope);
|
|
151
|
+
if (existing !== undefined) return existing;
|
|
152
|
+
|
|
153
|
+
const cache: IblPipelineCache = {
|
|
154
|
+
irradianceBakeCount: 0,
|
|
155
|
+
prefilterBakeCount: 0,
|
|
156
|
+
brdfLutBakeCount: 0,
|
|
157
|
+
};
|
|
158
|
+
scopeCaches.set(scope, cache);
|
|
159
|
+
return cache;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Check whether a DeviceScope generation has an active cache entry.
|
|
164
|
+
*/
|
|
165
|
+
export function hasIblCache(scope: DeviceScope): boolean {
|
|
166
|
+
return scopeCaches.has(scope);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ─── M3.5 composed ibl-* shader source registry ─────────────────────────────
|
|
170
|
+
//
|
|
171
|
+
// 4 composed WGSL strings -- one per render pipeline. Each string is the
|
|
172
|
+
// output of @forgeax/engine-naga composeShader after merging ibl_shared +
|
|
173
|
+
// the per-pass module. Built by ShaderCatalog / vite-plugin-shader at
|
|
174
|
+
// build-time so the runtime cache never reaches into engine-naga
|
|
175
|
+
// (AGENTS.md grep gate forbids).
|
|
176
|
+
|
|
177
|
+
export interface IblComposedShaders {
|
|
178
|
+
/** ibl-equirect-to-cube composed (cubemap_vs + equirectToCube_fs). */
|
|
179
|
+
readonly equirectToCube: string;
|
|
180
|
+
/** ibl-irradiance composed (cubemap_vs + irradianceConvolve_fs). */
|
|
181
|
+
readonly irradiance: string;
|
|
182
|
+
/** ibl-prefilter composed (cubemap_vs + prefilterEnv_fs). */
|
|
183
|
+
readonly prefilter: string;
|
|
184
|
+
/** ibl-brdf-lut composed (fullscreen_vs + brdfLutBake_fs). */
|
|
185
|
+
readonly brdfLut: string;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
let iblComposedShadersCache: IblComposedShaders | undefined;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Inject the composed ibl-* shader sources used by createIblPipelines.
|
|
192
|
+
* Called once by the engine bootstrap (createRenderer step "shader-load")
|
|
193
|
+
* with the 4 composed entries from ShaderCatalog.
|
|
194
|
+
*/
|
|
195
|
+
export function setIblComposedShaders(sources: IblComposedShaders): void {
|
|
196
|
+
iblComposedShadersCache = sources;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// ─── Standard cube vertices for cubemap face rendering ───────────────────────
|
|
200
|
+
// 36 vertices (6 faces * 2 triangles * 3 vertices), vec3<f32> format.
|
|
201
|
+
// Unit cube [-1, 1]^3 centered at origin.
|
|
202
|
+
export const CUBEMAP_FACE_VERTICES = new Float32Array([
|
|
203
|
+
// +X face (+1, 0, 0)
|
|
204
|
+
1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,
|
|
205
|
+
// -X face (-1, 0, 0)
|
|
206
|
+
-1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,
|
|
207
|
+
1.0,
|
|
208
|
+
// +Y face (0, +1, 0)
|
|
209
|
+
-1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,
|
|
210
|
+
// -Y face (0, -1, 0)
|
|
211
|
+
-1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0,
|
|
212
|
+
1.0,
|
|
213
|
+
// +Z face (0, 0, +1)
|
|
214
|
+
-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0,
|
|
215
|
+
// -Z face (0, 0, -1)
|
|
216
|
+
1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0,
|
|
217
|
+
-1.0,
|
|
218
|
+
]);
|
|
219
|
+
|
|
220
|
+
// 6 capture view-projection matrices (right-handed, from origin).
|
|
221
|
+
// Projection Y is negated for WebGPU top-left framebuffer origin.
|
|
222
|
+
// Target directions: +X, -X, +Y, -Y, +Z, -Z.
|
|
223
|
+
// Up vectors: -Y for X/Z faces, +Z for +Y, -Z for -Y.
|
|
224
|
+
export const CAPTURE_VIEW_PROJS = buildCaptureViewProjs();
|
|
225
|
+
|
|
226
|
+
function buildCaptureViewProjs(): Float32Array[] {
|
|
227
|
+
const targets: [number, number, number][] = [
|
|
228
|
+
[1, 0, 0],
|
|
229
|
+
[-1, 0, 0],
|
|
230
|
+
[0, 1, 0],
|
|
231
|
+
[0, -1, 0],
|
|
232
|
+
[0, 0, 1],
|
|
233
|
+
[0, 0, -1],
|
|
234
|
+
];
|
|
235
|
+
const ups: [number, number, number][] = [
|
|
236
|
+
[0, -1, 0],
|
|
237
|
+
[0, -1, 0],
|
|
238
|
+
[0, 0, 1],
|
|
239
|
+
[0, 0, -1],
|
|
240
|
+
[0, -1, 0],
|
|
241
|
+
[0, -1, 0],
|
|
242
|
+
];
|
|
243
|
+
|
|
244
|
+
const proj = cubemapCaptureProjection(Math.PI / 2, 0.1, 10.0);
|
|
245
|
+
|
|
246
|
+
return targets.map((_t, i) => {
|
|
247
|
+
const t = _t;
|
|
248
|
+
const u = ups[i] ?? [0, -1, 0];
|
|
249
|
+
const view = lookAtMatrix([0, 0, 0], t, u);
|
|
250
|
+
return mulMat4(proj, view);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
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
|
+
|
|
266
|
+
function lookAtMatrix(
|
|
267
|
+
eye: readonly number[],
|
|
268
|
+
target: readonly number[],
|
|
269
|
+
up: readonly number[],
|
|
270
|
+
): Float32Array {
|
|
271
|
+
const [ex, ey0, ez] = [eye[0] ?? 0, eye[1] ?? 0, eye[2] ?? 0];
|
|
272
|
+
const [tx, ty, tz] = [target[0] ?? 0, target[1] ?? 0, target[2] ?? 0];
|
|
273
|
+
const [upx, upy, upz] = [up[0] ?? 0, up[1] ?? 0, up[2] ?? 0];
|
|
274
|
+
let fx = ex - tx,
|
|
275
|
+
fy = ey0 - ty,
|
|
276
|
+
fz = ez - tz;
|
|
277
|
+
const fLen = Math.sqrt(fx * fx + fy * fy + fz * fz);
|
|
278
|
+
fx /= fLen;
|
|
279
|
+
fy /= fLen;
|
|
280
|
+
fz /= fLen;
|
|
281
|
+
|
|
282
|
+
let rx = upy * fz - upz * fy;
|
|
283
|
+
let ry = upz * fx - upx * fz;
|
|
284
|
+
let rz = upx * fy - upy * fx;
|
|
285
|
+
const rLen = Math.sqrt(rx * rx + ry * ry + rz * rz);
|
|
286
|
+
rx /= rLen;
|
|
287
|
+
ry /= rLen;
|
|
288
|
+
rz /= rLen;
|
|
289
|
+
|
|
290
|
+
const ux = fy * rz - fz * ry;
|
|
291
|
+
const uy = fz * rx - fx * rz;
|
|
292
|
+
const uz = fx * ry - fy * rx;
|
|
293
|
+
|
|
294
|
+
return new Float32Array([
|
|
295
|
+
rx,
|
|
296
|
+
ux,
|
|
297
|
+
fx,
|
|
298
|
+
0,
|
|
299
|
+
ry,
|
|
300
|
+
uy,
|
|
301
|
+
fy,
|
|
302
|
+
0,
|
|
303
|
+
rz,
|
|
304
|
+
uz,
|
|
305
|
+
fz,
|
|
306
|
+
0,
|
|
307
|
+
-(rx * ex + ry * ey0 + rz * ez),
|
|
308
|
+
-(ux * ex + uy * ey0 + uz * ez),
|
|
309
|
+
-(fx * ex + fy * ey0 + fz * ez),
|
|
310
|
+
1,
|
|
311
|
+
]);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Column-major matrix product `r = a * b` where each Float32Array stores
|
|
315
|
+
// 4 contiguous column vectors of 4 floats (WGSL `mat4x4<f32>` uniform
|
|
316
|
+
// layout). For column-major storage `flat[c*4 + row] = M[col=c, row]`, so:
|
|
317
|
+
// (a * b)[col=c, row=r] = sum_k a[col=k, row=r] * b[col=c, row=k]
|
|
318
|
+
// flat_out[c*4 + r] = sum_k a[k*4 + r] * b[c*4 + k]
|
|
319
|
+
//
|
|
320
|
+
// The prior row-major iteration silently transposed the result, producing
|
|
321
|
+
// `b * a` in WGSL's view -- IBL equirect-to-cube vertices then projected
|
|
322
|
+
// to clip with w=0 / w=-1, every face fell outside the [-1,1] frustum, no
|
|
323
|
+
// fragments drew, and every downstream IBL texture (irradiance / prefilter)
|
|
324
|
+
// inherited the clearValue=(0,0,0,1). Demo 3x3 sphere matrix rendered
|
|
325
|
+
// pure black because `ambient = kD * 0 + specular * 0 = 0` and there are
|
|
326
|
+
// no direct lights in the IBL demo scene.
|
|
327
|
+
function mulMat4(a: Float32Array, b: Float32Array): Float32Array {
|
|
328
|
+
const r = new Float32Array(16);
|
|
329
|
+
for (let c = 0; c < 4; c++) {
|
|
330
|
+
for (let row = 0; row < 4; row++) {
|
|
331
|
+
let sum = 0;
|
|
332
|
+
for (let k = 0; k < 4; k++) {
|
|
333
|
+
sum += (a[k * 4 + row] ?? 0) * (b[c * 4 + k] ?? 0);
|
|
334
|
+
}
|
|
335
|
+
r[c * 4 + row] = sum;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return r;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// ─── M3.5 t52: createIblPipelines (4 independent GPURenderPipelines) ─────────
|
|
342
|
+
|
|
343
|
+
// IBL output texture sizes (plan D-10 SSOT, mirrored in ibl-brdf-lut.wgsl).
|
|
344
|
+
export const IRRADIANCE_SIZE = 32;
|
|
345
|
+
export const PREFILTER_SIZE = 128;
|
|
346
|
+
export const PREFILTER_MIP_LEVELS = 5;
|
|
347
|
+
export const BRDF_LUT_SIZE = 256;
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Create 4 independent GPURenderPipelines + their shared / per-pass bind
|
|
351
|
+
* group layouts. Pipeline slots are stored on the per-device cache and
|
|
352
|
+
* survive across calls (D-1 startup-once cook).
|
|
353
|
+
*
|
|
354
|
+
* D-9: faceUniforms BGL (@group(0) for equirect/irradiance/prefilter) is
|
|
355
|
+
* a single instance reused across 3 pipelines (binary-compatible).
|
|
356
|
+
* group(1) is per-pipeline: texture_2d for equirect, texture_cube for
|
|
357
|
+
* irradiance + prefilter, none for brdf-lut.
|
|
358
|
+
*/
|
|
359
|
+
export async function createIblPipelines(
|
|
360
|
+
scope: DeviceScope,
|
|
361
|
+
device: IblRhiOwner,
|
|
362
|
+
factory: IblShaderModuleFactory,
|
|
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
|
+
});
|
|
378
|
+
}
|
|
379
|
+
// Keep the output format on the per-device cache so the four pipelines and
|
|
380
|
+
// their lazily-created side textures cannot drift. WebGL2 may need the
|
|
381
|
+
// renderable rgba8 fallback even when the source equirect remains float.
|
|
382
|
+
const outputFormat = cubeOutputFormat;
|
|
383
|
+
cache.outputFormat = outputFormat;
|
|
384
|
+
|
|
385
|
+
const composed = iblComposedShadersCache;
|
|
386
|
+
// Mock-device path: factory returns synthetic modules. Both production
|
|
387
|
+
// (composed) and unit-test (placeholder code) paths converge here.
|
|
388
|
+
const fallbackCode = '@vertex fn vs() -> @builtin(position) vec4<f32> { return vec4<f32>(0.0); }';
|
|
389
|
+
const src = composed ?? {
|
|
390
|
+
equirectToCube: fallbackCode,
|
|
391
|
+
irradiance: fallbackCode,
|
|
392
|
+
prefilter: fallbackCode,
|
|
393
|
+
brdfLut: fallbackCode,
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
const modules = await Promise.all([
|
|
397
|
+
factory(device, { code: src.equirectToCube, label: 'ibl-equirect-to-cube' }),
|
|
398
|
+
factory(device, { code: src.irradiance, label: 'ibl-irradiance' }),
|
|
399
|
+
factory(device, { code: src.prefilter, label: 'ibl-prefilter' }),
|
|
400
|
+
factory(device, { code: src.brdfLut, label: 'ibl-brdf-lut' }),
|
|
401
|
+
]);
|
|
402
|
+
for (const m of modules) {
|
|
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'));
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// D-9: faceUniforms BGL shared across 3 pipelines (equirect / irradiance /
|
|
415
|
+
// prefilter). The prefilter additionally needs binding(1) for prefUniforms;
|
|
416
|
+
// we keep a separate BGL for the prefilter group(0) to honour the WGSL
|
|
417
|
+
// declaration in ibl-prefilter.wgsl.
|
|
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;
|
|
470
|
+
|
|
471
|
+
// Pipeline layouts.
|
|
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);
|
|
492
|
+
|
|
493
|
+
const vertexLayout3F = {
|
|
494
|
+
arrayStride: 12,
|
|
495
|
+
attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x3' as const }],
|
|
496
|
+
};
|
|
497
|
+
|
|
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
|
+
}
|
|
561
|
+
|
|
562
|
+
function iblPipelineError(
|
|
563
|
+
stage: string,
|
|
564
|
+
code: IblPipelineError['code'],
|
|
565
|
+
cause?: RhiError,
|
|
566
|
+
): IblPipelineError {
|
|
567
|
+
return {
|
|
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 }) },
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// ─── M3.5 t53: runIblPrecompute (4-pass dispatch + queue.submit) ─────────────
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Options consumed by runIblPrecompute. The caller (the internal
|
|
579
|
+
* GpuResidencyCache equirect-to-cubemap projection) provides the equirect input
|
|
580
|
+
* + cubemap target GPU resources; the face-uniform / prefilter-uniform buffers
|
|
581
|
+
* come from the t55 helpers.
|
|
582
|
+
*/
|
|
583
|
+
export interface RunIblPrecomputeOptions {
|
|
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'] };
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Execute the 4 IBL precompute passes (equirect-to-cube / irradiance /
|
|
605
|
+
* prefilter / brdf-lut) in a single CommandEncoder and submit.
|
|
606
|
+
*
|
|
607
|
+
* Counter invariant (AC-20, plan D-7 / N-3): the
|
|
608
|
+
* `irradiance/prefilter/brdfLut BakeCount` counters are incremented
|
|
609
|
+
* AFTER queue.submit returns. If submit throws or returns Result.err, the
|
|
610
|
+
* counters stay at 0 -- this is the prime safety guard against the
|
|
611
|
+
* round-1 "counter += 1 as dispatch proxy" anti-pattern.
|
|
612
|
+
*
|
|
613
|
+
* Returns Result.err with code='ibl-precompute-not-dispatched' when the
|
|
614
|
+
* underlying device lacks queue.submit or one of the 4 pipelines was not
|
|
615
|
+
* created (createIblPipelines must run first).
|
|
616
|
+
*/
|
|
617
|
+
export function runIblPrecompute(
|
|
618
|
+
opts: RunIblPrecomputeOptions,
|
|
619
|
+
): Result<{ submitted: boolean }, IblPrecomputeError> {
|
|
620
|
+
const { device, scope } = opts;
|
|
621
|
+
const cache = getOrCreateIblCache(scope);
|
|
622
|
+
const outputFormat = cache.outputFormat ?? 'rgba16float';
|
|
623
|
+
|
|
624
|
+
if (
|
|
625
|
+
cache.equirectToCubePipeline === undefined ||
|
|
626
|
+
cache.irradiancePipeline === undefined ||
|
|
627
|
+
cache.prefilterPipeline === undefined ||
|
|
628
|
+
cache.brdfLutPipeline === undefined
|
|
629
|
+
) {
|
|
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
|
+
});
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Allocate side textures (irradiance / prefilter / brdf-lut) lazily.
|
|
639
|
+
// M5-amend Bug 1: dawn readback (t51 + reference baker) copies the
|
|
640
|
+
// side textures back to a buffer via copyTextureToBuffer, which
|
|
641
|
+
// requires the TextureUsage::CopySrc bit on the source. Without it
|
|
642
|
+
// Dawn fails-fast "usage doesn't include CopySrc".
|
|
643
|
+
|
|
644
|
+
if (cache.irradianceTexture === undefined) {
|
|
645
|
+
const textureResult = device.createTexture({
|
|
646
|
+
label: 'ibl-irradiance-cube',
|
|
647
|
+
size: { width: IRRADIANCE_SIZE, height: IRRADIANCE_SIZE, depthOrArrayLayers: 6 },
|
|
648
|
+
mipLevelCount: 1,
|
|
649
|
+
sampleCount: 1,
|
|
650
|
+
dimension: '2d',
|
|
651
|
+
format: outputFormat,
|
|
652
|
+
usage:
|
|
653
|
+
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |
|
|
654
|
+
GPU_TEXTURE_USAGE_COPY_DST |
|
|
655
|
+
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
656
|
+
viewFormats: [],
|
|
657
|
+
textureBindingViewDimension: undefined,
|
|
658
|
+
});
|
|
659
|
+
if (!textureResult.ok) return err(badAlloc('irradiance-texture', textureResult.error));
|
|
660
|
+
cache.irradianceTexture = textureResult.value;
|
|
661
|
+
const cubeViewResult = device.createTextureView(textureResult.value, {
|
|
662
|
+
label: 'ibl-irradiance-cube-view',
|
|
663
|
+
dimension: 'cube',
|
|
664
|
+
arrayLayerCount: 6,
|
|
665
|
+
});
|
|
666
|
+
if (!cubeViewResult.ok) return err(badAlloc('irradiance-view', cubeViewResult.error));
|
|
667
|
+
cache.irradianceView = cubeViewResult.value;
|
|
668
|
+
const faceViews: TextureView[] = [];
|
|
669
|
+
for (let f = 0; f < 6; f++) {
|
|
670
|
+
const viewResult = device.createTextureView(textureResult.value, {
|
|
671
|
+
label: `ibl-irradiance-face-${f}`,
|
|
672
|
+
dimension: '2d',
|
|
673
|
+
baseArrayLayer: f,
|
|
674
|
+
arrayLayerCount: 1,
|
|
675
|
+
});
|
|
676
|
+
if (!viewResult.ok) return err(badAlloc('irradiance-face-view', viewResult.error));
|
|
677
|
+
faceViews.push(viewResult.value);
|
|
678
|
+
}
|
|
679
|
+
cache.irradianceFaceViews = faceViews;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
if (cache.prefilterTexture === undefined) {
|
|
683
|
+
const textureResult = device.createTexture({
|
|
684
|
+
label: 'ibl-prefilter-cube',
|
|
685
|
+
size: { width: PREFILTER_SIZE, height: PREFILTER_SIZE, depthOrArrayLayers: 6 },
|
|
686
|
+
mipLevelCount: PREFILTER_MIP_LEVELS,
|
|
687
|
+
sampleCount: 1,
|
|
688
|
+
dimension: '2d',
|
|
689
|
+
format: outputFormat,
|
|
690
|
+
usage:
|
|
691
|
+
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |
|
|
692
|
+
GPU_TEXTURE_USAGE_COPY_DST |
|
|
693
|
+
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
694
|
+
viewFormats: [],
|
|
695
|
+
textureBindingViewDimension: undefined,
|
|
696
|
+
});
|
|
697
|
+
if (!textureResult.ok) return err(badAlloc('prefilter-texture', textureResult.error));
|
|
698
|
+
cache.prefilterTexture = textureResult.value;
|
|
699
|
+
const cubeViewResult = device.createTextureView(textureResult.value, {
|
|
700
|
+
label: 'ibl-prefilter-cube-view',
|
|
701
|
+
dimension: 'cube',
|
|
702
|
+
arrayLayerCount: 6,
|
|
703
|
+
baseMipLevel: 0,
|
|
704
|
+
mipLevelCount: PREFILTER_MIP_LEVELS,
|
|
705
|
+
});
|
|
706
|
+
if (!cubeViewResult.ok) return err(badAlloc('prefilter-view', cubeViewResult.error));
|
|
707
|
+
cache.prefilterView = cubeViewResult.value;
|
|
708
|
+
const mipViews: TextureView[][] = [];
|
|
709
|
+
for (let m = 0; m < PREFILTER_MIP_LEVELS; m++) {
|
|
710
|
+
const faces: TextureView[] = [];
|
|
711
|
+
for (let f = 0; f < 6; f++) {
|
|
712
|
+
const viewResult = device.createTextureView(textureResult.value, {
|
|
713
|
+
label: `ibl-prefilter-mip${m}-face${f}`,
|
|
714
|
+
dimension: '2d',
|
|
715
|
+
baseMipLevel: m,
|
|
716
|
+
mipLevelCount: 1,
|
|
717
|
+
baseArrayLayer: f,
|
|
718
|
+
arrayLayerCount: 1,
|
|
719
|
+
});
|
|
720
|
+
if (!viewResult.ok) return err(badAlloc('prefilter-face-view', viewResult.error));
|
|
721
|
+
faces.push(viewResult.value);
|
|
722
|
+
}
|
|
723
|
+
mipViews.push(faces);
|
|
724
|
+
}
|
|
725
|
+
cache.prefilterFaceViewsByMip = mipViews;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
if (cache.brdfLutTexture === undefined) {
|
|
729
|
+
const textureResult = device.createTexture({
|
|
730
|
+
label: 'ibl-brdf-lut',
|
|
731
|
+
size: { width: BRDF_LUT_SIZE, height: BRDF_LUT_SIZE, depthOrArrayLayers: 1 },
|
|
732
|
+
mipLevelCount: 1,
|
|
733
|
+
sampleCount: 1,
|
|
734
|
+
dimension: '2d',
|
|
735
|
+
format: outputFormat,
|
|
736
|
+
usage:
|
|
737
|
+
GPU_TEXTURE_USAGE_RENDER_ATTACHMENT_AND_TEXTURE_BINDING |
|
|
738
|
+
GPU_TEXTURE_USAGE_COPY_DST |
|
|
739
|
+
GPU_TEXTURE_USAGE_COPY_SRC,
|
|
740
|
+
viewFormats: [],
|
|
741
|
+
textureBindingViewDimension: undefined,
|
|
742
|
+
});
|
|
743
|
+
if (!textureResult.ok) return err(badAlloc('brdf-lut-texture', textureResult.error));
|
|
744
|
+
cache.brdfLutTexture = textureResult.value;
|
|
745
|
+
const viewResult = device.createTextureView(textureResult.value, {
|
|
746
|
+
label: 'ibl-brdf-lut-view',
|
|
747
|
+
dimension: '2d',
|
|
748
|
+
});
|
|
749
|
+
if (!viewResult.ok) return err(badAlloc('brdf-lut-view', viewResult.error));
|
|
750
|
+
cache.brdfLutView = viewResult.value;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// Shared sampler (filtering, linear-linear).
|
|
754
|
+
// U=repeat because equirect wraps horizontally (atan2 seam at ±π);
|
|
755
|
+
// V=clamp because equirect poles are clamped vertically.
|
|
756
|
+
const samplerResult = device.createSampler({
|
|
757
|
+
label: 'ibl-precompute-sampler',
|
|
758
|
+
magFilter: 'linear',
|
|
759
|
+
minFilter: 'linear',
|
|
760
|
+
mipmapFilter: 'linear',
|
|
761
|
+
addressModeU: 'repeat',
|
|
762
|
+
addressModeV: 'clamp-to-edge',
|
|
763
|
+
addressModeW: 'clamp-to-edge',
|
|
764
|
+
});
|
|
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
|
+
}
|
|
798
|
+
|
|
799
|
+
// Bind group: equirect group(1).
|
|
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;
|
|
810
|
+
|
|
811
|
+
// Bind group: cube group(1) for irradiance + prefilter.
|
|
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;
|
|
822
|
+
|
|
823
|
+
// (a) equirect-to-cube: 6 face draws.
|
|
824
|
+
const cubeFaceViews = opts.cubeFaceViews;
|
|
825
|
+
for (let face = 0; face < 6; face++) {
|
|
826
|
+
const cubeFaceView = cubeFaceViews[face];
|
|
827
|
+
if (cubeFaceView === undefined) return err(badAlloc('cube-face-view'));
|
|
828
|
+
const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
|
|
829
|
+
label: 'ibl-equirect-to-cube',
|
|
830
|
+
colorAttachments: [
|
|
831
|
+
{
|
|
832
|
+
view: cubeFaceView,
|
|
833
|
+
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
834
|
+
loadOp: 'clear',
|
|
835
|
+
storeOp: 'store',
|
|
836
|
+
},
|
|
837
|
+
],
|
|
838
|
+
});
|
|
839
|
+
// Face uniform: dynamic offset = face * 256.
|
|
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,
|
|
852
|
+
},
|
|
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);
|
|
860
|
+
pass.setBindGroup(1, equirectBg);
|
|
861
|
+
pass.setVertexBuffer(0, opts.cubeVertexBuffer);
|
|
862
|
+
pass.draw(6, 1, face * 6, 0);
|
|
863
|
+
pass.end();
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// (b) irradiance convolve: 6 face draws.
|
|
867
|
+
for (let face = 0; face < 6; face++) {
|
|
868
|
+
const irrFaceView = irrFaceViews[face];
|
|
869
|
+
if (irrFaceView === undefined) return err(badAlloc('irradiance-face-view'));
|
|
870
|
+
const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
|
|
871
|
+
label: 'ibl-irradiance',
|
|
872
|
+
colorAttachments: [
|
|
873
|
+
{
|
|
874
|
+
view: irrFaceView,
|
|
875
|
+
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
876
|
+
loadOp: 'clear',
|
|
877
|
+
storeOp: 'store',
|
|
878
|
+
},
|
|
879
|
+
],
|
|
880
|
+
});
|
|
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,
|
|
893
|
+
},
|
|
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);
|
|
901
|
+
pass.setBindGroup(1, cubeBg);
|
|
902
|
+
pass.setVertexBuffer(0, opts.cubeVertexBuffer);
|
|
903
|
+
pass.draw(6, 1, face * 6, 0);
|
|
904
|
+
pass.end();
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
// (c) prefilter env: 5 mips x 6 faces = 30 sub-passes.
|
|
908
|
+
for (let mip = 0; mip < PREFILTER_MIP_LEVELS; mip++) {
|
|
909
|
+
const mipFaceViews = prefMipViews[mip];
|
|
910
|
+
if (mipFaceViews === undefined) return err(badAlloc('prefilter-mip-views'));
|
|
911
|
+
for (let face = 0; face < 6; face++) {
|
|
912
|
+
const subIdx = mip * 6 + face;
|
|
913
|
+
const mipFaceView = mipFaceViews[face];
|
|
914
|
+
if (mipFaceView === undefined) return err(badAlloc('prefilter-face-view'));
|
|
915
|
+
const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
|
|
916
|
+
label: 'ibl-prefilter',
|
|
917
|
+
colorAttachments: [
|
|
918
|
+
{
|
|
919
|
+
view: mipFaceView,
|
|
920
|
+
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
921
|
+
loadOp: 'clear',
|
|
922
|
+
storeOp: 'store',
|
|
923
|
+
},
|
|
924
|
+
],
|
|
925
|
+
});
|
|
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,
|
|
938
|
+
},
|
|
939
|
+
},
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
binding: 1,
|
|
943
|
+
resource: {
|
|
944
|
+
kind: 'buffer',
|
|
945
|
+
value: {
|
|
946
|
+
buffer: opts.prefilterUniformsBuffer,
|
|
947
|
+
offset: subIdx * 256,
|
|
948
|
+
size: 16,
|
|
949
|
+
},
|
|
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);
|
|
957
|
+
pass.setBindGroup(1, cubeBg);
|
|
958
|
+
pass.setVertexBuffer(0, opts.cubeVertexBuffer);
|
|
959
|
+
pass.draw(6, 1, face * 6, 0);
|
|
960
|
+
pass.end();
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
// (d) brdf-lut: fullscreen triangle.
|
|
965
|
+
{
|
|
966
|
+
const pass: RhiRenderPassEncoder = encoder.beginRenderPass({
|
|
967
|
+
label: 'ibl-brdf-lut',
|
|
968
|
+
colorAttachments: [
|
|
969
|
+
{
|
|
970
|
+
view: brdfLutView,
|
|
971
|
+
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
972
|
+
loadOp: 'clear',
|
|
973
|
+
storeOp: 'store',
|
|
974
|
+
},
|
|
975
|
+
],
|
|
976
|
+
});
|
|
977
|
+
pass.setPipeline(brdfLutPipeline);
|
|
978
|
+
pass.draw(3, 1, 0, 0);
|
|
979
|
+
pass.end();
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
// Finish + submit. Counter increments are STRICTLY after submit; if
|
|
983
|
+
// submit throws or fails, counters stay at 0 (AC-20 critical invariant).
|
|
984
|
+
const finishRes = encoder.finish();
|
|
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));
|
|
989
|
+
|
|
990
|
+
// POST-SUBMIT counter increments (AC-20).
|
|
991
|
+
cache.irradianceBakeCount += 1;
|
|
992
|
+
cache.prefilterBakeCount += 1;
|
|
993
|
+
cache.brdfLutBakeCount += 1;
|
|
994
|
+
|
|
995
|
+
return ok({ submitted: true });
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
// Local helper -- structured error payload shared across allocation paths.
|
|
999
|
+
function badAlloc(stage: string, cause?: RhiError): IblPrecomputeError {
|
|
1000
|
+
return {
|
|
1001
|
+
code: 'ibl-precompute-not-dispatched',
|
|
1002
|
+
expected: `${stage} allocated successfully`,
|
|
1003
|
+
hint: `check the RHI Result for ${stage}; counters must not increment before queue.submit`,
|
|
1004
|
+
...(cause === undefined ? {} : { detail: { stage, rhiCode: cause.code } }),
|
|
1005
|
+
};
|
|
1006
|
+
}
|