diff --git a/projects/voxelization/resources/shaders/depthToMoments.comp b/projects/voxelization/resources/shaders/depthToMoments.comp index 5d327f54b0b2ce60273379428207530806e82f55..401f399fcdea32924edf905e03eef17e9ccb5c4f 100644 --- a/projects/voxelization/resources/shaders/depthToMoments.comp +++ b/projects/voxelization/resources/shaders/depthToMoments.comp @@ -6,9 +6,9 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -layout(set=0, binding=0) uniform texture2DMS srcTexture; -layout(set=0, binding=1) uniform sampler depthSampler; -layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D outImage; +layout(set=0, binding=0) uniform texture2DMS srcTexture; +layout(set=0, binding=1) uniform sampler depthSampler; +layout(set=0, binding=2, rgba16) uniform image2D outImage; layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/projects/voxelization/resources/shaders/lightInfo.inc b/projects/voxelization/resources/shaders/lightInfo.inc index c0df6551059d283a117b6dfa12ac21ec5109f0ae..7cbf605e4e54342743855d5f380db857da12f5f5 100644 --- a/projects/voxelization/resources/shaders/lightInfo.inc +++ b/projects/voxelization/resources/shaders/lightInfo.inc @@ -6,7 +6,6 @@ struct LightInfo{ vec3 sunColor; float sunStrength; mat4 lightMatrix; - vec2 warps; }; #endif // #ifndef LIGHT_INFO_INC \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/shadowBlur.comp b/projects/voxelization/resources/shaders/shadowBlur.comp new file mode 100644 index 0000000000000000000000000000000000000000..5daf72c69d164aa51755ca239ad83922a10198ee --- /dev/null +++ b/projects/voxelization/resources/shaders/shadowBlur.comp @@ -0,0 +1,42 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +layout(set=0, binding=0) uniform texture2D srcTexture; +layout(set=0, binding=1) uniform sampler depthSampler; +layout(set=0, binding=2, rgba16) 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); + + int blurRadius = 0; + int minOffset = -(blurRadius-1) / 2; + int maxOffset = -minOffset; + + vec2 pixelSize = vec2(1) / textureSize(sampler2D(srcTexture, depthSampler), 0); + + float wTotal = 0; + vec4 moments = vec4(0); + + float weights1D[3] = { 0.5, 0.25, 0.125 }; // gaussian + + for(int x = minOffset; x <= maxOffset; x++){ + for(int y = minOffset; y <= maxOffset; y++){ + vec2 uv = (coord + ivec2(x, y)) * pixelSize; + uv += 0.5 * pixelSize * sign(vec2(x, y)); // half pixel shift to take advantage of bilinear filtering + float w = weights1D[abs(x)] * weights1D[abs(y)]; + moments += w * texture(sampler2D(srcTexture, depthSampler), uv); + wTotal += w; + } + } + moments /= wTotal; + + imageStore(outImage, coord, moments); +} \ No newline at end of file diff --git a/projects/voxelization/src/ShadowMapping.cpp b/projects/voxelization/src/ShadowMapping.cpp index 72add6d56c5d4853b3b4022f3e2676c37016e198..8b5a51fbb8961fd540baed952fc81261e1630998 100644 --- a/projects/voxelization/src/ShadowMapping.cpp +++ b/projects/voxelization/src/ShadowMapping.cpp @@ -25,6 +25,16 @@ vkcv::ShaderProgram loadDepthToMomentsShader() { return shader; } +vkcv::ShaderProgram loadShadowBlurShader() { + vkcv::ShaderProgram shader; + vkcv::shader::GLSLCompiler compiler; + compiler.compile(vkcv::ShaderStage::COMPUTE, "resources/shaders/shadowBlur.comp", + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + shader.addShader(shaderStage, path); + }); + return shader; +} + glm::mat4 computeShadowViewProjectionMatrix( const glm::vec3& lightDirection, const vkcv::camera::Camera& camera, @@ -121,6 +131,7 @@ const vkcv::Multisampling msaa = vkcv::Multisampling::MSAA4 ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vertexLayout) : m_corePtr(corePtr), m_shadowMap(corePtr->createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1, false, true)), + m_shadowMapIntermediate(corePtr->createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1, false, true)), m_shadowMapDepth(corePtr->createImage(shadowMapDepthFormat, shadowMapResolution, shadowMapResolution, 1, false, false, false, msaa)), m_lightInfoBuffer(corePtr->createBuffer<LightInfo>(vkcv::BufferType::UNIFORM, sizeof(glm::vec3))){ @@ -162,8 +173,19 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert vkcv::DescriptorWrites depthToMomentDescriptorWrites; depthToMomentDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, m_shadowMapDepth.getHandle()) }; depthToMomentDescriptorWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, m_shadowSampler) }; - depthToMomentDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(2, m_shadowMap.getHandle()) }; + depthToMomentDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(2, m_shadowMapIntermediate.getHandle()) }; corePtr->writeDescriptorSet(m_depthToMomentsDescriptorSet, depthToMomentDescriptorWrites); + + // shadow blur + vkcv::ShaderProgram shadowBlurShader = loadShadowBlurShader(); + m_shadowBlurDescriptorSet = corePtr->createDescriptorSet(shadowBlurShader.getReflectedDescriptors()[0]); + m_shadowBlurPipe = corePtr->createComputePipeline(shadowBlurShader, { corePtr->getDescriptorSet(m_shadowBlurDescriptorSet).layout }); + + vkcv::DescriptorWrites shadowBlurDescriptorWrites; + shadowBlurDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, m_shadowMapIntermediate.getHandle()) }; + shadowBlurDescriptorWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, m_shadowSampler) }; + shadowBlurDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(2, m_shadowMap.getHandle()) }; + corePtr->writeDescriptorSet(m_shadowBlurDescriptorSet, shadowBlurDescriptorWrites); } void ShadowMapping::recordShadowMapRendering( @@ -172,8 +194,6 @@ void ShadowMapping::recordShadowMapRendering( const glm::vec3& lightColor, float lightStrength, float maxShadowDistance, - float exponentialWarpPositive, - float exponentialWarpNegative, const std::vector<vkcv::Mesh>& meshes, const std::vector<glm::mat4>& modelMatrices, const vkcv::camera::Camera& camera, @@ -187,8 +207,6 @@ void ShadowMapping::recordShadowMapRendering( std::cos(lightAngleRadian.x) * std::cos(lightAngleRadian.y), std::sin(lightAngleRadian.x), std::cos(lightAngleRadian.x) * std::sin(lightAngleRadian.y))); - lightInfo.exponentialWarpPositive = exponentialWarpPositive; - lightInfo.exponentialWarpNegative = exponentialWarpNegative; lightInfo.lightMatrix = computeShadowViewProjectionMatrix( lightInfo.direction, @@ -226,13 +244,23 @@ void ShadowMapping::recordShadowMapRendering( const uint32_t msaaSampleCount = msaaToSampleCount(msaa); - m_corePtr->prepareImageForStorage(cmdStream, m_shadowMap.getHandle()); + m_corePtr->prepareImageForStorage(cmdStream, m_shadowMapIntermediate.getHandle()); m_corePtr->recordComputeDispatchToCmdStream( cmdStream, m_depthToMomentsPipe, dispatchCount, { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_depthToMomentsDescriptorSet).vulkanHandle) }, vkcv::PushConstantData((void*)&msaaSampleCount, sizeof(msaaSampleCount))); + m_corePtr->prepareImageForSampling(cmdStream, m_shadowMapIntermediate.getHandle()); + + // blur + m_corePtr->prepareImageForStorage(cmdStream, m_shadowMap.getHandle()); + m_corePtr->recordComputeDispatchToCmdStream( + cmdStream, + m_shadowBlurPipe, + dispatchCount, + { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_shadowBlurDescriptorSet).vulkanHandle) }, + vkcv::PushConstantData(nullptr, 0)); m_corePtr->prepareImageForSampling(cmdStream, m_shadowMap.getHandle()); } diff --git a/projects/voxelization/src/ShadowMapping.hpp b/projects/voxelization/src/ShadowMapping.hpp index e9ad792caa4b3ca7fab755aff8ebeb46c65a5249..2b25220bfc06ba1646003d61ef05c66920e1b1b6 100644 --- a/projects/voxelization/src/ShadowMapping.hpp +++ b/projects/voxelization/src/ShadowMapping.hpp @@ -13,8 +13,6 @@ struct LightInfo { glm::vec3 sunColor; float sunStrength; glm::mat4 lightMatrix; - float exponentialWarpPositive; - float exponentialWarpNegative; }; class ShadowMapping { @@ -27,8 +25,6 @@ public: const glm::vec3& lightColor, 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, @@ -43,6 +39,7 @@ private: vkcv::Core* m_corePtr; vkcv::Image m_shadowMap; + vkcv::Image m_shadowMapIntermediate; vkcv::Image m_shadowMapDepth; vkcv::SamplerHandle m_shadowSampler; vkcv::Buffer<LightInfo> m_lightInfoBuffer; @@ -52,4 +49,7 @@ private: vkcv::PipelineHandle m_depthToMomentsPipe; vkcv::DescriptorSetHandle m_depthToMomentsDescriptorSet; + + vkcv::PipelineHandle m_shadowBlurPipe; + vkcv::DescriptorSetHandle m_shadowBlurDescriptorSet; }; \ No newline at end of file diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index 6c1167389fe13a849ffd2f6afefacb4ef6496abf..a5395baca1edc604c15762e41bd2a0017bb2c7c4 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -361,8 +361,6 @@ int main(int argc, const char** argv) { 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; @@ -427,8 +425,6 @@ int main(int argc, const char** argv) { lightColor, lightStrength, maxShadowDistance, - shadowExponentialWarpPositive, - shadowExponentialWarpNegative, meshes, modelMatrices, cameraManager.getActiveCamera(), @@ -520,8 +516,6 @@ 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 positive", &shadowExponentialWarpPositive); - ImGui::DragFloat("Shadow exponential warp negative", &shadowExponentialWarpNegative); ImGui::Checkbox("Draw voxel visualisation", &renderVoxelVis); ImGui::SliderInt("Visualisation mip", &voxelVisualisationMip, 0, 7);