From 3d19a3cd561cda7263d55808b5dc3c3b28d2da5c Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Wed, 18 Aug 2021 12:06:56 +0200 Subject: [PATCH] [#106] Adjusted velocity clamping, removed manual settings for min velocity and motion blur delta time limit --- .../resources/shaders/motionBlur.comp | 20 ++++++++++--------- projects/indirect_dispatch/src/App.cpp | 7 ++----- projects/indirect_dispatch/src/MotionBlur.cpp | 7 ++----- projects/indirect_dispatch/src/MotionBlur.hpp | 3 +-- .../src/MotionBlurConfig.hpp | 8 +------- 5 files changed, 17 insertions(+), 28 deletions(-) diff --git a/projects/indirect_dispatch/resources/shaders/motionBlur.comp b/projects/indirect_dispatch/resources/shaders/motionBlur.comp index 58f95854..43981689 100644 --- a/projects/indirect_dispatch/resources/shaders/motionBlur.comp +++ b/projects/indirect_dispatch/resources/shaders/motionBlur.comp @@ -12,8 +12,8 @@ layout(set=0, binding=5, 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 motionScaleFactor; // computed from delta time and shutter speed - float minVelocity; + // computed from delta time and shutter speed + float motionScaleFactor; // camera planes are needed to linearize depth float cameraNearPlane; float cameraFarPlane; @@ -76,12 +76,14 @@ vec2 processMotionVector(vec2 motion){ vec2 motionHalf = motion * 0.5; vec2 motionScaled = motionHalf * motionScaleFactor; // scale factor contains shutter speed and delta time - // pixels are anisotropic so the smaller dimension is used, so the clamping is conservative - float pixelSize = 1.f / max(imageSize(outImage).x, imageSize(outImage).y); - float velocity = length(motionScaled); - float epsilon = 0.0001; + float velocityPixels = length(motionScaled * imageSize(outImage)); + float epsilon = 0.0001; + + // pixels are anisotropic, so the ratio for clamping the velocity is computed in pixels instead of uv coordinates + vec2 motionPixel = motionScaled * imageSize(outImage); + // this clamps the motion to not exceed the radius given by the motion tile size - return motionScaled * max(0.5 * pixelSize, min(velocity, motionTileSize * pixelSize)) / (velocity + epsilon); + return motionScaled * max(0.5, min(velocityPixels, motionTileSize)) / (velocityPixels + epsilon); } SampleData loadSampleData(vec2 uv){ @@ -122,8 +124,8 @@ void main(){ SampleData mainPixel = loadSampleData(uv); - // early out on little movement - if(length(motionNeighbourhoodMax) <= minVelocity){ + // early out on movement less than half a pixel + if(length(motionNeighbourhoodMax * imageSize(outImage)) <= 0.5){ imageStore(outImage, coord, vec4(mainPixel.color, 0.f)); return; } diff --git a/projects/indirect_dispatch/src/App.cpp b/projects/indirect_dispatch/src/App.cpp index 60c3a075..b27798b6 100644 --- a/projects/indirect_dispatch/src/App.cpp +++ b/projects/indirect_dispatch/src/App.cpp @@ -94,7 +94,6 @@ void App::run() { float objectVerticalSpeed = 5; float objectAmplitude = 1; float objectMeanHeight = 1; - float motionBlurMinVelocity = 0.001; int cameraShutterSpeedInverse = 24; float motionVectorVisualisationRange = 0.008; @@ -114,7 +113,7 @@ void App::run() { sceneObjects.push_back(ground); Object sphere; - sphere.meshResources = m_sphereMesh; + sphere.meshResources = m_cubeMesh; sphere.modelMatrixUpdate = [&](float time, Object& obj) { const float currentHeight = objectMeanHeight + objectAmplitude * glm::sin(time * objectVerticalSpeed); obj.modelMatrix = glm::translate(glm::mat4(1), glm::vec3(0, currentHeight, 0)); @@ -249,8 +248,7 @@ void App::run() { cameraNear, cameraFar, fDeltaTimeSeconds, - cameraShutterSpeedInverse, - motionBlurMinVelocity); + cameraShutterSpeedInverse); } else { eMotionVectorMode debugViewMode; @@ -320,7 +318,6 @@ void App::run() { static_cast<int>(eMotionVectorMode::OptionCount)); ImGui::InputInt("Camera shutter speed inverse", &cameraShutterSpeedInverse); - ImGui::DragFloat("Motion blur min velocity", &motionBlurMinVelocity, 0.01, 0, 1); ImGui::InputFloat("Object movement speed", &objectVerticalSpeed); ImGui::InputFloat("Object movement amplitude", &objectAmplitude); diff --git a/projects/indirect_dispatch/src/MotionBlur.cpp b/projects/indirect_dispatch/src/MotionBlur.cpp index cc1bbc82..a731b8b9 100644 --- a/projects/indirect_dispatch/src/MotionBlur.cpp +++ b/projects/indirect_dispatch/src/MotionBlur.cpp @@ -58,8 +58,7 @@ vkcv::ImageHandle MotionBlur::render( const float cameraNear, const float cameraFar, const float deltaTimeSeconds, - const float cameraShutterSpeedInverse, - const float motionBlurMinVelocity) { + const float cameraShutterSpeedInverse) { computeMotionTiles(cmdStream, motionBufferFullRes); @@ -92,16 +91,14 @@ vkcv::ImageHandle MotionBlur::render( // must match layout in "motionBlur.comp" struct MotionBlurConstantData { float motionFactor; - float minVelocity; float cameraNearPlane; float cameraFarPlane; }; MotionBlurConstantData motionBlurConstantData; - const float deltaTimeMotionBlur = std::max(deltaTimeSeconds, MotionBlurConfig::timeScaleMax); + const float deltaTimeMotionBlur = deltaTimeSeconds; motionBlurConstantData.motionFactor = 1 / (deltaTimeMotionBlur * cameraShutterSpeedInverse); - motionBlurConstantData.minVelocity = motionBlurMinVelocity; motionBlurConstantData.cameraNearPlane = cameraNear; motionBlurConstantData.cameraFarPlane = cameraFar; diff --git a/projects/indirect_dispatch/src/MotionBlur.hpp b/projects/indirect_dispatch/src/MotionBlur.hpp index ba72ea64..a6232125 100644 --- a/projects/indirect_dispatch/src/MotionBlur.hpp +++ b/projects/indirect_dispatch/src/MotionBlur.hpp @@ -31,8 +31,7 @@ public: const float cameraNear, const float cameraFar, const float deltaTimeSeconds, - const float cameraShutterSpeedInverse, - const float motionBlurMinVelocity); + const float cameraShutterSpeedInverse); vkcv::ImageHandle renderMotionVectorVisualisation( const vkcv::CommandStreamHandle cmdStream, diff --git a/projects/indirect_dispatch/src/MotionBlurConfig.hpp b/projects/indirect_dispatch/src/MotionBlurConfig.hpp index ecd7f8f8..bdeb8acf 100644 --- a/projects/indirect_dispatch/src/MotionBlurConfig.hpp +++ b/projects/indirect_dispatch/src/MotionBlurConfig.hpp @@ -4,11 +4,5 @@ namespace MotionBlurConfig { const vk::Format motionVectorTileFormat = vk::Format::eR16G16Sfloat; const vk::Format outputColorFormat = vk::Format::eB10G11R11UfloatPack32; - const uint32_t maxMotionTileSize = 20; // must match "motionTileSize" in motionVectorMax.comp - - // small mouse movements are restricted to pixel level and therefore quite unprecise - // therefore extrapolating movement at high framerates results in big jerky movements - // this results in wide sudden motion blur, which looks quite bad - // as a workaround the time scale is limited to a maximum value - const float timeScaleMax = 1.f / 60; + const uint32_t maxMotionTileSize = 20; // must match "motionTileSize" in motionBlurConfig.inc } \ No newline at end of file -- GitLab