From d3cd36984d879f63ee812b24e803a72d76c8094b Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sat, 7 Jan 2023 07:42:42 +0800 Subject: [PATCH] Shadow map WIP --- Assets/Shaders/ShadowMap_VS.glsl | 1 + Assets/Shaders/ShadowMap_VS.shshaderb | Bin 0 -> 1537 bytes Assets/Shaders/ShadowMap_VS.shshaderb.shmeta | 3 + .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 7 +- .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 2 +- .../MiddleEnd/Batching/SHSuperBatch.cpp | 4 +- .../MiddleEnd/Batching/SHSuperBatch.h | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 22 +++- .../MiddleEnd/Interface/SHGraphicsSystem.h | 2 + .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 3 +- .../MiddleEnd/Pipeline/SHPipelineLibrary.cpp | 8 +- .../Graphics/Pipeline/SHVkPipelineLayout.cpp | 112 +++++++++--------- .../src/Graphics/RenderGraph/SHSubpass.cpp | 13 +- 13 files changed, 111 insertions(+), 68 deletions(-) create mode 100644 Assets/Shaders/ShadowMap_VS.shshaderb create mode 100644 Assets/Shaders/ShadowMap_VS.shshaderb.shmeta diff --git a/Assets/Shaders/ShadowMap_VS.glsl b/Assets/Shaders/ShadowMap_VS.glsl index bf353eb5..e078679e 100644 --- a/Assets/Shaders/ShadowMap_VS.glsl +++ b/Assets/Shaders/ShadowMap_VS.glsl @@ -5,6 +5,7 @@ layout(location = 0) in vec3 aVertexPos; +layout(location = 4) in mat4 worldTransform; layout(set = 1, binding = 0) uniform CameraData { diff --git a/Assets/Shaders/ShadowMap_VS.shshaderb b/Assets/Shaders/ShadowMap_VS.shshaderb new file mode 100644 index 0000000000000000000000000000000000000000..3a8734c9daf1a50b7a6993c299eb04bab307964a GIT binary patch literal 1537 zcmZ9LTW`}q5QVq7wY0RQlwN>Rl7^dvRPg`^2?0Vaavy>kRK%-gB?c{W9LsT2;Hf{M z@RRseeL>=Uwl}i6)nshUe|`(gSeOtbKZLZJoDp4@n1 zGdqrj&gXpe=eUit6Z=b@sVQ=3R_-9O$)TNOK|Ba&Ic`txG>T@qrtZnTSxx<|$sYux zFbxiaEGV>qu@Wal`&P+C%QX2IWEBhzQyZRvIv%}~bo?ERKI@7Hl|IaZ*`JNmX!tn| z;>p)>Iw~~rJ%VC9nuRe(s%LI2=N*O~FucRi1BM2Nu?OROc*?McN8a7HtC)2p78qyp z{2YfE&W$UW9%hLZb(~wRBc`q|b7z5FtwUqAj+nX&nX3bHb=(7;oaIR~Gv1S-)5RU_ zS;X$G7c*$&@19w+)^!T!baW;?*l%jrl5fklR8L=G>NoVue^gt>dRoTUw5R`$;zfD* zV7uBeb9V+gtS#Pkd3ut6UB>w`H75AL3ORYg;kjgLBbEA7hH;u1BXw{yus+_W^2s(JNS=; zQ;YVOdI{*_PAu?CA-s?G`bFEO4E<<+BPP1GWZ*8oqdgk`sD}Jq860ppXuB^%*C%n% z)G0B!8MaqqXm`ABiJ`ME)#!d8qaHr_w(PggCHGK9e>mKM`#zTOt@)mBbxUG+|1_mn Fvi~Asj5 literal 0 HcmV?d00001 diff --git a/Assets/Shaders/ShadowMap_VS.shshaderb.shmeta b/Assets/Shaders/ShadowMap_VS.shshaderb.shmeta new file mode 100644 index 00000000..837cec19 --- /dev/null +++ b/Assets/Shaders/ShadowMap_VS.shshaderb.shmeta @@ -0,0 +1,3 @@ +Name: ShadowMap_VS +ID: 44646107 +Type: 2 diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 7e4069f6..fd2ccd3b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -551,7 +551,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* SHBatch - Usage Functions */ /*---------------------------------------------------------------------------------*/ - void SHBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) + void SHBatch::Draw(Handle cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline/* = true*/) { if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) { @@ -566,7 +566,10 @@ namespace SHADE // Bind all required objects before drawing static std::array dynamicOffset{ 0 }; cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index)); - cmdBuffer->BindPipeline(pipeline); + + if (bindBatchPipeline) + cmdBuffer->BindPipeline(pipeline); + cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); if (matPropsDescSet[frameIndex]) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index d4ce068e..6d1f775f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -87,7 +87,7 @@ namespace SHADE void UpdateTransformBuffer(uint32_t frameIndex); void UpdateInstancedIntegerBuffer(uint32_t frameIndex); void Build(Handle device, Handle descPool, uint32_t frameIndex) ; - void Draw(Handle cmdBuffer, uint32_t frameIndex); + void Draw(Handle cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true); /*-----------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 58993026..8006d0be 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -107,12 +107,12 @@ namespace SHADE } } - void SHSuperBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept + void SHSuperBatch::Draw(Handle cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline /*= true*/) noexcept { // Build all batches for (auto& batch : batches) { - batch.Draw(cmdBuffer, frameIndex); + batch.Draw(cmdBuffer, frameIndex, bindBatchPipeline); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h index 75bd1829..4d831b9c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h @@ -57,7 +57,7 @@ namespace SHADE void Clear() noexcept; void UpdateBuffers(uint32_t frameIndex, Handle descPool); void Build(Handle device, Handle descPool, uint32_t frameIndex) noexcept; - void Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept; + void Draw(Handle cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true) noexcept; /*-----------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 19ad5473..ec592522 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -127,6 +127,8 @@ namespace SHADE SHFreetypeInstance::Init(); + SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_VS.glsl", false); + // Load Built In Shaders static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet(FS_DEFAULT); @@ -140,6 +142,8 @@ namespace SHADE static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet(TEXT_FS); static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet(RENDER_SC_VS); static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet(RENDER_SC_FS); + static constexpr AssetID SHADOW_MAP_VS = 44646107; shadowMapVS = SHResourceManager::LoadOrGet(SHADOW_MAP_VS); + } void SHGraphicsSystem::InitRenderGraph(void) noexcept @@ -752,9 +756,20 @@ namespace SHADE // we need to wait for the device to finish using the graph first device->WaitIdle(); - auto const& EVENT_DATA = reinterpret_cast*>(eventPtr.get())->data; - auto* lightComp = SHComponentManager::GetComponent(EVENT_DATA->lightEntity); - std::string resourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); + auto const& EVENT_DATA = reinterpret_cast*>(eventPtr.get())->data; + auto* lightComp = SHComponentManager::GetComponent(EVENT_DATA->lightEntity); + std::string resourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); + Handle companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphNodeNames::GBUFFER_PASS.data())->GetSubpass("G-Buffer Write"); + + if (!shadowMapPipeline) + { + SHPipelineLibrary tempLibrary{}; + Handle rgNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data()); + + tempLibrary.Init(device); + tempLibrary.CreateGraphicsPipelines({ shadowMapVS, {} }, rgNode->GetRenderpass(), companionSubpass); + shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, {} }); + } if (EVENT_DATA->generateRenderer) { @@ -773,6 +788,7 @@ namespace SHADE // Add a subpass to render to that shadow map auto newSubpass = shadowMapNode->RuntimeAddSubpass(resourceName + " Subpass", worldViewport, lightComp->GetRenderer()); newSubpass->AddDepthOutput(resourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL); + newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline // regenerate the node shadowMapNode->RuntimeStandaloneRegenerate(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 88d66ded..b8c43c75 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -464,6 +464,7 @@ namespace SHADE Handle textFS; Handle renderToSwapchainVS; Handle renderToSwapchainFS; + Handle shadowMapVS; // Fonts Handle testFont; @@ -478,6 +479,7 @@ namespace SHADE Handle debugDrawWireMeshDepthPipeline; Handle debugDrawFilledPipeline; Handle debugDrawFilledDepthPipeline; + Handle shadowMapPipeline; // initialized only when a shadow map is needed // Built-In Textures Handle defaultTexture; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index 31512f9b..17cffe17 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -378,11 +378,10 @@ namespace SHADE SHMatrix SHLightingSubSystem::GetViewMatrix(SHLightComponent* lightComp) noexcept { - SHTransformComponent* transform = SHComponentManager::GetComponent(lightComp->GetEID()); switch (lightComp->GetLightData().type) { case SH_LIGHT_TYPE::DIRECTIONAL: - return SHMatrix::LookAtRH(transform->GetLocalPosition(), lightComp->GetLightData().position, SHVec3(0.0f, 1.0f, 0.0f)); + return SHMatrix::LookAtRH(lightComp->GetLightData().position, lightComp->GetLightData().position + lightComp->GetLightData().direction, SHVec3(0.0f, 1.0f, 0.0f)); case SH_LIGHT_TYPE::POINT: return {}; case SH_LIGHT_TYPE::SPOT: diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp index baf09a2d..daa4d154 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -10,9 +10,15 @@ namespace SHADE Handle SHPipelineLibrary::CreateGraphicsPipelines(std::pair, Handle> const& vsFsPair, Handle renderpass, Handle subpass) noexcept { + std::vector> modules{}; + if (vsFsPair.first) + modules.push_back(vsFsPair.first); + if (vsFsPair.second) + modules.push_back(vsFsPair.second); + SHPipelineLayoutParams params { - .shaderModules = {vsFsPair.first, vsFsPair.second}, + .shaderModules = std::move (modules), .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts }; diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp index c2d83052..325b3f56 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp @@ -19,69 +19,71 @@ namespace SHADE for (auto& shaderModule : shaderModules) { - // References for convenience - auto const& reflectedData = shaderModule->GetReflectedData(); - auto const& pcInfo = reflectedData.GetPushConstantInfo(); - - // If a push constant block exists for the shader module - if (pcInfo.memberCount != 0) + if (shaderModule) { - bool exists = false; + // References for convenience + auto const& reflectedData = shaderModule->GetReflectedData(); + auto const& pcInfo = reflectedData.GetPushConstantInfo(); - // Check if push constant block already exists - for (uint32_t i = 0; i < pcInfos.size(); ++i) + // If a push constant block exists for the shader module + if (pcInfo.memberCount != 0) { - // If there is a block with the same name, member count and size - if (std::strcmp(pcInfos[i]->name, pcInfo.name) == 0 && pcInfos[i]->memberCount == pcInfo.memberCount && pcInfos[i]->size == pcInfo.size) + bool exists = false; + + // Check if push constant block already exists + for (uint32_t i = 0; i < pcInfos.size(); ++i) { - // We just take the existing pc range we built earlier, and allow it to be accessed in potentially other shader stages - vkPcRanges[i].stageFlags |= shaderModule->GetShaderStageFlagBits(); + // If there is a block with the same name, member count and size + if (std::strcmp(pcInfos[i]->name, pcInfo.name) == 0 && pcInfos[i]->memberCount == pcInfo.memberCount && pcInfos[i]->size == pcInfo.size) + { + // We just take the existing pc range we built earlier, and allow it to be accessed in potentially other shader stages + vkPcRanges[i].stageFlags |= shaderModule->GetShaderStageFlagBits(); - // Set flag and stop checking - exists = true; - break; - } - } - - // If the block doesn't exist yet - if (!exists) - { - // Loop through all member variables of the new push constant block - for (uint32_t i = 0; i < pcInfo.memberCount; ++i) - { - std::string variableName; - variableName.reserve(50); - variableName += pcInfo.name; - variableName += "."; - variableName += pcInfo.members[i].name; - - // Add the variable's offset info to the interface - pushConstantInterface.AddOffset(std::move(variableName), startOffset + pcInfo.members[i].offset); + // Set flag and stop checking + exists = true; + break; + } } - // New push constant range - vk::PushConstantRange newRange; + // If the block doesn't exist yet + if (!exists) + { + // Loop through all member variables of the new push constant block + for (uint32_t i = 0; i < pcInfo.memberCount; ++i) + { + std::string variableName; + variableName.reserve(50); + variableName += pcInfo.name; + variableName += "."; + variableName += pcInfo.members[i].name; - // set offset and size - newRange.offset = startOffset; - newRange.size = pcInfo.size; + // Add the variable's offset info to the interface + pushConstantInterface.AddOffset(std::move(variableName), startOffset + pcInfo.members[i].offset); + } - // Stage flags will be whatever shader stage of the shader that contains the push constant block - newRange.stageFlags = shaderModule->GetShaderStageFlagBits(); + // New push constant range + vk::PushConstantRange newRange; - // Add to the list foe checking later - pcInfos.push_back(&pcInfo); + // set offset and size + newRange.offset = startOffset; + newRange.size = pcInfo.size; - // For pipeline layout to consume - vkPcRanges.push_back(newRange); + // Stage flags will be whatever shader stage of the shader that contains the push constant block + newRange.stageFlags = shaderModule->GetShaderStageFlagBits(); - // Next push constant block will start next to the previous push constant block - startOffset += pcInfo.size; + // Add to the list foe checking later + pcInfos.push_back(&pcInfo); + + // For pipeline layout to consume + vkPcRanges.push_back(newRange); + + // Next push constant block will start next to the previous push constant block + startOffset += pcInfo.size; + } + + stageFlags |= shaderModule->GetShaderStageFlagBits(); } - - stageFlags |= shaderModule->GetShaderStageFlagBits(); } - } // After all the sizes of the push constant blocks have been added, record the size in the interface @@ -132,6 +134,9 @@ namespace SHADE //! Now we take descriptor set info from all shaders and prepare some bindings for the descriptor set for (auto& shaderModule : shaderModules) { + if (!shaderModule) + continue; + auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo(); auto const& reflectedSets = descBindingInfo.GetReflectedSets(); @@ -326,11 +331,10 @@ namespace SHADE { for (auto& mod : shaderModules) { - mod->AddCallback([this]() - { - RecreateIfNeeded(); - } - ); + if (mod) + { + mod->AddCallback([this]() { RecreateIfNeeded(); }); + } } RecreateIfNeeded (); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index cd5bae58..e1277953 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -229,8 +229,17 @@ namespace SHADE if (renderer) renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex); - // Draw all the batches - superBatch->Draw(commandBuffer, frameIndex); + // If companion subpass is not a valid handle, render super batch normally + if (!companionSubpass.companion) + { + // Draw all the batches + superBatch->Draw(commandBuffer, frameIndex); + } + else + { + commandBuffer->BindPipeline(companionSubpass.pipeline); + companionSubpass.companion->superBatch->Draw(commandBuffer, frameIndex, false); + } } // Draw all the exterior draw calls