diff --git a/projects/indirect_dispatch/resources/shaders/motionBlur.comp b/projects/indirect_dispatch/resources/shaders/motionBlur.comp
index 9fa4f97cc3c00d32dd06aa22d564b858074a78ee..091c21aa7ddfe9db1780aa64adc77fd5457a3843 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 e2967baccfbf187939919550c3a9a6b9a05563f7..2e27ebedcc4be1da93ff89a187fe1d3e992e8d22 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 0fac23895342bc0ee5e475da5534898c76c37b0f..1cfb09c87e8288b8ea80c6ddfbe5f0d4918b7f2e 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 92d548acde9c5a27e69c6daf4d92ca1da9d50a2c..c9fabd0f792f6570a66c86be293df2aaa1290c9b 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 b3cf6df82b2678d4a8fb0281cf4c712e2442fa31..49f650a97e2fea5821959ae53f468e6fe7de6ffe 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;