@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,741 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DriftTR's resolve on the device: `recon/resolve.ts`, operation for operation.
|
|
3
|
+
*
|
|
4
|
+
* **One core, two modules**, the arrangement `network.wgsl.ts` uses. The arithmetic below reads
|
|
5
|
+
* every texel through functions the including module defines, so the production module can read the
|
|
6
|
+
* renderer's reversed depth through a converting accessor while the parity check reads plain float
|
|
7
|
+
* textures of the numbers the reference was given. A second copy of the arithmetic — one for the
|
|
8
|
+
* frame and one for the check — is two sets of rounding decisions to keep in step, which is the
|
|
9
|
+
* thing this repository refuses everywhere else.
|
|
10
|
+
*
|
|
11
|
+
* **`floor(x + 0.5)`, never `round`.** JavaScript rounds a half away from zero and WGSL's `round`
|
|
12
|
+
* rounds a half to even, and this resolve rounds at every texel it picks: the nearest render texel
|
|
13
|
+
* to an output pixel, and the previous frame's texel under a reprojection. A half lands there
|
|
14
|
+
* whenever the ratio is two, or the jitter is zero, or an object moved by a whole texel — which is
|
|
15
|
+
* to say constantly, not rarely.
|
|
16
|
+
*
|
|
17
|
+
* **Rows flip in the accessors, not here.** The reference's images are rows from `v = 0` upward and
|
|
18
|
+
* a WebGPU texture's row 0 is the top one, so the production module's accessors subtract the
|
|
19
|
+
* texel's row from the height. The check's accessors do not, because its textures are written in
|
|
20
|
+
* the reference's own order.
|
|
21
|
+
*
|
|
22
|
+
* **Everything here is `f32` where the reference is `f64`.** The world positions a depth unprojects
|
|
23
|
+
* to, and the normals differenced from them, are where that costs the most: a cross product of two
|
|
24
|
+
* neighbouring positions is a subtraction of nearly equal numbers. `scripts/recon-parity.mjs`
|
|
25
|
+
* measures what it costs and states the bound it holds.
|
|
26
|
+
*
|
|
27
|
+
* The accessors an including module must define, before including the core:
|
|
28
|
+
*
|
|
29
|
+
* ```wgsl
|
|
30
|
+
* fn reconScene(x: i32, y: i32) -> vec3<f32> // render size, linear, clamped
|
|
31
|
+
* fn reconSceneBilinear(p: vec2<f32>) -> vec3<f32> // at continuous texel coordinates, clamped
|
|
32
|
+
* fn reconDepth(x: i32, y: i32) -> f32 // this frame's clip depth, the matrices' sense
|
|
33
|
+
* fn reconPreviousDepth(x: i32, y: i32) -> f32 // last frame's
|
|
34
|
+
* fn reconMotion(x: i32, y: i32) -> vec4<f32> // uv, previous view depth, flag
|
|
35
|
+
* fn reconHistory(x: i32, y: i32) -> vec4<f32> // output size, colour and gathered weight
|
|
36
|
+
* fn reconHistoryBilinear(p: vec2<f32>) -> vec4<f32>
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* and the uniform `recon: ReconParams`, whose struct this module declares.
|
|
40
|
+
*/
|
|
41
|
+
import { wgslSceneDepthToNdc } from '../../depthConvention.ts';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The parameters one resolve reads, as `ResolveFrame` minus its images.
|
|
45
|
+
*
|
|
46
|
+
* `hasHistory` is a `u32` because a uniform buffer has no `bool`. The three matrices are the
|
|
47
|
+
* unjittered ones, in the same convention as the depths the accessors return.
|
|
48
|
+
*/
|
|
49
|
+
export const RECON_PARAMS_WGSL = /* wgsl */ `
|
|
50
|
+
struct ReconParams {
|
|
51
|
+
renderSize: vec2<u32>,
|
|
52
|
+
outputSize: vec2<u32>,
|
|
53
|
+
jitter: vec2<f32>,
|
|
54
|
+
previousJitter: vec2<f32>,
|
|
55
|
+
inverseViewProj: mat4x4<f32>,
|
|
56
|
+
previousViewProj: mat4x4<f32>,
|
|
57
|
+
previousInverseViewProj: mat4x4<f32>,
|
|
58
|
+
eye: vec4<f32>,
|
|
59
|
+
previousEye: vec4<f32>,
|
|
60
|
+
alpha: f32,
|
|
61
|
+
sharpenAmount: f32,
|
|
62
|
+
clampGamma: f32,
|
|
63
|
+
hasHistory: u32,
|
|
64
|
+
depthTolerance: f32,
|
|
65
|
+
motionScale: f32,
|
|
66
|
+
normalFloor: f32,
|
|
67
|
+
normalCeiling: f32,
|
|
68
|
+
}
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
/** Floats in `ReconParams`, which is what a caller sizes its uniform buffer by. */
|
|
72
|
+
export const RECON_PARAM_FLOATS = 72;
|
|
73
|
+
|
|
74
|
+
/** `SAMPLE_SPREAD` and `CONFIDENT_WEIGHT`, which the reference exports and this must not restate. */
|
|
75
|
+
export const RECON_SAMPLE_SPREAD = 0.47;
|
|
76
|
+
export const RECON_CONFIDENT_WEIGHT = 1;
|
|
77
|
+
|
|
78
|
+
/** The workgroup edge both entry points dispatch over. */
|
|
79
|
+
export const RECON_WORKGROUP = 8;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* What the histories and the shown picture are stored in.
|
|
83
|
+
*
|
|
84
|
+
* **Half float, and the alpha carries a weight rather than an opacity.** The gathered weight is
|
|
85
|
+
* capped at `(1 - alpha) / alpha` plus one frame's gathering — about twelve at the default — and
|
|
86
|
+
* eleven bits of mantissa hold that to a part in two thousand, which is far inside what the
|
|
87
|
+
* disocclusion smoothstep can tell apart. Filterable, which the five-tap Catmull-Rom needs and no
|
|
88
|
+
* 32-bit float format offers, and storage-capable, which the dispatch writing it needs.
|
|
89
|
+
*/
|
|
90
|
+
export const RECON_HISTORY_FORMAT: GPUTextureFormat = 'rgba16float';
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* The arithmetic, as text. Defines `reconResolvePixel(ox, oy) -> vec4<f32>` — the next history's
|
|
94
|
+
* colour and the weight it has gathered — and `reconSharpenAt(ox, oy) -> vec3<f32>`, the picture
|
|
95
|
+
* shown, which reads the history the first has already written.
|
|
96
|
+
*/
|
|
97
|
+
export const RECON_RESOLVE_CORE_WGSL = /* wgsl */ `
|
|
98
|
+
const RECON_SAMPLE_SPREAD: f32 = ${RECON_SAMPLE_SPREAD};
|
|
99
|
+
const RECON_CONFIDENT_WEIGHT: f32 = ${RECON_CONFIDENT_WEIGHT}.0;
|
|
100
|
+
|
|
101
|
+
fn reconClampTexel(value: i32, size: i32) -> i32 {
|
|
102
|
+
return clamp(value, 0, size - 1);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* JavaScript's Math.round, which is not WGSL's round: a half goes up, not to even. */
|
|
106
|
+
fn reconRound(value: f32) -> f32 {
|
|
107
|
+
return floor(value + 0.5);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* Written out rather than the built-in, whose result is undefined where the edges are equal. */
|
|
111
|
+
fn reconSmoothstep(edge0: f32, edge1: f32, x: f32) -> f32 {
|
|
112
|
+
let t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
|
|
113
|
+
return t * t * (3.0 - 2.0 * t);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
fn reconWeightAt(dx: f32, dy: f32) -> f32 {
|
|
117
|
+
return exp(-(dx * dx + dy * dy) / (2.0 * RECON_SAMPLE_SPREAD * RECON_SAMPLE_SPREAD));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
fn reconToYCoCg(c: vec3<f32>) -> vec3<f32> {
|
|
121
|
+
return vec3<f32>(
|
|
122
|
+
c.r * 0.25 + c.g * 0.5 + c.b * 0.25,
|
|
123
|
+
c.r * 0.5 - c.b * 0.5,
|
|
124
|
+
-c.r * 0.25 + c.g * 0.5 - c.b * 0.25,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
fn reconFromYCoCg(c: vec3<f32>) -> vec3<f32> {
|
|
129
|
+
let base = c.x - c.z;
|
|
130
|
+
return vec3<f32>(base + c.y, c.x + c.z, base - c.y);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
struct ReconBox {
|
|
134
|
+
low: vec3<f32>,
|
|
135
|
+
high: vec3<f32>,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/*
|
|
139
|
+
* Each channel's mean plus or minus gamma of its standard deviation — and a channel whose nine
|
|
140
|
+
* samples all agree is that value exactly, because a mean of nine equal floats is not always one
|
|
141
|
+
* of them and a box a rounding wide lets a history through by a rounding.
|
|
142
|
+
*/
|
|
143
|
+
fn reconVarianceBox(samples: array<vec3<f32>, 9>, gamma: f32) -> ReconBox {
|
|
144
|
+
var s = samples;
|
|
145
|
+
var box: ReconBox;
|
|
146
|
+
for (var c = 0u; c < 3u; c = c + 1u) {
|
|
147
|
+
let first = s[0][c];
|
|
148
|
+
var same = true;
|
|
149
|
+
var sum = 0.0;
|
|
150
|
+
for (var i = 0u; i < 9u; i = i + 1u) {
|
|
151
|
+
let value = s[i][c];
|
|
152
|
+
sum = sum + value;
|
|
153
|
+
if (value != first) { same = false; }
|
|
154
|
+
}
|
|
155
|
+
if (same) {
|
|
156
|
+
box.low[c] = first;
|
|
157
|
+
box.high[c] = first;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
let mean = sum / 9.0;
|
|
161
|
+
var spread = 0.0;
|
|
162
|
+
for (var i = 0u; i < 9u; i = i + 1u) {
|
|
163
|
+
let d = s[i][c] - mean;
|
|
164
|
+
spread = spread + d * d;
|
|
165
|
+
}
|
|
166
|
+
let deviation = sqrt(spread / 9.0);
|
|
167
|
+
box.low[c] = mean - gamma * deviation;
|
|
168
|
+
box.high[c] = mean + gamma * deviation;
|
|
169
|
+
}
|
|
170
|
+
return box;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/*
|
|
174
|
+
* The history pulled towards the box's centre until it is inside, by one ratio for all three
|
|
175
|
+
* channels — a clamp per channel would land it on a corner and change its hue, which is coloured
|
|
176
|
+
* fringing on every moving edge. A channel with no extent bounds anything that differs from it
|
|
177
|
+
* infinitely, so such a history collapses onto the centre.
|
|
178
|
+
*/
|
|
179
|
+
fn reconClipToBox(history: vec3<f32>, low: vec3<f32>, high: vec3<f32>) -> vec3<f32> {
|
|
180
|
+
let centre = (low + high) * 0.5;
|
|
181
|
+
var offset = history - centre;
|
|
182
|
+
var extent = (high - low) * 0.5;
|
|
183
|
+
var ratio = 0.0;
|
|
184
|
+
var infinite = false;
|
|
185
|
+
for (var c = 0u; c < 3u; c = c + 1u) {
|
|
186
|
+
if (extent[c] > 1e-7) {
|
|
187
|
+
ratio = max(ratio, abs(offset[c]) / extent[c]);
|
|
188
|
+
} else if (abs(offset[c]) > 1e-7) {
|
|
189
|
+
infinite = true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (!infinite && !(ratio > 1.0)) { return history; }
|
|
193
|
+
var scale = 0.0;
|
|
194
|
+
if (!infinite) { scale = 1.0 / ratio; }
|
|
195
|
+
return centre + offset * scale;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
fn reconAccumulate(current: vec3<f32>, history: vec3<f32>, weight: f32, alpha: f32) -> vec3<f32> {
|
|
199
|
+
let kept = clamp(weight, 0.0, 1.0) * (1.0 - clamp(alpha, 0.0, 1.0));
|
|
200
|
+
return current * (1.0 - kept) + history * kept;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
fn reconCatmullRom(t: f32) -> vec4<f32> {
|
|
204
|
+
let t2 = t * t;
|
|
205
|
+
let t3 = t2 * t;
|
|
206
|
+
return vec4<f32>(
|
|
207
|
+
-0.5 * t3 + t2 - 0.5 * t,
|
|
208
|
+
1.5 * t3 - 2.5 * t2 + 1.0,
|
|
209
|
+
-1.5 * t3 + 2.0 * t2 + 0.5 * t,
|
|
210
|
+
0.5 * t3 - 0.5 * t2,
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/*
|
|
215
|
+
* Five bilinear taps standing for the sixteen-texel Catmull-Rom: each axis's middle pair folded
|
|
216
|
+
* into one tap placed between them, the corners dropped, the five weights renormalised. It is the
|
|
217
|
+
* five-tap form because the taps are the expensive part — which is only true while the bilinear is
|
|
218
|
+
* the sampler's, so the production module's accessor is a filtered sample and the check's is the
|
|
219
|
+
* reference's own arithmetic over loaded texels.
|
|
220
|
+
*/
|
|
221
|
+
struct ReconTaps {
|
|
222
|
+
at0: vec2<f32>,
|
|
223
|
+
at1: vec2<f32>,
|
|
224
|
+
at2: vec2<f32>,
|
|
225
|
+
at3: vec2<f32>,
|
|
226
|
+
at4: vec2<f32>,
|
|
227
|
+
weights: array<f32, 5>,
|
|
228
|
+
total: f32,
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
fn reconBicubicTaps(x: f32, y: f32) -> ReconTaps {
|
|
232
|
+
let x1 = floor(x);
|
|
233
|
+
let y1 = floor(y);
|
|
234
|
+
let wx = reconCatmullRom(x - x1);
|
|
235
|
+
let wy = reconCatmullRom(y - y1);
|
|
236
|
+
let wx12 = wx[1] + wx[2];
|
|
237
|
+
let wy12 = wy[1] + wy[2];
|
|
238
|
+
let x12 = x1 + wx[2] / wx12;
|
|
239
|
+
let y12 = y1 + wy[2] / wy12;
|
|
240
|
+
var taps: ReconTaps;
|
|
241
|
+
taps.at0 = vec2<f32>(x12, y1 - 1.0);
|
|
242
|
+
taps.at1 = vec2<f32>(x1 - 1.0, y12);
|
|
243
|
+
taps.at2 = vec2<f32>(x12, y12);
|
|
244
|
+
taps.at3 = vec2<f32>(x1 + 2.0, y12);
|
|
245
|
+
taps.at4 = vec2<f32>(x12, y1 + 2.0);
|
|
246
|
+
taps.weights[0] = wx12 * wy[0];
|
|
247
|
+
taps.weights[1] = wx[0] * wy12;
|
|
248
|
+
taps.weights[2] = wx12 * wy12;
|
|
249
|
+
taps.weights[3] = wx[3] * wy12;
|
|
250
|
+
taps.weights[4] = wx12 * wy[3];
|
|
251
|
+
taps.total =
|
|
252
|
+
taps.weights[0] + taps.weights[1] + taps.weights[2] + taps.weights[3] + taps.weights[4];
|
|
253
|
+
return taps;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* A colour cannot be negative, and Catmull-Rom's negative lobes undershoot beside a bright edge. */
|
|
257
|
+
fn reconSceneBicubic5(x: f32, y: f32) -> vec3<f32> {
|
|
258
|
+
let taps = reconBicubicTaps(x, y);
|
|
259
|
+
var sum = reconSceneBilinear(taps.at0) * taps.weights[0];
|
|
260
|
+
sum = sum + reconSceneBilinear(taps.at1) * taps.weights[1];
|
|
261
|
+
sum = sum + reconSceneBilinear(taps.at2) * taps.weights[2];
|
|
262
|
+
sum = sum + reconSceneBilinear(taps.at3) * taps.weights[3];
|
|
263
|
+
sum = sum + reconSceneBilinear(taps.at4) * taps.weights[4];
|
|
264
|
+
return max(sum / taps.total, vec3<f32>(0.0));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
fn reconHistoryBicubic5(x: f32, y: f32) -> vec4<f32> {
|
|
268
|
+
let taps = reconBicubicTaps(x, y);
|
|
269
|
+
var sum = reconHistoryBilinear(taps.at0) * taps.weights[0];
|
|
270
|
+
sum = sum + reconHistoryBilinear(taps.at1) * taps.weights[1];
|
|
271
|
+
sum = sum + reconHistoryBilinear(taps.at2) * taps.weights[2];
|
|
272
|
+
sum = sum + reconHistoryBilinear(taps.at3) * taps.weights[3];
|
|
273
|
+
sum = sum + reconHistoryBilinear(taps.at4) * taps.weights[4];
|
|
274
|
+
return max(sum / taps.total, vec4<f32>(0.0));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
struct ReconWorld {
|
|
278
|
+
ok: bool,
|
|
279
|
+
position: vec3<f32>,
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* The world position a clip depth stands for, and nothing where the matrix has no answer there. */
|
|
283
|
+
fn reconWorldFromDepth(m: mat4x4<f32>, u: f32, v: f32, clipDepth: f32) -> ReconWorld {
|
|
284
|
+
var out: ReconWorld;
|
|
285
|
+
out.position = vec3<f32>(0.0);
|
|
286
|
+
out.ok = false;
|
|
287
|
+
let x = u * 2.0 - 1.0;
|
|
288
|
+
let y = v * 2.0 - 1.0;
|
|
289
|
+
let w = m[0][3] * x + m[1][3] * y + m[2][3] * clipDepth + m[3][3];
|
|
290
|
+
if (!(abs(w) > 1e-12)) { return out; }
|
|
291
|
+
let p = m * vec4<f32>(x, y, clipDepth, 1.0);
|
|
292
|
+
out.position = p.xyz / w;
|
|
293
|
+
out.ok = all(abs(out.position) < vec3<f32>(3.4e38));
|
|
294
|
+
return out;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
struct ReconNormal {
|
|
298
|
+
ok: bool,
|
|
299
|
+
normal: vec3<f32>,
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/* Turned to face the eye, so the answer is the same whichever way the target's rows run. */
|
|
303
|
+
fn reconNormalFrom(
|
|
304
|
+
centre: vec3<f32>,
|
|
305
|
+
right: vec3<f32>,
|
|
306
|
+
up: vec3<f32>,
|
|
307
|
+
eye: vec3<f32>,
|
|
308
|
+
) -> ReconNormal {
|
|
309
|
+
var out: ReconNormal;
|
|
310
|
+
out.normal = vec3<f32>(0.0);
|
|
311
|
+
out.ok = false;
|
|
312
|
+
let a = right - centre;
|
|
313
|
+
let b = up - centre;
|
|
314
|
+
let n = cross(a, b);
|
|
315
|
+
let length2 = dot(n, n);
|
|
316
|
+
let scale2 = dot(a, a) * dot(b, b);
|
|
317
|
+
if (!(length2 > 1e-12 * scale2)) { return out; }
|
|
318
|
+
let toEye = dot(n, eye - centre);
|
|
319
|
+
var sign = 1.0;
|
|
320
|
+
if (toEye < 0.0) { sign = -1.0; }
|
|
321
|
+
out.normal = n * (sign / sqrt(length2));
|
|
322
|
+
out.ok = true;
|
|
323
|
+
return out;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
fn reconDisocclusion(
|
|
327
|
+
currDepth: f32,
|
|
328
|
+
histDepth: f32,
|
|
329
|
+
motionLength: f32,
|
|
330
|
+
normalDot: f32,
|
|
331
|
+
) -> f32 {
|
|
332
|
+
if (!(currDepth > 0.0) || !(histDepth > 0.0) || !(motionLength >= 0.0)) { return 0.0; }
|
|
333
|
+
let disagreement = abs(currDepth - histDepth) / currDepth;
|
|
334
|
+
let tolerance = recon.depthTolerance + recon.motionScale * motionLength;
|
|
335
|
+
let depth = 1.0 - reconSmoothstep(tolerance, 2.0 * tolerance, disagreement);
|
|
336
|
+
let normal = reconSmoothstep(recon.normalFloor, recon.normalCeiling, normalDot);
|
|
337
|
+
return depth * normal;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
struct ReconAt {
|
|
341
|
+
depth: f32,
|
|
342
|
+
position: vec3<f32>,
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/* A texel's world position at its unjittered uv, and the view depth it stands at, or zero. */
|
|
346
|
+
fn reconWorldAt(previous: bool, x: i32, y: i32) -> ReconAt {
|
|
347
|
+
let w = i32(recon.renderSize.x);
|
|
348
|
+
let h = i32(recon.renderSize.y);
|
|
349
|
+
let tx = reconClampTexel(x, w);
|
|
350
|
+
let ty = reconClampTexel(y, h);
|
|
351
|
+
var jitter = recon.jitter;
|
|
352
|
+
var m = recon.inverseViewProj;
|
|
353
|
+
var z = reconDepth(tx, ty);
|
|
354
|
+
if (previous) {
|
|
355
|
+
jitter = recon.previousJitter;
|
|
356
|
+
m = recon.previousInverseViewProj;
|
|
357
|
+
z = reconPreviousDepth(tx, ty);
|
|
358
|
+
}
|
|
359
|
+
let u = (f32(tx) + 0.5 - jitter.x) / f32(w);
|
|
360
|
+
let v = (f32(ty) + 0.5 - jitter.y) / f32(h);
|
|
361
|
+
var out: ReconAt;
|
|
362
|
+
out.depth = 0.0;
|
|
363
|
+
out.position = vec3<f32>(0.0);
|
|
364
|
+
let world = reconWorldFromDepth(m, u, v, z);
|
|
365
|
+
if (!world.ok) { return out; }
|
|
366
|
+
out.position = world.position;
|
|
367
|
+
/* The view depth is the clip w, which the inverse's w is the reciprocal of. */
|
|
368
|
+
let cw = m[0][3] * (u * 2.0 - 1.0) + m[1][3] * (v * 2.0 - 1.0) + m[2][3] * z + m[3][3];
|
|
369
|
+
out.depth = 1.0 / cw;
|
|
370
|
+
return out;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* The neighbour on the inside of the border, so the edge texels have a normal too. */
|
|
374
|
+
fn reconNormalAt(previous: bool, x: i32, y: i32) -> ReconNormal {
|
|
375
|
+
var out: ReconNormal;
|
|
376
|
+
out.normal = vec3<f32>(0.0);
|
|
377
|
+
out.ok = false;
|
|
378
|
+
let w = i32(recon.renderSize.x);
|
|
379
|
+
let h = i32(recon.renderSize.y);
|
|
380
|
+
let centre = reconWorldAt(previous, x, y);
|
|
381
|
+
if (!(centre.depth > 0.0)) { return out; }
|
|
382
|
+
var dx = -1;
|
|
383
|
+
if (x + 1 < w) { dx = 1; }
|
|
384
|
+
var dy = -1;
|
|
385
|
+
if (y + 1 < h) { dy = 1; }
|
|
386
|
+
let right = reconWorldAt(previous, x + dx, y);
|
|
387
|
+
if (!(right.depth > 0.0)) { return out; }
|
|
388
|
+
let up = reconWorldAt(previous, x, y + dy);
|
|
389
|
+
if (!(up.depth > 0.0)) { return out; }
|
|
390
|
+
var eye = recon.eye.xyz;
|
|
391
|
+
if (previous) { eye = recon.previousEye.xyz; }
|
|
392
|
+
return reconNormalFrom(centre.position, right.position, up.position, eye);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
struct ReconHistory {
|
|
396
|
+
weight: f32,
|
|
397
|
+
colour: vec4<f32>,
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/*
|
|
401
|
+
* The weight a pixel's history still deserves: none on the first frame, none where the surface was
|
|
402
|
+
* behind last frame's eye or off its picture, and otherwise what it gathered, scaled by whether it
|
|
403
|
+
* is the same surface.
|
|
404
|
+
*/
|
|
405
|
+
fn reconHistoryWeight(u: f32, v: f32, dx: i32, dy: i32) -> ReconHistory {
|
|
406
|
+
var out: ReconHistory;
|
|
407
|
+
out.weight = 0.0;
|
|
408
|
+
out.colour = vec4<f32>(0.0);
|
|
409
|
+
if (recon.hasHistory == 0u) { return out; }
|
|
410
|
+
let rw = f32(recon.renderSize.x);
|
|
411
|
+
let rh = f32(recon.renderSize.y);
|
|
412
|
+
let motion = reconMotion(dx, dy);
|
|
413
|
+
var mu = 0.0;
|
|
414
|
+
var mv = 0.0;
|
|
415
|
+
var expected = 0.0;
|
|
416
|
+
if (motion.w > 0.5) {
|
|
417
|
+
mu = motion.x;
|
|
418
|
+
mv = motion.y;
|
|
419
|
+
expected = motion.z;
|
|
420
|
+
} else {
|
|
421
|
+
let here = reconWorldAt(false, dx, dy);
|
|
422
|
+
if (!(here.depth > 0.0)) { return out; }
|
|
423
|
+
let clip = recon.previousViewProj * vec4<f32>(here.position, 1.0);
|
|
424
|
+
/*
|
|
425
|
+
* A surface behind last frame's eye has a w that is not positive: the disocclusion trusts no
|
|
426
|
+
* such depth, so it needs no refusal of its own here.
|
|
427
|
+
*/
|
|
428
|
+
expected = clip.w;
|
|
429
|
+
let du = (f32(dx) + 0.5 - recon.jitter.x) / rw;
|
|
430
|
+
let dv = (f32(dy) + 0.5 - recon.jitter.y) / rh;
|
|
431
|
+
mu = (clip.x / expected) * 0.5 + 0.5 - du;
|
|
432
|
+
mv = (clip.y / expected) * 0.5 + 0.5 - dv;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
let pu = u + mu;
|
|
436
|
+
let pv = v + mv;
|
|
437
|
+
if (!(pu >= 0.0 && pu <= 1.0 && pv >= 0.0 && pv <= 1.0)) { return out; }
|
|
438
|
+
out.colour = reconHistoryBicubic5(
|
|
439
|
+
pu * f32(recon.outputSize.x) - 0.5,
|
|
440
|
+
pv * f32(recon.outputSize.y) - 0.5,
|
|
441
|
+
);
|
|
442
|
+
let px = reconClampTexel(i32(reconRound(pu * rw + recon.previousJitter.x - 0.5)), i32(rw));
|
|
443
|
+
let py = reconClampTexel(i32(reconRound(pv * rh + recon.previousJitter.y - 0.5)), i32(rh));
|
|
444
|
+
let held = reconWorldAt(true, px, py).depth;
|
|
445
|
+
var normalDot = 1.0;
|
|
446
|
+
let here = reconNormalAt(false, dx, dy);
|
|
447
|
+
let there = reconNormalAt(true, px, py);
|
|
448
|
+
if (here.ok && there.ok) { normalDot = dot(here.normal, there.normal); }
|
|
449
|
+
let trust = reconDisocclusion(expected, held, length(vec2<f32>(mu, mv)), normalDot);
|
|
450
|
+
out.weight = out.colour.w * trust;
|
|
451
|
+
return out;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/* One output pixel: the history's next colour, before sharpening, and the weight it has gathered. */
|
|
455
|
+
fn reconResolvePixel(ox: i32, oy: i32) -> vec4<f32> {
|
|
456
|
+
let rw = i32(recon.renderSize.x);
|
|
457
|
+
let rh = i32(recon.renderSize.y);
|
|
458
|
+
let ow = i32(recon.outputSize.x);
|
|
459
|
+
let oh = i32(recon.outputSize.y);
|
|
460
|
+
let u = (f32(ox) + 0.5) / f32(ow);
|
|
461
|
+
let v = (f32(oy) + 0.5) / f32(oh);
|
|
462
|
+
let jx = recon.jitter.x;
|
|
463
|
+
let jy = recon.jitter.y;
|
|
464
|
+
|
|
465
|
+
/* Where this frame observed the pixel, and the render read there for the gaps. */
|
|
466
|
+
let rx = u * f32(rw) + jx - 0.5;
|
|
467
|
+
let ry = v * f32(rh) + jy - 0.5;
|
|
468
|
+
let sample = reconSceneBicubic5(rx, ry);
|
|
469
|
+
let nx = reconClampTexel(i32(reconRound(rx)), rw);
|
|
470
|
+
let ny = reconClampTexel(i32(reconRound(ry)), rh);
|
|
471
|
+
|
|
472
|
+
/* Each texel around: its weight, its colour in the box, and its depth. */
|
|
473
|
+
var nearest = reconDepth(nx, ny);
|
|
474
|
+
var dx = nx;
|
|
475
|
+
var dy = ny;
|
|
476
|
+
var gathered = 0.0;
|
|
477
|
+
var accum = vec3<f32>(0.0);
|
|
478
|
+
var neighbours: array<vec3<f32>, 9>;
|
|
479
|
+
for (var j = -1; j <= 1; j = j + 1) {
|
|
480
|
+
for (var i = -1; i <= 1; i = i + 1) {
|
|
481
|
+
let tx = reconClampTexel(nx + i, rw);
|
|
482
|
+
let ty = reconClampTexel(ny + j, rh);
|
|
483
|
+
let colour = reconScene(tx, ty);
|
|
484
|
+
let weight = reconWeightAt(
|
|
485
|
+
((f32(tx) + 0.5 - jx) / f32(rw)) * f32(ow) - (f32(ox) + 0.5),
|
|
486
|
+
((f32(ty) + 0.5 - jy) / f32(rh)) * f32(oh) - (f32(oy) + 0.5),
|
|
487
|
+
);
|
|
488
|
+
gathered = gathered + weight;
|
|
489
|
+
accum = accum + colour * weight;
|
|
490
|
+
neighbours[(j + 1) * 3 + (i + 1)] = reconToYCoCg(colour);
|
|
491
|
+
let z = reconDepth(tx, ty);
|
|
492
|
+
if (z < nearest) {
|
|
493
|
+
nearest = z;
|
|
494
|
+
dx = tx;
|
|
495
|
+
dy = ty;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
let box = reconVarianceBox(neighbours, recon.clampGamma);
|
|
500
|
+
accum = accum / gathered;
|
|
501
|
+
|
|
502
|
+
/* The history, and the weight it still deserves; a tenth of each frame is always new. */
|
|
503
|
+
let cap = (1.0 - recon.alpha) / recon.alpha;
|
|
504
|
+
let history = reconHistoryWeight(u, v, dx, dy);
|
|
505
|
+
let kept = min(cap, history.weight);
|
|
506
|
+
|
|
507
|
+
let total = kept + gathered;
|
|
508
|
+
var mixed = accum;
|
|
509
|
+
if (kept > 0.0) {
|
|
510
|
+
let clipped = reconClipToBox(reconToYCoCg(history.colour.xyz), box.low, box.high);
|
|
511
|
+
mixed = reconAccumulate(accum, reconFromYCoCg(clipped), 1.0, gathered / total);
|
|
512
|
+
}
|
|
513
|
+
let known = min(1.0, total / RECON_CONFIDENT_WEIGHT);
|
|
514
|
+
return vec4<f32>(sample * (1.0 - known) + mixed * known, total);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/*
|
|
518
|
+
* The centre pushed away from its four neighbours' mean, and held inside the range of the five —
|
|
519
|
+
* the halo a plain unsharp mask draws beside every edge is a value outside that range.
|
|
520
|
+
*/
|
|
521
|
+
fn reconSharpenAt(ox: i32, oy: i32) -> vec3<f32> {
|
|
522
|
+
let ow = i32(recon.outputSize.x);
|
|
523
|
+
let oh = i32(recon.outputSize.y);
|
|
524
|
+
let centre = reconHistory(reconClampTexel(ox, ow), reconClampTexel(oy, oh)).xyz;
|
|
525
|
+
var offsets = array<vec2<i32>, 4>(
|
|
526
|
+
vec2<i32>(-1, 0),
|
|
527
|
+
vec2<i32>(1, 0),
|
|
528
|
+
vec2<i32>(0, -1),
|
|
529
|
+
vec2<i32>(0, 1),
|
|
530
|
+
);
|
|
531
|
+
var low = centre;
|
|
532
|
+
var high = centre;
|
|
533
|
+
var sum = vec3<f32>(0.0);
|
|
534
|
+
for (var n = 0; n < 4; n = n + 1) {
|
|
535
|
+
let at = offsets[n];
|
|
536
|
+
let value = reconHistory(
|
|
537
|
+
reconClampTexel(ox + at.x, ow),
|
|
538
|
+
reconClampTexel(oy + at.y, oh),
|
|
539
|
+
).xyz;
|
|
540
|
+
sum = sum + value;
|
|
541
|
+
low = min(low, value);
|
|
542
|
+
high = max(high, value);
|
|
543
|
+
}
|
|
544
|
+
let pushed = centre + recon.sharpenAmount * (centre - sum / 4.0);
|
|
545
|
+
return min(high, max(low, pushed));
|
|
546
|
+
}
|
|
547
|
+
`;
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* The parity module: the core over plain float textures written in the reference's own row order,
|
|
551
|
+
* doing its own bilinear so the comparison is arithmetic rather than a tolerance on the device's
|
|
552
|
+
* sampler.
|
|
553
|
+
*
|
|
554
|
+
* Two entry points over one set of bindings. `resolveMain` writes four floats a pixel — the next
|
|
555
|
+
* history — and `sharpenMain` reads that history back at binding 4 and writes three.
|
|
556
|
+
*/
|
|
557
|
+
export function reconResolveParityWgsl(): string {
|
|
558
|
+
return /* wgsl */ `
|
|
559
|
+
@group(0) @binding(0) var sceneTexture: texture_2d<f32>;
|
|
560
|
+
@group(0) @binding(1) var depthTexture: texture_2d<f32>;
|
|
561
|
+
@group(0) @binding(2) var motionTexture: texture_2d<f32>;
|
|
562
|
+
@group(0) @binding(3) var previousDepthTexture: texture_2d<f32>;
|
|
563
|
+
@group(0) @binding(4) var historyTexture: texture_2d<f32>;
|
|
564
|
+
${RECON_PARAMS_WGSL}
|
|
565
|
+
@group(0) @binding(5) var<uniform> recon: ReconParams;
|
|
566
|
+
@group(0) @binding(6) var<storage, read_write> output: array<f32>;
|
|
567
|
+
|
|
568
|
+
fn reconScene(x: i32, y: i32) -> vec3<f32> {
|
|
569
|
+
return textureLoad(sceneTexture, vec2<i32>(x, y), 0).xyz;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
fn reconDepth(x: i32, y: i32) -> f32 {
|
|
573
|
+
return textureLoad(depthTexture, vec2<i32>(x, y), 0).x;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
fn reconPreviousDepth(x: i32, y: i32) -> f32 {
|
|
577
|
+
return textureLoad(previousDepthTexture, vec2<i32>(x, y), 0).x;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
fn reconMotion(x: i32, y: i32) -> vec4<f32> {
|
|
581
|
+
return textureLoad(motionTexture, vec2<i32>(x, y), 0);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
fn reconHistory(x: i32, y: i32) -> vec4<f32> {
|
|
585
|
+
return textureLoad(historyTexture, vec2<i32>(x, y), 0);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/* sampleBilinear's own arithmetic: floor, fraction, and the four texels clamped at the border. */
|
|
589
|
+
fn reconSceneBilinear(p: vec2<f32>) -> vec3<f32> {
|
|
590
|
+
let w = i32(recon.renderSize.x);
|
|
591
|
+
let h = i32(recon.renderSize.y);
|
|
592
|
+
let x0 = i32(floor(p.x));
|
|
593
|
+
let y0 = i32(floor(p.y));
|
|
594
|
+
let f = p - floor(p);
|
|
595
|
+
let a = reconScene(reconClampTexel(x0, w), reconClampTexel(y0, h));
|
|
596
|
+
let b = reconScene(reconClampTexel(x0 + 1, w), reconClampTexel(y0, h));
|
|
597
|
+
let c = reconScene(reconClampTexel(x0, w), reconClampTexel(y0 + 1, h));
|
|
598
|
+
let d = reconScene(reconClampTexel(x0 + 1, w), reconClampTexel(y0 + 1, h));
|
|
599
|
+
let top = a * (1.0 - f.x) + b * f.x;
|
|
600
|
+
let bottom = c * (1.0 - f.x) + d * f.x;
|
|
601
|
+
return top * (1.0 - f.y) + bottom * f.y;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
fn reconHistoryBilinear(p: vec2<f32>) -> vec4<f32> {
|
|
605
|
+
let w = i32(recon.outputSize.x);
|
|
606
|
+
let h = i32(recon.outputSize.y);
|
|
607
|
+
let x0 = i32(floor(p.x));
|
|
608
|
+
let y0 = i32(floor(p.y));
|
|
609
|
+
let f = p - floor(p);
|
|
610
|
+
let a = reconHistory(reconClampTexel(x0, w), reconClampTexel(y0, h));
|
|
611
|
+
let b = reconHistory(reconClampTexel(x0 + 1, w), reconClampTexel(y0, h));
|
|
612
|
+
let c = reconHistory(reconClampTexel(x0, w), reconClampTexel(y0 + 1, h));
|
|
613
|
+
let d = reconHistory(reconClampTexel(x0 + 1, w), reconClampTexel(y0 + 1, h));
|
|
614
|
+
let top = a * (1.0 - f.x) + b * f.x;
|
|
615
|
+
let bottom = c * (1.0 - f.x) + d * f.x;
|
|
616
|
+
return top * (1.0 - f.y) + bottom * f.y;
|
|
617
|
+
}
|
|
618
|
+
${RECON_RESOLVE_CORE_WGSL}
|
|
619
|
+
|
|
620
|
+
@compute @workgroup_size(${RECON_WORKGROUP}, ${RECON_WORKGROUP})
|
|
621
|
+
fn resolveMain(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
622
|
+
if (id.x >= recon.outputSize.x || id.y >= recon.outputSize.y) { return; }
|
|
623
|
+
let value = reconResolvePixel(i32(id.x), i32(id.y));
|
|
624
|
+
let at = (id.y * recon.outputSize.x + id.x) * 4u;
|
|
625
|
+
output[at] = value.x;
|
|
626
|
+
output[at + 1u] = value.y;
|
|
627
|
+
output[at + 2u] = value.z;
|
|
628
|
+
output[at + 3u] = value.w;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
@compute @workgroup_size(${RECON_WORKGROUP}, ${RECON_WORKGROUP})
|
|
632
|
+
fn sharpenMain(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
633
|
+
if (id.x >= recon.outputSize.x || id.y >= recon.outputSize.y) { return; }
|
|
634
|
+
let value = reconSharpenAt(i32(id.x), i32(id.y));
|
|
635
|
+
let at = (id.y * recon.outputSize.x + id.x) * 3u;
|
|
636
|
+
output[at] = value.x;
|
|
637
|
+
output[at + 1u] = value.y;
|
|
638
|
+
output[at + 2u] = value.z;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/*
|
|
642
|
+
* The rounding rule on its own, over a sweep that includes every exact half in the range.
|
|
643
|
+
*
|
|
644
|
+
* **A corpus cannot reach this.** The value the resolve rounds is a half only where the geometry
|
|
645
|
+
* puts it exactly on one, and there an f32 shader and an f64 reference land on opposite sides of
|
|
646
|
+
* the tie for reasons that have nothing to do with the tie-break rule. So the rule is checked where
|
|
647
|
+
* the two precisions agree about the input and can only differ about the answer.
|
|
648
|
+
*/
|
|
649
|
+
@compute @workgroup_size(${RECON_WORKGROUP})
|
|
650
|
+
fn roundMain(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
651
|
+
output[id.x] = reconRound(f32(id.x) * 0.5 - 8.0);
|
|
652
|
+
}
|
|
653
|
+
`;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* The production module: the core over the renderer's own attachments.
|
|
658
|
+
*
|
|
659
|
+
* **Three things differ from the check, and all three are in the accessors.** The depth textures
|
|
660
|
+
* hold the renderer's reversed depth, which `wgslSceneDepthToNdc` turns into the sense the matrices
|
|
661
|
+
* were built for — the resolve picks the *nearest* of nine depths, and under reversed-Z the nearest
|
|
662
|
+
* is the largest, so an unconverted accessor would dilate the motion of the furthest surface at
|
|
663
|
+
* every silhouette. A texture's row 0 is the top one and the reference's images run from `v = 0`
|
|
664
|
+
* upward, so every accessor mirrors the row. And the bilinear reads are the sampler's, which is
|
|
665
|
+
* what makes the five-tap form cheaper than the sixteen.
|
|
666
|
+
*/
|
|
667
|
+
export function reconResolveWgsl(): string {
|
|
668
|
+
return /* wgsl */ `
|
|
669
|
+
@group(0) @binding(0) var sceneTexture: texture_2d<f32>;
|
|
670
|
+
@group(0) @binding(1) var depthTexture: texture_2d<f32>;
|
|
671
|
+
@group(0) @binding(2) var motionTexture: texture_2d<f32>;
|
|
672
|
+
@group(0) @binding(3) var previousDepthTexture: texture_2d<f32>;
|
|
673
|
+
@group(0) @binding(4) var historyTexture: texture_2d<f32>;
|
|
674
|
+
@group(0) @binding(5) var linearSampler: sampler;
|
|
675
|
+
${RECON_PARAMS_WGSL}
|
|
676
|
+
@group(0) @binding(6) var<uniform> recon: ReconParams;
|
|
677
|
+
@group(0) @binding(7) var resolved: texture_storage_2d<rgba16float, write>;
|
|
678
|
+
/* Not "target": it is a reserved keyword in WGSL, as "meta" was in the cluster cull. */
|
|
679
|
+
|
|
680
|
+
/* Rows flip here: the reference's row 0 is the bottom one and a texture's is the top. */
|
|
681
|
+
fn reconRenderRow(y: i32) -> i32 {
|
|
682
|
+
return i32(recon.renderSize.y) - 1 - y;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
fn reconOutputRow(y: i32) -> i32 {
|
|
686
|
+
return i32(recon.outputSize.y) - 1 - y;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
fn reconScene(x: i32, y: i32) -> vec3<f32> {
|
|
690
|
+
return textureLoad(sceneTexture, vec2<i32>(x, reconRenderRow(y)), 0).xyz;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
fn reconDepth(x: i32, y: i32) -> f32 {
|
|
694
|
+
let stored = textureLoad(depthTexture, vec2<i32>(x, reconRenderRow(y)), 0).x;
|
|
695
|
+
return ${wgslSceneDepthToNdc('stored')};
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
fn reconPreviousDepth(x: i32, y: i32) -> f32 {
|
|
699
|
+
let stored = textureLoad(previousDepthTexture, vec2<i32>(x, reconRenderRow(y)), 0).x;
|
|
700
|
+
return ${wgslSceneDepthToNdc('stored')};
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
fn reconMotion(x: i32, y: i32) -> vec4<f32> {
|
|
704
|
+
return textureLoad(motionTexture, vec2<i32>(x, reconRenderRow(y)), 0);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
fn reconHistory(x: i32, y: i32) -> vec4<f32> {
|
|
708
|
+
return textureLoad(historyTexture, vec2<i32>(x, reconOutputRow(y)), 0);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/* A texel coordinate becomes the uv of its centre, with the row taken from the other end. */
|
|
712
|
+
fn reconSceneBilinear(p: vec2<f32>) -> vec3<f32> {
|
|
713
|
+
let size = vec2<f32>(f32(recon.renderSize.x), f32(recon.renderSize.y));
|
|
714
|
+
let uv = vec2<f32>(p.x + 0.5, size.y - 0.5 - p.y) / size;
|
|
715
|
+
return textureSampleLevel(sceneTexture, linearSampler, uv, 0.0).xyz;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
fn reconHistoryBilinear(p: vec2<f32>) -> vec4<f32> {
|
|
719
|
+
let size = vec2<f32>(f32(recon.outputSize.x), f32(recon.outputSize.y));
|
|
720
|
+
let uv = vec2<f32>(p.x + 0.5, size.y - 0.5 - p.y) / size;
|
|
721
|
+
return textureSampleLevel(historyTexture, linearSampler, uv, 0.0);
|
|
722
|
+
}
|
|
723
|
+
${RECON_RESOLVE_CORE_WGSL}
|
|
724
|
+
|
|
725
|
+
@compute @workgroup_size(${RECON_WORKGROUP}, ${RECON_WORKGROUP})
|
|
726
|
+
fn resolveMain(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
727
|
+
if (id.x >= recon.outputSize.x || id.y >= recon.outputSize.y) { return; }
|
|
728
|
+
let y = i32(recon.outputSize.y) - 1 - i32(id.y);
|
|
729
|
+
let value = reconResolvePixel(i32(id.x), y);
|
|
730
|
+
textureStore(resolved, vec2<i32>(i32(id.x), i32(id.y)), value);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
@compute @workgroup_size(${RECON_WORKGROUP}, ${RECON_WORKGROUP})
|
|
734
|
+
fn sharpenMain(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
735
|
+
if (id.x >= recon.outputSize.x || id.y >= recon.outputSize.y) { return; }
|
|
736
|
+
let y = i32(recon.outputSize.y) - 1 - i32(id.y);
|
|
737
|
+
let value = reconSharpenAt(i32(id.x), y);
|
|
738
|
+
textureStore(resolved, vec2<i32>(i32(id.x), i32(id.y)), vec4<f32>(value, 1.0));
|
|
739
|
+
}
|
|
740
|
+
`;
|
|
741
|
+
}
|