@forgeax/engine-render 0.1.32 → 0.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1374 -142
- package/dist/assembly/analytic-fog-registration.d.ts +3 -0
- package/dist/assembly/analytic-fog-registration.d.ts.map +1 -0
- package/dist/assembly/backend-contract.d.ts +2 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -1
- package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
- package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
- package/dist/assembly/canvas-draw-guard.d.ts +3 -0
- package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
- package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
- package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
- package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
- package/dist/assembly/factory.d.ts +1 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/fxaa-registration.d.ts +4 -0
- package/dist/assembly/fxaa-registration.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +3 -3
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/lod-observation.d.ts +4 -0
- package/dist/assembly/lod-observation.d.ts.map +1 -0
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
- package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
- package/dist/assembly/material-shader-policy.d.ts +16 -2
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
- package/dist/assembly/motion-blur-registration.d.ts +3 -0
- package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
- package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/render-feature-post-processes.d.ts +6 -0
- package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
- package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-inspection.d.ts +11 -0
- package/dist/assembly/renderer-inspection.d.ts.map +1 -1
- package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
- package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
- package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
- package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +2 -2
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
- package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +1 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/authoring.mjs +1 -1
- package/dist/barrel-distortion.d.ts +47 -0
- package/dist/barrel-distortion.d.ts.map +1 -0
- package/dist/bloom-admission.d.ts +13 -0
- package/dist/bloom-admission.d.ts.map +1 -0
- package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
- package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
- package/dist/{chunk-JCIRYQ4V.mjs → chunk-HEB564WF.mjs} +10 -4
- package/dist/chunk-HEB564WF.mjs.map +1 -0
- package/dist/{chunk-JRIPCMYC.mjs → chunk-MKDIT2EM.mjs} +1584 -375
- package/dist/chunk-MKDIT2EM.mjs.map +1 -0
- package/dist/{chunk-S665NJNF.mjs → chunk-OCDLEI6I.mjs} +3 -3
- package/dist/{chunk-S665NJNF.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
- package/dist/chunk-ODZWR6JQ.mjs +4927 -0
- package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
- package/dist/{chunk-DRR7D3KX.mjs → chunk-SHFUFJ5N.mjs} +192 -18
- package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
- package/dist/{chunk-4NNZQCL3.mjs → chunk-UI5SFODX.mjs} +223 -277
- package/dist/chunk-UI5SFODX.mjs.map +1 -0
- package/dist/{chunk-GWCEMDVR.mjs → chunk-UINHLCZA.mjs} +787 -80
- package/dist/chunk-UINHLCZA.mjs.map +1 -0
- package/dist/{chunk-6TFBXLRJ.mjs → chunk-WEX45HKH.mjs} +222 -337
- package/dist/chunk-WEX45HKH.mjs.map +1 -0
- package/dist/cloud/density.d.ts +55 -0
- package/dist/cloud/density.d.ts.map +1 -0
- package/dist/cloud/extract.d.ts +25 -0
- package/dist/cloud/extract.d.ts.map +1 -0
- package/dist/cloud/feature.d.ts +57 -0
- package/dist/cloud/feature.d.ts.map +1 -0
- package/dist/cloud/frame-context.d.ts +8 -0
- package/dist/cloud/frame-context.d.ts.map +1 -0
- package/dist/cloud/inspection.d.ts +59 -0
- package/dist/cloud/inspection.d.ts.map +1 -0
- package/dist/cloud/optics.d.ts +56 -0
- package/dist/cloud/optics.d.ts.map +1 -0
- package/dist/cloud/parameters.d.ts +73 -0
- package/dist/cloud/parameters.d.ts.map +1 -0
- package/dist/cloud/resources.d.ts +60 -0
- package/dist/cloud/resources.d.ts.map +1 -0
- package/dist/cloud/shadow.d.ts +42 -0
- package/dist/cloud/shadow.d.ts.map +1 -0
- package/dist/cloud/temporal.d.ts +74 -0
- package/dist/cloud/temporal.d.ts.map +1 -0
- package/dist/components/atmosphere.d.ts +2 -0
- package/dist/components/atmosphere.d.ts.map +1 -1
- package/dist/components/barrel-distortion.d.ts +13 -0
- package/dist/components/barrel-distortion.d.ts.map +1 -0
- package/dist/components/camera.d.ts +20 -4
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/cloud-layer.d.ts +29 -0
- package/dist/components/cloud-layer.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/instances.d.ts +20 -6
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/components/mesh-filter.d.ts +6 -5
- package/dist/components/mesh-filter.d.ts.map +1 -1
- package/dist/components/motion-blur.d.ts +1 -0
- package/dist/components/motion-blur.d.ts.map +1 -1
- package/dist/construct-renderer.d.ts +1 -1
- package/dist/construct-renderer.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +9751 -3528
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +6 -0
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/dynamic-geometry.d.ts +5 -1
- package/dist/dynamic-geometry.d.ts.map +1 -1
- package/dist/environment/analytic-fog.d.ts +6 -0
- package/dist/environment/analytic-fog.d.ts.map +1 -0
- package/dist/errors/cloud.d.ts +59 -0
- package/dist/errors/cloud.d.ts.map +1 -0
- package/dist/errors/render.d.ts +23 -5
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/examples/single-layer-medium-surface.d.ts +47 -0
- package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +12 -1
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/extract/environment.d.ts +2 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/features/barrel-distortion.d.ts +29 -0
- package/dist/features/barrel-distortion.d.ts.map +1 -0
- package/dist/features/error-reporting.d.ts +17 -0
- package/dist/features/error-reporting.d.ts.map +1 -0
- package/dist/features/host.d.ts +15 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
- package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
- package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
- package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
- package/dist/features/plan.d.ts +15 -4
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +9 -5
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/render-graph-compute.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +5 -0
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +1 -0
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/targets.d.ts +2 -0
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +44 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +15 -7
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-dirty-ranges.d.ts +11 -0
- package/dist/gpu-dirty-ranges.d.ts.map +1 -0
- package/dist/gpu-driven/batch-topology.d.ts +17 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/material-artifacts.d.ts +6 -0
- package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
- package/dist/gpu-driven/prepared-draw.d.ts +7 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster-material.d.ts +178 -0
- package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +50 -4
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/resource-allocation.d.ts +31 -0
- package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
- package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
- package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +35 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +11 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +2 -2
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +10 -1
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +31 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +258 -8
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +178 -3
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instance-buffer-cache.d.ts +4 -4
- package/dist/instance-buffer-cache.d.ts.map +1 -1
- package/dist/instances.d.ts +49 -94
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +7 -7
- package/dist/pbr-pipeline.d.ts +19 -1
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
- package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
- package/dist/pipeline/standard-output/types.d.ts +4 -2
- package/dist/pipeline/standard-output/types.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts +28 -19
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +1 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +2 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/record/barrel-distortion-frame.d.ts +15 -0
- package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
- package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
- package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
- package/dist/record/fold-buckets.d.ts +95 -0
- package/dist/record/fold-buckets.d.ts.map +1 -0
- package/dist/record/fold-instance-buffer.d.ts +6 -0
- package/dist/record/fold-instance-buffer.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +1 -0
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +40 -3
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +14 -62
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-draw-receipts.d.ts +11 -0
- package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +8 -0
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +21 -5
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +7 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +13 -2
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +6 -5
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/motion-blur-receipt.d.ts +11 -0
- package/dist/record/motion-blur-receipt.d.ts.map +1 -0
- package/dist/record/probe-blend-buffer.d.ts +16 -0
- package/dist/record/probe-blend-buffer.d.ts.map +1 -0
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +34 -31
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +2 -0
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +6 -4
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +22 -2
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +11 -3
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/record/volume-params.d.ts +9 -0
- package/dist/record/volume-params.d.ts.map +1 -0
- package/dist/recovery/render-system-candidate.d.ts +10 -0
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +66 -8
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +106 -3
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +3 -2
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +24 -10
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-presentation.d.ts +23 -0
- package/dist/render-system-presentation.d.ts.map +1 -0
- package/dist/render-system-producer-roots.d.ts +10 -0
- package/dist/render-system-producer-roots.d.ts.map +1 -0
- package/dist/render-system-residency.d.ts +12 -0
- package/dist/render-system-residency.d.ts.map +1 -0
- package/dist/render-system.d.ts +26 -15
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/probe-blend.d.ts +27 -0
- package/dist/scene/probe-blend.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +14 -5
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +9 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/surface/dynamic-input.d.ts +133 -0
- package/dist/surface/dynamic-input.d.ts.map +1 -0
- package/dist/surface/gpu-driven.d.ts +41 -0
- package/dist/surface/gpu-driven.d.ts.map +1 -0
- package/dist/surface/submission-observation.d.ts +136 -0
- package/dist/surface/submission-observation.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +7 -0
- package/dist/temporal/frame.d.ts.map +1 -1
- package/dist/temporal/gpu.d.ts +13 -1
- package/dist/temporal/gpu.d.ts.map +1 -1
- package/dist/temporal/index.mjs +5 -5
- package/dist/temporal/inspection.d.ts.map +1 -1
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
- package/dist/temporal/view.d.ts +6 -1
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/transmission/single-layer-medium.d.ts +89 -0
- package/dist/transmission/single-layer-medium.d.ts.map +1 -0
- package/dist/typed-render-graph-primitives.d.ts +24 -9
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/component.d.ts +9 -5
- package/dist/volume/component.d.ts.map +1 -1
- package/dist/volume/extract.d.ts +1 -1
- package/dist/volume/extract.d.ts.map +1 -1
- package/dist/volume/inspection.d.ts +2 -0
- package/dist/volume/inspection.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +4 -1
- package/dist/volume/passes.d.ts.map +1 -1
- package/dist/volume/resources.d.ts.map +1 -1
- package/dist/volume/temporal.d.ts +3 -1
- package/dist/volume/temporal.d.ts.map +1 -1
- package/package.json +22 -21
- package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
- package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
- package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
- package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
- package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
- package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
- package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
- package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
- package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
- package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
- package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
- package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
- package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
- package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
- package/src/__tests__/environment-selection.unit.test.ts +12 -0
- package/src/__tests__/factory-contract.integration.test.ts +626 -113
- package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
- package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
- package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
- package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
- package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
- package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +7 -6
- package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +103 -4
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
- package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
- package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
- package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
- package/src/__tests__/gpu-scene.unit.test.ts +210 -9
- package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
- package/src/__tests__/instances-culling.integration.test.ts +10 -36
- package/src/__tests__/instances-store.unit.test.ts +105 -238
- package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
- package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
- package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
- package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
- package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
- package/src/__tests__/motion-blur-compute.dawn.test.ts +589 -0
- package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
- package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
- package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +21 -0
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
- package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
- package/src/__tests__/probe-bindings.unit.test.ts +582 -1
- package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
- package/src/__tests__/public-surface.test-d.ts +8 -0
- package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +9 -0
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
- package/src/__tests__/render-feature-error-reporting.unit.test.ts +44 -0
- package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
- package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
- package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
- package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
- package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
- package/src/__tests__/render-scene-temporal-retry.unit.test.ts +37 -6
- package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
- package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
- package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
- package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +33 -11
- package/src/__tests__/resource-allocation.unit.test.ts +123 -0
- package/src/__tests__/shader-manifest-fixture.ts +4 -4
- package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
- package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +17 -0
- package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
- package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
- package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
- package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
- package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
- package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
- package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
- package/src/__tests__/standard-pipeline.integration.test.ts +200 -9
- package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
- package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
- package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
- package/src/__tests__/temporal-performance.integration.test.ts +3 -3
- package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
- package/src/__tests__/temporal-view.unit.test.ts +2 -1
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
- package/src/__tests__/visibility-instances.integration.test.ts +7 -19
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
- package/src/__tests__/volume-optics-oracle.unit.test.ts +7 -3
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +189 -15
- package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
- package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
- package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +558 -68
- package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +23 -5
- package/src/assembly/analytic-fog-registration.ts +14 -0
- package/src/assembly/backend-contract.ts +30 -0
- package/src/assembly/barrel-distortion-inspection.ts +22 -0
- package/src/assembly/canvas-draw-guard.ts +11 -0
- package/src/assembly/cloud-shadow-entry.ts +22 -0
- package/src/assembly/dynamic-geometry-host.ts +65 -37
- package/src/assembly/dynamic-geometry-runtime.ts +7 -1
- package/src/assembly/factory.ts +2 -30
- package/src/assembly/fxaa-registration.ts +17 -0
- package/src/assembly/host-contract.ts +3 -3
- package/src/assembly/lod-observation.ts +12 -0
- package/src/assembly/material/assembly.ts +25 -13
- package/src/assembly/material/pipeline-helpers.ts +53 -12
- package/src/assembly/material-shader-policy.ts +55 -0
- package/src/assembly/material-shader-prewarm.ts +21 -10
- package/src/assembly/motion-blur-registration.ts +17 -0
- package/src/assembly/recovery/device-loss-fanout.ts +13 -0
- package/src/assembly/recovery/renderer-recover.ts +41 -18
- package/src/assembly/render-feature-post-processes.ts +54 -0
- package/src/assembly/renderer-facade.ts +6 -1
- package/src/assembly/renderer-feature-inspection.ts +8 -2
- package/src/assembly/renderer-frame-transaction.ts +23 -0
- package/src/assembly/renderer-inspection.ts +28 -0
- package/src/assembly/skin-palette-owner.ts +1 -1
- package/src/assembly/temporal-post-process-prewarm.ts +40 -0
- package/src/assembly/webgpu-pbr-ready.ts +9 -1
- package/src/assembly/webgpu-ready-contract.ts +8 -3
- package/src/assembly/webgpu-ready-per-pass.ts +104 -0
- package/src/assembly/webgpu-ready.ts +296 -306
- package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
- package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
- package/src/assembly/webgpu-renderer.ts +228 -281
- package/src/assembly/webgpu-vertex-layouts.ts +1 -1
- package/src/barrel-distortion.ts +247 -0
- package/src/bloom-admission.ts +21 -0
- package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
- package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
- package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
- package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
- package/src/cloud/density.ts +600 -0
- package/src/cloud/extract.ts +110 -0
- package/src/cloud/feature.ts +1810 -0
- package/src/cloud/frame-context.ts +42 -0
- package/src/cloud/inspection.ts +130 -0
- package/src/cloud/optics.ts +285 -0
- package/src/cloud/parameters.ts +255 -0
- package/src/cloud/resources.ts +122 -0
- package/src/cloud/shadow.ts +167 -0
- package/src/cloud/temporal.ts +226 -0
- package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
- package/src/components/atmosphere.ts +4 -0
- package/src/components/barrel-distortion.ts +46 -0
- package/src/components/camera.ts +66 -10
- package/src/components/cloud-layer.ts +47 -0
- package/src/components/index.ts +2 -0
- package/src/components/instances.ts +18 -45
- package/src/components/mesh-filter.ts +11 -9
- package/src/components/motion-blur.ts +1 -0
- package/src/components/sprite-instances.ts +1 -1
- package/src/construct-renderer.ts +1 -1
- package/src/device/gpu-residency.ts +56 -12
- package/src/dynamic-geometry.ts +12 -1
- package/src/environment/analytic-fog.ts +44 -0
- package/src/environment/background.ts +2 -2
- package/src/errors/cloud.ts +103 -0
- package/src/errors/render.ts +58 -8
- package/src/examples/single-layer-medium-surface.ts +59 -0
- package/src/extract/camera.ts +35 -8
- package/src/extract/contracts.ts +12 -0
- package/src/extract/environment.ts +4 -0
- package/src/features/barrel-distortion.ts +172 -0
- package/src/features/error-reporting.ts +98 -0
- package/src/features/host.ts +138 -24
- package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
- package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
- package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
- package/src/features/motion-blur/motion-blur-params.ts +70 -2
- package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
- package/src/features/plan.ts +33 -8
- package/src/features/prepared-gpu-work.ts +86 -35
- package/src/features/render-graph-compute.ts +13 -5
- package/src/features/render-graph-contribution.ts +11 -0
- package/src/features/render-graph-raster.ts +45 -3
- package/src/features/targets.ts +66 -0
- package/src/features/types.ts +47 -0
- package/src/fullscreen-post-process-pass.ts +41 -9
- package/src/gpu-dirty-ranges.ts +48 -0
- package/src/gpu-driven/batch-topology.ts +53 -0
- package/src/gpu-driven/material-artifacts.ts +35 -32
- package/src/gpu-driven/prepared-draw.ts +27 -14
- package/src/gpu-driven/production-raster-material.ts +1894 -0
- package/src/gpu-driven/production-raster.ts +904 -787
- package/src/gpu-driven/resource-allocation.ts +142 -0
- package/src/gpu-driven/shadow-ownership.ts +71 -0
- package/src/gpu-driven/view-gpu.ts +181 -10
- package/src/gpu-scene.ts +259 -101
- package/src/hdrp-buffers.ts +4 -3
- package/src/ibl/skylight-bind-group.ts +49 -7
- package/src/index.ts +228 -9
- package/src/inspection-types.ts +222 -2
- package/src/instance-buffer-cache.ts +4 -4
- package/src/instances.ts +151 -492
- package/src/pbr-pipeline.ts +219 -13
- package/src/pipeline/single-layer-medium-passes.ts +267 -0
- package/src/pipeline/standard-forward-lane.ts +313 -57
- package/src/pipeline/standard-output/graph.ts +8 -2
- package/src/pipeline/standard-output/types.ts +12 -1
- package/src/pipeline/standard-pipeline.ts +291 -18
- package/src/pipeline/standard-post.ts +397 -102
- package/src/pipeline-builder.ts +1 -1
- package/src/pipeline-spec.ts +5 -5
- package/src/plugin.ts +4 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
- package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
- package/src/prepare/prepared-graphics-resolver.ts +2 -0
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
- package/src/record/__tests__/temporal-payload.unit.test.ts +3 -2
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
- package/src/record/barrel-distortion-frame.ts +110 -0
- package/src/record/dynamic-geometry-consumption.ts +39 -9
- package/src/record/fold-buckets.ts +852 -0
- package/src/record/fold-instance-buffer.ts +51 -0
- package/src/record/frame-lighting.ts +36 -2
- package/src/record/frame-snapshot.ts +44 -4
- package/src/record/frame-targets.ts +10 -6
- package/src/record/frame.ts +373 -1099
- package/src/record/gpu-draw-receipts.ts +38 -0
- package/src/record/gpu-timing.ts +48 -5
- package/src/record/main-pass-geometry.ts +281 -83
- package/src/record/main-pass-material.ts +66 -4
- package/src/record/main-pass-sprite-draws.ts +13 -66
- package/src/record/main-pass.ts +156 -20
- package/src/record/mesh-ssbo.ts +43 -6
- package/src/record/motion-blur-receipt.ts +91 -0
- package/src/record/probe-blend-buffer.ts +180 -0
- package/src/record/recovery-pipeline.ts +35 -3
- package/src/record/render-context.ts +51 -31
- package/src/record/shadow-pass.ts +36 -2
- package/src/record/skybox-post-pass.ts +150 -200
- package/src/record/typed-frame-graph.ts +824 -44
- package/src/record/view-ubo.ts +26 -3
- package/src/record/volume-params.ts +225 -0
- package/src/recovery/render-system-candidate.ts +257 -52
- package/src/reflection/record-owner.ts +7 -3
- package/src/render-contract.ts +71 -8
- package/src/render-graph-primitives.ts +7 -1
- package/src/render-pipeline.ts +136 -1
- package/src/render-system-extract-tail.ts +72 -60
- package/src/render-system-extract.ts +117 -87
- package/src/render-system-presentation.ts +56 -0
- package/src/render-system-producer-roots.ts +96 -0
- package/src/render-system-residency.ts +159 -0
- package/src/render-system.ts +601 -482
- package/src/scene/probe-blend.ts +96 -4
- package/src/scene/render-scene.ts +431 -281
- package/src/ssao-buffers.ts +95 -2
- package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
- package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
- package/src/surface/dynamic-input.ts +658 -0
- package/src/surface/gpu-driven.ts +147 -0
- package/src/surface/submission-observation.ts +517 -0
- package/src/systems/skin-palette-allocator.ts +4 -1
- package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
- package/src/temporal/frame-coordinator.ts +8 -1
- package/src/temporal/frame.ts +20 -0
- package/src/temporal/gpu.ts +101 -17
- package/src/temporal/inspection.ts +7 -1
- package/src/temporal/standard-scene-data.ts +5 -0
- package/src/temporal/target-coverage-attachment.ts +4 -0
- package/src/temporal/view.ts +13 -2
- package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
- package/src/transmission/single-layer-medium.ts +322 -0
- package/src/typed-render-graph-primitives.ts +191 -50
- package/src/volume/component.ts +10 -10
- package/src/volume/extract.ts +11 -5
- package/src/volume/inspection.ts +3 -0
- package/src/volume/passes.ts +95 -8
- package/src/volume/resources.ts +2 -1
- package/src/volume/temporal.ts +11 -0
- package/dist/chunk-4NNZQCL3.mjs.map +0 -1
- package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
- package/dist/chunk-DRR7D3KX.mjs.map +0 -1
- package/dist/chunk-GWCEMDVR.mjs.map +0 -1
- package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
- package/dist/chunk-JRIPCMYC.mjs.map +0 -1
- package/dist/chunk-LULCA3OF.mjs +0 -1713
- package/dist/chunk-LULCA3OF.mjs.map +0 -1
- package/dist/chunk-PA5DRJNI.mjs.map +0 -1
|
@@ -75,7 +75,6 @@ import {
|
|
|
75
75
|
type TextureAsset,
|
|
76
76
|
type TextureShape,
|
|
77
77
|
type MeshAsset as TypesMeshAsset,
|
|
78
|
-
toShared,
|
|
79
78
|
} from '@forgeax/engine-types';
|
|
80
79
|
import { GpuBuffer, GpuTexture } from '../gpu-resource';
|
|
81
80
|
import {
|
|
@@ -570,6 +569,12 @@ export class GpuResidencyCache {
|
|
|
570
569
|
// equirect source always resolves to the same cubemap (idempotent, A2).
|
|
571
570
|
private readonly cubemapIdempotentMap: Map<number, Handle<'EquirectAsset', 'shared'>> = new Map();
|
|
572
571
|
private readonly meshGpuHandles: Map<string | number, MeshGpuHandles> = new Map();
|
|
572
|
+
/**
|
|
573
|
+
* Lower-detail POD identities packed into each resident mesh entry. The
|
|
574
|
+
* GPU entry only carries byte ranges; keeping the source identities beside
|
|
575
|
+
* it lets a later draw upgrade a root-only upload without hashing vertices.
|
|
576
|
+
*/
|
|
577
|
+
private readonly meshLodAssets = new WeakMap<MeshGpuHandles, readonly TypesMeshAsset[]>();
|
|
573
578
|
private readonly meshLifetimes = new WeakMap<MeshGpuHandles, MeshResidencyLifetime>();
|
|
574
579
|
private readonly retiredMeshes = new Set<MeshGpuHandles>();
|
|
575
580
|
|
|
@@ -832,7 +837,7 @@ export class GpuResidencyCache {
|
|
|
832
837
|
handle: Handle<'MeshAsset', 'shared'>,
|
|
833
838
|
worldId: World | number = 0,
|
|
834
839
|
): { freed: number; errors: RhiError[] } {
|
|
835
|
-
const id = this.worldKey(
|
|
840
|
+
const id = this.worldKey(Number(handle), worldId);
|
|
836
841
|
const entry = this.meshGpuHandles.get(id);
|
|
837
842
|
if (entry === undefined) return { freed: 0, errors: [] };
|
|
838
843
|
|
|
@@ -1090,7 +1095,7 @@ export class GpuResidencyCache {
|
|
|
1090
1095
|
handle: Handle<'MeshAsset', 'shared'>,
|
|
1091
1096
|
worldId: World | number = 0,
|
|
1092
1097
|
): MeshGpuHandles | undefined {
|
|
1093
|
-
return this.meshGpuHandles.get(this.worldKey(
|
|
1098
|
+
return this.meshGpuHandles.get(this.worldKey(Number(handle), worldId));
|
|
1094
1099
|
}
|
|
1095
1100
|
|
|
1096
1101
|
/** Candidate leases retain the concrete allocation even after cache invalidation. */
|
|
@@ -1098,7 +1103,7 @@ export class GpuResidencyCache {
|
|
|
1098
1103
|
handle: Handle<'MeshAsset', 'shared'>,
|
|
1099
1104
|
worldId: World | number = 0,
|
|
1100
1105
|
): MeshResidencyLease | undefined {
|
|
1101
|
-
const key = this.worldKey(
|
|
1106
|
+
const key = this.worldKey(Number(handle), worldId);
|
|
1102
1107
|
const entry = this.meshGpuHandles.get(key);
|
|
1103
1108
|
return entry === undefined
|
|
1104
1109
|
? undefined
|
|
@@ -1110,7 +1115,7 @@ export class GpuResidencyCache {
|
|
|
1110
1115
|
|
|
1111
1116
|
/** In-place author changes immediately miss the cache; old submissions keep their allocation. */
|
|
1112
1117
|
invalidateMesh(handle: number, worldId: World | number = 0): void {
|
|
1113
|
-
const key = this.worldKey(
|
|
1118
|
+
const key = this.worldKey(handle, worldId);
|
|
1114
1119
|
const entry = this.meshGpuHandles.get(key);
|
|
1115
1120
|
if (entry !== undefined) this.retireMeshEntry(key, entry);
|
|
1116
1121
|
}
|
|
@@ -1156,9 +1161,32 @@ export class GpuResidencyCache {
|
|
|
1156
1161
|
// path, not routed here).
|
|
1157
1162
|
switch (pod.kind) {
|
|
1158
1163
|
case 'mesh': {
|
|
1159
|
-
|
|
1164
|
+
// Recycled shared slots can coexist with an older GPU submission.
|
|
1165
|
+
// The generation is part of mesh residency identity, not only its slot.
|
|
1166
|
+
const key = this.worldKey(Number(handle), worldId);
|
|
1160
1167
|
const existing = this.meshGpuHandles.get(key);
|
|
1161
|
-
if (existing !== undefined)
|
|
1168
|
+
if (existing !== undefined) {
|
|
1169
|
+
// A root mesh can become resident before its lower-detail assets are
|
|
1170
|
+
// available. Preserve the fast hit for the common case, but publish
|
|
1171
|
+
// a complete chain once the caller supplies one. Never downgrade a
|
|
1172
|
+
// resident chain when a later call has no lower assets yet.
|
|
1173
|
+
if (lodMeshes.length === 0) return ok(existing);
|
|
1174
|
+
const previousLodAssets = this.meshLodAssets.get(existing);
|
|
1175
|
+
const sameLodChain =
|
|
1176
|
+
previousLodAssets !== undefined &&
|
|
1177
|
+
previousLodAssets.length === lodMeshes.length &&
|
|
1178
|
+
previousLodAssets.every((asset, index) => asset === lodMeshes[index]);
|
|
1179
|
+
if (sameLodChain) return ok(existing);
|
|
1180
|
+
|
|
1181
|
+
const projected = deriveRenderDataMesh(pod);
|
|
1182
|
+
if (!projected.ok) return projected;
|
|
1183
|
+
const upgraded = this.uploadMeshById(key, pod, projected.value, lodMeshes);
|
|
1184
|
+
if (!upgraded.ok) return upgraded;
|
|
1185
|
+
// uploadMeshById publishes the new entry before this call so the
|
|
1186
|
+
// old allocation stays available to any already-recorded frame.
|
|
1187
|
+
this.retireMeshEntry(key, existing);
|
|
1188
|
+
return upgraded;
|
|
1189
|
+
}
|
|
1162
1190
|
const projected = deriveRenderDataMesh(pod);
|
|
1163
1191
|
if (!projected.ok) return projected;
|
|
1164
1192
|
return this.uploadMeshById(key, pod, projected.value, lodMeshes);
|
|
@@ -1204,7 +1232,7 @@ export class GpuResidencyCache {
|
|
|
1204
1232
|
): Result<RecoveryResidencyPreparation, RhiError | AssetError | ImageError> {
|
|
1205
1233
|
const id = handleSlot(handle);
|
|
1206
1234
|
if (pod.kind === 'mesh') {
|
|
1207
|
-
const key = this.worldKey(
|
|
1235
|
+
const key = this.worldKey(Number(handle), worldId);
|
|
1208
1236
|
if (this.meshGpuHandles.has(key)) return ok({});
|
|
1209
1237
|
const projected = deriveRenderDataMesh(pod);
|
|
1210
1238
|
if (!projected.ok) return projected;
|
|
@@ -2035,6 +2063,10 @@ export class GpuResidencyCache {
|
|
|
2035
2063
|
// Vertex-only mesh: skip the index buffer entirely. The indexed path below
|
|
2036
2064
|
// is unchanged byte-for-byte when `indices` is present.
|
|
2037
2065
|
let ibo: Buffer | null = null;
|
|
2066
|
+
const cleanupUpload = (): void => {
|
|
2067
|
+
if (ibo !== null) device.destroyBuffer(ibo);
|
|
2068
|
+
device.destroyBuffer(vbo);
|
|
2069
|
+
};
|
|
2038
2070
|
if (indices !== undefined) {
|
|
2039
2071
|
const iboResult = device.createBuffer({
|
|
2040
2072
|
label: `mesh-${id}-ibo`,
|
|
@@ -2042,17 +2074,24 @@ export class GpuResidencyCache {
|
|
|
2042
2074
|
usage: renderData.indexUsage,
|
|
2043
2075
|
mappedAtCreation: false,
|
|
2044
2076
|
});
|
|
2045
|
-
if (!iboResult.ok)
|
|
2077
|
+
if (!iboResult.ok) {
|
|
2078
|
+
cleanupUpload();
|
|
2079
|
+
return iboResult;
|
|
2080
|
+
}
|
|
2046
2081
|
ibo = iboResult.value;
|
|
2047
2082
|
}
|
|
2048
2083
|
|
|
2049
2084
|
const vboWriteResult = device.queue.writeBuffer(vbo, 0, vertices);
|
|
2050
|
-
if (!vboWriteResult.ok)
|
|
2085
|
+
if (!vboWriteResult.ok) {
|
|
2086
|
+
cleanupUpload();
|
|
2087
|
+
return err(vboWriteResult.error);
|
|
2088
|
+
}
|
|
2051
2089
|
|
|
2052
2090
|
if (indices !== undefined) {
|
|
2053
2091
|
const indexSrc = new Uint8Array(indexBytes);
|
|
2054
2092
|
indexSrc.set(new Uint8Array(indices.buffer, indices.byteOffset, indexBytesUnpadded));
|
|
2055
|
-
if (ibo === null)
|
|
2093
|
+
if (ibo === null) {
|
|
2094
|
+
cleanupUpload();
|
|
2056
2095
|
return err(
|
|
2057
2096
|
new RhiError({
|
|
2058
2097
|
code: 'webgpu-runtime-error',
|
|
@@ -2060,8 +2099,12 @@ export class GpuResidencyCache {
|
|
|
2060
2099
|
hint: 'the indexed mesh upload lost its RHI index-buffer owner',
|
|
2061
2100
|
}),
|
|
2062
2101
|
);
|
|
2102
|
+
}
|
|
2063
2103
|
const iboWriteResult = device.queue.writeBuffer(ibo, 0, indexSrc);
|
|
2064
|
-
if (!iboWriteResult.ok)
|
|
2104
|
+
if (!iboWriteResult.ok) {
|
|
2105
|
+
cleanupUpload();
|
|
2106
|
+
return err(iboWriteResult.error);
|
|
2107
|
+
}
|
|
2065
2108
|
}
|
|
2066
2109
|
|
|
2067
2110
|
// The geometry projection already contains every packed attribute,
|
|
@@ -2085,6 +2128,7 @@ export class GpuResidencyCache {
|
|
|
2085
2128
|
...(lodRanges === undefined ? {} : { lodRanges }),
|
|
2086
2129
|
};
|
|
2087
2130
|
this.meshGpuHandles.set(id, entry);
|
|
2131
|
+
this.meshLodAssets.set(entry, lodMeshes);
|
|
2088
2132
|
this.meshResidencyEpoch += 1;
|
|
2089
2133
|
return ok(entry);
|
|
2090
2134
|
}
|
package/src/dynamic-geometry.ts
CHANGED
|
@@ -53,6 +53,9 @@ export interface DynamicGeometryCandidate {
|
|
|
53
53
|
readonly state: DynamicGeometryCandidateState;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/** Record-stage lane that consumed a published dynamic-geometry candidate. */
|
|
57
|
+
export type DynamicGeometryRecordStageLane = 'cpu' | 'gpu' | 'mixed';
|
|
58
|
+
|
|
56
59
|
/** Receipt that ties candidate publication to the sole Renderer FrameReceipt. */
|
|
57
60
|
export interface DynamicGeometryReceipt {
|
|
58
61
|
readonly candidateId: string;
|
|
@@ -69,6 +72,8 @@ export interface DynamicGeometryReceipt {
|
|
|
69
72
|
};
|
|
70
73
|
/** Whether the Renderer record stage consumed this candidate for this frame. */
|
|
71
74
|
readonly recordStageConsumed: boolean;
|
|
75
|
+
/** Lane evidence from the exact submitted record stage, when attached. */
|
|
76
|
+
readonly recordStageLane?: DynamicGeometryRecordStageLane;
|
|
72
77
|
/** Actual frame fixed step; may be newer than the preparation step. */
|
|
73
78
|
readonly publicationFixedStep?: number;
|
|
74
79
|
}
|
|
@@ -271,6 +276,9 @@ export interface DynamicGeometryLifecycle {
|
|
|
271
276
|
worlds?: readonly object[],
|
|
272
277
|
fixedStep?: number,
|
|
273
278
|
canPublish?: (candidate: DynamicGeometryCandidate) => boolean,
|
|
279
|
+
recordStageLane?: (
|
|
280
|
+
candidate: DynamicGeometryCandidate,
|
|
281
|
+
) => DynamicGeometryRecordStageLane | undefined,
|
|
274
282
|
): readonly DynamicGeometryReceipt[];
|
|
275
283
|
invalidateWorld(world: object, completion?: Promise<unknown>): void;
|
|
276
284
|
invalidateGeneration(generation: number): void;
|
|
@@ -610,7 +618,7 @@ export function createDynamicGeometryLifecycle(
|
|
|
610
618
|
meshBytes = Math.max(0, meshBytes - record.candidate.meshBytes);
|
|
611
619
|
return ok(undefined);
|
|
612
620
|
},
|
|
613
|
-
publishFrame(frame, worlds, fixedStep, canPublish) {
|
|
621
|
+
publishFrame(frame, worlds, fixedStep, canPublish, recordStageLane) {
|
|
614
622
|
if (disposed || frame.deviceGeneration !== currentGeneration) return [];
|
|
615
623
|
const receipts: DynamicGeometryReceipt[] = [];
|
|
616
624
|
for (const record of records.values()) {
|
|
@@ -630,6 +638,8 @@ export function createDynamicGeometryLifecycle(
|
|
|
630
638
|
continue;
|
|
631
639
|
}
|
|
632
640
|
if (canPublish !== undefined && !canPublish(record.candidate)) continue;
|
|
641
|
+
const consumedLane =
|
|
642
|
+
canPublish === undefined ? undefined : recordStageLane?.(record.candidate);
|
|
633
643
|
record.candidate = Object.freeze({ ...record.candidate, state: 'published' as const });
|
|
634
644
|
const receipt = Object.freeze({
|
|
635
645
|
candidateId: record.candidate.candidateId,
|
|
@@ -642,6 +652,7 @@ export function createDynamicGeometryLifecycle(
|
|
|
642
652
|
frameId: frame.frameId,
|
|
643
653
|
deviceGeneration: frame.deviceGeneration,
|
|
644
654
|
recordStageConsumed: canPublish !== undefined,
|
|
655
|
+
...(consumedLane === undefined ? {} : { recordStageLane: consumedLane }),
|
|
645
656
|
...(fixedStep === undefined ? {} : { publicationFixedStep: fixedStep }),
|
|
646
657
|
frame: Object.freeze({ ...frame }),
|
|
647
658
|
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { mat4 } from '@forgeax/engine-math';
|
|
2
|
+
import type { FogFrame } from '../extract/environment';
|
|
3
|
+
import { computeProjectionMatrix, computeViewMatrix } from '../record/helpers';
|
|
4
|
+
import type { CameraSnapshot } from '../render-contract';
|
|
5
|
+
|
|
6
|
+
/** Numerical reference for the shader's closed-form height-density integral. */
|
|
7
|
+
export function analyticFogOpacity(
|
|
8
|
+
fog: Pick<FogFrame, 'density' | 'heightFalloff' | 'maxOpacity'>,
|
|
9
|
+
originY: number,
|
|
10
|
+
endY: number,
|
|
11
|
+
distance: number,
|
|
12
|
+
): number {
|
|
13
|
+
const rho = fog.density * Math.exp(Math.max(-60, Math.min(60, -fog.heightFalloff * originY)));
|
|
14
|
+
const t = Math.max(-60, Math.min(60, fog.heightFalloff * (endY - originY)));
|
|
15
|
+
const integral = Math.abs(t) < 0.001 ? 1 - t / 2 + (t * t) / 6 : -Math.expm1(-t) / t;
|
|
16
|
+
return fog.maxOpacity * -Math.expm1(-Math.min(80, Math.max(0, rho * distance * integral)));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function encodeAnalyticFogParams(fog: FogFrame, camera: CameraSnapshot): Uint8Array {
|
|
20
|
+
const projection = computeProjectionMatrix(camera);
|
|
21
|
+
// Match the scene depth's jittered projection before temporal resolve.
|
|
22
|
+
const jitter = camera.temporal?.currentJitterUv;
|
|
23
|
+
if (jitter !== undefined) {
|
|
24
|
+
for (let column = 0; column < 4; column++) {
|
|
25
|
+
projection[column * 4] =
|
|
26
|
+
(projection[column * 4] ?? 0) + jitter[0] * 2 * (projection[column * 4 + 3] ?? 0);
|
|
27
|
+
projection[column * 4 + 1] =
|
|
28
|
+
(projection[column * 4 + 1] ?? 0) - jitter[1] * 2 * (projection[column * 4 + 3] ?? 0);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const inverse = mat4.invert(
|
|
32
|
+
mat4.create(),
|
|
33
|
+
mat4.multiply(mat4.create(), projection, computeViewMatrix(camera)),
|
|
34
|
+
);
|
|
35
|
+
const data = new Float32Array(28);
|
|
36
|
+
data.set(inverse, 0);
|
|
37
|
+
data.set(camera.position, 16);
|
|
38
|
+
data.set([...fog.color, fog.density], 20);
|
|
39
|
+
data.set(
|
|
40
|
+
[fog.heightFalloff, fog.maxOpacity, camera.near, camera.projection === 'orthographic' ? 1 : 0],
|
|
41
|
+
24,
|
|
42
|
+
);
|
|
43
|
+
return new Uint8Array(data.buffer);
|
|
44
|
+
}
|
|
@@ -88,8 +88,8 @@ export function addAtmosphereBackground(
|
|
|
88
88
|
settings.mieDirectionalG,
|
|
89
89
|
settings.sunAngularRadius,
|
|
90
90
|
settings.sunAngularRadius > 0 ? 1 : 0,
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
settings.circumsolarStrength,
|
|
92
|
+
settings.circumsolarWidth,
|
|
93
93
|
]);
|
|
94
94
|
frame.runtime.device.queue
|
|
95
95
|
.writeBuffer(resources.buffer(params.value).unwrap(), 0, values)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/** Closed errors produced by the CloudLayer authoring and resource route. */
|
|
2
|
+
|
|
3
|
+
export interface CloudLayerInvalidParameterDetail {
|
|
4
|
+
readonly field: string;
|
|
5
|
+
readonly value: unknown;
|
|
6
|
+
readonly expected: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class CloudLayerInvalidParameterError extends Error {
|
|
10
|
+
readonly code = 'cloud-layer-invalid-parameter' as const;
|
|
11
|
+
readonly expected: string;
|
|
12
|
+
readonly hint: string;
|
|
13
|
+
readonly detail: CloudLayerInvalidParameterDetail;
|
|
14
|
+
|
|
15
|
+
constructor(field: string, value: unknown, expected: string) {
|
|
16
|
+
super(`CloudLayer.${field} is invalid`);
|
|
17
|
+
this.name = 'CloudLayerInvalidParameterError';
|
|
18
|
+
this.expected = `CloudLayer.${field} must be ${expected}`;
|
|
19
|
+
this.hint = `set CloudLayer.${field} to ${expected}`;
|
|
20
|
+
this.detail = { field, value, expected };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface CloudLayerOwnerConflictDetail {
|
|
25
|
+
readonly count: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class CloudLayerOwnerConflictError extends Error {
|
|
29
|
+
readonly code = 'cloud-layer-owner-conflict' as const;
|
|
30
|
+
readonly expected = 'at most one CloudLayer owns a World frame';
|
|
31
|
+
readonly hint = 'remove additional CloudLayer owners before extraction';
|
|
32
|
+
readonly detail: CloudLayerOwnerConflictDetail;
|
|
33
|
+
|
|
34
|
+
constructor(count: number) {
|
|
35
|
+
super(`CloudLayer owner cardinality is ${count}`);
|
|
36
|
+
this.name = 'CloudLayerOwnerConflictError';
|
|
37
|
+
this.detail = { count };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface CloudLayerCacheInvalidDetail {
|
|
42
|
+
readonly sourceKey: string;
|
|
43
|
+
readonly reason: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class CloudLayerCacheInvalidError extends Error {
|
|
47
|
+
readonly code = 'cloud-layer-cache-invalid' as const;
|
|
48
|
+
readonly expected = 'the density cache payload matches its reconstructible source';
|
|
49
|
+
readonly hint = 'discard the derived cache and rebuild it from CloudLayer source facts';
|
|
50
|
+
readonly detail: CloudLayerCacheInvalidDetail;
|
|
51
|
+
|
|
52
|
+
constructor(sourceKey: string, reason: string) {
|
|
53
|
+
super(`CloudLayer cache is invalid: ${reason}`);
|
|
54
|
+
this.name = 'CloudLayerCacheInvalidError';
|
|
55
|
+
this.detail = { sourceKey, reason };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface CloudLayerCapabilityMissingDetail {
|
|
60
|
+
readonly capability: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class CloudLayerCapabilityMissingError extends Error {
|
|
64
|
+
readonly code = 'cloud-layer-capability-missing' as const;
|
|
65
|
+
readonly expected = 'the selected backend exposes the capability required by the cloud lane';
|
|
66
|
+
readonly hint =
|
|
67
|
+
'inspect the capability report, disable the cloud lane on this backend, or retry on a backend with the required capability';
|
|
68
|
+
readonly detail: CloudLayerCapabilityMissingDetail;
|
|
69
|
+
|
|
70
|
+
constructor(capability: string) {
|
|
71
|
+
super(`CloudLayer capability is unavailable: ${capability}`);
|
|
72
|
+
this.name = 'CloudLayerCapabilityMissingError';
|
|
73
|
+
this.detail = { capability };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface CloudLayerResourceFailureDetail {
|
|
78
|
+
readonly stage: 'cache' | 'shadow' | 'view' | 'history' | 'retire';
|
|
79
|
+
readonly generation: number;
|
|
80
|
+
readonly cause?: unknown;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export class CloudLayerResourceFailureError extends Error {
|
|
84
|
+
readonly code = 'cloud-layer-resource-failed' as const;
|
|
85
|
+
readonly expected = 'cloud resources are created, submitted and retired as one generation';
|
|
86
|
+
readonly hint = 'keep the last-known-good cloud generation and retry after recovery';
|
|
87
|
+
readonly detail: CloudLayerResourceFailureDetail;
|
|
88
|
+
|
|
89
|
+
constructor(detail: CloudLayerResourceFailureDetail) {
|
|
90
|
+
super(`CloudLayer ${detail.stage} resource failed at generation ${detail.generation}`);
|
|
91
|
+
this.name = 'CloudLayerResourceFailureError';
|
|
92
|
+
this.detail = detail;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export type CloudLayerError =
|
|
97
|
+
| CloudLayerInvalidParameterError
|
|
98
|
+
| CloudLayerOwnerConflictError
|
|
99
|
+
| CloudLayerCacheInvalidError
|
|
100
|
+
| CloudLayerCapabilityMissingError
|
|
101
|
+
| CloudLayerResourceFailureError;
|
|
102
|
+
|
|
103
|
+
export type CloudLayerErrorCode = CloudLayerError['code'];
|
package/src/errors/render.ts
CHANGED
|
@@ -19,6 +19,8 @@ import type {
|
|
|
19
19
|
SurfaceFailureKind,
|
|
20
20
|
} from '@forgeax/engine-render-graph';
|
|
21
21
|
import type { DeviceResourceKind, DeviceScopeReceipt } from '../device/resource-types';
|
|
22
|
+
import type { SunCardinalityError } from '../environment/frame';
|
|
23
|
+
import type { MotionBlurValidationError } from '../features/motion-blur/motion-blur-params';
|
|
22
24
|
import type {
|
|
23
25
|
PreparedKind,
|
|
24
26
|
RenderFeatureCapabilityKey,
|
|
@@ -28,6 +30,7 @@ import type {
|
|
|
28
30
|
import type { AutoExposureError } from '../pipeline/standard-output/auto-exposure/inspection';
|
|
29
31
|
import type { SceneDataLane, SceneDataSchemaId } from '../temporal/scene-data';
|
|
30
32
|
import type { TransmissionCapabilityFact } from '../transmission/backdrop';
|
|
33
|
+
import type { CloudLayerError } from './cloud';
|
|
31
34
|
import type { RecoveryOutcome, RecoveryPhase } from './recover';
|
|
32
35
|
|
|
33
36
|
// Public render errors keep one machine-readable order: closed `code`,
|
|
@@ -783,6 +786,8 @@ export interface RenderFeatureStageFailedDetail {
|
|
|
783
786
|
readonly stage: RenderFeatureStage;
|
|
784
787
|
readonly recovery: RenderFeatureRecovery;
|
|
785
788
|
readonly cleanupFailures?: readonly RenderFeatureCleanupFailure[];
|
|
789
|
+
/** Original stage exception when the feature did not return a RenderError. */
|
|
790
|
+
readonly cause?: unknown;
|
|
786
791
|
}
|
|
787
792
|
|
|
788
793
|
export interface RenderFeatureCapabilityMissingDetail {
|
|
@@ -947,6 +952,7 @@ export class RenderFeatureStageFailedError extends Error {
|
|
|
947
952
|
order: number,
|
|
948
953
|
stage: RenderFeatureStage,
|
|
949
954
|
recovery: RenderFeatureRecovery,
|
|
955
|
+
cause?: unknown,
|
|
950
956
|
) {
|
|
951
957
|
const expected = `feature '${featureIdentity}' completes its ${stage} stage without an error`;
|
|
952
958
|
const hint = renderFeatureRecoveryHintByRecovery[recovery](featureIdentity, stage);
|
|
@@ -954,7 +960,13 @@ export class RenderFeatureStageFailedError extends Error {
|
|
|
954
960
|
this.name = 'RenderFeatureStageFailedError';
|
|
955
961
|
this.expected = expected;
|
|
956
962
|
this.hint = hint;
|
|
957
|
-
this.detail = {
|
|
963
|
+
this.detail = {
|
|
964
|
+
featureIdentity,
|
|
965
|
+
order,
|
|
966
|
+
stage,
|
|
967
|
+
recovery,
|
|
968
|
+
...(cause === undefined ? {} : { cause }),
|
|
969
|
+
};
|
|
958
970
|
}
|
|
959
971
|
}
|
|
960
972
|
|
|
@@ -1381,6 +1393,27 @@ export type DynamicResolutionError =
|
|
|
1381
1393
|
| DynamicResolutionRequiresTaaError
|
|
1382
1394
|
| DynamicResolutionTimingUnavailableError;
|
|
1383
1395
|
|
|
1396
|
+
export interface BarrelDistortionInvalidParameterDetail {
|
|
1397
|
+
readonly field: 'width' | 'height' | 'strength' | 'centerX' | 'centerY';
|
|
1398
|
+
readonly value: number;
|
|
1399
|
+
readonly expected: string;
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
export class BarrelDistortionInvalidParameterError extends Error {
|
|
1403
|
+
readonly code = 'barrel-distortion-invalid-parameter' as const;
|
|
1404
|
+
readonly expected: string;
|
|
1405
|
+
readonly hint: string;
|
|
1406
|
+
readonly detail: BarrelDistortionInvalidParameterDetail;
|
|
1407
|
+
|
|
1408
|
+
constructor(detail: BarrelDistortionInvalidParameterDetail) {
|
|
1409
|
+
super(`BarrelDistortion.${detail.field} is invalid`);
|
|
1410
|
+
this.name = 'BarrelDistortionInvalidParameterError';
|
|
1411
|
+
this.expected = `BarrelDistortion.${detail.field} must be ${detail.expected}`;
|
|
1412
|
+
this.hint = `set BarrelDistortion.${detail.field} to a value that is ${detail.expected}`;
|
|
1413
|
+
this.detail = detail;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1384
1417
|
export interface OwnerStageFailedDetail {
|
|
1385
1418
|
readonly owner: 'environment' | 'temporal' | 'fog' | 'renderer';
|
|
1386
1419
|
readonly stage: 'extract' | 'prepare' | 'record' | 'finish' | 'submit';
|
|
@@ -1828,8 +1861,8 @@ export interface VolumeOwnerConflictDetail {
|
|
|
1828
1861
|
|
|
1829
1862
|
export class VolumeOwnerConflictError extends Error {
|
|
1830
1863
|
readonly code = 'volume-owner-conflict' as const;
|
|
1831
|
-
readonly expected = '
|
|
1832
|
-
readonly hint = '
|
|
1864
|
+
readonly expected = 'at most eight local VolumetricFog owners per rendered World';
|
|
1865
|
+
readonly hint = 'reduce simultaneously visible volume owners and retry extraction';
|
|
1833
1866
|
readonly detail: VolumeOwnerConflictDetail;
|
|
1834
1867
|
|
|
1835
1868
|
constructor(ownerCount: number) {
|
|
@@ -1883,13 +1916,26 @@ export interface VolumeInvalidParametersDetail {
|
|
|
1883
1916
|
export class VolumeInvalidParametersError extends Error {
|
|
1884
1917
|
readonly code = 'volume-invalid-parameters' as const;
|
|
1885
1918
|
readonly expected = 'volume parameters remain finite and inside their closed ranges';
|
|
1886
|
-
readonly hint = 'repair extinction, albedo, emission, anisotropy, or
|
|
1919
|
+
readonly hint = 'repair extinction, albedo, emission, anisotropy, maxDistance, or sampling';
|
|
1887
1920
|
readonly detail: VolumeInvalidParametersDetail;
|
|
1888
1921
|
|
|
1889
|
-
constructor(input: {
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1922
|
+
constructor(input: {
|
|
1923
|
+
readonly maxDistance?: number;
|
|
1924
|
+
readonly anisotropy?: number;
|
|
1925
|
+
readonly sampling?: string;
|
|
1926
|
+
}) {
|
|
1927
|
+
const invalidSampling =
|
|
1928
|
+
input.sampling !== undefined && input.sampling !== 'noise' && input.sampling !== 'density';
|
|
1929
|
+
const field = invalidSampling
|
|
1930
|
+
? 'sampling'
|
|
1931
|
+
: input.maxDistance !== undefined && input.maxDistance <= 0
|
|
1932
|
+
? 'maxDistance'
|
|
1933
|
+
: 'parameters';
|
|
1934
|
+
const value = invalidSampling
|
|
1935
|
+
? input.sampling
|
|
1936
|
+
: field === 'maxDistance'
|
|
1937
|
+
? input.maxDistance
|
|
1938
|
+
: input.anisotropy;
|
|
1893
1939
|
super(`volume-invalid-parameters: ${field} is outside the authored range`);
|
|
1894
1940
|
this.name = 'VolumeInvalidParametersError';
|
|
1895
1941
|
this.detail = { field, value };
|
|
@@ -1966,12 +2012,16 @@ export type RenderError =
|
|
|
1966
2012
|
| RenderFeatureDrawRecordingFailedError
|
|
1967
2013
|
| EnvironmentSourceConflictError
|
|
1968
2014
|
| FogCardinalityError
|
|
2015
|
+
| SunCardinalityError
|
|
1969
2016
|
| TaaCapsInsufficientError
|
|
1970
2017
|
| EnvironmentGenerationFailedError
|
|
1971
2018
|
| AtmosphereInvalidParameterError
|
|
2019
|
+
| BarrelDistortionInvalidParameterError
|
|
2020
|
+
| CloudLayerError
|
|
1972
2021
|
| DynamicResolutionInvalidParameterError
|
|
1973
2022
|
| DynamicResolutionRequiresTaaError
|
|
1974
2023
|
| DynamicResolutionTimingUnavailableError
|
|
2024
|
+
| MotionBlurValidationError
|
|
1975
2025
|
| OwnerStageFailedError
|
|
1976
2026
|
| PointsLinesInvalidStyleError
|
|
1977
2027
|
| PointsLinesTopologyMismatchError
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { MaterialRootAsset } from '@forgeax/engine-types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A public root asset showing the model declaration and its bounded input.
|
|
5
|
+
* The page is shared by every material instance; Render supplies the page
|
|
6
|
+
* bytes and each instance publishes its own range.
|
|
7
|
+
*/
|
|
8
|
+
export const SINGLE_LAYER_MEDIUM_SURFACE_EXAMPLE = {
|
|
9
|
+
kind: 'material',
|
|
10
|
+
surface: {
|
|
11
|
+
model: 'single-layer-medium',
|
|
12
|
+
module: 'game::water_surface_a',
|
|
13
|
+
dynamicInput: {
|
|
14
|
+
name: 'waterEvents',
|
|
15
|
+
fields: [
|
|
16
|
+
{ name: 'position', type: 'vec3<f32>' },
|
|
17
|
+
{ name: 'time', type: 'f32' },
|
|
18
|
+
{ name: 'eventId', type: 'u32' },
|
|
19
|
+
],
|
|
20
|
+
maxRecords: 64,
|
|
21
|
+
maxDomains: 8,
|
|
22
|
+
maxPageBytes: 2048,
|
|
23
|
+
maxBindings: 1,
|
|
24
|
+
maxEventsPerSample: 8,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
passes: [
|
|
28
|
+
{
|
|
29
|
+
name: 'color',
|
|
30
|
+
program: { module: 'forgeax::single-layer-medium' },
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
parameters: [],
|
|
34
|
+
values: {},
|
|
35
|
+
} as const satisfies MaterialRootAsset;
|
|
36
|
+
|
|
37
|
+
/** Two different imported Surface implementations consuming one model ABI. */
|
|
38
|
+
export const SINGLE_LAYER_MEDIUM_SURFACE_EXAMPLES = [
|
|
39
|
+
{
|
|
40
|
+
module: 'game::water_surface_a',
|
|
41
|
+
source: `#define_import_path game::water_surface_a
|
|
42
|
+
#import forgeax_material::single_layer_medium_surface_v1::{SingleLayerMediumSurfaceInput, SingleLayerMediumSurfaceData}
|
|
43
|
+
fn evaluate_surface(input : SingleLayerMediumSurfaceInput) -> SingleLayerMediumSurfaceData {
|
|
44
|
+
let event = read_waterEvents(input.eventRangeStart);
|
|
45
|
+
let normal = normalize(input.geometricNormalWS + vec3<f32>(0.0, 0.0, event.time * 0.02));
|
|
46
|
+
return SingleLayerMediumSurfaceData(normal, 0.18, 1.0, 0.0, vec3<f32>(0.18, 0.06, 0.02), vec3<f32>(0.02, 0.04, 0.08), 1.333, 0.2, 1000.0);
|
|
47
|
+
}`,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
module: 'game::water_surface_b',
|
|
51
|
+
source: `#define_import_path game::water_surface_b
|
|
52
|
+
#import forgeax_material::single_layer_medium_surface_v1::{SingleLayerMediumSurfaceInput, SingleLayerMediumSurfaceData}
|
|
53
|
+
fn evaluate_surface(input : SingleLayerMediumSurfaceInput) -> SingleLayerMediumSurfaceData {
|
|
54
|
+
let event = read_waterEvents(input.eventRangeStart);
|
|
55
|
+
let normal = normalize(input.geometricNormalWS + vec3<f32>(event.position.xy * 0.01, 0.0));
|
|
56
|
+
return SingleLayerMediumSurfaceData(normal, 0.32, 1.0, clamp(event.time * 0.1, 0.0, 1.0), vec3<f32>(0.04, 0.02, 0.01), vec3<f32>(0.08, 0.05, 0.02), 1.333, -0.1, 800.0);
|
|
57
|
+
}`,
|
|
58
|
+
},
|
|
59
|
+
] as const;
|
package/src/extract/camera.ts
CHANGED
|
@@ -2,13 +2,17 @@ import type { EntityHandle, World } from '@forgeax/engine-ecs';
|
|
|
2
2
|
import { readRenderArrayView } from '@forgeax/engine-ecs/projection';
|
|
3
3
|
import { mat4, vec3 } from '@forgeax/engine-math';
|
|
4
4
|
import { GlobalTransform } from '@forgeax/engine-scene';
|
|
5
|
+
import {
|
|
6
|
+
BarrelDistortion,
|
|
7
|
+
validateBarrelDistortionParameters,
|
|
8
|
+
} from '../components/barrel-distortion';
|
|
5
9
|
import {
|
|
6
10
|
antialiasFromF32,
|
|
7
|
-
bloomEnabledFromF32,
|
|
8
11
|
Camera,
|
|
9
12
|
cameraExposureFromColumns,
|
|
10
13
|
cameraProjectionFromF32,
|
|
11
14
|
tonemapFromF32,
|
|
15
|
+
validateCameraBloom,
|
|
12
16
|
validateCameraColorGrading,
|
|
13
17
|
} from '../components/camera';
|
|
14
18
|
import { DepthOfField } from '../components/depth-of-field';
|
|
@@ -22,6 +26,7 @@ import {
|
|
|
22
26
|
depthOfFieldRequestFailure,
|
|
23
27
|
resolveDepthOfFieldParams,
|
|
24
28
|
} from '../features/depth-of-field/depth-of-field-params';
|
|
29
|
+
import { resolveMotionBlurParams } from '../features/motion-blur/motion-blur-params';
|
|
25
30
|
import type { CameraSnapshot } from '../render-contract';
|
|
26
31
|
import { getActiveCamera, selectActiveCameraIndex } from '../systems/active-camera';
|
|
27
32
|
|
|
@@ -37,13 +42,23 @@ export function extractCameraSnapshots(world: World): CameraSnapshot[] {
|
|
|
37
42
|
const cameraQuery = world
|
|
38
43
|
.query({
|
|
39
44
|
read: [Camera],
|
|
40
|
-
optional: [
|
|
45
|
+
optional: [
|
|
46
|
+
MotionBlur,
|
|
47
|
+
DynamicResolution,
|
|
48
|
+
ScreenSpaceReflection,
|
|
49
|
+
DepthOfField,
|
|
50
|
+
BarrelDistortion,
|
|
51
|
+
],
|
|
41
52
|
with: [GlobalTransform],
|
|
42
53
|
})
|
|
43
54
|
.unwrap();
|
|
44
55
|
for (const row of cameraQuery) {
|
|
45
56
|
const cam = row.get(Camera);
|
|
46
57
|
const motionBlur = row.get(MotionBlur);
|
|
58
|
+
const barrelDistortion = row.get(BarrelDistortion);
|
|
59
|
+
const motionBlurResult = resolveMotionBlurParams(motionBlur);
|
|
60
|
+
if (!motionBlurResult.ok) throw motionBlurResult.error;
|
|
61
|
+
const motionBlurParams = motionBlurResult.value;
|
|
47
62
|
const depthOfField = row.get(DepthOfField);
|
|
48
63
|
validateCameraColorGrading(cam.temperature, cam.tint, cam.colorLutStrength);
|
|
49
64
|
const dynamicResolution = row.get(DynamicResolution);
|
|
@@ -58,12 +73,21 @@ export function extractCameraSnapshots(world: World): CameraSnapshot[] {
|
|
|
58
73
|
? undefined
|
|
59
74
|
: depthOfFieldRequestFailure(depthOfFieldResult.error);
|
|
60
75
|
const screenSpaceReflection = row.get(ScreenSpaceReflection);
|
|
76
|
+
const bloom = validateCameraBloom(
|
|
77
|
+
cam.bloom,
|
|
78
|
+
cam.bloomThreshold,
|
|
79
|
+
cam.bloomIntensity,
|
|
80
|
+
cam.bloomSoftKnee,
|
|
81
|
+
cam.bloomScatter,
|
|
82
|
+
);
|
|
61
83
|
const entity = row.entity as EntityHandle;
|
|
62
84
|
const worldMat = readWorldMatrix(world, entity);
|
|
63
85
|
if (worldMat === undefined) continue;
|
|
64
86
|
const antialias = antialiasFromF32(cam.antialias);
|
|
65
87
|
const dynamicResolutionResult = validateDynamicResolutionCamera(dynamicResolution, antialias);
|
|
66
88
|
if (!dynamicResolutionResult.ok) throw dynamicResolutionResult.error;
|
|
89
|
+
const barrelDistortionResult = validateBarrelDistortionParameters(barrelDistortion);
|
|
90
|
+
if (!barrelDistortionResult.ok) throw barrelDistortionResult.error;
|
|
67
91
|
cameras.push({
|
|
68
92
|
entityKey: entity as number,
|
|
69
93
|
historyVersion: cam.historyVersion,
|
|
@@ -92,10 +116,11 @@ export function extractCameraSnapshots(world: World): CameraSnapshot[] {
|
|
|
92
116
|
...(dynamicResolutionResult.value === undefined
|
|
93
117
|
? {}
|
|
94
118
|
: { dynamicResolution: dynamicResolutionResult.value }),
|
|
95
|
-
bloom
|
|
119
|
+
bloom,
|
|
96
120
|
bloomThreshold: cam.bloomThreshold,
|
|
97
121
|
bloomIntensity: cam.bloomIntensity,
|
|
98
|
-
|
|
122
|
+
bloomSoftKnee: cam.bloomSoftKnee,
|
|
123
|
+
bloomScatter: cam.bloomScatter,
|
|
99
124
|
clearColor: [
|
|
100
125
|
cam.clearColor[0] ?? 0,
|
|
101
126
|
cam.clearColor[1] ?? 0,
|
|
@@ -106,15 +131,17 @@ export function extractCameraSnapshots(world: World): CameraSnapshot[] {
|
|
|
106
131
|
? { depthOfField: depthOfFieldResult.value }
|
|
107
132
|
: {}),
|
|
108
133
|
...(depthOfFieldError === undefined ? {} : { depthOfFieldError }),
|
|
109
|
-
...(
|
|
134
|
+
...(motionBlurParams === undefined
|
|
110
135
|
? {}
|
|
111
136
|
: {
|
|
112
137
|
motionBlur: {
|
|
113
|
-
shutterAngle:
|
|
114
|
-
maxRadiusPixels:
|
|
115
|
-
sampleCount:
|
|
138
|
+
shutterAngle: motionBlurParams.shutterAngle,
|
|
139
|
+
maxRadiusPixels: motionBlurParams.maxRadiusPixels,
|
|
140
|
+
sampleCount: motionBlurParams.sampleCount,
|
|
141
|
+
targetFps: motionBlurParams.targetFps,
|
|
116
142
|
},
|
|
117
143
|
}),
|
|
144
|
+
...(barrelDistortion === undefined ? {} : { barrelDistortion: barrelDistortionResult.value }),
|
|
118
145
|
...(screenSpaceReflection === undefined
|
|
119
146
|
? {}
|
|
120
147
|
: {
|