Skip to content
Snippets Groups Projects
Commit ea971356 authored by Alexander Gauggel's avatar Alexander Gauggel
Browse files

[#82] Add MSAA to moment shadow map

parent 40f9aa74
Branches
Tags
1 merge request!70Resolve "Voxel cone tracing"
...@@ -5,4 +5,5 @@ namespace vkcv { ...@@ -5,4 +5,5 @@ namespace vkcv {
enum class Multisampling { None, MSAA2X, MSAA4X, MSAA8X }; enum class Multisampling { None, MSAA2X, MSAA4X, MSAA8X };
vk::SampleCountFlagBits msaaToVkSampleCountFlag(Multisampling msaa); vk::SampleCountFlagBits msaaToVkSampleCountFlag(Multisampling msaa);
uint32_t msaaToSampleCount(Multisampling msaa);
} }
#version 450
#extension GL_GOOGLE_include_directive : enable
#extension GL_ARB_texture_multisample : enable
#include "shadowMapping.inc"
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(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout( push_constant ) uniform constants{
int msaaCount;
};
void main(){
if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){
return;
}
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
float z = 0;
for(int i = 0; i < msaaCount; i++){
z += texelFetch(sampler2DMS(srcTexture, depthSampler), uv, i).r;
}
z /= msaaCount;
float z2 = z*z;
vec4 moments = vec4(z, z2, z2*z, z2*z2);
vec4 momentsQuantized = quantizeMoments(moments);
imageStore(outImage, uv, momentsQuantized);
}
\ No newline at end of file
...@@ -2,21 +2,6 @@ ...@@ -2,21 +2,6 @@
#extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_separate_shader_objects : enable
#extension GL_GOOGLE_include_directive : enable #extension GL_GOOGLE_include_directive : enable
#include "lightInfo.inc"
#include "shadowMapping.inc"
layout(set=0, binding=0) uniform LightInfoBuffer {
LightInfo lightInfo;
};
layout(location = 0) out vec4 outMoments;
layout(location = 0) in vec4 passPos;
void main() { void main() {
float z = passPos.z / passPos.w;
float z2 = z*z;
outMoments = vec4(z, z2, z2*z, z2*z2);
outMoments = quantizeMoments(outMoments);
} }
\ No newline at end of file
...@@ -3,17 +3,12 @@ ...@@ -3,17 +3,12 @@
#extension GL_GOOGLE_include_directive : enable #extension GL_GOOGLE_include_directive : enable
#include "lightInfo.inc"
layout(location = 0) in vec3 inPosition; layout(location = 0) in vec3 inPosition;
layout( push_constant ) uniform constants{ layout( push_constant ) uniform constants{
mat4 mvp; mat4 mvp;
}; };
layout(location = 0) out vec4 passPos;
void main() { void main() {
gl_Position = mvp * vec4(inPosition, 1.0); gl_Position = mvp * vec4(inPosition, 1.0);
passPos = gl_Position;
} }
\ No newline at end of file
...@@ -15,6 +15,16 @@ vkcv::ShaderProgram loadShadowShader() { ...@@ -15,6 +15,16 @@ vkcv::ShaderProgram loadShadowShader() {
return shader; return shader;
} }
vkcv::ShaderProgram loadDepthToMomentsShader() {
vkcv::ShaderProgram shader;
vkcv::shader::GLSLCompiler compiler;
compiler.compile(vkcv::ShaderStage::COMPUTE, "resources/shaders/depthToMoments.comp",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
shader.addShader(shaderStage, path);
});
return shader;
}
glm::mat4 computeShadowViewProjectionMatrix( glm::mat4 computeShadowViewProjectionMatrix(
const glm::vec3& lightDirection, const glm::vec3& lightDirection,
const vkcv::camera::Camera& camera, const vkcv::camera::Camera& camera,
...@@ -103,30 +113,24 @@ glm::mat4 computeShadowViewProjectionMatrix( ...@@ -103,30 +113,24 @@ glm::mat4 computeShadowViewProjectionMatrix(
return vulkanCorrectionMatrix * crop * view; return vulkanCorrectionMatrix * crop * view;
} }
const vk::Format shadowMapFormat = vk::Format::eR16G16B16A16Unorm; const vk::Format shadowMapFormat = vk::Format::eR16G16B16A16Unorm;
const vk::Format shadowMapDepthFormat = vk::Format::eD16Unorm; const vk::Format shadowMapDepthFormat = vk::Format::eD32Sfloat;
const uint32_t shadowMapResolution = 2048; const uint32_t shadowMapResolution = 2048;
const vkcv::Multisampling msaa = vkcv::Multisampling::MSAA4X;
ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vertexLayout) : ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vertexLayout) :
m_corePtr(corePtr), m_corePtr(corePtr),
m_shadowMap(corePtr->createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1, false, false, true)), m_shadowMap(corePtr->createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1, false, true)),
m_shadowMapDepth(corePtr->createImage(shadowMapDepthFormat, shadowMapResolution, shadowMapResolution)), m_shadowMapDepth(corePtr->createImage(shadowMapDepthFormat, shadowMapResolution, shadowMapResolution, 1, false, false, false, msaa)),
m_lightInfoBuffer(corePtr->createBuffer<LightInfo>(vkcv::BufferType::UNIFORM, sizeof(glm::vec3))){ m_lightInfoBuffer(corePtr->createBuffer<LightInfo>(vkcv::BufferType::UNIFORM, sizeof(glm::vec3))){
vkcv::ShaderProgram shadowShader = loadShadowShader(); vkcv::ShaderProgram shadowShader = loadShadowShader();
// descriptor set
m_shadowDescriptorSet = corePtr->createDescriptorSet(shadowShader.getReflectedDescriptors()[0]);
vkcv::DescriptorWrites shadowDescriptorWrites;
shadowDescriptorWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(0, m_lightInfoBuffer.getHandle()) };
corePtr->writeDescriptorSet(m_shadowDescriptorSet, shadowDescriptorWrites);
// pass // pass
const std::vector<vkcv::AttachmentDescription> shadowAttachments = { const std::vector<vkcv::AttachmentDescription> shadowAttachments = {
vkcv::AttachmentDescription(vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, shadowMapFormat),
vkcv::AttachmentDescription(vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, shadowMapDepthFormat) vkcv::AttachmentDescription(vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, shadowMapDepthFormat)
}; };
const vkcv::PassConfig shadowPassConfig(shadowAttachments); vkcv::PassConfig shadowPassConfig(shadowAttachments, msaa);
m_shadowMapPass = corePtr->createPass(shadowPassConfig); m_shadowMapPass = corePtr->createPass(shadowPassConfig);
// pipeline // pipeline
...@@ -136,9 +140,10 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert ...@@ -136,9 +140,10 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert
shadowMapResolution, shadowMapResolution,
m_shadowMapPass, m_shadowMapPass,
vertexLayout, vertexLayout,
{ corePtr->getDescriptorSet(m_shadowDescriptorSet).layout }, {},
false false
}; };
shadowPipeConfig.m_multisampling = msaa;
shadowPipeConfig.m_EnableDepthClamping = true; shadowPipeConfig.m_EnableDepthClamping = true;
m_shadowMapPipe = corePtr->createGraphicsPipeline(shadowPipeConfig); m_shadowMapPipe = corePtr->createGraphicsPipeline(shadowPipeConfig);
...@@ -148,10 +153,21 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert ...@@ -148,10 +153,21 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert
vkcv::SamplerMipmapMode::NEAREST, vkcv::SamplerMipmapMode::NEAREST,
vkcv::SamplerAddressMode::CLAMP_TO_EDGE vkcv::SamplerAddressMode::CLAMP_TO_EDGE
); );
// depth to moments
vkcv::ShaderProgram depthToMomentsShader = loadDepthToMomentsShader();
m_depthToMomentsDescriptorSet = corePtr->createDescriptorSet(depthToMomentsShader.getReflectedDescriptors()[0]);
m_depthToMomentsPipe = corePtr->createComputePipeline(depthToMomentsShader, { corePtr->getDescriptorSet(m_depthToMomentsDescriptorSet).layout });
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()) };
corePtr->writeDescriptorSet(m_depthToMomentsDescriptorSet, depthToMomentDescriptorWrites);
} }
void ShadowMapping::recordShadowMapRendering( void ShadowMapping::recordShadowMapRendering(
const vkcv::CommandStreamHandle& cmdStream, const vkcv::CommandStreamHandle& cmdStream,
const glm::vec2& lightAngleRadian, const glm::vec2& lightAngleRadian,
const glm::vec3& lightColor, const glm::vec3& lightColor,
float lightStrength, float lightStrength,
...@@ -165,9 +181,9 @@ void ShadowMapping::recordShadowMapRendering( ...@@ -165,9 +181,9 @@ void ShadowMapping::recordShadowMapRendering(
float voxelVolumeExtent) { float voxelVolumeExtent) {
LightInfo lightInfo; LightInfo lightInfo;
lightInfo.sunColor = lightColor; lightInfo.sunColor = lightColor;
lightInfo.sunStrength = lightStrength; lightInfo.sunStrength = lightStrength;
lightInfo.direction = glm::normalize(glm::vec3( lightInfo.direction = glm::normalize(glm::vec3(
std::cos(lightAngleRadian.x) * std::cos(lightAngleRadian.y), std::cos(lightAngleRadian.x) * std::cos(lightAngleRadian.y),
std::sin(lightAngleRadian.x), std::sin(lightAngleRadian.x),
std::cos(lightAngleRadian.x) * std::sin(lightAngleRadian.y))); std::cos(lightAngleRadian.x) * std::sin(lightAngleRadian.y)));
...@@ -190,7 +206,7 @@ void ShadowMapping::recordShadowMapRendering( ...@@ -190,7 +206,7 @@ void ShadowMapping::recordShadowMapRendering(
std::vector<vkcv::DrawcallInfo> drawcalls; std::vector<vkcv::DrawcallInfo> drawcalls;
for (const auto& mesh : meshes) { for (const auto& mesh : meshes) {
drawcalls.push_back(vkcv::DrawcallInfo(mesh, { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_shadowDescriptorSet).vulkanHandle) })); drawcalls.push_back(vkcv::DrawcallInfo(mesh, {}));
} }
m_corePtr->recordDrawcallsToCmdStream( m_corePtr->recordDrawcallsToCmdStream(
...@@ -199,7 +215,24 @@ void ShadowMapping::recordShadowMapRendering( ...@@ -199,7 +215,24 @@ void ShadowMapping::recordShadowMapRendering(
m_shadowMapPipe, m_shadowMapPipe,
shadowPushConstantData, shadowPushConstantData,
drawcalls, drawcalls,
{ m_shadowMap.getHandle(), m_shadowMapDepth.getHandle() }); { m_shadowMapDepth.getHandle() });
m_corePtr->prepareImageForSampling(cmdStream, m_shadowMapDepth.getHandle());
// depth to moments
uint32_t dispatchCount[3];
dispatchCount[0] = (uint32_t)std::ceilf(shadowMapResolution / 8.f);
dispatchCount[1] = (uint32_t)std::ceilf(shadowMapResolution / 8.f);
dispatchCount[2] = 1;
const uint32_t msaaSampleCount = msaaToSampleCount(msaa);
m_corePtr->prepareImageForStorage(cmdStream, m_shadowMap.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_shadowMap.getHandle()); m_corePtr->prepareImageForSampling(cmdStream, m_shadowMap.getHandle());
} }
......
...@@ -42,12 +42,14 @@ public: ...@@ -42,12 +42,14 @@ public:
private: private:
vkcv::Core* m_corePtr; vkcv::Core* m_corePtr;
vkcv::Image m_shadowMap; vkcv::Image m_shadowMap;
vkcv::Image m_shadowMapDepth; vkcv::Image m_shadowMapDepth;
vkcv::SamplerHandle m_shadowSampler; vkcv::SamplerHandle m_shadowSampler;
vkcv::Buffer<LightInfo> m_lightInfoBuffer; vkcv::Buffer<LightInfo> m_lightInfoBuffer;
vkcv::DescriptorSetHandle m_shadowDescriptorSet;
vkcv::PassHandle m_shadowMapPass;
vkcv::PassHandle m_shadowMapPass; vkcv::PipelineHandle m_shadowMapPipe;
vkcv::PipelineHandle m_shadowMapPipe;
vkcv::PipelineHandle m_depthToMomentsPipe;
vkcv::DescriptorSetHandle m_depthToMomentsDescriptorSet;
}; };
\ No newline at end of file
...@@ -11,4 +11,14 @@ namespace vkcv { ...@@ -11,4 +11,14 @@ namespace vkcv {
default: vkcv_log(vkcv::LogLevel::ERROR, "Unknown Multisampling enum setting"); return vk::SampleCountFlagBits::e1; default: vkcv_log(vkcv::LogLevel::ERROR, "Unknown Multisampling enum setting"); return vk::SampleCountFlagBits::e1;
} }
} }
uint32_t msaaToSampleCount(Multisampling msaa) {
switch (msaa) {
case Multisampling::None: return 1;
case Multisampling::MSAA2X: return 2;
case Multisampling::MSAA4X: return 4;
case Multisampling::MSAA8X: return 8;
default: vkcv_log(vkcv::LogLevel::ERROR, "Unknown Multisampling enum setting"); return 1;
}
}
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment