From a8b06ccff13d4bbbca0b1c1e0cbe07edbc59f448 Mon Sep 17 00:00:00 2001
From: Alexander Gauggel <agauggel@uni-koblenz.de>
Date: Sat, 21 Aug 2021 20:28:13 +0200
Subject: [PATCH] [#106] Add option to disable motion blur and color copy
 shader to prepare for per tile optimization

---
 .../shaders/motionBlurColorCopy.comp          | 20 ++++++++
 projects/indirect_dispatch/src/App.cpp        |  8 +++
 projects/indirect_dispatch/src/MotionBlur.cpp | 50 ++++++++++++++++---
 projects/indirect_dispatch/src/MotionBlur.hpp | 20 ++++++--
 4 files changed, 86 insertions(+), 12 deletions(-)
 create mode 100644 projects/indirect_dispatch/resources/shaders/motionBlurColorCopy.comp

diff --git a/projects/indirect_dispatch/resources/shaders/motionBlurColorCopy.comp b/projects/indirect_dispatch/resources/shaders/motionBlurColorCopy.comp
new file mode 100644
index 00000000..890b814e
--- /dev/null
+++ b/projects/indirect_dispatch/resources/shaders/motionBlurColorCopy.comp
@@ -0,0 +1,20 @@
+#version 440
+#extension GL_GOOGLE_include_directive : enable
+#include "motionBlurConfig.inc"
+
+layout(set=0, binding=0)                    uniform texture2D   inColor;
+layout(set=0, binding=1)                    uniform sampler     nearestSampler;
+layout(set=0, binding=2, r11f_g11f_b10f)    uniform image2D     outImage;
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+void main(){
+
+    if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage))))
+        return;
+   
+    ivec2   coord = ivec2(gl_GlobalInvocationID.xy);
+    vec3    color = texelFetch(sampler2D(inColor, nearestSampler), coord, 0).rgb;
+    
+    imageStore(outImage, coord, vec4(color, 0.f));
+}
\ No newline at end of file
diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp
index 3cfc39d7..2b46be6b 100644
--- a/projects/indirect_dispatch/src/App.cpp
+++ b/projects/indirect_dispatch/src/App.cpp
@@ -95,6 +95,7 @@ void App::run() {
 
 	eMotionVectorVisualisationMode  motionVectorVisualisationMode   = eMotionVectorVisualisationMode::None;
 	eMotionVectorMode               motionBlurMotionMode            = eMotionVectorMode::MaxTileNeighbourhood;
+    eMotionBlurMode                 motionBlurMode                  = eMotionBlurMode::Default;
 
 	bool    freezeFrame                     = false;
 	float   motionBlurTileOffsetLength      = 3;
@@ -299,6 +300,7 @@ void App::run() {
 				m_renderTargets.colorBuffer,
 				m_renderTargets.depthBuffer,
 				motionBlurMotionMode,
+				motionBlurMode,
 				cameraNear,
 				cameraFar,
 				fDeltaTimeSeconds,
@@ -360,6 +362,12 @@ void App::run() {
 		ImGui::Checkbox("Freeze frame", &freezeFrame);
 		ImGui::InputFloat("Motion tile offset length", &motionBlurTileOffsetLength);
 
+		ImGui::Combo(
+			"Motion blur mode",
+			reinterpret_cast<int*>(&motionBlurMode),
+			MotionBlurModeLabels,
+			static_cast<int>(eMotionBlurMode::OptionCount));
+
 		ImGui::Combo(
 			"Debug view",
 			reinterpret_cast<int*>(&motionVectorVisualisationMode),
diff --git a/projects/indirect_dispatch/src/MotionBlur.cpp b/projects/indirect_dispatch/src/MotionBlur.cpp
index 35085dc7..3a8594f6 100644
--- a/projects/indirect_dispatch/src/MotionBlur.cpp
+++ b/projects/indirect_dispatch/src/MotionBlur.cpp
@@ -39,6 +39,9 @@ bool MotionBlur::initialize(vkcv::Core* corePtr, const uint32_t targetWidth, con
 	if (!loadComputePass(*m_core, "resources/shaders/motionBlurIndirectArguments.comp", &m_indirectArgumentPass))
 		return false;
 
+	if (!loadComputePass(*m_core, "resources/shaders/motionBlurColorCopy.comp", &m_colorCopyPass))
+		return false;
+
 	m_indirectArgumentBuffer = m_core->createBuffer<uint32_t>(vkcv::BufferType::STORAGE, 3, vkcv::BufferMemoryType::DEVICE_LOCAL, true).getHandle();
 
 	vkcv::DescriptorWrites indirectArgumentDescriptorWrites;
@@ -67,6 +70,7 @@ vkcv::ImageHandle MotionBlur::render(
 	const vkcv::ImageHandle         colorBuffer,
 	const vkcv::ImageHandle         depthBuffer,
 	const eMotionVectorMode         motionVectorMode,
+	const eMotionBlurMode           mode,
 	const float                     cameraNear,
 	const float                     cameraFar,
 	const float                     deltaTimeSeconds,
@@ -121,6 +125,17 @@ vkcv::ImageHandle MotionBlur::render(
 
 	m_core->writeDescriptorSet(m_motionBlurPass.descriptorSet, motionBlurDescriptorWrites);
 
+
+	vkcv::DescriptorWrites colorCopyDescriptorWrites;
+	colorCopyDescriptorWrites.sampledImageWrites = {
+		vkcv::SampledImageDescriptorWrite(0, colorBuffer) };
+	colorCopyDescriptorWrites.samplerWrites = {
+		vkcv::SamplerDescriptorWrite(1, m_nearestSampler) };
+	colorCopyDescriptorWrites.storageImageWrites = {
+		vkcv::StorageImageDescriptorWrite(2, m_renderTargets.outputColor) };
+
+	m_core->writeDescriptorSet(m_colorCopyPass.descriptorSet, colorCopyDescriptorWrites);
+
 	// must match layout in "motionBlur.comp"
 	struct MotionBlurConstantData {
 		float motionFactor;
@@ -145,13 +160,34 @@ vkcv::ImageHandle MotionBlur::render(
 	m_core->prepareImageForSampling(cmdStream, depthBuffer);
 	m_core->prepareImageForSampling(cmdStream, inputMotionTiles);
 
-	m_core->recordComputeIndirectDispatchToCmdStream(
-		cmdStream,
-		m_motionBlurPass.pipeline,
-		m_indirectArgumentBuffer,
-		0,
-		{ vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_motionBlurPass.descriptorSet).vulkanHandle) },
-		motionBlurPushConstants);
+	if (mode == eMotionBlurMode::Default) {
+		m_core->recordComputeIndirectDispatchToCmdStream(
+			cmdStream,
+			m_motionBlurPass.pipeline,
+			m_indirectArgumentBuffer,
+			0,
+			{ vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_motionBlurPass.descriptorSet).vulkanHandle) },
+			motionBlurPushConstants);
+	}
+	else if(mode == eMotionBlurMode::Disabled) {
+		m_core->recordComputeIndirectDispatchToCmdStream(
+			cmdStream,
+			m_colorCopyPass.pipeline,
+			m_indirectArgumentBuffer,
+			0,
+			{ vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_colorCopyPass.descriptorSet).vulkanHandle) },
+			vkcv::PushConstants(0));
+	}
+	else {
+		vkcv_log(vkcv::LogLevel::ERROR, "Unknown eMotionBlurMode enum option");
+		m_core->recordComputeIndirectDispatchToCmdStream(
+			cmdStream,
+			m_colorCopyPass.pipeline,
+			m_indirectArgumentBuffer,
+			0,
+			{ vkcv::DescriptorSetUsage(0, m_core->getDescriptorSet(m_colorCopyPass.descriptorSet).vulkanHandle) },
+			vkcv::PushConstants(0));
+	}
 
 	return m_renderTargets.outputColor;
 }
diff --git a/projects/indirect_dispatch/src/MotionBlur.hpp b/projects/indirect_dispatch/src/MotionBlur.hpp
index 7fede9d9..0158f328 100644
--- a/projects/indirect_dispatch/src/MotionBlur.hpp
+++ b/projects/indirect_dispatch/src/MotionBlur.hpp
@@ -5,17 +5,25 @@
 
 // selection for motion blur input and visualisation
 enum class eMotionVectorMode : int {
-	FullResolution = 0,
-	MaxTile = 1,
-	MaxTileNeighbourhood = 2,
-	OptionCount = 3
-};
+	FullResolution          = 0,
+	MaxTile                 = 1,
+	MaxTileNeighbourhood    = 2,
+	OptionCount             = 3 };
 
 static const char* MotionVectorModeLabels[3] = {
 	"Full resolution",
 	"Max tile",
 	"Tile neighbourhood max" };
 
+enum class eMotionBlurMode : int {
+	Default     = 0,
+	Disabled    = 1,
+	OptionCount = 2 };
+
+static const char* MotionBlurModeLabels[2] = {
+	"Default",
+	"Disabled" };
+
 class MotionBlur {
 public:
 
@@ -28,6 +36,7 @@ public:
 		const vkcv::ImageHandle         colorBuffer,
 		const vkcv::ImageHandle         depthBuffer,
 		const eMotionVectorMode         motionVectorMode,
+		const eMotionBlurMode           mode,
 		const float                     cameraNear,
 		const float                     cameraFar,
 		const float                     deltaTimeSeconds,
@@ -56,6 +65,7 @@ private:
 	ComputePassHandles m_motionVectorMaxNeighbourhoodPass;
 	ComputePassHandles m_motionVectorVisualisationPass;
 	ComputePassHandles m_indirectArgumentPass;
+	ComputePassHandles m_colorCopyPass;
 
 	vkcv::BufferHandle m_indirectArgumentBuffer;
 };
\ No newline at end of file
-- 
GitLab