Implemented Shadow maps (still needs improvement) #314

Merged
Xenosas1337 merged 22 commits from SP3-1-Rendering into main 2023-01-16 15:40:30 +08:00
13 changed files with 111 additions and 68 deletions
Showing only changes of commit d3cd36984d - Show all commits

View File

@ -5,6 +5,7 @@
layout(location = 0) in vec3 aVertexPos; layout(location = 0) in vec3 aVertexPos;
layout(location = 4) in mat4 worldTransform;
layout(set = 1, binding = 0) uniform CameraData layout(set = 1, binding = 0) uniform CameraData
{ {

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: ShadowMap_VS
ID: 44646107
Type: 2

View File

@ -551,7 +551,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* SHBatch - Usage Functions */ /* SHBatch - Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline/* = true*/)
{ {
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
{ {
@ -566,7 +566,10 @@ namespace SHADE
// Bind all required objects before drawing // Bind all required objects before drawing
static std::array<uint32_t, 1> dynamicOffset{ 0 }; static std::array<uint32_t, 1> dynamicOffset{ 0 };
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index)); 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::TRANSFORM, transformDataBuffer[frameIndex], 0);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
if (matPropsDescSet[frameIndex]) if (matPropsDescSet[frameIndex])

View File

@ -87,7 +87,7 @@ namespace SHADE
void UpdateTransformBuffer(uint32_t frameIndex); void UpdateTransformBuffer(uint32_t frameIndex);
void UpdateInstancedIntegerBuffer(uint32_t frameIndex); void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ; void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex); void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Getter Functions */ /* Getter Functions */

View File

@ -107,12 +107,12 @@ namespace SHADE
} }
} }
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline /*= true*/) noexcept
{ {
// Build all batches // Build all batches
for (auto& batch : batches) for (auto& batch : batches)
{ {
batch.Draw(cmdBuffer, frameIndex); batch.Draw(cmdBuffer, frameIndex, bindBatchPipeline);
} }
} }

View File

@ -57,7 +57,7 @@ namespace SHADE
void Clear() noexcept; void Clear() noexcept;
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool); void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept; void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept; void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true) noexcept;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Getter Functions */ /* Getter Functions */

View File

@ -127,6 +127,8 @@ namespace SHADE
SHFreetypeInstance::Init(); SHFreetypeInstance::Init();
SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_VS.glsl", false);
// Load Built In Shaders // Load Built In Shaders
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT); static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT); static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
@ -140,6 +142,8 @@ namespace SHADE
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS); static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS); static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS);
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS); static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS);
static constexpr AssetID SHADOW_MAP_VS = 44646107; shadowMapVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_MAP_VS);
} }
void SHGraphicsSystem::InitRenderGraph(void) noexcept void SHGraphicsSystem::InitRenderGraph(void) noexcept
@ -752,9 +756,20 @@ 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 resourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity);
Handle<SHSubpass> companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphNodeNames::GBUFFER_PASS.data())->GetSubpass("G-Buffer Write");
if (!shadowMapPipeline)
{
SHPipelineLibrary tempLibrary{};
Handle<SHRenderGraphNode> 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) if (EVENT_DATA->generateRenderer)
{ {
@ -773,6 +788,7 @@ namespace SHADE
// Add a subpass to render to that shadow map // Add a subpass to render to that shadow map
auto newSubpass = shadowMapNode->RuntimeAddSubpass(resourceName + " Subpass", worldViewport, lightComp->GetRenderer()); auto newSubpass = shadowMapNode->RuntimeAddSubpass(resourceName + " Subpass", worldViewport, lightComp->GetRenderer());
newSubpass->AddDepthOutput(resourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL); newSubpass->AddDepthOutput(resourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline
// regenerate the node // regenerate the node
shadowMapNode->RuntimeStandaloneRegenerate(); shadowMapNode->RuntimeStandaloneRegenerate();

View File

@ -464,6 +464,7 @@ namespace SHADE
Handle<SHVkShaderModule> textFS; Handle<SHVkShaderModule> textFS;
Handle<SHVkShaderModule> renderToSwapchainVS; Handle<SHVkShaderModule> renderToSwapchainVS;
Handle<SHVkShaderModule> renderToSwapchainFS; Handle<SHVkShaderModule> renderToSwapchainFS;
Handle<SHVkShaderModule> shadowMapVS;
// Fonts // Fonts
Handle<SHFont> testFont; Handle<SHFont> testFont;
@ -478,6 +479,7 @@ namespace SHADE
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline; Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
Handle<SHVkPipeline> debugDrawFilledPipeline; Handle<SHVkPipeline> debugDrawFilledPipeline;
Handle<SHVkPipeline> debugDrawFilledDepthPipeline; Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
Handle<SHVkPipeline> shadowMapPipeline; // initialized only when a shadow map is needed
// Built-In Textures // Built-In Textures
Handle<SHTexture> defaultTexture; Handle<SHTexture> defaultTexture;

View File

@ -378,11 +378,10 @@ namespace SHADE
SHMatrix SHLightingSubSystem::GetViewMatrix(SHLightComponent* lightComp) noexcept SHMatrix SHLightingSubSystem::GetViewMatrix(SHLightComponent* lightComp) noexcept
{ {
SHTransformComponent* transform = SHComponentManager::GetComponent<SHTransformComponent>(lightComp->GetEID());
switch (lightComp->GetLightData().type) switch (lightComp->GetLightData().type)
{ {
case SH_LIGHT_TYPE::DIRECTIONAL: 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: case SH_LIGHT_TYPE::POINT:
return {}; return {};
case SH_LIGHT_TYPE::SPOT: case SH_LIGHT_TYPE::SPOT:

View File

@ -10,9 +10,15 @@ namespace SHADE
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass) noexcept Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass) noexcept
{ {
std::vector<Handle<SHVkShaderModule>> modules{};
if (vsFsPair.first)
modules.push_back(vsFsPair.first);
if (vsFsPair.second)
modules.push_back(vsFsPair.second);
SHPipelineLayoutParams params SHPipelineLayoutParams params
{ {
.shaderModules = {vsFsPair.first, vsFsPair.second}, .shaderModules = std::move (modules),
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
}; };

View File

@ -19,69 +19,71 @@ namespace SHADE
for (auto& shaderModule : shaderModules) for (auto& shaderModule : shaderModules)
{ {
// References for convenience if (shaderModule)
auto const& reflectedData = shaderModule->GetReflectedData();
auto const& pcInfo = reflectedData.GetPushConstantInfo();
// If a push constant block exists for the shader module
if (pcInfo.memberCount != 0)
{ {
bool exists = false; // References for convenience
auto const& reflectedData = shaderModule->GetReflectedData();
auto const& pcInfo = reflectedData.GetPushConstantInfo();
// Check if push constant block already exists // If a push constant block exists for the shader module
for (uint32_t i = 0; i < pcInfos.size(); ++i) if (pcInfo.memberCount != 0)
{ {
// If there is a block with the same name, member count and size bool exists = false;
if (std::strcmp(pcInfos[i]->name, pcInfo.name) == 0 && pcInfos[i]->memberCount == pcInfo.memberCount && pcInfos[i]->size == pcInfo.size)
// 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 // If there is a block with the same name, member count and size
vkPcRanges[i].stageFlags |= shaderModule->GetShaderStageFlagBits(); 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 // Set flag and stop checking
exists = true; exists = true;
break; 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);
} }
// New push constant range // If the block doesn't exist yet
vk::PushConstantRange newRange; 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 // Add the variable's offset info to the interface
newRange.offset = startOffset; pushConstantInterface.AddOffset(std::move(variableName), startOffset + pcInfo.members[i].offset);
newRange.size = pcInfo.size; }
// Stage flags will be whatever shader stage of the shader that contains the push constant block // New push constant range
newRange.stageFlags = shaderModule->GetShaderStageFlagBits(); vk::PushConstantRange newRange;
// Add to the list foe checking later // set offset and size
pcInfos.push_back(&pcInfo); newRange.offset = startOffset;
newRange.size = pcInfo.size;
// For pipeline layout to consume // Stage flags will be whatever shader stage of the shader that contains the push constant block
vkPcRanges.push_back(newRange); newRange.stageFlags = shaderModule->GetShaderStageFlagBits();
// Next push constant block will start next to the previous push constant block // Add to the list foe checking later
startOffset += pcInfo.size; 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 // 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 //! Now we take descriptor set info from all shaders and prepare some bindings for the descriptor set
for (auto& shaderModule : shaderModules) for (auto& shaderModule : shaderModules)
{ {
if (!shaderModule)
continue;
auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo(); auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo();
auto const& reflectedSets = descBindingInfo.GetReflectedSets(); auto const& reflectedSets = descBindingInfo.GetReflectedSets();
@ -326,11 +331,10 @@ namespace SHADE
{ {
for (auto& mod : shaderModules) for (auto& mod : shaderModules)
{ {
mod->AddCallback([this]() if (mod)
{ {
RecreateIfNeeded(); mod->AddCallback([this]() { RecreateIfNeeded(); });
} }
);
} }
RecreateIfNeeded (); RecreateIfNeeded ();

View File

@ -229,8 +229,17 @@ namespace SHADE
if (renderer) if (renderer)
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex); renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
// Draw all the batches // If companion subpass is not a valid handle, render super batch normally
superBatch->Draw(commandBuffer, frameIndex); 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 // Draw all the exterior draw calls