parent
6b91f3c493
commit
a2d5a1fd44
18 changed files with 41 additions and 68 deletions
|
|
@ -62,7 +62,6 @@ public:
|
||||||
|
|
||||||
struct UBOFS {
|
struct UBOFS {
|
||||||
float cascadeSplits[4];
|
float cascadeSplits[4];
|
||||||
glm::mat4 cascadeViewProjMat[4];
|
|
||||||
glm::mat4 inverseViewMat;
|
glm::mat4 inverseViewMat;
|
||||||
glm::vec3 lightDir;
|
glm::vec3 lightDir;
|
||||||
float _pad;
|
float _pad;
|
||||||
|
|
@ -76,9 +75,7 @@ public:
|
||||||
VkPipeline sceneShadowPCF;
|
VkPipeline sceneShadowPCF;
|
||||||
} pipelines;
|
} pipelines;
|
||||||
|
|
||||||
struct DescriptorSetLayouts {
|
VkDescriptorSetLayout descriptorSetLayout;
|
||||||
VkDescriptorSetLayout base;
|
|
||||||
} descriptorSetLayouts;
|
|
||||||
VkDescriptorSet descriptorSet;
|
VkDescriptorSet descriptorSet;
|
||||||
|
|
||||||
// For simplicity all pipelines use the same push constant block layout
|
// For simplicity all pipelines use the same push constant block layout
|
||||||
|
|
@ -92,12 +89,6 @@ public:
|
||||||
VkRenderPass renderPass;
|
VkRenderPass renderPass;
|
||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout;
|
||||||
VkPipeline pipeline;
|
VkPipeline pipeline;
|
||||||
vks::Buffer uniformBuffer;
|
|
||||||
|
|
||||||
struct UniformBlock {
|
|
||||||
std::array<glm::mat4, SHADOW_MAP_CASCADE_COUNT> cascadeViewProjMat;
|
|
||||||
} ubo;
|
|
||||||
|
|
||||||
} depthPass;
|
} depthPass;
|
||||||
|
|
||||||
// Layered depth image containing the shadow cascade depths
|
// Layered depth image containing the shadow cascade depths
|
||||||
|
|
@ -117,18 +108,17 @@ public:
|
||||||
// Contains all resources required for a single shadow map cascade
|
// Contains all resources required for a single shadow map cascade
|
||||||
struct Cascade {
|
struct Cascade {
|
||||||
VkFramebuffer frameBuffer;
|
VkFramebuffer frameBuffer;
|
||||||
VkDescriptorSet descriptorSet;
|
|
||||||
VkImageView view;
|
VkImageView view;
|
||||||
|
|
||||||
float splitDepth;
|
float splitDepth;
|
||||||
glm::mat4 viewProjMatrix;
|
glm::mat4 viewProjMatrix;
|
||||||
|
|
||||||
void destroy(VkDevice device) {
|
void destroy(VkDevice device) {
|
||||||
vkDestroyImageView(device, view, nullptr);
|
vkDestroyImageView(device, view, nullptr);
|
||||||
vkDestroyFramebuffer(device, frameBuffer, nullptr);
|
vkDestroyFramebuffer(device, frameBuffer, nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std::array<Cascade, SHADOW_MAP_CASCADE_COUNT> cascades;
|
std::array<Cascade, SHADOW_MAP_CASCADE_COUNT> cascades;
|
||||||
|
// Per-cascade matrices will be passed to the shaders as a linear array
|
||||||
|
vks::Buffer cascadeViewProjMatricesBuffer;
|
||||||
|
|
||||||
VulkanExample() : VulkanExampleBase()
|
VulkanExample() : VulkanExampleBase()
|
||||||
{
|
{
|
||||||
|
|
@ -159,9 +149,9 @@ public:
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||||
vkDestroyPipelineLayout(device, depthPass.pipelineLayout, nullptr);
|
vkDestroyPipelineLayout(device, depthPass.pipelineLayout, nullptr);
|
||||||
|
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.base, nullptr);
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
||||||
|
|
||||||
depthPass.uniformBuffer.destroy();
|
cascadeViewProjMatricesBuffer.destroy();
|
||||||
uniformBuffers.VS.destroy();
|
uniformBuffers.VS.destroy();
|
||||||
uniformBuffers.FS.destroy();
|
uniformBuffers.FS.destroy();
|
||||||
}
|
}
|
||||||
|
|
@ -174,10 +164,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Render the example scene with given command buffer, pipeline layout and descriptor set
|
Render the example scene to acommand buffer using the supplied pipeline layout and for the selected shadow cascade index
|
||||||
Used by the scene rendering and depth pass generation command buffer
|
Used by the scene rendering and depth pass generation command buffer
|
||||||
*/
|
*/
|
||||||
void renderScene(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VkDescriptorSet descriptorSet, uint32_t cascadeIndex = 0) {
|
void renderScene(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, uint32_t cascadeIndex = 0) {
|
||||||
// We use push constants for passing shadow cascade info to the shaders
|
// We use push constants for passing shadow cascade info to the shaders
|
||||||
PushConstBlock pushConstBlock = { glm::vec4(0.0f), cascadeIndex };
|
PushConstBlock pushConstBlock = { glm::vec4(0.0f), cascadeIndex };
|
||||||
|
|
||||||
|
|
@ -197,10 +187,10 @@ public:
|
||||||
glm::vec3(-1.25f, -0.25f, -1.25f),
|
glm::vec3(-1.25f, -0.25f, -1.25f),
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto position : positions) {
|
for (auto& position : positions) {
|
||||||
pushConstBlock.position = glm::vec4(position, 0.0f);
|
pushConstBlock.position = glm::vec4(position, 0.0f);
|
||||||
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstBlock), &pushConstBlock);
|
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstBlock), &pushConstBlock);
|
||||||
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
|
// This will also bind the texture images to set 1
|
||||||
models.tree.draw(commandBuffer, vkglTF::RenderFlags::BindImages, pipelineLayout);
|
models.tree.draw(commandBuffer, vkglTF::RenderFlags::BindImages, pipelineLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -377,12 +367,11 @@ public:
|
||||||
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
|
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
|
||||||
|
|
||||||
// One pass per cascade
|
// One pass per cascade
|
||||||
// The layer that this pass renders to is defined by the cascade's image view (selected via the cascade's descriptor set)
|
|
||||||
for (uint32_t j = 0; j < SHADOW_MAP_CASCADE_COUNT; j++) {
|
for (uint32_t j = 0; j < SHADOW_MAP_CASCADE_COUNT; j++) {
|
||||||
renderPassBeginInfo.framebuffer = cascades[j].frameBuffer;
|
renderPassBeginInfo.framebuffer = cascades[j].frameBuffer;
|
||||||
vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, depthPass.pipeline);
|
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, depthPass.pipeline);
|
||||||
renderScene(drawCmdBuffers[i], depthPass.pipelineLayout, cascades[j].descriptorSet, j);
|
renderScene(drawCmdBuffers[i], depthPass.pipelineLayout, j);
|
||||||
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -430,7 +419,7 @@ public:
|
||||||
|
|
||||||
// Render shadowed scene
|
// Render shadowed scene
|
||||||
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, (filterPCF) ? pipelines.sceneShadowPCF : pipelines.sceneShadow);
|
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, (filterPCF) ? pipelines.sceneShadowPCF : pipelines.sceneShadow);
|
||||||
renderScene(drawCmdBuffers[i], pipelineLayout, descriptorSet);
|
renderScene(drawCmdBuffers[i], pipelineLayout);
|
||||||
|
|
||||||
drawUI(drawCmdBuffers[i]);
|
drawUI(drawCmdBuffers[i]);
|
||||||
|
|
||||||
|
|
@ -470,44 +459,31 @@ public:
|
||||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0),
|
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0),
|
||||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 1),
|
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 1),
|
||||||
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT, 2),
|
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT, 2),
|
||||||
|
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 3),
|
||||||
};
|
};
|
||||||
VkDescriptorSetLayoutCreateInfo descriptorLayout =
|
VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings);
|
||||||
vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings);
|
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout));
|
||||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayouts.base));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Descriptor sets
|
Descriptor sets
|
||||||
*/
|
*/
|
||||||
|
|
||||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
|
||||||
|
|
||||||
VkDescriptorImageInfo depthMapDescriptor =
|
VkDescriptorImageInfo depthMapDescriptor =
|
||||||
vks::initializers::descriptorImageInfo(depth.sampler, depth.view, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
|
vks::initializers::descriptorImageInfo(depth.sampler, depth.view, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
|
||||||
|
|
||||||
VkDescriptorSetAllocateInfo allocInfo =
|
VkDescriptorSetAllocateInfo allocInfo =
|
||||||
vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.base, 1);
|
vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
|
||||||
|
|
||||||
// Scene rendering / debug display
|
// Scene rendering / debug display
|
||||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
|
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
|
||||||
writeDescriptorSets = {
|
const std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
|
||||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.VS.descriptor),
|
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.VS.descriptor),
|
||||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &depthMapDescriptor),
|
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &depthMapDescriptor),
|
||||||
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2, &uniformBuffers.FS.descriptor),
|
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2, &uniformBuffers.FS.descriptor),
|
||||||
|
vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3, &cascadeViewProjMatricesBuffer.descriptor),
|
||||||
};
|
};
|
||||||
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL);
|
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL);
|
||||||
|
|
||||||
// Per-cascade descriptor sets
|
|
||||||
// Each descriptor set represents a single layer of the array texture
|
|
||||||
for (uint32_t i = 0; i < SHADOW_MAP_CASCADE_COUNT; i++) {
|
|
||||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &cascades[i].descriptorSet));
|
|
||||||
VkDescriptorImageInfo cascadeImageInfo = vks::initializers::descriptorImageInfo(depth.sampler, depth.view, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
|
|
||||||
writeDescriptorSets = {
|
|
||||||
vks::initializers::writeDescriptorSet(cascades[i].descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &depthPass.uniformBuffer.descriptor),
|
|
||||||
vks::initializers::writeDescriptorSet(cascades[i].descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &cascadeImageInfo)
|
|
||||||
};
|
|
||||||
vkUpdateDescriptorSets(device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Pipeline layouts
|
Pipeline layouts
|
||||||
*/
|
*/
|
||||||
|
|
@ -515,7 +491,7 @@ public:
|
||||||
// Shared pipeline layout (scene and depth map debug display)
|
// Shared pipeline layout (scene and depth map debug display)
|
||||||
{
|
{
|
||||||
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstBlock), 0);
|
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstBlock), 0);
|
||||||
std::array<VkDescriptorSetLayout, 2> setLayouts = { descriptorSetLayouts.base, vkglTF::descriptorSetLayoutImage };
|
std::array<VkDescriptorSetLayout, 2> setLayouts = { descriptorSetLayout, vkglTF::descriptorSetLayoutImage };
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast<uint32_t>(setLayouts.size()));
|
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast<uint32_t>(setLayouts.size()));
|
||||||
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
|
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
|
||||||
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
|
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
|
||||||
|
|
@ -525,7 +501,7 @@ public:
|
||||||
// Depth pass pipeline layout
|
// Depth pass pipeline layout
|
||||||
{
|
{
|
||||||
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstBlock), 0);
|
VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstBlock), 0);
|
||||||
std::array<VkDescriptorSetLayout, 2> setLayouts = { descriptorSetLayouts.base, vkglTF::descriptorSetLayoutImage };
|
std::array<VkDescriptorSetLayout, 2> setLayouts = { descriptorSetLayout, vkglTF::descriptorSetLayoutImage };
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast<uint32_t>(setLayouts.size()));
|
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast<uint32_t>(setLayouts.size()));
|
||||||
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
|
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
|
||||||
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
|
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
|
||||||
|
|
@ -599,12 +575,12 @@ public:
|
||||||
|
|
||||||
void prepareUniformBuffers()
|
void prepareUniformBuffers()
|
||||||
{
|
{
|
||||||
// Shadow map generation buffer blocks
|
// Cascade matrices
|
||||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||||
&depthPass.uniformBuffer,
|
&cascadeViewProjMatricesBuffer,
|
||||||
sizeof(depthPass.ubo)));
|
sizeof(glm::mat4) * SHADOW_MAP_CASCADE_COUNT));
|
||||||
|
|
||||||
// Scene uniform buffer blocks
|
// Scene uniform buffer blocks
|
||||||
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
VK_CHECK_RESULT(vulkanDevice->createBuffer(
|
||||||
|
|
@ -619,7 +595,7 @@ public:
|
||||||
sizeof(uboFS)));
|
sizeof(uboFS)));
|
||||||
|
|
||||||
// Map persistent
|
// Map persistent
|
||||||
VK_CHECK_RESULT(depthPass.uniformBuffer.map());
|
VK_CHECK_RESULT(cascadeViewProjMatricesBuffer.map());
|
||||||
VK_CHECK_RESULT(uniformBuffers.VS.map());
|
VK_CHECK_RESULT(uniformBuffers.VS.map());
|
||||||
VK_CHECK_RESULT(uniformBuffers.FS.map());
|
VK_CHECK_RESULT(uniformBuffers.FS.map());
|
||||||
|
|
||||||
|
|
@ -725,10 +701,11 @@ public:
|
||||||
/*
|
/*
|
||||||
Depth rendering
|
Depth rendering
|
||||||
*/
|
*/
|
||||||
|
std::vector<glm::mat4> cascadeViewProjMatrices(SHADOW_MAP_CASCADE_COUNT);
|
||||||
for (uint32_t i = 0; i < SHADOW_MAP_CASCADE_COUNT; i++) {
|
for (uint32_t i = 0; i < SHADOW_MAP_CASCADE_COUNT; i++) {
|
||||||
depthPass.ubo.cascadeViewProjMat[i] = cascades[i].viewProjMatrix;
|
cascadeViewProjMatrices[i] = cascades[i].viewProjMatrix;
|
||||||
}
|
}
|
||||||
memcpy(depthPass.uniformBuffer.mapped, &depthPass.ubo, sizeof(depthPass.ubo));
|
memcpy(cascadeViewProjMatricesBuffer.mapped, cascadeViewProjMatrices.data(), sizeof(glm::mat4) * SHADOW_MAP_CASCADE_COUNT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Scene rendering
|
Scene rendering
|
||||||
|
|
@ -736,14 +713,10 @@ public:
|
||||||
uboVS.projection = camera.matrices.perspective;
|
uboVS.projection = camera.matrices.perspective;
|
||||||
uboVS.view = camera.matrices.view;
|
uboVS.view = camera.matrices.view;
|
||||||
uboVS.model = glm::mat4(1.0f);
|
uboVS.model = glm::mat4(1.0f);
|
||||||
|
|
||||||
uboVS.lightDir = normalize(-lightPos);
|
uboVS.lightDir = normalize(-lightPos);
|
||||||
|
|
||||||
memcpy(uniformBuffers.VS.mapped, &uboVS, sizeof(uboVS));
|
memcpy(uniformBuffers.VS.mapped, &uboVS, sizeof(uboVS));
|
||||||
|
|
||||||
for (uint32_t i = 0; i < SHADOW_MAP_CASCADE_COUNT; i++) {
|
for (uint32_t i = 0; i < SHADOW_MAP_CASCADE_COUNT; i++) {
|
||||||
uboFS.cascadeSplits[i] = cascades[i].splitDepth;
|
uboFS.cascadeSplits[i] = cascades[i].splitDepth;
|
||||||
uboFS.cascadeViewProjMat[i] = cascades[i].viewProjMatrix;
|
|
||||||
}
|
}
|
||||||
uboFS.inverseViewMat = glm::inverse(camera.matrices.view);
|
uboFS.inverseViewMat = glm::inverse(camera.matrices.view);
|
||||||
uboFS.lightDir = normalize(-lightPos);
|
uboFS.lightDir = normalize(-lightPos);
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -11,16 +11,12 @@ layout(push_constant) uniform PushConsts {
|
||||||
uint cascadeIndex;
|
uint cascadeIndex;
|
||||||
} pushConsts;
|
} pushConsts;
|
||||||
|
|
||||||
layout (binding = 0) uniform UBO {
|
layout (set = 0, binding = 3) uniform UBO {
|
||||||
mat4[SHADOW_MAP_CASCADE_COUNT] cascadeViewProjMat;
|
mat4[SHADOW_MAP_CASCADE_COUNT] cascadeViewProjMat;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
layout (location = 0) out vec2 outUV;
|
layout (location = 0) out vec2 outUV;
|
||||||
|
|
||||||
out gl_PerVertex {
|
|
||||||
vec4 gl_Position;
|
|
||||||
};
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outUV = inUV;
|
outUV = inUV;
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -19,13 +19,16 @@ layout (location = 0) out vec4 outFragColor;
|
||||||
|
|
||||||
layout (set = 0, binding = 2) uniform UBO {
|
layout (set = 0, binding = 2) uniform UBO {
|
||||||
vec4 cascadeSplits;
|
vec4 cascadeSplits;
|
||||||
mat4 cascadeViewProjMat[SHADOW_MAP_CASCADE_COUNT];
|
|
||||||
mat4 inverseViewMat;
|
mat4 inverseViewMat;
|
||||||
vec3 lightDir;
|
vec3 lightDir;
|
||||||
float _pad;
|
float _pad;
|
||||||
int colorCascades;
|
int colorCascades;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
|
||||||
|
layout (set = 0, binding = 3) uniform CVPM {
|
||||||
|
mat4 matrices[SHADOW_MAP_CASCADE_COUNT];
|
||||||
|
} cascadeViewProjMatrices;
|
||||||
|
|
||||||
const mat4 biasMat = mat4(
|
const mat4 biasMat = mat4(
|
||||||
0.5, 0.0, 0.0, 0.0,
|
0.5, 0.0, 0.0, 0.0,
|
||||||
0.0, 0.5, 0.0, 0.0,
|
0.0, 0.5, 0.0, 0.0,
|
||||||
|
|
@ -84,7 +87,7 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Depth compare for shadowing
|
// Depth compare for shadowing
|
||||||
vec4 shadowCoord = (biasMat * ubo.cascadeViewProjMat[cascadeIndex]) * vec4(inPos, 1.0);
|
vec4 shadowCoord = (biasMat * cascadeViewProjMatrices.matrices[cascadeIndex]) * vec4(inPos, 1.0);
|
||||||
|
|
||||||
float shadow = 0;
|
float shadow = 0;
|
||||||
if (enablePCF == 1) {
|
if (enablePCF == 1) {
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -22,10 +22,6 @@ layout(push_constant) uniform PushConsts {
|
||||||
uint cascadeIndex;
|
uint cascadeIndex;
|
||||||
} pushConsts;
|
} pushConsts;
|
||||||
|
|
||||||
out gl_PerVertex {
|
|
||||||
vec4 gl_Position;
|
|
||||||
};
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outColor = inColor;
|
outColor = inColor;
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2020 Google LLC
|
// Copyright 2020 Google LLC
|
||||||
|
// Copyright 2024 Sascha Willems
|
||||||
|
|
||||||
struct VSInput
|
struct VSInput
|
||||||
{
|
{
|
||||||
|
|
@ -17,8 +18,7 @@ struct PushConsts {
|
||||||
struct UBO {
|
struct UBO {
|
||||||
float4x4 cascadeViewProjMat[SHADOW_MAP_CASCADE_COUNT];
|
float4x4 cascadeViewProjMat[SHADOW_MAP_CASCADE_COUNT];
|
||||||
};
|
};
|
||||||
|
cbuffer ubo : register(b3) { UBO ubo; }
|
||||||
cbuffer ubo : register(b0) { UBO ubo; }
|
|
||||||
|
|
||||||
struct VSOutput
|
struct VSOutput
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2020 Google LLC
|
// Copyright 2020 Google LLC
|
||||||
|
// Copyright 2024 Sascha Willems
|
||||||
|
|
||||||
#define SHADOW_MAP_CASCADE_COUNT 4
|
#define SHADOW_MAP_CASCADE_COUNT 4
|
||||||
|
|
||||||
|
|
@ -22,7 +23,6 @@ struct VSOutput
|
||||||
|
|
||||||
struct UBO {
|
struct UBO {
|
||||||
float4 cascadeSplits;
|
float4 cascadeSplits;
|
||||||
float4x4 cascadeViewProjMat[SHADOW_MAP_CASCADE_COUNT];
|
|
||||||
float4x4 inverseViewMat;
|
float4x4 inverseViewMat;
|
||||||
float3 lightDir;
|
float3 lightDir;
|
||||||
float _pad;
|
float _pad;
|
||||||
|
|
@ -30,6 +30,11 @@ struct UBO {
|
||||||
};
|
};
|
||||||
cbuffer ubo : register(b2) { UBO ubo; };
|
cbuffer ubo : register(b2) { UBO ubo; };
|
||||||
|
|
||||||
|
struct CVPM {
|
||||||
|
float4x4 matrices[SHADOW_MAP_CASCADE_COUNT];
|
||||||
|
};
|
||||||
|
cbuffer cascadeViewProjMatrices : register(b3) { CVPM cascadeViewProjMatrices; }
|
||||||
|
|
||||||
static const float4x4 biasMat = float4x4(
|
static const float4x4 biasMat = float4x4(
|
||||||
0.5, 0.0, 0.0, 0.5,
|
0.5, 0.0, 0.0, 0.5,
|
||||||
0.0, 0.5, 0.0, 0.5,
|
0.0, 0.5, 0.0, 0.5,
|
||||||
|
|
@ -90,7 +95,7 @@ float4 main(VSOutput input) : SV_TARGET
|
||||||
}
|
}
|
||||||
|
|
||||||
// Depth compare for shadowing
|
// Depth compare for shadowing
|
||||||
float4 shadowCoord = mul(biasMat, mul(ubo.cascadeViewProjMat[cascadeIndex], float4(input.Pos, 1.0)));
|
float4 shadowCoord = mul(biasMat, mul(cascadeViewProjMatrices.matrices[cascadeIndex], float4(input.Pos, 1.0)));
|
||||||
|
|
||||||
float shadow = 0;
|
float shadow = 0;
|
||||||
if (enablePCF == 1) {
|
if (enablePCF == 1) {
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue