@driftengine/core 3.62.0 → 4.0.0
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/CHANGELOG.json +122 -0
- package/NOTICE +20 -0
- package/README.md +1 -1
- package/dist/core/loop.js +18 -2
- package/dist/core/storage.js +5 -0
- package/dist/geometry/meshBuilder.d.ts +1 -1
- package/dist/geometry/meshBuilder.js +6 -2
- package/dist/index.d.ts +70 -4
- package/dist/index.js +123 -2
- package/dist/input/input.js +6 -1
- package/dist/math/exact.d.ts +13 -3
- package/dist/math/exact.js +68 -3
- package/dist/math/frustum.d.ts +17 -2
- package/dist/math/frustum.js +24 -0
- package/dist/render/backend/api.d.ts +34 -1
- package/dist/render/backend/api.js +22 -1
- package/dist/render/backend/budget.d.ts +7 -6
- package/dist/render/backend/budget.js +7 -6
- package/dist/render/backend/createRenderer.d.ts +57 -0
- package/dist/render/backend/createRenderer.js +51 -2
- package/dist/render/backend/materialChanges.d.ts +41 -0
- package/dist/render/backend/materialChanges.js +38 -0
- package/dist/render/backend/select.js +8 -0
- package/dist/render/backend/webgl2/renderer.d.ts +80 -1
- package/dist/render/backend/webgl2/renderer.js +208 -10
- package/dist/render/backend/webgpu/buffers.d.ts +20 -1
- package/dist/render/backend/webgpu/buffers.js +116 -58
- package/dist/render/backend/webgpu/fieldCompose.d.ts +156 -0
- package/dist/render/backend/webgpu/fieldCompose.js +396 -0
- package/dist/render/backend/webgpu/giFieldPass.d.ts +66 -0
- package/dist/render/backend/webgpu/giFieldPass.js +137 -0
- package/dist/render/backend/webgpu/gpuDrivenPass.d.ts +728 -0
- package/dist/render/backend/webgpu/gpuDrivenPass.js +2473 -0
- package/dist/render/backend/webgpu/linePass.d.ts +4 -14
- package/dist/render/backend/webgpu/linePass.js +4 -33
- package/dist/render/backend/webgpu/probeBake.d.ts +148 -0
- package/dist/render/backend/webgpu/probeBake.js +493 -0
- package/dist/render/backend/webgpu/renderer.d.ts +379 -24
- package/dist/render/backend/webgpu/renderer.js +1369 -76
- package/dist/render/backend/webgpu/scatterPass.js +15 -1
- package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +47 -14
- package/dist/render/backend/webgpu/surfaceTexturePass.js +128 -80
- package/dist/render/causticsRenderer.d.ts +3 -1
- package/dist/render/causticsRenderer.js +4 -1
- package/dist/render/depthConvention.d.ts +12 -0
- package/dist/render/depthConvention.js +14 -0
- package/dist/render/deviceFeatures.d.ts +32 -0
- package/dist/render/deviceFeatures.js +41 -0
- package/dist/render/fog.d.ts +79 -0
- package/dist/render/fog.js +138 -0
- package/dist/render/frame/alias.d.ts +30 -0
- package/dist/render/frame/alias.js +61 -0
- package/dist/render/frame/deps.d.ts +37 -0
- package/dist/render/frame/deps.js +122 -0
- package/dist/render/frame/flushGraph.d.ts +43 -0
- package/dist/render/frame/flushGraph.js +84 -0
- package/dist/render/frame/graphSchedule.d.ts +49 -0
- package/dist/render/frame/graphSchedule.js +120 -0
- package/dist/render/frame/index.d.ts +15 -0
- package/dist/render/frame/index.js +8 -0
- package/dist/render/frame/lifetime.d.ts +24 -0
- package/dist/render/frame/lifetime.js +36 -0
- package/dist/render/frame/passTimings.d.ts +42 -0
- package/dist/render/frame/passTimings.js +38 -0
- package/dist/render/frame/validate.d.ts +15 -0
- package/dist/render/frame/validate.js +22 -0
- package/dist/render/frame/virtual.d.ts +44 -0
- package/dist/render/frame/virtual.js +61 -0
- package/dist/render/gi/chain.d.ts +82 -0
- package/dist/render/gi/chain.js +135 -0
- package/dist/render/gi/denoise.d.ts +114 -0
- package/dist/render/gi/denoise.js +169 -0
- package/dist/render/gi/fieldScene.d.ts +125 -0
- package/dist/render/gi/fieldScene.js +219 -0
- package/dist/render/gi/globalField.d.ts +157 -0
- package/dist/render/gi/globalField.js +373 -0
- package/dist/render/gi/probeGridFit.d.ts +24 -0
- package/dist/render/gi/probeGridFit.js +71 -0
- package/dist/render/gi/probeTrace.d.ts +82 -0
- package/dist/render/gi/probeTrace.js +128 -0
- package/dist/render/gi/probeVolume.d.ts +136 -0
- package/dist/render/gi/probeVolume.js +191 -0
- package/dist/render/gi/reflection.d.ts +73 -0
- package/dist/render/gi/reflection.js +109 -0
- package/dist/render/gi/traceField.d.ts +91 -0
- package/dist/render/gi/traceField.js +129 -0
- package/dist/render/gi/traceScreen.d.ts +68 -0
- package/dist/render/gi/traceScreen.js +82 -0
- package/dist/render/gpuScene.d.ts +38 -0
- package/dist/render/gpuScene.js +41 -0
- package/dist/render/gpudriven/alphaTest.d.ts +28 -0
- package/dist/render/gpudriven/alphaTest.js +32 -0
- package/dist/render/gpudriven/clusterUpload.d.ts +59 -0
- package/dist/render/gpudriven/clusterUpload.js +75 -0
- package/dist/render/gpudriven/clusterWorld.d.ts +57 -0
- package/dist/render/gpudriven/clusterWorld.js +155 -0
- package/dist/render/gpudriven/compact.d.ts +51 -0
- package/dist/render/gpudriven/compact.js +68 -0
- package/dist/render/gpudriven/cullClusters.d.ts +129 -0
- package/dist/render/gpudriven/cullClusters.js +237 -0
- package/dist/render/gpudriven/decodeTables.d.ts +64 -0
- package/dist/render/gpudriven/decodeTables.js +219 -0
- package/dist/render/gpudriven/frustum.d.ts +25 -0
- package/dist/render/gpudriven/frustum.js +59 -0
- package/dist/render/gpudriven/geometryHarness.d.ts +15 -0
- package/dist/render/gpudriven/geometryHarness.js +31 -0
- package/dist/render/gpudriven/hzb.d.ts +60 -0
- package/dist/render/gpudriven/hzb.js +97 -0
- package/dist/render/gpudriven/ibl.d.ts +85 -0
- package/dist/render/gpudriven/ibl.js +129 -0
- package/dist/render/gpudriven/indirect.d.ts +67 -0
- package/dist/render/gpudriven/indirect.js +77 -0
- package/dist/render/gpudriven/instances.d.ts +43 -0
- package/dist/render/gpudriven/instances.js +172 -0
- package/dist/render/gpudriven/lit.d.ts +165 -0
- package/dist/render/gpudriven/lit.js +165 -0
- package/dist/render/gpudriven/lodCut.d.ts +28 -0
- package/dist/render/gpudriven/lodCut.js +38 -0
- package/dist/render/gpudriven/materialBin.d.ts +60 -0
- package/dist/render/gpudriven/materialBin.js +108 -0
- package/dist/render/gpudriven/materialTable.d.ts +88 -0
- package/dist/render/gpudriven/materialTable.js +115 -0
- package/dist/render/gpudriven/pipeline.d.ts +135 -0
- package/dist/render/gpudriven/pipeline.js +237 -0
- package/dist/render/gpudriven/rangeAlloc.d.ts +50 -0
- package/dist/render/gpudriven/rangeAlloc.js +112 -0
- package/dist/render/gpudriven/sceneUpload.d.ts +96 -0
- package/dist/render/gpudriven/sceneUpload.js +115 -0
- package/dist/render/gpudriven/shadeBins.d.ts +92 -0
- package/dist/render/gpudriven/shadeBins.js +182 -0
- package/dist/render/gpudriven/shadow.d.ts +136 -0
- package/dist/render/gpudriven/shadow.js +224 -0
- package/dist/render/gpudriven/shadowCamera.d.ts +87 -0
- package/dist/render/gpudriven/shadowCamera.js +345 -0
- package/dist/render/gpudriven/streamScene.d.ts +194 -0
- package/dist/render/gpudriven/streamScene.js +459 -0
- package/dist/render/gpudriven/surfaceFrame.d.ts +25 -0
- package/dist/render/gpudriven/surfaceFrame.js +51 -0
- package/dist/render/gpudriven/twoPhase.d.ts +122 -0
- package/dist/render/gpudriven/twoPhase.js +160 -0
- package/dist/render/gpudriven/visbuffer.d.ts +25 -0
- package/dist/render/gpudriven/visbuffer.js +37 -0
- package/dist/render/halfFloat.d.ts +10 -0
- package/dist/render/halfFloat.js +23 -4
- package/dist/render/inference/attentionTiled.d.ts +27 -0
- package/dist/render/inference/attentionTiled.js +117 -0
- package/dist/render/inference/denseKernels.d.ts +29 -0
- package/dist/render/inference/denseKernels.js +312 -0
- package/dist/render/inference/device.d.ts +21 -0
- package/dist/render/inference/device.js +32 -0
- package/dist/render/inference/deviceGraph.d.ts +34 -0
- package/dist/render/inference/deviceGraph.js +17 -0
- package/dist/render/inference/fuse.d.ts +15 -0
- package/dist/render/inference/fuse.js +37 -0
- package/dist/render/inference/kernelKit.d.ts +52 -0
- package/dist/render/inference/kernelKit.js +70 -0
- package/dist/render/inference/kernels.d.ts +3 -0
- package/dist/render/inference/kernels.js +11 -0
- package/dist/render/inference/plan.d.ts +13 -0
- package/dist/render/inference/plan.js +18 -0
- package/dist/render/inference/reuse.d.ts +39 -0
- package/dist/render/inference/reuse.js +65 -0
- package/dist/render/inference/runner.d.ts +31 -0
- package/dist/render/inference/runner.js +175 -0
- package/dist/render/inference/schedule.d.ts +39 -0
- package/dist/render/inference/schedule.js +59 -0
- package/dist/render/inference/shapeKernels.d.ts +10 -0
- package/dist/render/inference/shapeKernels.js +80 -0
- package/dist/render/inference/spatialKernels.d.ts +21 -0
- package/dist/render/inference/spatialKernels.js +179 -0
- package/dist/render/inference/splatRaster.wgsl.d.ts +75 -0
- package/dist/render/inference/splatRaster.wgsl.js +337 -0
- package/dist/render/inference/splatTiles.d.ts +79 -0
- package/dist/render/inference/splatTiles.js +161 -0
- package/dist/render/lineBatch.d.ts +2 -5
- package/dist/render/lineBatch.js +4 -24
- package/dist/render/mesh.d.ts +4 -0
- package/dist/render/mesh.js +45 -1
- package/dist/render/pass.d.ts +145 -8
- package/dist/render/prefilterEnvMap.d.ts +22 -0
- package/dist/render/prefilterEnvMap.js +31 -0
- package/dist/render/readback.d.ts +30 -0
- package/dist/render/readback.js +47 -0
- package/dist/render/recon/clamp.d.ts +36 -0
- package/dist/render/recon/clamp.js +92 -0
- package/dist/render/recon/disocclusion.d.ts +60 -0
- package/dist/render/recon/disocclusion.js +109 -0
- package/dist/render/recon/frameGen.d.ts +81 -0
- package/dist/render/recon/frameGen.js +150 -0
- package/dist/render/recon/frameSizes.d.ts +34 -0
- package/dist/render/recon/frameSizes.js +58 -0
- package/dist/render/recon/jitter.d.ts +60 -0
- package/dist/render/recon/jitter.js +118 -0
- package/dist/render/recon/motionVectors.d.ts +55 -0
- package/dist/render/recon/motionVectors.js +107 -0
- package/dist/render/recon/reproject.d.ts +41 -0
- package/dist/render/recon/reproject.js +131 -0
- package/dist/render/recon/resolve.d.ts +90 -0
- package/dist/render/recon/resolve.js +313 -0
- package/dist/render/recon/tier.d.ts +24 -0
- package/dist/render/recon/tier.js +8 -0
- package/dist/render/reflectionProbe.d.ts +26 -0
- package/dist/render/reflectionProbe.js +33 -0
- package/dist/render/renderQuality.d.ts +69 -0
- package/dist/render/renderQuality.js +22 -0
- package/dist/render/screenSpaceReflection.d.ts +23 -0
- package/dist/render/screenSpaceReflection.js +22 -3
- package/dist/render/sdfFont.js +2 -0
- package/dist/render/segmentQuads.d.ts +13 -0
- package/dist/render/segmentQuads.js +32 -0
- package/dist/render/shaders/flat/lobes.d.ts +27 -0
- package/dist/render/shaders/flat/lobes.js +33 -3
- package/dist/render/shaders/flat/preamble.d.ts +7 -0
- package/dist/render/shaders/flat/preamble.js +24 -1
- package/dist/render/shaders/flat/probeGrid.d.ts +1 -1
- package/dist/render/shaders/flat/probeGrid.js +71 -2
- package/dist/render/shaders/generated/flat.wgsl.d.ts +48 -8
- package/dist/render/shaders/generated/flat.wgsl.js +64 -24
- package/dist/render/shaders/gi/composeField.wgsl.d.ts +56 -0
- package/dist/render/shaders/gi/composeField.wgsl.js +231 -0
- package/dist/render/shaders/gi/marchField.wgsl.d.ts +30 -0
- package/dist/render/shaders/gi/marchField.wgsl.js +141 -0
- package/dist/render/shaders/gi/probeBake.wgsl.d.ts +113 -0
- package/dist/render/shaders/gi/probeBake.wgsl.js +635 -0
- package/dist/render/shaders/gi/probeTrace.wgsl.d.ts +72 -0
- package/dist/render/shaders/gi/probeTrace.wgsl.js +261 -0
- package/dist/render/shaders/gi/probeVolume.wgsl.d.ts +49 -0
- package/dist/render/shaders/gi/probeVolume.wgsl.js +242 -0
- package/dist/render/shaders/gi/sampleField.wgsl.d.ts +32 -0
- package/dist/render/shaders/gi/sampleField.wgsl.js +134 -0
- package/dist/render/shaders/gpudriven/blendRaster.wgsl.d.ts +26 -0
- package/dist/render/shaders/gpudriven/blendRaster.wgsl.js +339 -0
- package/dist/render/shaders/gpudriven/compact.wgsl.d.ts +29 -0
- package/dist/render/shaders/gpudriven/compact.wgsl.js +58 -0
- package/dist/render/shaders/gpudriven/cull.wgsl.d.ts +90 -0
- package/dist/render/shaders/gpudriven/cull.wgsl.js +423 -0
- package/dist/render/shaders/gpudriven/decode.wgsl.d.ts +72 -0
- package/dist/render/shaders/gpudriven/decode.wgsl.js +349 -0
- package/dist/render/shaders/gpudriven/environment.wgsl.d.ts +44 -0
- package/dist/render/shaders/gpudriven/environment.wgsl.js +137 -0
- package/dist/render/shaders/gpudriven/fog.wgsl.d.ts +28 -0
- package/dist/render/shaders/gpudriven/fog.wgsl.js +107 -0
- package/dist/render/shaders/gpudriven/frameBlock.wgsl.d.ts +13 -0
- package/dist/render/shaders/gpudriven/frameBlock.wgsl.js +62 -0
- package/dist/render/shaders/gpudriven/materialBin.wgsl.d.ts +51 -0
- package/dist/render/shaders/gpudriven/materialBin.wgsl.js +112 -0
- package/dist/render/shaders/gpudriven/materialTable.wgsl.d.ts +25 -0
- package/dist/render/shaders/gpudriven/materialTable.wgsl.js +43 -0
- package/dist/render/shaders/gpudriven/meshTransform.wgsl.d.ts +18 -0
- package/dist/render/shaders/gpudriven/meshTransform.wgsl.js +37 -0
- package/dist/render/shaders/gpudriven/present.wgsl.d.ts +43 -0
- package/dist/render/shaders/gpudriven/present.wgsl.js +127 -0
- package/dist/render/shaders/gpudriven/shade.wgsl.d.ts +127 -0
- package/dist/render/shaders/gpudriven/shade.wgsl.js +874 -0
- package/dist/render/shaders/gpudriven/shadow.wgsl.d.ts +44 -0
- package/dist/render/shaders/gpudriven/shadow.wgsl.js +308 -0
- package/dist/render/shaders/gpudriven/visbufferRaster.wgsl.d.ts +28 -0
- package/dist/render/shaders/gpudriven/visbufferRaster.wgsl.js +245 -0
- package/dist/render/shaders/network.wgsl.d.ts +101 -0
- package/dist/render/shaders/network.wgsl.js +206 -0
- package/dist/render/shaders/recon/motion.wgsl.d.ts +44 -0
- package/dist/render/shaders/recon/motion.wgsl.js +96 -0
- package/dist/render/shaders/recon/resolve.wgsl.d.ts +51 -0
- package/dist/render/shaders/recon/resolve.wgsl.js +733 -0
- package/dist/render/temporalAa.js +8 -33
- package/dist/render/textLayout.js +12 -6
- package/dist/render/textRenderer.d.ts +3 -1
- package/dist/render/textRenderer.js +4 -1
- package/dist/render/translucentQueue.d.ts +6 -0
- package/dist/render/translucentQueue.js +11 -0
- package/dist/render/windStreakRenderer.d.ts +2 -1
- package/dist/render/windStreakRenderer.js +3 -1
- package/dist/world/cell.d.ts +63 -0
- package/dist/world/cell.js +181 -0
- package/dist/world/cellStream.d.ts +103 -0
- package/dist/world/cellStream.js +198 -0
- package/dist/world/freeze.d.ts +81 -0
- package/dist/world/freeze.js +114 -0
- package/dist/world/rebase.d.ts +29 -0
- package/dist/world/rebase.js +41 -0
- package/package.json +8 -3
- package/scripts/frames.mjs +92 -0
- package/scripts/gpuCompute.mjs +323 -0
- package/scripts/png.d.mts +16 -0
- package/scripts/png.mjs +25 -0
- package/src/core/loop.ts +19 -2
- package/src/core/storage.ts +5 -0
- package/src/geometry/meshBuilder.ts +5 -1
- package/src/index.ts +261 -4
- package/src/input/input.ts +6 -1
- package/src/math/exact.ts +69 -3
- package/src/math/frustum.ts +52 -3
- package/src/render/backend/api.ts +42 -1
- package/src/render/backend/budget.ts +7 -6
- package/src/render/backend/createRenderer.ts +92 -3
- package/src/render/backend/materialChanges.ts +54 -0
- package/src/render/backend/select.ts +8 -0
- package/src/render/backend/webgl2/renderer.ts +211 -9
- package/src/render/backend/webgpu/buffers.ts +182 -69
- package/src/render/backend/webgpu/fieldCompose.ts +482 -0
- package/src/render/backend/webgpu/giFieldPass.ts +200 -0
- package/src/render/backend/webgpu/gpuDrivenPass.ts +2993 -0
- package/src/render/backend/webgpu/linePass.ts +4 -39
- package/src/render/backend/webgpu/probeBake.ts +588 -0
- package/src/render/backend/webgpu/renderer.ts +1481 -76
- package/src/render/backend/webgpu/scatterPass.ts +15 -1
- package/src/render/backend/webgpu/surfaceTexturePass.ts +158 -88
- package/src/render/causticsRenderer.ts +5 -2
- package/src/render/depthConvention.ts +15 -0
- package/src/render/deviceFeatures.ts +77 -0
- package/src/render/fog.ts +185 -0
- package/src/render/frame/alias.ts +97 -0
- package/src/render/frame/deps.ts +155 -0
- package/src/render/frame/flushGraph.ts +135 -0
- package/src/render/frame/graphSchedule.ts +170 -0
- package/src/render/frame/index.ts +52 -0
- package/src/render/frame/lifetime.ts +61 -0
- package/src/render/frame/passTimings.ts +69 -0
- package/src/render/frame/validate.ts +40 -0
- package/src/render/frame/virtual.ts +91 -0
- package/src/render/gi/chain.ts +225 -0
- package/src/render/gi/denoise.ts +276 -0
- package/src/render/gi/fieldScene.ts +264 -0
- package/src/render/gi/globalField.ts +543 -0
- package/src/render/gi/probeGridFit.ts +89 -0
- package/src/render/gi/probeTrace.ts +143 -0
- package/src/render/gi/probeVolume.ts +288 -0
- package/src/render/gi/reflection.ts +163 -0
- package/src/render/gi/traceField.ts +223 -0
- package/src/render/gi/traceScreen.ts +106 -0
- package/src/render/gpuScene.ts +80 -0
- package/src/render/gpudriven/alphaTest.ts +33 -0
- package/src/render/gpudriven/clusterUpload.ts +123 -0
- package/src/render/gpudriven/clusterWorld.ts +239 -0
- package/src/render/gpudriven/compact.ts +80 -0
- package/src/render/gpudriven/cullClusters.ts +333 -0
- package/src/render/gpudriven/decodeTables.ts +332 -0
- package/src/render/gpudriven/frustum.ts +70 -0
- package/src/render/gpudriven/geometryHarness.ts +51 -0
- package/src/render/gpudriven/hzb.ts +113 -0
- package/src/render/gpudriven/ibl.ts +147 -0
- package/src/render/gpudriven/indirect.ts +89 -0
- package/src/render/gpudriven/instances.ts +234 -0
- package/src/render/gpudriven/lit.ts +329 -0
- package/src/render/gpudriven/lodCut.ts +62 -0
- package/src/render/gpudriven/materialBin.ts +131 -0
- package/src/render/gpudriven/materialTable.ts +164 -0
- package/src/render/gpudriven/pipeline.ts +336 -0
- package/src/render/gpudriven/rangeAlloc.ts +122 -0
- package/src/render/gpudriven/sceneUpload.ts +173 -0
- package/src/render/gpudriven/shadeBins.ts +222 -0
- package/src/render/gpudriven/shadow.ts +285 -0
- package/src/render/gpudriven/shadowCamera.ts +406 -0
- package/src/render/gpudriven/streamScene.ts +575 -0
- package/src/render/gpudriven/surfaceFrame.ts +68 -0
- package/src/render/gpudriven/twoPhase.ts +214 -0
- package/src/render/gpudriven/visbuffer.ts +41 -0
- package/src/render/halfFloat.ts +22 -4
- package/src/render/inference/attentionTiled.ts +132 -0
- package/src/render/inference/denseKernels.ts +369 -0
- package/src/render/inference/device.ts +44 -0
- package/src/render/inference/deviceGraph.ts +39 -0
- package/src/render/inference/fuse.ts +47 -0
- package/src/render/inference/kernelKit.ts +120 -0
- package/src/render/inference/kernels.ts +18 -0
- package/src/render/inference/plan.ts +26 -0
- package/src/render/inference/reuse.ts +79 -0
- package/src/render/inference/runner.ts +204 -0
- package/src/render/inference/schedule.ts +80 -0
- package/src/render/inference/shapeKernels.ts +112 -0
- package/src/render/inference/spatialKernels.ts +220 -0
- package/src/render/inference/splatRaster.wgsl.ts +348 -0
- package/src/render/inference/splatTiles.ts +186 -0
- package/src/render/lineBatch.ts +4 -24
- package/src/render/mesh.ts +46 -1
- package/src/render/pass.ts +155 -10
- package/src/render/prefilterEnvMap.ts +33 -0
- package/src/render/readback.ts +73 -0
- package/src/render/recon/clamp.ts +113 -0
- package/src/render/recon/disocclusion.ts +143 -0
- package/src/render/recon/frameGen.ts +191 -0
- package/src/render/recon/frameSizes.ts +64 -0
- package/src/render/recon/jitter.ts +126 -0
- package/src/render/recon/motionVectors.ts +138 -0
- package/src/render/recon/reproject.ts +179 -0
- package/src/render/recon/resolve.ts +444 -0
- package/src/render/recon/tier.ts +31 -0
- package/src/render/reflectionProbe.ts +34 -0
- package/src/render/renderQuality.ts +87 -0
- package/src/render/screenSpaceReflection.ts +37 -3
- package/src/render/sdfFont.ts +2 -0
- package/src/render/segmentQuads.ts +39 -0
- package/src/render/shaders/flat/lobes.ts +35 -3
- package/src/render/shaders/flat/preamble.ts +25 -1
- package/src/render/shaders/flat/probeGrid.ts +77 -2
- package/src/render/shaders/generated/flat.wgsl.ts +64 -24
- package/src/render/shaders/gi/composeField.wgsl.ts +239 -0
- package/src/render/shaders/gi/marchField.wgsl.ts +146 -0
- package/src/render/shaders/gi/probeBake.wgsl.ts +649 -0
- package/src/render/shaders/gi/probeTrace.wgsl.ts +269 -0
- package/src/render/shaders/gi/probeVolume.wgsl.ts +246 -0
- package/src/render/shaders/gi/sampleField.wgsl.ts +140 -0
- package/src/render/shaders/gpudriven/blendRaster.wgsl.ts +343 -0
- package/src/render/shaders/gpudriven/compact.wgsl.ts +59 -0
- package/src/render/shaders/gpudriven/cull.wgsl.ts +433 -0
- package/src/render/shaders/gpudriven/decode.wgsl.ts +373 -0
- package/src/render/shaders/gpudriven/environment.wgsl.ts +141 -0
- package/src/render/shaders/gpudriven/fog.wgsl.ts +110 -0
- package/src/render/shaders/gpudriven/frameBlock.wgsl.ts +62 -0
- package/src/render/shaders/gpudriven/materialBin.wgsl.ts +116 -0
- package/src/render/shaders/gpudriven/materialTable.wgsl.ts +46 -0
- package/src/render/shaders/gpudriven/meshTransform.wgsl.ts +37 -0
- package/src/render/shaders/gpudriven/present.wgsl.ts +129 -0
- package/src/render/shaders/gpudriven/shade.wgsl.ts +884 -0
- package/src/render/shaders/gpudriven/shadow.wgsl.ts +322 -0
- package/src/render/shaders/gpudriven/visbufferRaster.wgsl.ts +251 -0
- package/src/render/shaders/network.wgsl.ts +238 -0
- package/src/render/shaders/recon/motion.wgsl.ts +101 -0
- package/src/render/shaders/recon/resolve.wgsl.ts +741 -0
- package/src/render/temporalAa.ts +9 -33
- package/src/render/textLayout.ts +12 -6
- package/src/render/textRenderer.ts +5 -2
- package/src/render/translucentQueue.ts +11 -0
- package/src/render/windStreakRenderer.ts +4 -2
- package/src/world/cell.ts +231 -0
- package/src/world/cellStream.ts +278 -0
- package/src/world/freeze.ts +157 -0
- package/src/world/rebase.ts +56 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grouping the frame's pixels by the material that has to shade them.
|
|
3
|
+
*
|
|
4
|
+
* **A visibility buffer defers the shading and does not organise it.** Neighbouring pixels can
|
|
5
|
+
* hold triangles from different meshes with different materials, so shading it in place means
|
|
6
|
+
* every invocation branching on a material it cannot know until it has read the buffer — which on
|
|
7
|
+
* a wide machine is every lane in a group taking every branch. Binning first turns that into one
|
|
8
|
+
* dispatch per material, each of which shades pixels that all want the same code.
|
|
9
|
+
*
|
|
10
|
+
* **A material with no pixels gets a zero-length bin and a zero-workgroup dispatch, never an
|
|
11
|
+
* absent one.** The arguments are indexed by material identifier, so dropping an empty one shifts
|
|
12
|
+
* every later material's block and the scene shades with the wrong code — a picture that is
|
|
13
|
+
* plausible, entirely wrong, and correlates with nothing a consumer changed. `binsPresent` is the
|
|
14
|
+
* separate question of how many materials actually appear, which is a number to report rather
|
|
15
|
+
* than a length to index by.
|
|
16
|
+
*
|
|
17
|
+
* **Offsets are a prefix sum and the cursors are a copy of it.** The scatter needs somewhere to
|
|
18
|
+
* count from that is not the offsets themselves, or the second pixel of a bin overwrites the
|
|
19
|
+
* first's offset and every later bin starts in the wrong place.
|
|
20
|
+
*/
|
|
21
|
+
import { INDIRECT_DISPATCH_WORDS, writeDispatchArgs } from './indirect.js';
|
|
22
|
+
import { VIS_TRIANGLE_BITS, visibilityCovered } from './visbuffer.js';
|
|
23
|
+
/** Invocations a shading group covers. One pixel each; the bins are lists, not rectangles. */
|
|
24
|
+
export const BIN_GROUP_SIZE = 64;
|
|
25
|
+
/** Words in one material's dispatch block, so a caller can size the buffer. */
|
|
26
|
+
export const BIN_DISPATCH_WORDS = INDIRECT_DISPATCH_WORDS;
|
|
27
|
+
/**
|
|
28
|
+
* Which material a pixel wants, or -1 where nothing covered it.
|
|
29
|
+
*
|
|
30
|
+
* **The sentinel test survives perturbation and is kept**, which is worth the sentence because it
|
|
31
|
+
* looks like the load-bearing line and is not. `VIS_EMPTY` is `0xffffffff`, so its cluster field
|
|
32
|
+
* reads as 33,554,431 — and the range test one line down refuses any cluster past the table, which
|
|
33
|
+
* every real table is far smaller than. Deleting either check alone therefore changes no answer
|
|
34
|
+
* this repository can produce. What the sentinel test decides is a table sized to the full
|
|
35
|
+
* twenty-five bits, which is 134 MB and nothing allocates; what the range test decides is a
|
|
36
|
+
* visibility buffer left over from a frame with more geometry in it, which is a real case and is
|
|
37
|
+
* the one `gpu-parity.mjs` generates. Both are kept because they answer different questions and
|
|
38
|
+
* one of them is cheap insurance against the other's assumption.
|
|
39
|
+
*/
|
|
40
|
+
export function materialAt(visibility, materialOf, pixel) {
|
|
41
|
+
const packed = visibility[pixel];
|
|
42
|
+
if (!visibilityCovered(packed))
|
|
43
|
+
return -1;
|
|
44
|
+
const cluster = packed >>> VIS_TRIANGLE_BITS;
|
|
45
|
+
const material = materialOf[cluster];
|
|
46
|
+
return material === undefined ? -1 : material;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* How many pixels each material owns, and how many pixels were covered at all.
|
|
50
|
+
*
|
|
51
|
+
* `counts` is cleared here rather than by the caller, because a count buffer reused across frames
|
|
52
|
+
* without clearing grows without bound and the bins then run off the end of the pixel list —
|
|
53
|
+
* which appears as the shading reading a neighbouring bin's pixels.
|
|
54
|
+
*/
|
|
55
|
+
export function countBins(visibility, materialOf, counts) {
|
|
56
|
+
counts.fill(0);
|
|
57
|
+
let covered = 0;
|
|
58
|
+
for (let pixel = 0; pixel < visibility.length; pixel += 1) {
|
|
59
|
+
const material = materialAt(visibility, materialOf, pixel);
|
|
60
|
+
if (material < 0 || material >= counts.length)
|
|
61
|
+
continue;
|
|
62
|
+
counts[material] = counts[material] + 1;
|
|
63
|
+
covered += 1;
|
|
64
|
+
}
|
|
65
|
+
return covered;
|
|
66
|
+
}
|
|
67
|
+
/** Where each material's pixels begin: the exclusive prefix sum of the counts. */
|
|
68
|
+
export function binOffsets(counts, offsets) {
|
|
69
|
+
let running = 0;
|
|
70
|
+
for (let material = 0; material < counts.length; material += 1) {
|
|
71
|
+
offsets[material] = running;
|
|
72
|
+
running += counts[material];
|
|
73
|
+
}
|
|
74
|
+
return running;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Write every covered pixel's index into its material's slice of `pixels`.
|
|
78
|
+
*
|
|
79
|
+
* `cursors` starts as a copy of `offsets` and is advanced as the scatter runs, so `offsets` stays
|
|
80
|
+
* readable afterwards — which the shading dispatch needs, because it is what tells a group where
|
|
81
|
+
* its material's list starts.
|
|
82
|
+
*/
|
|
83
|
+
export function fillBins(visibility, materialOf, offsets, cursors, pixels) {
|
|
84
|
+
cursors.set(offsets);
|
|
85
|
+
for (let pixel = 0; pixel < visibility.length; pixel += 1) {
|
|
86
|
+
const material = materialAt(visibility, materialOf, pixel);
|
|
87
|
+
if (material < 0 || material >= offsets.length)
|
|
88
|
+
continue;
|
|
89
|
+
const at = cursors[material];
|
|
90
|
+
pixels[at] = pixel;
|
|
91
|
+
cursors[material] = at + 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** One dispatch block per **declared** material, zero groups where the bin is empty. */
|
|
95
|
+
export function binDispatchArgs(counts, out, groupSize = BIN_GROUP_SIZE) {
|
|
96
|
+
for (let material = 0; material < counts.length; material += 1) {
|
|
97
|
+
writeDispatchArgs(out, material * BIN_DISPATCH_WORDS, counts[material], groupSize);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** How many materials the frame actually contains, which is not how many it declares. */
|
|
101
|
+
export function binsPresent(counts) {
|
|
102
|
+
let present = 0;
|
|
103
|
+
for (let material = 0; material < counts.length; material += 1) {
|
|
104
|
+
if (counts[material] > 0)
|
|
105
|
+
present += 1;
|
|
106
|
+
}
|
|
107
|
+
return present;
|
|
108
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** A GPU-driven material as the shading pass reads it: five blocks, one of them integers. */
|
|
2
|
+
import type { GpuDrivenMaterial } from '../backend/webgpu/gpuDrivenPass.ts';
|
|
3
|
+
import type { GpuDrivenProgram } from './decodeTables.ts';
|
|
4
|
+
/**
|
|
5
|
+
* **The forward path's maps, as decode programs.** `SurfaceMaterial` binds an albedo, a normal and
|
|
6
|
+
* an occlusion-roughness-metallic image, and its scales and strengths mean what they mean there —
|
|
7
|
+
* the ORM map *replaces* roughness and the scale gives the scaling back, and occlusion strength is
|
|
8
|
+
* a mix from one rather than a multiply. Defaults are `SurfaceMaterial`'s.
|
|
9
|
+
*/
|
|
10
|
+
export interface GpuDrivenTextures {
|
|
11
|
+
readonly baseColour?: GpuDrivenProgram;
|
|
12
|
+
readonly normal?: GpuDrivenProgram;
|
|
13
|
+
/** Occlusion in R, roughness in G, metallic in B — glTF's packing, as `SurfaceMaterial.orm`. */
|
|
14
|
+
readonly orm?: GpuDrivenProgram;
|
|
15
|
+
/**
|
|
16
|
+
* Where the surface glows, in colour, as `SurfaceMaterial.emissive`'s map: the glow is the albedo
|
|
17
|
+
* times this times the material's `emissive`, so a black texel glows nowhere and the scalar
|
|
18
|
+
* still says how brightly the rest does. **glTF's rule and flat/main.ts's**, which the facade of
|
|
19
|
+
* a city at dusk needed — lit windows in a wall that does not glow — and the pipeline could not
|
|
20
|
+
* say until 2026-09-18.
|
|
21
|
+
*/
|
|
22
|
+
readonly emissive?: GpuDrivenProgram;
|
|
23
|
+
readonly uScale?: number;
|
|
24
|
+
readonly vScale?: number;
|
|
25
|
+
/** Defaults to 1 when a `normal` program is given and 0 when it is not. */
|
|
26
|
+
readonly normalStrength?: number;
|
|
27
|
+
readonly roughnessScale?: number;
|
|
28
|
+
readonly metallicScale?: number;
|
|
29
|
+
readonly occlusionStrength?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Words a material entry: tint and emissive, the surface scalars, four program indices, the UV
|
|
33
|
+
* scale and two strengths, the two ORM scales with the cutout and blend flags, and
|
|
34
|
+
* the opacity with three spare.
|
|
35
|
+
*
|
|
36
|
+
* **It was eight until 2026-09-17**, and metalness took its last spare lane the same day, so the
|
|
37
|
+
* programs and the scales needed three more blocks rather than squeezing into what was left. It
|
|
38
|
+
* became twenty-four on 2026-09-18, when transparency arrived and there was nowhere left to put an
|
|
39
|
+
* opacity: the cutout took lane 18 and the blend flag took 19, and lane 11 is a reserved program
|
|
40
|
+
* slot rather than a gap. A sixteen-byte block is 1 kB across the whole table, against the 64 kB a
|
|
41
|
+
* uniform buffer may hold.
|
|
42
|
+
*/
|
|
43
|
+
export declare const GPU_DRIVEN_MATERIAL_FLOATS = 24;
|
|
44
|
+
/**
|
|
45
|
+
* Below this base-colour alpha the raster discards a fragment. Zero means no test.
|
|
46
|
+
*
|
|
47
|
+
* **Lane 18 rather than lane 11**, which looks spare and is not: the loop below initialises lanes
|
|
48
|
+
* 8 to 11 to `DECODE_NO_PROGRAM`, so eleven is a fourth program slot somebody reserved rather than
|
|
49
|
+
* a gap, and a scalar written there would be read back as a program index. Taking 18 leaves the
|
|
50
|
+
* reservation alone and leaves 19 after it.
|
|
51
|
+
*/
|
|
52
|
+
export declare const MATERIAL_ALPHA_CUTOFF = 18;
|
|
53
|
+
/**
|
|
54
|
+
* Non-zero where this material's clusters are drawn blended rather than into the visibility buffer.
|
|
55
|
+
*
|
|
56
|
+
* **The last spare lane of twenty**, and a flag rather than an opacity because the opacity is the
|
|
57
|
+
* tint's fourth component. What this selects is which of the two halves of the frame a cluster
|
|
58
|
+
* belongs to, which the cut asks once per cluster.
|
|
59
|
+
*/
|
|
60
|
+
export declare const MATERIAL_BLEND = 19;
|
|
61
|
+
/**
|
|
62
|
+
* How much of a blended surface is its own colour rather than what is behind it. One is opaque.
|
|
63
|
+
*
|
|
64
|
+
* **It is not the tint's fourth component**, which is the emissive gain and has been since the
|
|
65
|
+
* table was eight floats, and it is not `alphaCutoff`, which decides whether a fragment exists at
|
|
66
|
+
* all. A material that does not blend never reads this.
|
|
67
|
+
*/
|
|
68
|
+
export declare const MATERIAL_OPACITY = 20;
|
|
69
|
+
/**
|
|
70
|
+
* Where a material's emissive program is: the fourth program lane, which the table reserved and
|
|
71
|
+
* initialised to none before anything used it.
|
|
72
|
+
*/
|
|
73
|
+
export declare const MATERIAL_EMISSIVE_PROGRAM = 11;
|
|
74
|
+
export interface MaterialPrograms {
|
|
75
|
+
readonly programs: readonly GpuDrivenProgram[];
|
|
76
|
+
/** Four a material — base colour, normal, ORM, emissive — each an index into `programs` or none. */
|
|
77
|
+
readonly indices: Uint32Array;
|
|
78
|
+
}
|
|
79
|
+
/** Every program the materials name, once each by identity, and where each material's are. */
|
|
80
|
+
export declare function collectPrograms(materials: readonly GpuDrivenMaterial[]): MaterialPrograms;
|
|
81
|
+
/**
|
|
82
|
+
* The table, `slots` entries long.
|
|
83
|
+
*
|
|
84
|
+
* **Written through a `DataView` because one block is integers.** A program index written as a
|
|
85
|
+
* float would be read by `vec4<u32>` as the float's bits, which names a program four billion
|
|
86
|
+
* places away and draws nothing — or, clamped, the last program in the table.
|
|
87
|
+
*/
|
|
88
|
+
export declare function writeMaterialTable(materials: readonly GpuDrivenMaterial[], indices: Uint32Array, slots: number): ArrayBuffer;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/** A GPU-driven material as the shading pass reads it: five blocks, one of them integers. */
|
|
2
|
+
import { DECODE_NO_PROGRAM } from '../shaders/gpudriven/decode.wgsl.js';
|
|
3
|
+
/**
|
|
4
|
+
* Words a material entry: tint and emissive, the surface scalars, four program indices, the UV
|
|
5
|
+
* scale and two strengths, the two ORM scales with the cutout and blend flags, and
|
|
6
|
+
* the opacity with three spare.
|
|
7
|
+
*
|
|
8
|
+
* **It was eight until 2026-09-17**, and metalness took its last spare lane the same day, so the
|
|
9
|
+
* programs and the scales needed three more blocks rather than squeezing into what was left. It
|
|
10
|
+
* became twenty-four on 2026-09-18, when transparency arrived and there was nowhere left to put an
|
|
11
|
+
* opacity: the cutout took lane 18 and the blend flag took 19, and lane 11 is a reserved program
|
|
12
|
+
* slot rather than a gap. A sixteen-byte block is 1 kB across the whole table, against the 64 kB a
|
|
13
|
+
* uniform buffer may hold.
|
|
14
|
+
*/
|
|
15
|
+
export const GPU_DRIVEN_MATERIAL_FLOATS = 24;
|
|
16
|
+
/**
|
|
17
|
+
* Below this base-colour alpha the raster discards a fragment. Zero means no test.
|
|
18
|
+
*
|
|
19
|
+
* **Lane 18 rather than lane 11**, which looks spare and is not: the loop below initialises lanes
|
|
20
|
+
* 8 to 11 to `DECODE_NO_PROGRAM`, so eleven is a fourth program slot somebody reserved rather than
|
|
21
|
+
* a gap, and a scalar written there would be read back as a program index. Taking 18 leaves the
|
|
22
|
+
* reservation alone and leaves 19 after it.
|
|
23
|
+
*/
|
|
24
|
+
export const MATERIAL_ALPHA_CUTOFF = 18;
|
|
25
|
+
/**
|
|
26
|
+
* Non-zero where this material's clusters are drawn blended rather than into the visibility buffer.
|
|
27
|
+
*
|
|
28
|
+
* **The last spare lane of twenty**, and a flag rather than an opacity because the opacity is the
|
|
29
|
+
* tint's fourth component. What this selects is which of the two halves of the frame a cluster
|
|
30
|
+
* belongs to, which the cut asks once per cluster.
|
|
31
|
+
*/
|
|
32
|
+
export const MATERIAL_BLEND = 19;
|
|
33
|
+
/**
|
|
34
|
+
* How much of a blended surface is its own colour rather than what is behind it. One is opaque.
|
|
35
|
+
*
|
|
36
|
+
* **It is not the tint's fourth component**, which is the emissive gain and has been since the
|
|
37
|
+
* table was eight floats, and it is not `alphaCutoff`, which decides whether a fragment exists at
|
|
38
|
+
* all. A material that does not blend never reads this.
|
|
39
|
+
*/
|
|
40
|
+
export const MATERIAL_OPACITY = 20;
|
|
41
|
+
/**
|
|
42
|
+
* Where a material's emissive program is: the fourth program lane, which the table reserved and
|
|
43
|
+
* initialised to none before anything used it.
|
|
44
|
+
*/
|
|
45
|
+
export const MATERIAL_EMISSIVE_PROGRAM = 11;
|
|
46
|
+
/** Program lanes a material, and the stride `collectPrograms` writes its indices at. */
|
|
47
|
+
const PROGRAM_LANES = 4;
|
|
48
|
+
/** Every program the materials name, once each by identity, and where each material's are. */
|
|
49
|
+
export function collectPrograms(materials) {
|
|
50
|
+
const programs = [];
|
|
51
|
+
const known = new Map();
|
|
52
|
+
const indexOf = (program) => {
|
|
53
|
+
if (program === undefined)
|
|
54
|
+
return DECODE_NO_PROGRAM;
|
|
55
|
+
const found = known.get(program);
|
|
56
|
+
if (found !== undefined)
|
|
57
|
+
return found;
|
|
58
|
+
programs.push(program);
|
|
59
|
+
known.set(program, programs.length - 1);
|
|
60
|
+
return programs.length - 1;
|
|
61
|
+
};
|
|
62
|
+
const indices = new Uint32Array(materials.length * PROGRAM_LANES);
|
|
63
|
+
materials.forEach((material, m) => {
|
|
64
|
+
indices[m * PROGRAM_LANES] = indexOf(material.textures?.baseColour);
|
|
65
|
+
indices[m * PROGRAM_LANES + 1] = indexOf(material.textures?.normal);
|
|
66
|
+
indices[m * PROGRAM_LANES + 2] = indexOf(material.textures?.orm);
|
|
67
|
+
indices[m * PROGRAM_LANES + 3] = indexOf(material.textures?.emissive);
|
|
68
|
+
});
|
|
69
|
+
return { programs, indices };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The table, `slots` entries long.
|
|
73
|
+
*
|
|
74
|
+
* **Written through a `DataView` because one block is integers.** A program index written as a
|
|
75
|
+
* float would be read by `vec4<u32>` as the float's bits, which names a program four billion
|
|
76
|
+
* places away and draws nothing — or, clamped, the last program in the table.
|
|
77
|
+
*/
|
|
78
|
+
export function writeMaterialTable(materials, indices, slots) {
|
|
79
|
+
const buffer = new ArrayBuffer(slots * GPU_DRIVEN_MATERIAL_FLOATS * 4);
|
|
80
|
+
const view = new DataView(buffer);
|
|
81
|
+
const float = (m, lane, value) => view.setFloat32((m * GPU_DRIVEN_MATERIAL_FLOATS + lane) * 4, value, true);
|
|
82
|
+
const word = (m, lane, value) => view.setUint32((m * GPU_DRIVEN_MATERIAL_FLOATS + lane) * 4, value, true);
|
|
83
|
+
for (let m = 0; m < slots; m += 1) {
|
|
84
|
+
for (let lane = 8; lane < 12; lane += 1)
|
|
85
|
+
word(m, lane, DECODE_NO_PROGRAM);
|
|
86
|
+
}
|
|
87
|
+
materials.forEach((material, m) => {
|
|
88
|
+
float(m, 0, material.tint[0]);
|
|
89
|
+
float(m, 1, material.tint[1]);
|
|
90
|
+
float(m, 2, material.tint[2]);
|
|
91
|
+
float(m, 3, material.emissive);
|
|
92
|
+
/* Roughness one and specular zero: the matte this pipeline drew before either existed. */
|
|
93
|
+
float(m, 4, material.roughness ?? 1);
|
|
94
|
+
float(m, 5, material.specular ?? 0);
|
|
95
|
+
float(m, 6, material.reflectivity ?? 0);
|
|
96
|
+
float(m, 7, material.metalness ?? 0);
|
|
97
|
+
for (let lane = 0; lane < PROGRAM_LANES; lane += 1) {
|
|
98
|
+
word(m, 8 + lane, indices[m * PROGRAM_LANES + lane]);
|
|
99
|
+
}
|
|
100
|
+
const textures = material.textures;
|
|
101
|
+
float(m, 12, textures?.uScale ?? 1);
|
|
102
|
+
float(m, 13, textures?.vScale ?? 1);
|
|
103
|
+
float(m, 14, textures?.normal === undefined ? 0 : (textures.normalStrength ?? 1));
|
|
104
|
+
float(m, 15, textures?.occlusionStrength ?? 1);
|
|
105
|
+
float(m, 16, textures?.roughnessScale ?? 1);
|
|
106
|
+
float(m, 17, textures?.metallicScale ?? 1);
|
|
107
|
+
/* Zero is off, so a material that says nothing about cutout writes the table it wrote before. */
|
|
108
|
+
float(m, MATERIAL_ALPHA_CUTOFF, material.alphaCutoff ?? 0);
|
|
109
|
+
/* Zero is opaque, so a material that says nothing about blending stays in the opaque half. */
|
|
110
|
+
float(m, MATERIAL_BLEND, material.blend === true ? 1 : 0);
|
|
111
|
+
/* One, so a material that asked to blend and said nothing else is as solid as an opaque one. */
|
|
112
|
+
float(m, MATERIAL_OPACITY, material.opacity ?? 1);
|
|
113
|
+
});
|
|
114
|
+
return buffer;
|
|
115
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GPU-driven frame, as an order and a set of dependencies.
|
|
3
|
+
*
|
|
4
|
+
* **Every stage of Wave 2A exists on its own and this is what says how they fit together.** The
|
|
5
|
+
* frame's colour is cleared, the directional map is drawn, the meshes wholly outside the view are
|
|
6
|
+
* flagged, the cut through the cluster graph is chosen without them and phase one culls what was
|
|
7
|
+
* visible last frame, phase one draws, the depth pyramid is reduced from that, phase two culls the
|
|
8
|
+
* rest against it and draws, the visibility is copied where a dispatch can read it, binned by
|
|
9
|
+
* material, and each bin is shaded. Twelve stages, and the edges between them are what stop a
|
|
10
|
+
* scheduler reordering the ones that must not move — see `twoPhase.ts` for the one that matters
|
|
11
|
+
* most.
|
|
12
|
+
*
|
|
13
|
+
* **The pipeline is opt-in and WebGPU only.** `gpuDrivenSupported` is `indirectSupport`, which is
|
|
14
|
+
* false on WebGL2 and not a thing a fallback can paper over: without an indirect draw the counts
|
|
15
|
+
* this frame produces would have to come back to the processor, and a readback is slower than the
|
|
16
|
+
* draw it would replace. Selecting it on a backend that cannot run it **fails at creation** rather
|
|
17
|
+
* than falling back, because a silent fallback means a consumer ships believing they have a
|
|
18
|
+
* pipeline they do not.
|
|
19
|
+
*
|
|
20
|
+
* **This is what `GpuDrivenPass` is scheduled by**, since 2026-09-17: the pass records these stages
|
|
21
|
+
* into a `Deps` table each frame, `scheduleGraph` decides which of them run, and the pass encodes
|
|
22
|
+
* the ones it kept in the order it kept them. Until then this was a description beside an encoder
|
|
23
|
+
* with its own fixed order — and the description had drifted, naming a separate instance cull the
|
|
24
|
+
* encoder never had and a colour both draws wrote when neither does. The instance cull is a stage
|
|
25
|
+
* of the encoder now, 2026-09-17, which is `wave2a`'s fifth task finally reaching the frame. Binding real buffers and
|
|
26
|
+
* issuing real dispatches stays the backend's; what moved here is the decision about what runs.
|
|
27
|
+
*/
|
|
28
|
+
import type { Deps } from '../frame/deps.ts';
|
|
29
|
+
/** Whether a backend can run this pipeline at all. */
|
|
30
|
+
export declare function gpuDrivenSupported(backend: 'webgl2' | 'webgpu'): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Why a backend cannot, in the words a consumer sees.
|
|
33
|
+
*
|
|
34
|
+
* A sentence rather than a code, because the one thing the reader needs is that this is a property
|
|
35
|
+
* of the backend and not of their scene — and `''` where it can.
|
|
36
|
+
*/
|
|
37
|
+
export declare function gpuDrivenRefusal(backend: 'webgl2' | 'webgpu'): string;
|
|
38
|
+
/**
|
|
39
|
+
* Every resource a GPU-driven frame moves between its stages, as an identifier each.
|
|
40
|
+
*
|
|
41
|
+
* **Named for what the encoder actually binds**, which the first version of this table was not: it
|
|
42
|
+
* described both draws writing the colour, which neither does, and an instance cull the encoder did
|
|
43
|
+
* not then have. A description that is not the encoder is a comment, and this one is what the
|
|
44
|
+
* encoder is scheduled by.
|
|
45
|
+
*/
|
|
46
|
+
export interface GpuDrivenResources {
|
|
47
|
+
/** Everything uploaded once: bounds, cones, errors, indices, vertices, transforms, materials. */
|
|
48
|
+
readonly clusters: number;
|
|
49
|
+
/** Which clusters last frame drew. Imported: this frame reads it and never writes it. */
|
|
50
|
+
readonly history: number;
|
|
51
|
+
readonly shadowMap: number;
|
|
52
|
+
/** Which meshes are wholly outside the view, one flag a mesh. */
|
|
53
|
+
readonly instances: number;
|
|
54
|
+
/** The cut through the cluster graph, one flag a cluster, with hidden meshes left out. */
|
|
55
|
+
readonly cut: number;
|
|
56
|
+
/** The cull's verdict, one flag a cluster, written by each phase for its own half. */
|
|
57
|
+
readonly keep: number;
|
|
58
|
+
/** Each phase's compacted list and the indirect draw that counts it. */
|
|
59
|
+
readonly listOne: number;
|
|
60
|
+
readonly listTwo: number;
|
|
61
|
+
/** Which clusters this frame drew, which is next frame's history. */
|
|
62
|
+
readonly drawn: number;
|
|
63
|
+
readonly depth: number;
|
|
64
|
+
/** The visibility attachment, and the buffer it is copied into so a dispatch can read it. */
|
|
65
|
+
readonly visibility: number;
|
|
66
|
+
readonly visibilityCopy: number;
|
|
67
|
+
readonly hzb: number;
|
|
68
|
+
readonly binCounts: number;
|
|
69
|
+
readonly binOffsets: number;
|
|
70
|
+
/** A copy of the offsets the scatter advances, because the offsets must survive it. */
|
|
71
|
+
readonly binCursors: number;
|
|
72
|
+
readonly binPixels: number;
|
|
73
|
+
readonly colour: number;
|
|
74
|
+
/** The compacted list of blended clusters and the indirect draw that counts it. */
|
|
75
|
+
readonly blendList: number;
|
|
76
|
+
/** The two weighted-transparency targets, and what resolving them writes. */
|
|
77
|
+
readonly oitAccum: number;
|
|
78
|
+
readonly oitReveal: number;
|
|
79
|
+
}
|
|
80
|
+
/** The identifiers one frame uses. A frame is its own graph, so they start at zero. */
|
|
81
|
+
export declare const GPU_DRIVEN_RESOURCES: GpuDrivenResources;
|
|
82
|
+
/**
|
|
83
|
+
* What each stage is called, in the order they are recorded — one render or compute pass each, or
|
|
84
|
+
* one copy between them.
|
|
85
|
+
*/
|
|
86
|
+
export declare const GPU_DRIVEN_PASSES: readonly ['clearColour', 'shadow', 'instanceCull', 'cut', 'phaseOneDraw', 'pyramid', 'phaseTwoCull', 'phaseTwoDraw', 'blendCull', 'blendDraw', 'visibilityCopy', 'bin', 'cursorCopy', 'shade', 'blendResolve'];
|
|
87
|
+
export type GpuDrivenPassName = (typeof GPU_DRIVEN_PASSES)[number];
|
|
88
|
+
/**
|
|
89
|
+
* **Every stage is ordered, so none merges with a neighbour.** Two adjacent compute stages could
|
|
90
|
+
* share a pass as far as their results go; they do not, because each is bracketed by its own pair
|
|
91
|
+
* of timestamps and a pair brackets a pass. What the schedule decides here is which stages run,
|
|
92
|
+
* and it checks the order the names give against the edges the stages declare.
|
|
93
|
+
*/
|
|
94
|
+
export declare const GPU_DRIVEN_ORDERED: Uint8Array;
|
|
95
|
+
/** Where each pass landed in the dependency table, by name. */
|
|
96
|
+
export type GpuDrivenNodes = Readonly<Record<GpuDrivenPassName, number>>;
|
|
97
|
+
/** What about this frame changes which stages it needs. */
|
|
98
|
+
export interface GpuDrivenFrameShape {
|
|
99
|
+
/**
|
|
100
|
+
* Whether the shading reads the directional map. A frame whose shadow strength is zero does not:
|
|
101
|
+
* the lookup answers one before any arithmetic, so the map's contents cannot reach a pixel and
|
|
102
|
+
* the stage that renders it is culled rather than run for nothing.
|
|
103
|
+
*/
|
|
104
|
+
readonly shadowed: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Whether any material in the table asks to be blended.
|
|
107
|
+
*
|
|
108
|
+
* A frame with none schedules the whole transparent half away — the second run of the cut, the
|
|
109
|
+
* blended draw and the resolve — so a scene that never mentions transparency encodes the frame it
|
|
110
|
+
* encoded before transparency existed, command for command. `gpuDrivenPass.test.ts` holds that
|
|
111
|
+
* against a fixed list rather than against a promise.
|
|
112
|
+
*/
|
|
113
|
+
readonly blended: boolean;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Record the whole frame, in order, and answer the index its first stage landed at.
|
|
117
|
+
*
|
|
118
|
+
* Allocates nothing once a resource table has been seen, which is what lets `GpuDrivenPass` call it
|
|
119
|
+
* every frame. Stage `i` of `GPU_DRIVEN_PASSES` is node `first + i`.
|
|
120
|
+
*/
|
|
121
|
+
export declare function recordGpuDrivenStages(deps: Deps, res: GpuDrivenResources, shape: GpuDrivenFrameShape): number;
|
|
122
|
+
/** Record the whole frame and answer where each pass went, by name. For a reader, not a frame. */
|
|
123
|
+
export declare function recordGpuDrivenFrame(deps: Deps, res: GpuDrivenResources, shape: GpuDrivenFrameShape): GpuDrivenNodes;
|
|
124
|
+
/**
|
|
125
|
+
* What a frame leaves behind, which is what `scheduleGraph` is asked to keep alive.
|
|
126
|
+
*
|
|
127
|
+
* The colour, which the blit presents, and the history, which next frame's phase one reads. The
|
|
128
|
+
* depth, the pyramid, the visibility buffer and every bin are this frame's working set and nothing
|
|
129
|
+
* outside reads them. Naming more than is needed keeps resources alive that could have been
|
|
130
|
+
* aliased — which is `alias.ts`'s whole subject — and naming fewer culls a pass that was doing
|
|
131
|
+
* something.
|
|
132
|
+
*/
|
|
133
|
+
export declare function gpuDrivenLive(res: GpuDrivenResources): readonly number[];
|
|
134
|
+
/** What a frame reads without having written: the scene, and last frame's history. */
|
|
135
|
+
export declare function gpuDrivenImports(res: GpuDrivenResources): readonly number[];
|