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 00000000..3a8734c9 Binary files /dev/null and b/Assets/Shaders/ShadowMap_VS.shshaderb differ 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