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