Implemented different shadow mapping technique

This commit is contained in:
Brandon Mak 2023-02-15 21:34:22 +08:00
parent 3a28873496
commit 5acca02363
7 changed files with 58 additions and 28 deletions

View File

@ -8440,6 +8440,11 @@
IsActive: true IsActive: true
NumberOfChildren: 0 NumberOfChildren: 0
Components: Components:
Transform Component:
Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
IsActive: true
Light Component: Light Component:
Position: {x: 0, y: 0, z: 0} Position: {x: 0, y: 0, z: 0}
Type: Directional Type: Directional
@ -8469,14 +8474,14 @@
NumberOfChildren: 0 NumberOfChildren: 0
Components: Components:
Transform Component: Transform Component:
Translate: {x: 2, y: 1.5, z: -5.5999999} Translate: {x: 0.242245644, y: 1.56757355, z: -6.07086945}
Rotate: {x: -0, y: 0, z: -0} Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 1, y: 1, z: 1} Scale: {x: 1, y: 1, z: 1}
IsActive: true IsActive: true
Light Component: Light Component:
Position: {x: 2, y: 1.5, z: -5.5999999} Position: {x: 2, y: 1.5, z: -5.5999999}
Type: Directional Type: Directional
Direction: {x: -0.245000005, y: 0, z: 0} Direction: {x: 0, y: 0, z: -1}
Color: {x: 0, y: 0, z: 0, w: 1} Color: {x: 0, y: 0, z: 0, w: 1}
Layer: 4294967295 Layer: 4294967295
Strength: 1 Strength: 1

View File

@ -48,19 +48,34 @@ layout(std430, set = 1, binding = 4) buffer AmbientLightData
AmbientLightStruct aLightData[]; AmbientLightStruct aLightData[];
} AmbLightData; } AmbLightData;
float LinStep (float val, float low, float high)
{
return clamp ((val - low)/(high - low), 0.0f, 1.0f);
}
float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV) float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV)
{ {
// clip space for fragment from light view space
vec4 fragPosLightPOV = lightPV * worldSpaceFragPos; vec4 fragPosLightPOV = lightPV * worldSpaceFragPos;
// Perform perspective division and convert to 0 to 1 range
vec3 converted = (fragPosLightPOV.xyz / fragPosLightPOV.w) * vec3(0.5f) + vec3(0.5f); vec3 converted = (fragPosLightPOV.xyz / fragPosLightPOV.w) * vec3(0.5f) + vec3(0.5f);
float sampledDepth = texture(shadowMap, converted.xy).r; // float sampledDepth = texture(shadowMap, converted.xy).r;
// float sampledDepth = texture(shadowMap, converted.xy).z;
vec2 moments = texture(shadowMap, converted.xy).xy;
if (converted.x < 0.0f || converted.x > 1.0f || converted.y < 0.0f || converted.y > 1.0f) if (converted.x < 0.0f || converted.x > 1.0f || converted.y < 0.0f || converted.y > 1.0f)
return 1.0f; return 1.0f;
if (fragPosLightPOV.z > sampledDepth && fragPosLightPOV.w > 0.0f) if (fragPosLightPOV.z > moments.x && fragPosLightPOV.w > 0.0f)
{ {
return 0.7f; float p = step (fragPosLightPOV.z, moments.x);
float variance = max (moments.y - (moments.x * moments.x), 0.00002f);
float d = fragPosLightPOV.z - moments.x;
float pMax = LinStep (variance / (variance + (d * d)), 0.9f, 1.0f);
return min (max (p, pMax), 1.0f);
} }
else else
return 1.0f; return 1.0f;

View File

@ -3,8 +3,10 @@
#extension GL_ARB_shading_language_420pack : enable #extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require #extension GL_EXT_nonuniform_qualifier : require
layout(location = 0) out vec4 shadowMap;
void main() void main()
{ {
// shadowMap = vec4 (0.0f, 0.0f, gl_FragCoord.z, 1.0f);
shadowMap = vec4 (gl_FragCoord.z, gl_FragCoord.z * gl_FragCoord.z, 0.0f, 1.0f);
} }

View File

@ -129,6 +129,7 @@ namespace SHADE
//SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_FS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/PureCopy_CS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/PureCopy_CS.glsl", false);
@ -588,18 +589,18 @@ namespace SHADE
static bool shadowAdded = false; static bool shadowAdded = false;
if (shadowAdded == false/* && SHInputManager::GetKey(SHInputManager::SH_KEYCODE::B)*/) if (shadowAdded == false && SHInputManager::GetKey(SHInputManager::SH_KEYCODE::B))
{ {
shadowAdded = true; shadowAdded = true;
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>(); auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
if (lightComps.size() > 2) //if (lightComps.size() > 2)
{
lightComps[2].SetEnableShadow(true);
}
//for (auto& comp : lightComps)
//{ //{
// comp.SetEnableShadow(true); // lightComps[2].SetEnableShadow(true);
//} //}
for (auto& comp : lightComps)
{
comp.SetEnableShadow(true);
}
} }
renderGraph->Begin(frameIndex); renderGraph->Begin(frameIndex);
@ -779,10 +780,11 @@ namespace SHADE
// we need to wait for the device to finish using the graph first // we need to wait for the device to finish using the graph first
device->WaitIdle(); device->WaitIdle();
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightEnableShadowEvent>*>(eventPtr.get())->data; auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightEnableShadowEvent>*>(eventPtr.get())->data;
auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(EVENT_DATA->lightEntity); auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(EVENT_DATA->lightEntity);
std::string resourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity);
Handle<SHSubpass> companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS); std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity);
Handle<SHSubpass> companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS);
if (EVENT_DATA->generateRenderer) if (EVENT_DATA->generateRenderer)
{ {
@ -795,14 +797,16 @@ namespace SHADE
} }
// Add the shadow map resource to the graph // Add the shadow map resource to the graph
renderGraph->AddResource(resourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT}, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat); renderGraph->AddResource(depthResourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH}, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat);
renderGraph->AddResource(shadowMapResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat);
// link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer. // link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer.
auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + resourceName, {resourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data()); auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, {depthResourceName.c_str(), shadowMapResourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data());
// Add a subpass to render to that shadow map // Add a subpass to render to that shadow map
auto newSubpass = shadowMapNode->RuntimeAddSubpass(resourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer()); auto newSubpass = shadowMapNode->RuntimeAddSubpass(shadowMapResourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer());
newSubpass->AddDepthOutput(resourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH); newSubpass->AddColorOutput(shadowMapResourceName);
newSubpass->AddDepthOutput(depthResourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH);
// regenerate the node // regenerate the node
shadowMapNode->RuntimeStandaloneRegenerate(); shadowMapNode->RuntimeStandaloneRegenerate();
@ -828,7 +832,7 @@ namespace SHADE
newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline
// add the shadow map to the lighting system // add the shadow map to the lighting system
uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(resourceName), EVENT_DATA->lightEntity); uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(shadowMapResourceName), EVENT_DATA->lightEntity);
auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()); auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data());
nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX); nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX);

