From d3c4a125845cc1d5767bd86e11ba23c64b70ec89 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Fri, 20 Aug 2021 17:28:55 +0200 Subject: [PATCH] [#106] Replace motion tile offset noise with unaligned dither for less visible noise --- .../resources/shaders/motionBlur.comp | 23 ++++--------------- projects/indirect_dispatch/src/App.cpp | 2 +- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/projects/indirect_dispatch/resources/shaders/motionBlur.comp b/projects/indirect_dispatch/resources/shaders/motionBlur.comp index 804c0ceb..503a7afa 100644 --- a/projects/indirect_dispatch/resources/shaders/motionBlur.comp +++ b/projects/indirect_dispatch/resources/shaders/motionBlur.comp @@ -113,34 +113,18 @@ SampleData loadSampleData(vec2 uv){ return data; } +const int ditherSize = 4; + // simple binary dither pattern // could be optimized to avoid modulo and branch float dither(ivec2 coord){ - int ditherSize = 4; - bool x = coord.x % ditherSize < (ditherSize / 2); bool y = coord.y % ditherSize < (ditherSize / 2); return x ^^ y ? 1 : 0; } -// from https://www.shadertoy.com/view/ttc3zr -uvec2 murmurHash22(uvec2 src) { - const uint M = 0x5bd1e995u; - uvec2 h = uvec2(1190494759u, 2147483647u); - src *= M; src ^= src>>24u; src *= M; - h *= M; h ^= src.x; h *= M; h ^= src.y; - h ^= h>>13u; h *= M; h ^= h>>15u; - return h; -} - -vec2 hash22(vec2 src) { - uvec2 h = murmurHash22(floatBitsToUint(src)); - return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0; -} - - void main(){ if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))) @@ -151,7 +135,8 @@ void main(){ vec2 uv = vec2(coord + 0.5) / textureRes; // + 0.5 to shift uv into pixel center // the motion tile lookup is jittered, so the hard edges in the blur are replaced by noise - vec2 motionOffset = motionTileOffsetLength * (hash22(coord) * 2 - 1) / textureRes; + // dither is shifted, so it does not line up with motion tiles + vec2 motionOffset = motionTileOffsetLength * (dither(coord + ivec2(ditherSize / 2)) * 2 - 1) / textureRes; vec2 motionNeighbourhoodMax = processMotionVector(texture(sampler2D(inMotionNeighbourhoodMax, nearestSampler), uv + motionOffset).rg); SampleData mainPixel = loadSampleData(uv); diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp index 230ef92c..cc7bff04 100644 --- a/projects/indirect_dispatch/src/App.cpp +++ b/projects/indirect_dispatch/src/App.cpp @@ -97,7 +97,7 @@ void App::run() { eMotionVectorMode motionBlurMotionMode = eMotionVectorMode::MaxTileNeighbourhood; bool freezeFrame = false; - float motionBlurTileOffsetLength = 10; + float motionBlurTileOffsetLength = 3; float objectVerticalSpeed = 5; float objectAmplitude = 0; float objectMeanHeight = 1; -- GitLab