From b45b32034344a19a0f4f07f2bc9ff207c72a2078 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Sun, 22 Aug 2021 16:51:42 +0200 Subject: [PATCH] [#106] Fixed minor artifacts due to incorrect motion tile lookup --- .../resources/shaders/motionBlur.comp | 4 ++-- .../resources/shaders/motionBlurFastPath.comp | 2 +- .../resources/shaders/motionVectorVisualisation.comp | 7 ++++--- projects/indirect_dispatch/src/App.cpp | 2 +- projects/indirect_dispatch/src/MotionBlur.cpp | 11 ++++++++++- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/projects/indirect_dispatch/resources/shaders/motionBlur.comp b/projects/indirect_dispatch/resources/shaders/motionBlur.comp index 9fa4f97c..091c21aa 100644 --- a/projects/indirect_dispatch/resources/shaders/motionBlur.comp +++ b/projects/indirect_dispatch/resources/shaders/motionBlur.comp @@ -117,8 +117,8 @@ void main(){ // the motion tile lookup is jittered, so the hard edges in the blur are replaced by noise // 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, motionScaleFactor, imageSize(outImage)); + float motionOffset = motionTileOffsetLength * (dither(coord + ivec2(ditherSize / 2)) * 2 - 1); + vec2 motionNeighbourhoodMax = processMotionVector(texelFetch(sampler2D(inMotionNeighbourhoodMax, nearestSampler), ivec2(coord + motionOffset) / motionTileSize, 0).rg, motionScaleFactor, imageSize(outImage)); SampleData mainPixel = loadSampleData(uv); diff --git a/projects/indirect_dispatch/resources/shaders/motionBlurFastPath.comp b/projects/indirect_dispatch/resources/shaders/motionBlurFastPath.comp index e2967bac..2e27ebed 100644 --- a/projects/indirect_dispatch/resources/shaders/motionBlurFastPath.comp +++ b/projects/indirect_dispatch/resources/shaders/motionBlurFastPath.comp @@ -33,7 +33,7 @@ void main(){ ivec2 textureRes = textureSize(sampler2D(inColor, nearestSampler), 0); vec2 uv = vec2(coord + 0.5) / textureRes; // + 0.5 to shift uv into pixel center - vec2 motionNeighbourhoodMax = processMotionVector(texture(sampler2D(inMotionNeighbourhoodMax, nearestSampler), uv).rg, motionScaleFactor, imageSize(outImage)); + vec2 motionNeighbourhoodMax = processMotionVector(texelFetch(sampler2D(inMotionNeighbourhoodMax, nearestSampler), coord / motionTileSize, 0).rg, motionScaleFactor, imageSize(outImage)); // early out on movement less than half a pixel if(length(motionNeighbourhoodMax * imageSize(outImage)) <= 0.5){ diff --git a/projects/indirect_dispatch/resources/shaders/motionVectorVisualisation.comp b/projects/indirect_dispatch/resources/shaders/motionVectorVisualisation.comp index 0fac2389..1cfb09c8 100644 --- a/projects/indirect_dispatch/resources/shaders/motionVectorVisualisation.comp +++ b/projects/indirect_dispatch/resources/shaders/motionVectorVisualisation.comp @@ -1,6 +1,8 @@ #version 440 #extension GL_GOOGLE_include_directive : enable +#include "motionBlurConfig.inc" + layout(set=0, binding=0) uniform texture2D inMotion; layout(set=0, binding=1) uniform sampler textureSampler; layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D outImage; @@ -18,9 +20,8 @@ void main(){ if(any(greaterThanEqual(coord, outImageRes))) return; - - vec2 uv = vec2(coord) / outImageRes; - vec2 motionVector = texture(sampler2D(inMotion, textureSampler), uv).rg; + + vec2 motionVector = texelFetch(sampler2D(inMotion, textureSampler), coord / motionTileSize, 0).rg; vec2 motionVectorNormalized = clamp(motionVector / range, -1, 1); vec2 color = motionVectorNormalized * 0.5 + 0.5; diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp index 92d548ac..c9fabd0f 100644 --- a/projects/indirect_dispatch/src/App.cpp +++ b/projects/indirect_dispatch/src/App.cpp @@ -92,7 +92,7 @@ void App::run() { float objectRotationSpeedY = 5; int cameraShutterSpeedInverse = 24; float motionVectorVisualisationRange = 0.008; - float motionBlurFastPathThreshold = 1; + float motionBlurFastPathThreshold = 2; glm::mat4 viewProjection = m_cameraManager.getActiveCamera().getMVP(); glm::mat4 viewProjectionPrevious = m_cameraManager.getActiveCamera().getMVP(); diff --git a/projects/indirect_dispatch/src/MotionBlur.cpp b/projects/indirect_dispatch/src/MotionBlur.cpp index b3cf6df8..49f650a9 100644 --- a/projects/indirect_dispatch/src/MotionBlur.cpp +++ b/projects/indirect_dispatch/src/MotionBlur.cpp @@ -234,6 +234,15 @@ vkcv::ImageHandle MotionBlur::render( vkcv::PushConstants motionBlurPushConstants(sizeof(motionBlurConstantData)); motionBlurPushConstants.appendDrawcall(motionBlurConstantData); + struct FastPathConstants { + float motionFactor; + }; + FastPathConstants fastPathConstants; + fastPathConstants.motionFactor = motionBlurConstantData.motionFactor; + + vkcv::PushConstants fastPathPushConstants(sizeof(FastPathConstants)); + fastPathPushConstants.appendDrawcall(fastPathConstants); + m_core->prepareImageForStorage(cmdStream, m_renderTargets.outputColor); m_core->prepareImageForSampling(cmdStream, colorBuffer); m_core->prepareImageForSampling(cmdStream, depthBuffer); @@ -262,7 +271,7 @@ vkcv::ImageHandle MotionBlur::render( m_fastPathWorkTileBuffer, 0, { vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_motionBlurFastPathPass.descriptorSet).vulkanHandle) }, - vkcv::PushConstants(0)); + fastPathPushConstants); } else if(mode == eMotionBlurMode::Disabled) { return colorBuffer; -- GitLab