From eb723db1c4c51049c7c858b29734627267aab60c Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Fri, 25 Jun 2021 11:38:28 +0200 Subject: [PATCH] [#82] Stabilize shadows --- projects/voxelization/src/ShadowMapping.cpp | 25 +++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/projects/voxelization/src/ShadowMapping.cpp b/projects/voxelization/src/ShadowMapping.cpp index 9c81aa09..051d0673 100644 --- a/projects/voxelization/src/ShadowMapping.cpp +++ b/projects/voxelization/src/ShadowMapping.cpp @@ -1,6 +1,11 @@ #include "ShadowMapping.hpp" #include <vkcv/shader/GLSLCompiler.hpp> +const vk::Format shadowMapFormat = vk::Format::eR32G32B32A32Sfloat; +const vk::Format shadowMapDepthFormat = vk::Format::eD32Sfloat; +const uint32_t shadowMapResolution = 2048; +const vkcv::Multisampling msaa = vkcv::Multisampling::MSAA8X; + vkcv::ShaderProgram loadShadowShader() { vkcv::ShaderProgram shader; vkcv::shader::GLSLCompiler compiler; @@ -114,13 +119,20 @@ glm::mat4 computeShadowViewProjectionMatrix( getMinMaxView(viewFrustumCorners); getMinMaxView(voxelVolumeCorners); - glm::vec3 scale = glm::vec3(2) / (maxView - minView); - - // rotationaly invariant to avoid swimming when moving camera - scale = glm::vec3(glm::max(glm::max(scale.x, scale.y), scale.z)); + // rotationaly invariant to avoid shadow swimming when moving camera + // could potentially be wasteful, but guarantees stability, regardless of camera and voxel volume + glm::vec3 scale = glm::vec3(1.f / glm::max(far, voxelVolumeExtent)); glm::vec3 offset = -0.5f * (maxView + minView) * scale; + // snap to texel to avoid shadow swimming when moving + glm::vec2 offset2D = glm::vec2(offset); + glm::vec2 frustumExtent2D = glm::vec2(1) / glm::vec2(scale); + glm::vec2 texelSize = glm::vec2(frustumExtent2D / static_cast<float>(shadowMapResolution)); + offset2D = glm::ceil(offset2D / texelSize) * texelSize; + offset.x = offset2D.x; + offset.y = offset2D.y; + glm::mat4 crop(1); crop[0][0] = scale.x; crop[1][1] = scale.y; @@ -137,11 +149,6 @@ glm::mat4 computeShadowViewProjectionMatrix( return vulkanCorrectionMatrix * crop * view; } -const vk::Format shadowMapFormat = vk::Format::eR32G32B32A32Sfloat; -const vk::Format shadowMapDepthFormat = vk::Format::eD32Sfloat; -const uint32_t shadowMapResolution = 2048; -const vkcv::Multisampling msaa = vkcv::Multisampling::MSAA8X; - ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vertexLayout) : m_corePtr(corePtr), m_shadowMap(corePtr->createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1, true, true)), -- GitLab