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{
vec3 L; float padding;
vec3 sunColor;
float sunStrength;
mat4 lightMatrix;
};
\ No newline at end of file
float exponentialWarp;
};
#endif // #ifndef LIGHT_INFO_INC
\ No newline at end of file
#version 450
#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
#extension GL_ARB_separate_shader_objects : enable
#extension GL_GOOGLE_include_directive : enable
#include "lightInfo.inc"
layout(location = 0) in vec3 inPosition;
layout( push_constant ) uniform constants{
mat4 mvp;
};
layout(location = 0) out vec4 passPos;
void main() {
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){
vec4 lightPos = lightInfo.lightMatrix * vec4(worldPos, 1);
lightPos /= lightPos.w;
......@@ -9,8 +14,9 @@ float shadowTest(vec3 worldPos, LightInfo lightInfo, texture2D shadowMap, sample
lightPos.z = clamp(lightPos.z, 0, 1);
// using exponential shadow mapping
float shadowMapSample = texture(sampler2D(shadowMap, shadowMapSampler), lightPos.xy).r;
float bias = 0.01f;
shadowMapSample += bias;
return shadowMapSample < lightPos.z ? 0 : 1;
}
\ No newline at end of file
return clamp(exp(-lightInfo.exponentialWarp * lightPos.z) * shadowMapSample, 0, 1);
}
#endif // #ifndef SHADOW_MAPPING_INC
\ No newline at end of file
......@@ -103,37 +103,48 @@ glm::mat4 computeShadowViewProjectionMatrix(
return vulkanCorrectionMatrix * crop * view;
}
const vk::Format shadowMapFormat = vk::Format::eD16Unorm;
const uint32_t shadowMapResolution = 2048;
const vk::Format shadowMapFormat = vk::Format::eR32Sfloat;
const vk::Format shadowMapDepthFormat = vk::Format::eD16Unorm;
const uint32_t shadowMapResolution = 2048;
ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vertexLayout) :
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))){
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 = {
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);
m_shadowMapPass = corePtr->createPass(shadowPassConfig);
// pipeline
vkcv::PipelineConfig shadowPipeConfig{
shadowShader,
shadowMapResolution,
shadowMapResolution,
m_shadowMapPass,
vertexLayout,
{},
{ corePtr->getDescriptorSet(m_shadowDescriptorSet).layout },
false
};
shadowPipeConfig.m_EnableDepthClamping = true;
m_shadowMapPipe = corePtr->createGraphicsPipeline(shadowPipeConfig);
// shadow map
m_shadowSampler = corePtr->createSampler(
vkcv::SamplerFilterType::NEAREST,
vkcv::SamplerFilterType::NEAREST,
vkcv::SamplerFilterType::LINEAR,
vkcv::SamplerFilterType::LINEAR,
vkcv::SamplerMipmapMode::NEAREST,
vkcv::SamplerAddressMode::CLAMP_TO_EDGE
);
......@@ -145,6 +156,7 @@ void ShadowMapping::recordShadowMapRendering(
const glm::vec3& lightColor,
float lightStrength,
float maxShadowDistance,
float exponentialWarp,
const std::vector<vkcv::Mesh>& meshes,
const std::vector<glm::mat4>& modelMatrices,
const vkcv::camera::Camera& camera,
......@@ -158,6 +170,7 @@ 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.lightMatrix = computeShadowViewProjectionMatrix(
lightInfo.direction,
......@@ -175,7 +188,7 @@ void ShadowMapping::recordShadowMapRendering(
std::vector<vkcv::DrawcallInfo> drawcalls;
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(
......@@ -184,7 +197,7 @@ void ShadowMapping::recordShadowMapRendering(
m_shadowMapPipe,
shadowPushConstantData,
drawcalls,
{ m_shadowMap.getHandle() });
{ m_shadowMap.getHandle(), m_shadowMapDepth.getHandle() });
m_corePtr->prepareImageForSampling(cmdStream, m_shadowMap.getHandle());
}
......
......@@ -13,6 +13,7 @@ struct LightInfo {
glm::vec3 sunColor;
float sunStrength;
glm::mat4 lightMatrix;
float exponentialWarp;
};
class ShadowMapping {
......@@ -23,8 +24,9 @@ public:
const vkcv::CommandStreamHandle& cmdStream,
const glm::vec2& lightAngleRadian,
const glm::vec3& lightColor,
const float lightStrength,
float lightStrength,
float maxShadowDistance,
float exponentialWarp,
const std::vector<vkcv::Mesh>& meshes,
const std::vector<glm::mat4>& modelMatrices,
const vkcv::camera::Camera& camera,
......@@ -39,8 +41,10 @@ private:
vkcv::Core* m_corePtr;
vkcv::Image m_shadowMap;
vkcv::Image m_shadowMapDepth;
vkcv::SamplerHandle m_shadowSampler;
vkcv::Buffer<LightInfo> m_lightInfoBuffer;
vkcv::DescriptorSetHandle m_shadowDescriptorSet;
vkcv::PassHandle m_shadowMapPass;
vkcv::PipelineHandle m_shadowMapPipe;
......
......@@ -325,10 +325,11 @@ 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;
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;
int voxelVisualisationMip = 0;
float voxelizationExtent = 30.f;
......@@ -377,6 +378,7 @@ int main(int argc, const char** argv) {
lightColor,
lightStrength,
maxShadowDistance,
shadowExponentialWarp,
meshes,
modelMatrices,
cameraManager.getActiveCamera(),
......@@ -444,6 +446,7 @@ 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::Checkbox("Draw voxel visualisation", &renderVoxelVis);
ImGui::SliderInt("Visualisation mip", &voxelVisualisationMip, 0, 7);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment