From b5f2879871b32cc098fa0dfa9794d82afe74506a Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Mon, 16 Aug 2021 23:14:16 +0200 Subject: [PATCH] [#106] Replaced motion blur noise with dither to reduce visible noise --- .../resources/shaders/motionBlur.comp | 28 +++++++++---------- .../shaders/motionVectorMaxNeighbourhood.comp | 2 -- projects/indirect_dispatch/src/App.cpp | 2 -- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/projects/indirect_dispatch/resources/shaders/motionBlur.comp b/projects/indirect_dispatch/resources/shaders/motionBlur.comp index 233947d1..62bae130 100644 --- a/projects/indirect_dispatch/resources/shaders/motionBlur.comp +++ b/projects/indirect_dispatch/resources/shaders/motionBlur.comp @@ -15,7 +15,6 @@ layout( push_constant ) uniform constants{ // camera planes are needed to linearize depth float cameraNearPlane; float cameraFarPlane; - float time; }; float linearizeDepth(float depth, float near, float far){ @@ -77,19 +76,16 @@ SampleData loadSampleData(vec2 uv){ return data; } -// simple hash/noise function from: https://www.shadertoy.com/view/ttc3zr -uint murmurHash12(uvec2 src) { - const uint M = 0x5bd1e995u; - uint h = 1190494759u; - 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; -} - -float hash12(vec2 src) { - uint h = murmurHash12(floatBitsToUint(src)); - return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0; +// 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; } void main(){ @@ -126,7 +122,9 @@ void main(){ vec2 uvEnd = clamp(uv + mainPixel.motion, 0, 1); // samples are placed evenly, but the entire filter is jittered - float random = hash12(uv + time) - 0.5; // in range [-0.5, 0.5] + // dither returns either 0 or 1 + // the sampleUV code expects an offset in range [-0.5, 0.5], so the dither is rescaled to a binary -0.25/0.25 + float random = dither(coord) * 0.5 - 0.25; for(int i = 0; i < sampleCount; i++){ vec2 sampleUV = mix(uvStart, uvEnd, (i + random + 1) / float(sampleCount + 1)); diff --git a/projects/indirect_dispatch/resources/shaders/motionVectorMaxNeighbourhood.comp b/projects/indirect_dispatch/resources/shaders/motionVectorMaxNeighbourhood.comp index 85d45235..90f9acce 100644 --- a/projects/indirect_dispatch/resources/shaders/motionVectorMaxNeighbourhood.comp +++ b/projects/indirect_dispatch/resources/shaders/motionVectorMaxNeighbourhood.comp @@ -7,8 +7,6 @@ layout(set=0, binding=2, rgba8) uniform image2D outMotionMaxNeighbourhood; layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -const int motionTileSize = 8; - void main(){ ivec2 outImageRes = imageSize(outMotionMaxNeighbourhood); diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp index 0856173a..02442423 100644 --- a/projects/indirect_dispatch/src/App.cpp +++ b/projects/indirect_dispatch/src/App.cpp @@ -305,7 +305,6 @@ void App::run() { float minVelocity; float cameraNearPlane; float cameraFarPlane; - float time; }; MotionBlurConstantData motionBlurConstantData; @@ -323,7 +322,6 @@ void App::run() { m_cameraManager.getActiveCamera().getNearFar(cameraNear, cameraFar); motionBlurConstantData.cameraNearPlane = cameraNear; motionBlurConstantData.cameraFarPlane = cameraFar; - motionBlurConstantData.time = fCurrentTime; vkcv::PushConstants motionBlurPushConstants(sizeof(motionBlurConstantData)); motionBlurPushConstants.appendDrawcall(motionBlurConstantData); -- GitLab