diff --git a/projects/indirect_dispatch/resources/shaders/motionBlurColorCopy.comp b/projects/indirect_dispatch/resources/shaders/motionBlurColorCopy.comp new file mode 100644 index 0000000000000000000000000000000000000000..890b814e0feadb646971148978d1b91952904ca9 --- /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 3cfc39d747a550a6af921ce6805e8ebdc90c4560..2b46be6b914b36160cb25bf89fda7cc6fc5414c2 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 35085dc74697f4424d77a571bd4fc438e2d12a27..3a8594f68871139ce3eeb7d9e3d8ec2fb1058dcd 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 7fede9d9557548e9125554510b465e0c8ed6e660..0158f328e82895d462d3dd87f82de60e5aee1052 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