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

[#82] Exponential shadow mapping prototype

parent 6eedb5e3
No related branches found
No related tags found
1 merge request!70Resolve "Voxel cone tracing"
Pipeline #25955 failed
This commit is part of merge request !70. Comments created here will be created in the context of that merge request.
#ifndef LIGHT_INFO_INC
#define LIGHT_INFO_INC
struct LightInfo{ struct LightInfo{
vec3 L; float padding; vec3 L; float padding;
vec3 sunColor; vec3 sunColor;
float sunStrength; float sunStrength;
mat4 lightMatrix; mat4 lightMatrix;
}; float exponentialWarp;
\ No newline at end of file };
#endif // #ifndef LIGHT_INFO_INC
\ No newline at end of file
#version 450 #version 450
#extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_separate_shader_objects : enable
#extension GL_GOOGLE_include_directive : enable
void main() { #include "shadowMapping.inc"
layout(set=0, binding=0) uniform LightInfoBuffer {
LightInfo lightInfo;
};
layout(location = 0) out float outExponentialDepth;
layout(location = 0) in vec4 passPos;
void main() {
float z = passPos.z / passPos.w;
outExponentialDepth = exp(z * lightInfo.exponentialWarp);
} }
\ No newline at end of file
#version 450 #version 450
#extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_separate_shader_objects : 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
#ifndef SHADOW_MAPPING_INC
#define SHADOW_MAPPING_INC
#include "lightInfo.inc"
float shadowTest(vec3 worldPos, LightInfo lightInfo, texture2D shadowMap, sampler shadowMapSampler){ float shadowTest(vec3 worldPos, LightInfo lightInfo, texture2D shadowMap, sampler shadowMapSampler){
vec4 lightPos = lightInfo.lightMatrix * vec4(worldPos, 1); vec4 lightPos = lightInfo.lightMatrix * vec4(worldPos, 1);
lightPos /= lightPos.w; lightPos /= lightPos.w;
...@@ -9,8 +14,9 @@ float shadowTest(vec3 worldPos, LightInfo lightInfo, texture2D shadowMap, sample ...@@ -9,8 +14,9 @@ float shadowTest(vec3 worldPos, LightInfo lightInfo, texture2D shadowMap, sample
lightPos.z = clamp(lightPos.z, 0, 1); lightPos.z = clamp(lightPos.z, 0, 1);
// using exponential shadow mapping
float shadowMapSample = texture(sampler2D(shadowMap, shadowMapSampler), lightPos.xy).r; float shadowMapSample = texture(sampler2D(shadowMap, shadowMapSampler), lightPos.xy).r;
float bias = 0.01f; return clamp(exp(-lightInfo.exponentialWarp * lightPos.z) * shadowMapSample, 0, 1);
shadowMapSample += bias; }
return shadowMapSample < lightPos.z ? 0 : 1;
} #endif // #ifndef SHADOW_MAPPING_INC
\ No newline at end of file \ No newline at end of file
...@@ -103,37 +103,48 @@ glm::mat4 computeShadowViewProjectionMatrix( ...@@ -103,37 +103,48 @@ glm::mat4 computeShadowViewProjectionMatrix(
return vulkanCorrectionMatrix * crop * view; return vulkanCorrectionMatrix * crop * view;
} }
const vk::Format shadowMapFormat = vk::Format::eD16Unorm; const vk::Format shadowMapFormat = vk::Format::eR32Sfloat;
const uint32_t shadowMapResolution = 2048; const vk::Format shadowMapDepthFormat = vk::Format::eD16Unorm;
const uint32_t shadowMapResolution = 2048;
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)), m_shadowMap(corePtr->createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1, false, false, true)),
m_shadowMapDepth(corePtr->createImage(shadowMapDepthFormat, shadowMapResolution, shadowMapResolution)),
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
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, shadowMapFormat),
vkcv::AttachmentDescription(vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, shadowMapDepthFormat)
}; };
const vkcv::PassConfig shadowPassConfig(shadowAttachments); const vkcv::PassConfig shadowPassConfig(shadowAttachments);
m_shadowMapPass = corePtr->createPass(shadowPassConfig); m_shadowMapPass = corePtr->createPass(shadowPassConfig);
// pipeline
vkcv::PipelineConfig shadowPipeConfig{ vkcv::PipelineConfig shadowPipeConfig{
shadowShader, shadowShader,
shadowMapResolution, shadowMapResolution,
shadowMapResolution, shadowMapResolution,
m_shadowMapPass, m_shadowMapPass,
vertexLayout, vertexLayout,
{}, { corePtr->getDescriptorSet(m_shadowDescriptorSet).layout },
false false
}; };
shadowPipeConfig.m_EnableDepthClamping = true; shadowPipeConfig.m_EnableDepthClamping = true;
m_shadowMapPipe = corePtr->createGraphicsPipeline(shadowPipeConfig); m_shadowMapPipe = corePtr->createGraphicsPipeline(shadowPipeConfig);
// shadow map
m_shadowSampler = corePtr->createSampler( m_shadowSampler = corePtr->createSampler(
vkcv::SamplerFilterType::NEAREST, vkcv::SamplerFilterType::LINEAR,
vkcv::SamplerFilterType::NEAREST, vkcv::SamplerFilterType::LINEAR,
vkcv::SamplerMipmapMode::NEAREST, vkcv::SamplerMipmapMode::NEAREST,
vkcv::SamplerAddressMode::CLAMP_TO_EDGE vkcv::SamplerAddressMode::CLAMP_TO_EDGE
); );
...@@ -145,6 +156,7 @@ void ShadowMapping::recordShadowMapRendering( ...@@ -145,6 +156,7 @@ void ShadowMapping::recordShadowMapRendering(
const glm::vec3& lightColor, const glm::vec3& lightColor,
float lightStrength, float lightStrength,
float maxShadowDistance, float maxShadowDistance,
float exponentialWarp,
const std::vector<vkcv::Mesh>& meshes, const std::vector<vkcv::Mesh>& meshes,
const std::vector<glm::mat4>& modelMatrices, const std::vector<glm::mat4>& modelMatrices,
const vkcv::camera::Camera& camera, const vkcv::camera::Camera& camera,
...@@ -158,6 +170,7 @@ void ShadowMapping::recordShadowMapRendering( ...@@ -158,6 +170,7 @@ void ShadowMapping::recordShadowMapRendering(
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)));
lightInfo.exponentialWarp = exponentialWarp;
lightInfo.lightMatrix = computeShadowViewProjectionMatrix( lightInfo.lightMatrix = computeShadowViewProjectionMatrix(
lightInfo.direction, lightInfo.direction,
...@@ -175,7 +188,7 @@ void ShadowMapping::recordShadowMapRendering( ...@@ -175,7 +188,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, {})); drawcalls.push_back(vkcv::DrawcallInfo(mesh, { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_shadowDescriptorSet).vulkanHandle) }));
} }
m_corePtr->recordDrawcallsToCmdStream( m_corePtr->recordDrawcallsToCmdStream(
...@@ -184,7 +197,7 @@ void ShadowMapping::recordShadowMapRendering( ...@@ -184,7 +197,7 @@ void ShadowMapping::recordShadowMapRendering(
m_shadowMapPipe, m_shadowMapPipe,
shadowPushConstantData, shadowPushConstantData,
drawcalls, drawcalls,
{ m_shadowMap.getHandle() }); { m_shadowMap.getHandle(), m_shadowMapDepth.getHandle() });
m_corePtr->prepareImageForSampling(cmdStream, m_shadowMap.getHandle()); m_corePtr->prepareImageForSampling(cmdStream, m_shadowMap.getHandle());
} }
......
...@@ -13,6 +13,7 @@ struct LightInfo { ...@@ -13,6 +13,7 @@ struct LightInfo {
glm::vec3 sunColor; glm::vec3 sunColor;
float sunStrength; float sunStrength;
glm::mat4 lightMatrix; glm::mat4 lightMatrix;
float exponentialWarp;
}; };
class ShadowMapping { class ShadowMapping {
...@@ -23,8 +24,9 @@ public: ...@@ -23,8 +24,9 @@ public:
const vkcv::CommandStreamHandle& cmdStream, const vkcv::CommandStreamHandle& cmdStream,
const glm::vec2& lightAngleRadian, const glm::vec2& lightAngleRadian,
const glm::vec3& lightColor, const glm::vec3& lightColor,
const float lightStrength, float lightStrength,
float maxShadowDistance, float maxShadowDistance,
float exponentialWarp,
const std::vector<vkcv::Mesh>& meshes, const std::vector<vkcv::Mesh>& meshes,
const std::vector<glm::mat4>& modelMatrices, const std::vector<glm::mat4>& modelMatrices,
const vkcv::camera::Camera& camera, const vkcv::camera::Camera& camera,
...@@ -39,8 +41,10 @@ private: ...@@ -39,8 +41,10 @@ private:
vkcv::Core* m_corePtr; vkcv::Core* m_corePtr;
vkcv::Image m_shadowMap; vkcv::Image m_shadowMap;
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;
......
...@@ -325,10 +325,11 @@ int main(int argc, const char** argv) { ...@@ -325,10 +325,11 @@ int main(int argc, const char** argv) {
vkcv::gui::GUI gui(core, window); vkcv::gui::GUI gui(core, window);
glm::vec2 lightAnglesDegree = glm::vec2(90.f, 0.f); glm::vec2 lightAnglesDegree = glm::vec2(90.f, 0.f);
glm::vec3 lightColor = glm::vec3(1); glm::vec3 lightColor = glm::vec3(1);
float lightStrength = 25.f; float lightStrength = 25.f;
float maxShadowDistance = 30.f; float maxShadowDistance = 30.f;
float shadowExponentialWarp = 60.f;
int voxelVisualisationMip = 0; int voxelVisualisationMip = 0;
float voxelizationExtent = 30.f; float voxelizationExtent = 30.f;
...@@ -377,6 +378,7 @@ int main(int argc, const char** argv) { ...@@ -377,6 +378,7 @@ int main(int argc, const char** argv) {
lightColor, lightColor,
lightStrength, lightStrength,
maxShadowDistance, maxShadowDistance,
shadowExponentialWarp,
meshes, meshes,
modelMatrices, modelMatrices,
cameraManager.getActiveCamera(), cameraManager.getActiveCamera(),
...@@ -444,6 +446,7 @@ int main(int argc, const char** argv) { ...@@ -444,6 +446,7 @@ int main(int argc, const char** argv) {
ImGui::DragFloat("Sun strength", &lightStrength); ImGui::DragFloat("Sun strength", &lightStrength);
ImGui::DragFloat("Max shadow distance", &maxShadowDistance); ImGui::DragFloat("Max shadow distance", &maxShadowDistance);
maxShadowDistance = std::max(maxShadowDistance, 1.f); maxShadowDistance = std::max(maxShadowDistance, 1.f);
ImGui::DragFloat("Shadow exponential warp", &shadowExponentialWarp);
ImGui::Checkbox("Draw voxel visualisation", &renderVoxelVis); ImGui::Checkbox("Draw voxel visualisation", &renderVoxelVis);
ImGui::SliderInt("Visualisation mip", &voxelVisualisationMip, 0, 7); ImGui::SliderInt("Visualisation mip", &voxelVisualisationMip, 0, 7);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment