From 07f23c39a5ec7143f559cdba4a56920dc4bc7def Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Wed, 23 Jun 2021 10:31:07 +0200 Subject: [PATCH] [#82] EVSM prototype --- .../resources/shaders/lightInfo.inc | 2 +- .../resources/shaders/shadow.frag | 7 ++-- .../resources/shaders/shadowMapping.inc | 41 +++++++++++++++++-- projects/voxelization/src/ShadowMapping.cpp | 8 ++-- projects/voxelization/src/ShadowMapping.hpp | 4 +- projects/voxelization/src/main.cpp | 17 ++++---- 6 files changed, 60 insertions(+), 19 deletions(-) diff --git a/projects/voxelization/resources/shaders/lightInfo.inc b/projects/voxelization/resources/shaders/lightInfo.inc index ed7f8d8b..c0df6551 100644 --- a/projects/voxelization/resources/shaders/lightInfo.inc +++ b/projects/voxelization/resources/shaders/lightInfo.inc @@ -6,7 +6,7 @@ struct LightInfo{ vec3 sunColor; float sunStrength; mat4 lightMatrix; - float exponentialWarp; + vec2 warps; }; #endif // #ifndef LIGHT_INFO_INC \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/shadow.frag b/projects/voxelization/resources/shaders/shadow.frag index a0bc121d..83500f94 100644 --- a/projects/voxelization/resources/shaders/shadow.frag +++ b/projects/voxelization/resources/shaders/shadow.frag @@ -8,11 +8,12 @@ layout(set=0, binding=0) uniform LightInfoBuffer { LightInfo lightInfo; }; -layout(location = 0) out float outExponentialDepth; +layout(location = 0) out vec4 outMoments; layout(location = 0) in vec4 passPos; void main() { - float z = passPos.z / passPos.w; - outExponentialDepth = exp(z * lightInfo.exponentialWarp); + float z = passPos.z / passPos.w; + vec2 zWarped = applyDepthWarp(z, lightInfo.warps); + outMoments = vec4(zWarped, zWarped*zWarped); } \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/shadowMapping.inc b/projects/voxelization/resources/shaders/shadowMapping.inc index e0a218d5..91461c91 100644 --- a/projects/voxelization/resources/shaders/shadowMapping.inc +++ b/projects/voxelization/resources/shaders/shadowMapping.inc @@ -3,6 +3,32 @@ #include "lightInfo.inc" +vec2 applyDepthWarp(float z, vec2 warp){ + z = 2 * z - 1; + float positive = exp( z * warp.x); + float negative = -exp(-z * warp.y); + return vec2(positive, negative); +} + +float rescale(float a, float b, float v) +{ + return clamp((v - a) / (b - a), 0, 1); +} + +float reduceVSMBleeding(float shadowValue, float newMin) +{ + return rescale(newMin, 1.0f, shadowValue); +} + +float chebyshevInequality(float mean, float meanSquare, float sampleIn){ + float variance = meanSquare - mean * mean; + float d = sampleIn - mean; + float pMax = clamp(variance / (variance + d*d), 0, 1); + pMax = reduceVSMBleeding(pMax, 0.1); + + return pMax; +} + float shadowTest(vec3 worldPos, LightInfo lightInfo, texture2D shadowMap, sampler shadowMapSampler){ vec4 lightPos = lightInfo.lightMatrix * vec4(worldPos, 1); lightPos /= lightPos.w; @@ -12,11 +38,18 @@ float shadowTest(vec3 worldPos, LightInfo lightInfo, texture2D shadowMap, sample return 1; } - lightPos.z = clamp(lightPos.z, 0, 1); + lightPos.z = clamp(lightPos.z, 0, 1); + vec2 warpedSample = applyDepthWarp(lightPos.z, lightInfo.warps); - // using exponential shadow mapping - float shadowMapSample = texture(sampler2D(shadowMap, shadowMapSampler), lightPos.xy).r; - return clamp(exp(-lightInfo.exponentialWarp * lightPos.z) * shadowMapSample, 0, 1); + // using exponential variance shadow mapping + vec4 shadowMapSample = texture(sampler2D(shadowMap, shadowMapSampler), lightPos.xy); + vec2 positiveMoments = shadowMapSample.rb; + vec2 negativeMoments = shadowMapSample.ga; + + float s1 = chebyshevInequality(positiveMoments.r, positiveMoments.g, warpedSample.x); + float s2 = chebyshevInequality(negativeMoments.r, negativeMoments.g, warpedSample.y); + + return min(s1, s2); } #endif // #ifndef SHADOW_MAPPING_INC \ No newline at end of file diff --git a/projects/voxelization/src/ShadowMapping.cpp b/projects/voxelization/src/ShadowMapping.cpp index 456ef2cd..83ce118a 100644 --- a/projects/voxelization/src/ShadowMapping.cpp +++ b/projects/voxelization/src/ShadowMapping.cpp @@ -103,7 +103,7 @@ glm::mat4 computeShadowViewProjectionMatrix( return vulkanCorrectionMatrix * crop * view; } -const vk::Format shadowMapFormat = vk::Format::eR32Sfloat; +const vk::Format shadowMapFormat = vk::Format::eR32G32B32A32Sfloat; const vk::Format shadowMapDepthFormat = vk::Format::eD16Unorm; const uint32_t shadowMapResolution = 2048; @@ -156,7 +156,8 @@ void ShadowMapping::recordShadowMapRendering( const glm::vec3& lightColor, float lightStrength, float maxShadowDistance, - float exponentialWarp, + float exponentialWarpPositive, + float exponentialWarpNegative, const std::vector<vkcv::Mesh>& meshes, const std::vector<glm::mat4>& modelMatrices, const vkcv::camera::Camera& camera, @@ -170,7 +171,8 @@ void ShadowMapping::recordShadowMapRendering( std::cos(lightAngleRadian.x) * std::cos(lightAngleRadian.y), std::sin(lightAngleRadian.x), std::cos(lightAngleRadian.x) * std::sin(lightAngleRadian.y))); - lightInfo.exponentialWarp = exponentialWarp; + lightInfo.exponentialWarpPositive = exponentialWarpPositive; + lightInfo.exponentialWarpNegative = exponentialWarpNegative; lightInfo.lightMatrix = computeShadowViewProjectionMatrix( lightInfo.direction, diff --git a/projects/voxelization/src/ShadowMapping.hpp b/projects/voxelization/src/ShadowMapping.hpp index d72ca06c..541ad383 100644 --- a/projects/voxelization/src/ShadowMapping.hpp +++ b/projects/voxelization/src/ShadowMapping.hpp @@ -13,7 +13,8 @@ struct LightInfo { glm::vec3 sunColor; float sunStrength; glm::mat4 lightMatrix; - float exponentialWarp; + float exponentialWarpPositive; + float exponentialWarpNegative; }; class ShadowMapping { @@ -27,6 +28,7 @@ public: float lightStrength, float maxShadowDistance, float exponentialWarp, + float exponentialWarpNegative, const std::vector<vkcv::Mesh>& meshes, const std::vector<glm::mat4>& modelMatrices, const vkcv::camera::Camera& camera, diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index a56113d0..b488426d 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -325,11 +325,12 @@ int main(int argc, const char** argv) { vkcv::gui::GUI gui(core, window); - glm::vec2 lightAnglesDegree = glm::vec2(90.f, 0.f); - glm::vec3 lightColor = glm::vec3(1); - float lightStrength = 25.f; - float maxShadowDistance = 30.f; - float shadowExponentialWarp = 60.f; + glm::vec2 lightAnglesDegree = glm::vec2(90.f, 0.f); + glm::vec3 lightColor = glm::vec3(1); + float lightStrength = 25.f; + float maxShadowDistance = 30.f; + float shadowExponentialWarpPositive = 60.f; + float shadowExponentialWarpNegative = 60.f; int voxelVisualisationMip = 0; float voxelizationExtent = 30.f; @@ -378,7 +379,8 @@ int main(int argc, const char** argv) { lightColor, lightStrength, maxShadowDistance, - shadowExponentialWarp, + shadowExponentialWarpPositive, + shadowExponentialWarpNegative, meshes, modelMatrices, cameraManager.getActiveCamera(), @@ -446,7 +448,8 @@ int main(int argc, const char** argv) { ImGui::DragFloat("Sun strength", &lightStrength); ImGui::DragFloat("Max shadow distance", &maxShadowDistance); maxShadowDistance = std::max(maxShadowDistance, 1.f); - ImGui::DragFloat("Shadow exponential warp", &shadowExponentialWarp); + ImGui::DragFloat("Shadow exponential warp positive", &shadowExponentialWarpPositive); + ImGui::DragFloat("Shadow exponential warp negative", &shadowExponentialWarpNegative); ImGui::Checkbox("Draw voxel visualisation", &renderVoxelVis); ImGui::SliderInt("Visualisation mip", &voxelVisualisationMip, 0, 7); -- GitLab