@driftengine/core 3.63.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 +111 -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 +69 -4
- package/dist/index.js +112 -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 +19 -9
- package/dist/render/backend/webgpu/surfaceTexturePass.js +58 -32
- 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 +246 -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 +63 -36
- 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,406 @@
|
|
|
1
|
+
/** Where the second pipeline's light stands, and the two corrections its map needs. */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* **The light's projection, fitted to the scene's bounding sphere rather than the camera.**
|
|
5
|
+
*
|
|
6
|
+
* The forward path fits a cascade to the *view* frustum, which is what a large world wants: the map
|
|
7
|
+
* follows the camera and spends its texels where the viewer is. It also costs that path a snapping
|
|
8
|
+
* rule, because a box that moves continuously makes every shadow edge crawl as the camera turns.
|
|
9
|
+
*
|
|
10
|
+
* This one fitted the whole scene, and still does while the scene is no larger than the radius a
|
|
11
|
+
* caller names: its rigs are a few metres across, so a sphere around the lot is a box that never
|
|
12
|
+
* moves and therefore never shimmers. **What that gave up was stated rather than discovered** — a
|
|
13
|
+
* world too big for one map gets a soft, coarse shadow everywhere — and a world arrived: the voxel
|
|
14
|
+
* sandbox's port. So past that radius `fitShadow` follows the eye instead, snapped as the forward
|
|
15
|
+
* path's cascade is. One sphere rather than a cascade of them: `docs/CAPABILITIES.md` records what
|
|
16
|
+
* that costs at a distance.
|
|
17
|
+
*
|
|
18
|
+
* **A sphere rather than an eight-corner box**, because a box's extent in light space depends on
|
|
19
|
+
* the sun's direction and a sphere's does not — so the fit is the same size at every hour, and a
|
|
20
|
+
* shadow that grows softer as the sun moves is the sun moving rather than the fit breathing.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { SHADOW_DEPTH_FADE } from './shadow.ts';
|
|
24
|
+
|
|
25
|
+
/** Where the basis stops taking `y` as its reference. Any sun steeper than this is overhead. */
|
|
26
|
+
const OVERHEAD = 0.99;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A bounding sphere over every cluster, from the world bounds the cull buffer already holds.
|
|
30
|
+
*
|
|
31
|
+
* **It reads the transformed bounds rather than transforming them itself**, which it did until
|
|
32
|
+
* 2026-09-17 and which was one of two places in this pipeline that multiplied a cluster by its
|
|
33
|
+
* mesh's matrix. `clusterWorld.ts` is the other and is now the only one: two copies of that
|
|
34
|
+
* arithmetic can disagree about the scale a sphere takes, and a light's box that disagrees with the
|
|
35
|
+
* cull's bounds clips casters out of a map that the cull believes are in it — which is a surface
|
|
36
|
+
* lit with something standing in front of it.
|
|
37
|
+
*
|
|
38
|
+
* `stride` is how many floats a cluster occupies; `CLUSTER_CULL_FLOATS` for the cull buffer, where
|
|
39
|
+
* the centre and radius are the first four of eight.
|
|
40
|
+
*
|
|
41
|
+
* `out` is the centre and the radius, four floats.
|
|
42
|
+
*/
|
|
43
|
+
export function sceneShadowBounds(
|
|
44
|
+
/** Centre and radius, four floats at every `stride`, in world space. */
|
|
45
|
+
bounds: Float32Array,
|
|
46
|
+
stride: number,
|
|
47
|
+
count: number,
|
|
48
|
+
out: Float32Array,
|
|
49
|
+
): Float32Array {
|
|
50
|
+
let lowX = Infinity;
|
|
51
|
+
let lowY = Infinity;
|
|
52
|
+
let lowZ = Infinity;
|
|
53
|
+
let highX = -Infinity;
|
|
54
|
+
let highY = -Infinity;
|
|
55
|
+
let highZ = -Infinity;
|
|
56
|
+
|
|
57
|
+
for (let c = 0; c < count; c += 1) {
|
|
58
|
+
const at = c * stride;
|
|
59
|
+
const cx = bounds[at] as number;
|
|
60
|
+
const cy = bounds[at + 1] as number;
|
|
61
|
+
const cz = bounds[at + 2] as number;
|
|
62
|
+
const radius = bounds[at + 3] as number;
|
|
63
|
+
/*
|
|
64
|
+
* **A record of no radius is a slot nobody holds, not a cluster at the origin.** A streaming
|
|
65
|
+
* scene's buffers are sized by capacity, so the records past what is live are zeros — and
|
|
66
|
+
* counting them stretches this box all the way back to the origin over empty space, which puts
|
|
67
|
+
* the light's whole depth range across a volume that is mostly nothing. A static scene has no
|
|
68
|
+
* such records and is unaffected: a baked cluster always has a positive radius.
|
|
69
|
+
*/
|
|
70
|
+
if (!(radius > 0)) continue;
|
|
71
|
+
lowX = Math.min(lowX, cx - radius);
|
|
72
|
+
lowY = Math.min(lowY, cy - radius);
|
|
73
|
+
lowZ = Math.min(lowZ, cz - radius);
|
|
74
|
+
highX = Math.max(highX, cx + radius);
|
|
75
|
+
highY = Math.max(highY, cy + radius);
|
|
76
|
+
highZ = Math.max(highZ, cz + radius);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!Number.isFinite(lowX)) {
|
|
80
|
+
/*
|
|
81
|
+
* **A scene with no clusters is a unit sphere, not a point.** A radius of zero divides by zero
|
|
82
|
+
* in the fit below and every entry of the matrix comes back NaN — which reaches the device as
|
|
83
|
+
* a draw that covers nothing and a lookup that is never inside the map, so the frame is simply
|
|
84
|
+
* unshadowed and nothing says why.
|
|
85
|
+
*/
|
|
86
|
+
out[0] = 0;
|
|
87
|
+
out[1] = 0;
|
|
88
|
+
out[2] = 0;
|
|
89
|
+
out[3] = 1;
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
out[0] = (lowX + highX) * 0.5;
|
|
94
|
+
out[1] = (lowY + highY) * 0.5;
|
|
95
|
+
out[2] = (lowZ + highZ) * 0.5;
|
|
96
|
+
out[3] = Math.max(
|
|
97
|
+
Math.hypot(highX - lowX, highY - lowY, highZ - lowZ) * 0.5,
|
|
98
|
+
/* Never zero, for the reason above: one flat quad is a legal scene. */
|
|
99
|
+
1e-3,
|
|
100
|
+
);
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The light's view-projection, in the OpenGL convention the rest of this engine builds matrices in:
|
|
106
|
+
* `x` and `y` in -1..1 and `z` in -1..1 as well. Returns the metres its depth range spans.
|
|
107
|
+
*
|
|
108
|
+
* **Written out rather than composed from a look-at and an orthographic**, because the product is
|
|
109
|
+
* four lines and the two halves are not independently useful. The whole of it is: project onto the
|
|
110
|
+
* light's basis, divide by the radius, and negate the depth axis so that *nearer the light* is
|
|
111
|
+
* smaller — which is the direction a depth test with `less` wants and is the opposite of the
|
|
112
|
+
* frame's reversed depth. `depthConvention.ts` carries why shadows are not reversed.
|
|
113
|
+
*
|
|
114
|
+
* `lightDir` points **toward** the light, as `Environment.directionalDir` does.
|
|
115
|
+
*/
|
|
116
|
+
/** The light's right, up and toward-the-light axes, nine numbers. See `lightBasis`. */
|
|
117
|
+
const BASIS = new Float64Array(9);
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The light's three axes, which depend on its direction and on nothing else.
|
|
121
|
+
*
|
|
122
|
+
* **One basis for both fits, and the following fit needs it to be exactly this.** Snapping a map
|
|
123
|
+
* to whole texels only holds its edges still if the texel grid it snaps to is fixed, and the grid
|
|
124
|
+
* is this basis: `lightMatrix.ts` says the same about the forward path's, where anchoring the light
|
|
125
|
+
* at the focus instead would move light space under the snap and cancel it.
|
|
126
|
+
*/
|
|
127
|
+
function lightBasis(lightDir: readonly [number, number, number], out: Float64Array): void {
|
|
128
|
+
const length = Math.hypot(lightDir[0], lightDir[1], lightDir[2]) || 1;
|
|
129
|
+
const ax = lightDir[0] / length;
|
|
130
|
+
const ay = lightDir[1] / length;
|
|
131
|
+
const az = lightDir[2] / length;
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
* **The reference direction moves when the sun is overhead, and a sun overhead is the common
|
|
135
|
+
* case.** `cross(up, axis)` collapses as the two line up, so a light within a degree of straight
|
|
136
|
+
* down produces a basis of denormals and a map that is mostly one texel. Noon is not an edge
|
|
137
|
+
* case in a day cycle.
|
|
138
|
+
*/
|
|
139
|
+
const upX = Math.abs(ay) > OVERHEAD ? 0 : 0;
|
|
140
|
+
const upY = Math.abs(ay) > OVERHEAD ? 0 : 1;
|
|
141
|
+
const upZ = Math.abs(ay) > OVERHEAD ? 1 : 0;
|
|
142
|
+
|
|
143
|
+
let rx = upY * az - upZ * ay;
|
|
144
|
+
let ry = upZ * ax - upX * az;
|
|
145
|
+
let rz = upX * ay - upY * ax;
|
|
146
|
+
const rLength = Math.hypot(rx, ry, rz) || 1;
|
|
147
|
+
rx /= rLength;
|
|
148
|
+
ry /= rLength;
|
|
149
|
+
rz /= rLength;
|
|
150
|
+
|
|
151
|
+
/* The third axis is the cross of the other two, so the basis is orthonormal by construction. */
|
|
152
|
+
out[0] = rx;
|
|
153
|
+
out[1] = ry;
|
|
154
|
+
out[2] = rz;
|
|
155
|
+
out[3] = ay * rz - az * ry;
|
|
156
|
+
out[4] = az * rx - ax * rz;
|
|
157
|
+
out[5] = ax * ry - ay * rx;
|
|
158
|
+
out[6] = ax;
|
|
159
|
+
out[7] = ay;
|
|
160
|
+
out[8] = az;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function fitDirectionalShadow(
|
|
164
|
+
centre: ArrayLike<number>,
|
|
165
|
+
radius: number,
|
|
166
|
+
lightDir: readonly [number, number, number],
|
|
167
|
+
out: Float32Array,
|
|
168
|
+
): number {
|
|
169
|
+
lightBasis(lightDir, BASIS);
|
|
170
|
+
const rx = BASIS[0] as number;
|
|
171
|
+
const ry = BASIS[1] as number;
|
|
172
|
+
const rz = BASIS[2] as number;
|
|
173
|
+
const ux = BASIS[3] as number;
|
|
174
|
+
const uy = BASIS[4] as number;
|
|
175
|
+
const uz = BASIS[5] as number;
|
|
176
|
+
const ax = BASIS[6] as number;
|
|
177
|
+
const ay = BASIS[7] as number;
|
|
178
|
+
const az = BASIS[8] as number;
|
|
179
|
+
|
|
180
|
+
const scale = 1 / Math.max(radius, 1e-6);
|
|
181
|
+
const put = (column: number, x: number, y: number, z: number): void => {
|
|
182
|
+
out[column * 4] = x;
|
|
183
|
+
out[column * 4 + 1] = y;
|
|
184
|
+
out[column * 4 + 2] = z;
|
|
185
|
+
out[column * 4 + 3] = 0;
|
|
186
|
+
};
|
|
187
|
+
/* Rows are the basis and columns are the axes: row 0 is the light's right, row 2 its depth. */
|
|
188
|
+
put(0, rx * scale, ux * scale, -ax * scale);
|
|
189
|
+
put(1, ry * scale, uy * scale, -ay * scale);
|
|
190
|
+
put(2, rz * scale, uz * scale, -az * scale);
|
|
191
|
+
|
|
192
|
+
const dot = (x: number, y: number, z: number): number =>
|
|
193
|
+
x * (centre[0] as number) + y * (centre[1] as number) + z * (centre[2] as number);
|
|
194
|
+
out[12] = -dot(rx, ry, rz) * scale;
|
|
195
|
+
out[13] = -dot(ux, uy, uz) * scale;
|
|
196
|
+
/* Positive, because the depth row is already negated: the centre of the scene lands at zero. */
|
|
197
|
+
out[14] = dot(ax, ay, az) * scale;
|
|
198
|
+
out[15] = 1;
|
|
199
|
+
|
|
200
|
+
/* The box is a diameter deep, which is what turns a stored depth difference into metres. */
|
|
201
|
+
return 2 * Math.max(radius, 1e-6);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* **The map for a frame: the whole scene while it fits inside `follow` metres, and a sphere of that
|
|
206
|
+
* radius around the eye once it does not.**
|
|
207
|
+
*
|
|
208
|
+
* The scene fit is right for what this pipeline was first given — rigs a few metres across, a box
|
|
209
|
+
* that never moves and so never shimmers — and wrong for a world, which is what the voxel
|
|
210
|
+
* sandbox's port made this pipeline draw: at radius 14 its sphere is hundreds of metres across and
|
|
211
|
+
* a 2048 map over it has texels a quarter of a metre wide. So past a radius the caller names, the
|
|
212
|
+
* map follows the eye, as the forward path's does in `lightMatrix.ts`. **At or under it nothing
|
|
213
|
+
* changes, to the bit**, and with no radius at all nothing ever does — which is what keeps the three
|
|
214
|
+
* rigs the control rather than a second fit's first customer.
|
|
215
|
+
*
|
|
216
|
+
* **Why the scene's size rather than whether the eye is inside it**: a fit that switched as the eye
|
|
217
|
+
* crossed a boundary would jump the whole map between two scales mid-walk, where a scene grows past
|
|
218
|
+
* the radius once and stays there.
|
|
219
|
+
*
|
|
220
|
+
* `sphere` is the scene's centre and radius, four floats, as `sceneShadowBounds` writes them.
|
|
221
|
+
* Returns the metres the depth range spans, which the lookup multiplies a stored difference by.
|
|
222
|
+
*/
|
|
223
|
+
export function fitShadow(
|
|
224
|
+
sphere: ArrayLike<number>,
|
|
225
|
+
eye: ArrayLike<number>,
|
|
226
|
+
follow: number | undefined,
|
|
227
|
+
lightDir: readonly [number, number, number],
|
|
228
|
+
mapSize: number,
|
|
229
|
+
out: Float32Array,
|
|
230
|
+
): number {
|
|
231
|
+
const radius = sphere[3] as number;
|
|
232
|
+
/* No radius is an infinite one: a scene is never larger, so the fit never follows. */
|
|
233
|
+
if (!(radius > (follow ?? Infinity))) {
|
|
234
|
+
return fitDirectionalShadow(sphere, radius, lightDir, out);
|
|
235
|
+
}
|
|
236
|
+
return fitFollowingShadow(eye, follow as number, sphere, lightDir, mapSize, out);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* A sphere of `radius` around `focus`, **snapped to whole texels of a fixed light space**, and deep
|
|
241
|
+
* enough toward the light to hold every caster the scene has there.
|
|
242
|
+
*
|
|
243
|
+
* **Snapped, or every edge crawls.** The basis is the light's alone, so the grid is fixed; the
|
|
244
|
+
* focus's three light-space coordinates are rounded to it, and the map moves in whole texels or not
|
|
245
|
+
* at all. A world point then falls in the same texel until the map steps, rather than at a new
|
|
246
|
+
* sub-texel offset every frame.
|
|
247
|
+
*
|
|
248
|
+
* **Deep enough toward the sun for every caster.** A receiver is inside the sphere, and anything
|
|
249
|
+
* that shadows one lies between it and the light — so the range reaches toward the light as far as
|
|
250
|
+
* the scene's own far side, which is where the last possible caster is. `lightMatrix.ts` reaches
|
|
251
|
+
* three radii; a dusk sun over a city casts a tower's shadow further than that, and the scene's
|
|
252
|
+
* sphere is known exactly here. **The reach is rounded up to whole radii**, so it changes only when
|
|
253
|
+
* the eye has walked a radius along the light rather than rescaling every stored depth each frame.
|
|
254
|
+
*
|
|
255
|
+
* **And symmetric about the eye, which is not for casters but for the lookup.** The lookup gives
|
|
256
|
+
* up on the last stretch of stored depth, `SHADOW_DEPTH_FADE`, because in the scene fit that is the
|
|
257
|
+
* scene's far rim. The first version of this reached only a radius away from the sun, which put
|
|
258
|
+
* every receiver in that stretch — the ground below the eye came out less shadowed the further
|
|
259
|
+
* below it was, and the sphere's far side not at all. Symmetric, a receiver at most a radius from
|
|
260
|
+
* the eye is stored within `radius / reach` of the middle, and the least reach is the whole number
|
|
261
|
+
* of radii that keeps that short of the fade.
|
|
262
|
+
*/
|
|
263
|
+
function fitFollowingShadow(
|
|
264
|
+
focus: ArrayLike<number>,
|
|
265
|
+
radius: number,
|
|
266
|
+
sphere: ArrayLike<number>,
|
|
267
|
+
lightDir: readonly [number, number, number],
|
|
268
|
+
mapSize: number,
|
|
269
|
+
out: Float32Array,
|
|
270
|
+
): number {
|
|
271
|
+
lightBasis(lightDir, BASIS);
|
|
272
|
+
const rx = BASIS[0] as number;
|
|
273
|
+
const ry = BASIS[1] as number;
|
|
274
|
+
const rz = BASIS[2] as number;
|
|
275
|
+
const ux = BASIS[3] as number;
|
|
276
|
+
const uy = BASIS[4] as number;
|
|
277
|
+
const uz = BASIS[5] as number;
|
|
278
|
+
const ax = BASIS[6] as number;
|
|
279
|
+
const ay = BASIS[7] as number;
|
|
280
|
+
const az = BASIS[8] as number;
|
|
281
|
+
const fx = focus[0] as number;
|
|
282
|
+
const fy = focus[1] as number;
|
|
283
|
+
const fz = focus[2] as number;
|
|
284
|
+
|
|
285
|
+
const texel = (2 * radius) / Math.max(1, mapSize);
|
|
286
|
+
const across = Math.round((rx * fx + ry * fy + rz * fz) / texel) * texel;
|
|
287
|
+
const up = Math.round((ux * fx + uy * fy + uz * fz) / texel) * texel;
|
|
288
|
+
const along = Math.round((ax * fx + ay * fy + az * fz) / texel) * texel;
|
|
289
|
+
|
|
290
|
+
const farSide =
|
|
291
|
+
ax * (sphere[0] as number) +
|
|
292
|
+
ay * (sphere[1] as number) +
|
|
293
|
+
az * (sphere[2] as number) +
|
|
294
|
+
(sphere[3] as number);
|
|
295
|
+
/*
|
|
296
|
+
* A receiver a radius from the eye is stored at 0.5 + radius / (2 reach); keeping that below the
|
|
297
|
+
* fade's start needs reach >= radius / (2 (start - 0.5)), which is 1.25 radii and so two.
|
|
298
|
+
*/
|
|
299
|
+
const least = Math.ceil(1 / (2 * ((SHADOW_DEPTH_FADE[0] as number) - 0.5)));
|
|
300
|
+
const reach = radius * Math.max(least, Math.ceil((farSide - along) / radius));
|
|
301
|
+
|
|
302
|
+
const scale = 1 / radius;
|
|
303
|
+
const depth = 1 / reach;
|
|
304
|
+
const put = (column: number, x: number, y: number, z: number): void => {
|
|
305
|
+
out[column * 4] = x;
|
|
306
|
+
out[column * 4 + 1] = y;
|
|
307
|
+
out[column * 4 + 2] = z;
|
|
308
|
+
out[column * 4 + 3] = 0;
|
|
309
|
+
};
|
|
310
|
+
put(0, rx * scale, ux * scale, -ax * depth);
|
|
311
|
+
put(1, ry * scale, uy * scale, -ay * depth);
|
|
312
|
+
put(2, rz * scale, uz * scale, -az * depth);
|
|
313
|
+
out[12] = -across * scale;
|
|
314
|
+
out[13] = -up * scale;
|
|
315
|
+
/* Nearer the light is smaller, as in the scene fit: the sunward end lands at -1. */
|
|
316
|
+
out[14] = along * depth;
|
|
317
|
+
out[15] = 1;
|
|
318
|
+
return 2 * reach;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* **Two corrections, and the difference is one negated row.**
|
|
323
|
+
*
|
|
324
|
+
* The lookup wants the light-space position with `x` and `y` still in -1..1 — it remaps those
|
|
325
|
+
* itself — and `z` already in the 0..1 WebGPU clips to. That is `SHADOW_LOOKUP_CORRECTION`, and it
|
|
326
|
+
* is `SHADOW_CLIP_CORRECTION` in `webgpu/renderer.ts` under another name, for the same reason: a
|
|
327
|
+
* map is sampled rather than presented.
|
|
328
|
+
*
|
|
329
|
+
* The raster wants the same depth and the **opposite rows**, and this is the part that is easy to
|
|
330
|
+
* get backwards. A generated vertex stage ends with `gl_Position.y = -gl_Position.y`, which naga
|
|
331
|
+
* writes and nothing here does — so the forward path's shadow pass is handed the unflipped matrix
|
|
332
|
+
* and emits a flipped picture, while a hand-written stage handed the same matrix emits an unflipped
|
|
333
|
+
* one and stores every row at the mirror of where the lookup goes looking. Flipping it here is what
|
|
334
|
+
* puts the two pipelines' maps in the same orientation, so one lookup can read either.
|
|
335
|
+
*
|
|
336
|
+
* **And the flip reverses the winding with it**, which is why the pipeline that uses this declares
|
|
337
|
+
* `frontFace: 'cw'` — the same pair `depthPass.ts` carries, arrived at from the other side.
|
|
338
|
+
*
|
|
339
|
+
* Neither reverses depth. `depthConvention.ts` leaves shadow maps conventional, so the row is
|
|
340
|
+
* `0.5z + 0.5` where the frame's is `0.5 - 0.5z`, and the pass that renders one clears to
|
|
341
|
+
* `SHADOW_DEPTH_CLEAR` and compares with `less`.
|
|
342
|
+
*/
|
|
343
|
+
export const SHADOW_LOOKUP_CORRECTION = new Float32Array([
|
|
344
|
+
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 1,
|
|
345
|
+
]);
|
|
346
|
+
|
|
347
|
+
export const SHADOW_RASTER_CORRECTION = new Float32Array([
|
|
348
|
+
1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 1,
|
|
349
|
+
]);
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* How far toward the light the light's cone test stands its eye, in metres.
|
|
353
|
+
*
|
|
354
|
+
* **A directional light has no eye, and the cone test wants one.** Stood this far toward the sun,
|
|
355
|
+
* every direction from the eye to a cluster in the map is the sun's own to within the cluster's
|
|
356
|
+
* distance from the camera over this — three hundred-thousandths of a radian across a city three
|
|
357
|
+
* kilometres wide — so the perspective test answers the directional one the map's raster applies
|
|
358
|
+
* when it culls the faces turned from the light. A triangle it could cull wrongly is that close to
|
|
359
|
+
* edge-on to the sun, and covers a thousandth of a texel of any map. In `float32` the eye is good
|
|
360
|
+
* to eight metres of the hundred million, which moves the direction by less again.
|
|
361
|
+
*/
|
|
362
|
+
export const LIGHT_CONE_DISTANCE = 1e8;
|
|
363
|
+
|
|
364
|
+
/** The eye the light's cone test reads: `eye` moved `LIGHT_CONE_DISTANCE` toward the light. */
|
|
365
|
+
export function lightConeEye(
|
|
366
|
+
eye: ArrayLike<number>,
|
|
367
|
+
lightDir: ArrayLike<number>,
|
|
368
|
+
out: [number, number, number],
|
|
369
|
+
): [number, number, number] {
|
|
370
|
+
const x = lightDir[0] as number;
|
|
371
|
+
const y = lightDir[1] as number;
|
|
372
|
+
const z = lightDir[2] as number;
|
|
373
|
+
const scale = LIGHT_CONE_DISTANCE / (Math.hypot(x, y, z) || 1);
|
|
374
|
+
out[0] = (eye[0] as number) + x * scale;
|
|
375
|
+
out[1] = (eye[1] as number) + y * scale;
|
|
376
|
+
out[2] = (eye[2] as number) + z * scale;
|
|
377
|
+
return out;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* The raster's matrix with its depth turned over, `1 - z`, and nothing else moved: what the light's
|
|
382
|
+
* cull projects a cluster through, because the light's pyramid is stored turned over
|
|
383
|
+
* (`shadowPyramidBase`) so the camera's cull and reduction can read it. Applied after
|
|
384
|
+
* `SHADOW_RASTER_CORRECTION`, so the rows are the raster's, which are the map's and the pyramid's.
|
|
385
|
+
*/
|
|
386
|
+
export const SHADOW_CULL_CORRECTION = new Float32Array([
|
|
387
|
+
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 1, 1,
|
|
388
|
+
]);
|
|
389
|
+
|
|
390
|
+
/** `out = correction · light`, column-major. */
|
|
391
|
+
export function correctShadowMatrix(
|
|
392
|
+
correction: Float32Array,
|
|
393
|
+
light: Float32Array,
|
|
394
|
+
out: Float32Array,
|
|
395
|
+
): Float32Array {
|
|
396
|
+
for (let column = 0; column < 4; column += 1) {
|
|
397
|
+
for (let row = 0; row < 4; row += 1) {
|
|
398
|
+
let sum = 0;
|
|
399
|
+
for (let k = 0; k < 4; k += 1) {
|
|
400
|
+
sum += (correction[k * 4 + row] as number) * (light[column * 4 + k] as number);
|
|
401
|
+
}
|
|
402
|
+
out[column * 4 + row] = sum;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return out;
|
|
406
|
+
}
|