View File

@ -395,7 +395,11 @@ namespace SHADE
switch (lightComp->GetLightData().type) switch (lightComp->GetLightData().type)
{ {
case SH_LIGHT_TYPE::DIRECTIONAL: case SH_LIGHT_TYPE::DIRECTIONAL:
return SHMatrix::Transpose(SHMatrix::LookAtLH(lightComp->GetLightData().position, SHVec3::Normalise (lightComp->GetLightData().direction), SHVec3(0.0f, -1.0f, 0.0f))); {
SHTransformComponent* transform = SHComponentManager::GetComponent<SHTransformComponent>(lightComp->GetEID());
return SHMatrix::Transpose(SHMatrix::LookAtLH(transform->GetWorldPosition(), SHVec3::Normalise(lightComp->GetLightData().direction), SHVec3(0.0f, -1.0f, 0.0f)));
}
//return SHMatrix::Transpose(SHMatrix::LookAtLH(/*lightComp->GetLightData().position*/SHVec3(1.27862f, 4.78952f, 4.12811f), SHVec3(-0.280564f, -0.66262f, -0.69422f), SHVec3(0.0f, -1.0f, 0.0f))); //return SHMatrix::Transpose(SHMatrix::LookAtLH(/*lightComp->GetLightData().position*/SHVec3(1.27862f, 4.78952f, 4.12811f), SHVec3(-0.280564f, -0.66262f, -0.69422f), SHVec3(0.0f, -1.0f, 0.0f)));
case SH_LIGHT_TYPE::POINT: case SH_LIGHT_TYPE::POINT:
return {}; return {};
@ -518,7 +522,7 @@ namespace SHADE
if (auto renderer = light.GetRenderer()) if (auto renderer = light.GetRenderer())
{ {
//SHMatrix orthoMatrix = SHMatrix::OrthographicRH() //SHMatrix orthoMatrix = SHMatrix::OrthographicRH()
renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(10.0f, 10.0f, 1.0f, 50.0f)); renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(12.0f, 12.0f, 1.0f, 80.0f));
} }
auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type); auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type);
@ -627,16 +631,16 @@ namespace SHADE
// add to barriers // add to barriers
shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier
{ {
.srcAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentWrite, .srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead,
.dstAccessMask = vk::AccessFlagBits::eShaderRead, .dstAccessMask = vk::AccessFlagBits::eShaderRead,
.oldLayout = vk::ImageLayout::eDepthAttachmentOptimal, .oldLayout = vk::ImageLayout::eColorAttachmentOptimal,
.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal, .newLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = newShadowMap->GetImage()->GetVkImage(), .image = newShadowMap->GetImage()->GetVkImage(),
.subresourceRange = vk::ImageSubresourceRange .subresourceRange = vk::ImageSubresourceRange
{ {
.aspectMask = vk::ImageAspectFlagBits::eDepth, .aspectMask = vk::ImageAspectFlagBits::eColor,
.baseMipLevel = 0, .baseMipLevel = 0,
.levelCount = 1, .levelCount = 1,
.baseArrayLayer = 0, .baseArrayLayer = 0,
@ -651,7 +655,7 @@ namespace SHADE
void SHLightingSubSystem::PrepareShadowMapsForRead(Handle<SHVkCommandBuffer> cmdBuffer) noexcept void SHLightingSubSystem::PrepareShadowMapsForRead(Handle<SHVkCommandBuffer> cmdBuffer) noexcept
{ {
// Issue barrier to transition shadow maps for reading in compute shader // Issue barrier to transition shadow maps for reading in compute shader
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers); cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers);
} }
//void SHLightingSubSystem::HandleResize(Handle<SHRenderGraphNodeCompute> compute) noexcept //void SHLightingSubSystem::HandleResize(Handle<SHRenderGraphNodeCompute> compute) noexcept