From f59d2c33f5bcce1df0fd8bd2d90f727f8edfaefa Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Thu, 12 Aug 2021 16:37:46 +0200 Subject: [PATCH] [#106] Better motion vector visualisation --- .../resources/shaders/gammaCorrection.comp | 3 - .../shaders/motionVectorVisualisation.comp | 29 ++++++++ projects/indirect_dispatch/src/App.cpp | 71 ++++++++++++++----- projects/indirect_dispatch/src/App.hpp | 1 + 4 files changed, 83 insertions(+), 21 deletions(-) create mode 100644 projects/indirect_dispatch/resources/shaders/motionVectorVisualisation.comp diff --git a/projects/indirect_dispatch/resources/shaders/gammaCorrection.comp b/projects/indirect_dispatch/resources/shaders/gammaCorrection.comp index d1c3c049..7a6e129d 100644 --- a/projects/indirect_dispatch/resources/shaders/gammaCorrection.comp +++ b/projects/indirect_dispatch/resources/shaders/gammaCorrection.comp @@ -18,9 +18,6 @@ void main(){ vec2 uv = vec2(coord) / outImageRes; vec3 linearColor = texture(sampler2D(inTexture, textureSampler), uv).rgb; - // in case of motion vector visualisation negative values are possible - linearColor = abs(linearColor); - vec3 gammaCorrected = pow(linearColor, vec3(1 / 2.2)); imageStore(outImage, coord, vec4(gammaCorrected, 0.f)); diff --git a/projects/indirect_dispatch/resources/shaders/motionVectorVisualisation.comp b/projects/indirect_dispatch/resources/shaders/motionVectorVisualisation.comp new file mode 100644 index 00000000..0fac2389 --- /dev/null +++ b/projects/indirect_dispatch/resources/shaders/motionVectorVisualisation.comp @@ -0,0 +1,29 @@ +#version 440 +#extension GL_GOOGLE_include_directive : enable + +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; + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +layout( push_constant ) uniform constants{ + float range; +}; + +void main(){ + + ivec2 outImageRes = imageSize(outImage); + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + + if(any(greaterThanEqual(coord, outImageRes))) + return; + + vec2 uv = vec2(coord) / outImageRes; + vec2 motionVector = texture(sampler2D(inMotion, textureSampler), uv).rg; + vec2 motionVectorNormalized = clamp(motionVector / range, -1, 1); + + vec2 color = motionVectorNormalized * 0.5 + 0.5; + + imageStore(outImage, coord, vec4(color, 0.5, 0)); +} \ No newline at end of file diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp index 68ff0060..d3afc681 100644 --- a/projects/indirect_dispatch/src/App.cpp +++ b/projects/indirect_dispatch/src/App.cpp @@ -47,6 +47,9 @@ bool App::initialize() { if (!loadComputePass(m_core, "resources/shaders/motionVectorMaxNeighbourhood.comp", &m_motionVectorMaxNeighbourhoodPass)) return false; + if (!loadComputePass(m_core, "resources/shaders/motionVectorVisualisation.comp", &m_motionVectorVisualisationPass)) + return false; + if (!loadMesh(m_core, "resources/models/sphere.gltf", & m_sphereMesh)) return false; @@ -103,9 +106,10 @@ void App::run() { eDebugView debugView = eDebugView::None; eMotionBlurInput motionBlurInput = eMotionBlurInput::MotionVectorMaxTileNeighbourhood; - float objectVerticalSpeed = 0.005; - float motionBlurMinVelocity = 0.001; - int cameraShutterSpeedInverse = 30; + float objectVerticalSpeed = 0.005; + float motionBlurMinVelocity = 0.001; + int cameraShutterSpeedInverse = 30; + float motionVectorVisualisationRange = 0.008; glm::mat4 mvpPrevious = glm::mat4(1.f); glm::mat4 viewProjectionPrevious = m_cameraManager.getActiveCamera().getMVP(); @@ -301,24 +305,51 @@ void App::run() { { vkcv::DescriptorSetUsage(0, m_core.getDescriptorSet(m_motionBlurDummyPass.descriptorSet).vulkanHandle) }, motionBlurPushConstants); - // gamma correction - vkcv::ImageHandle gammaCorrectionInput; - if (debugView == eDebugView::None) - gammaCorrectionInput = m_renderTargets.motionBlurOutput; - else if (debugView == eDebugView::MotionVector) - gammaCorrectionInput = m_renderTargets.motionBuffer; - else if (debugView == eDebugView::MotionVectorMaxTile) - gammaCorrectionInput = m_renderTargets.motionMax; - else if (debugView == eDebugView::MotionVectorMaxTileNeighbourhood) - gammaCorrectionInput = m_renderTargets.motionMaxNeighbourhood; - else { - vkcv_log(vkcv::LogLevel::ERROR, "Unknown eDebugView enum value"); - gammaCorrectionInput = m_renderTargets.motionBlurOutput; + // motion vector debug visualisation + // writes to motion blur output + if (debugView != eDebugView::None) { + vkcv::ImageHandle visualisationInput; + if (debugView == eDebugView::MotionVector) + visualisationInput = m_renderTargets.motionBuffer; + else if (debugView == eDebugView::MotionVectorMaxTile) + visualisationInput = m_renderTargets.motionMax; + else if (debugView == eDebugView::MotionVectorMaxTileNeighbourhood) + visualisationInput = m_renderTargets.motionMaxNeighbourhood; + else { + vkcv_log(vkcv::LogLevel::ERROR, "Unknown eDebugView enum value"); + visualisationInput = m_renderTargets.motionBlurOutput; + } + + vkcv::DescriptorWrites motionVectorVisualisationDescriptorWrites; + motionVectorVisualisationDescriptorWrites.sampledImageWrites = { + vkcv::SampledImageDescriptorWrite(0, visualisationInput) }; + motionVectorVisualisationDescriptorWrites.samplerWrites = { + vkcv::SamplerDescriptorWrite(1, m_linearSampler) }; + motionVectorVisualisationDescriptorWrites.storageImageWrites = { + vkcv::StorageImageDescriptorWrite(2, m_renderTargets.motionBlurOutput) }; + + m_core.writeDescriptorSet( + m_motionVectorVisualisationPass.descriptorSet, + motionVectorVisualisationDescriptorWrites); + + m_core.prepareImageForSampling(cmdStream, visualisationInput); + m_core.prepareImageForStorage(cmdStream, m_renderTargets.motionBlurOutput); + + vkcv::PushConstants motionVectorVisualisationPushConstants(sizeof(float)); + motionVectorVisualisationPushConstants.appendDrawcall(motionVectorVisualisationRange); + + m_core.recordComputeDispatchToCmdStream( + cmdStream, + m_motionVectorVisualisationPass.pipeline, + fullScreenImageDispatch, + { vkcv::DescriptorSetUsage(0, m_core.getDescriptorSet(m_motionVectorVisualisationPass.descriptorSet).vulkanHandle) }, + motionVectorVisualisationPushConstants); } + // gamma correction vkcv::DescriptorWrites gammaCorrectionDescriptorWrites; gammaCorrectionDescriptorWrites.sampledImageWrites = { - vkcv::SampledImageDescriptorWrite(0, gammaCorrectionInput) }; + vkcv::SampledImageDescriptorWrite(0, m_renderTargets.motionBlurOutput) }; gammaCorrectionDescriptorWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, m_linearSampler) }; gammaCorrectionDescriptorWrites.storageImageWrites = { @@ -326,7 +357,7 @@ void App::run() { m_core.writeDescriptorSet(m_gammaCorrectionPass.descriptorSet, gammaCorrectionDescriptorWrites); - m_core.prepareImageForSampling(cmdStream, gammaCorrectionInput); + m_core.prepareImageForSampling(cmdStream, m_renderTargets.motionBlurOutput); m_core.prepareImageForStorage (cmdStream, swapchainInput); m_core.recordComputeDispatchToCmdStream( @@ -348,6 +379,10 @@ void App::run() { debugViewLabels, static_cast<int>(eDebugView::OptionCount)); + if (debugView != eDebugView::None) { + ImGui::InputFloat("Motion vector visualisation range", &motionVectorVisualisationRange); + } + ImGui::Combo( "Motion blur input", reinterpret_cast<int*>(&motionBlurInput), diff --git a/projects/indirect_dispatch/src/App.hpp b/projects/indirect_dispatch/src/App.hpp index 9bbdde94..5f4fd7eb 100644 --- a/projects/indirect_dispatch/src/App.hpp +++ b/projects/indirect_dispatch/src/App.hpp @@ -30,6 +30,7 @@ private: ComputePassHandles m_motionBlurDummyPass; ComputePassHandles m_motionVectorMaxPass; ComputePassHandles m_motionVectorMaxNeighbourhoodPass; + ComputePassHandles m_motionVectorVisualisationPass; RenderTargets m_renderTargets; vkcv::SamplerHandle m_linearSampler; -- GitLab