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
11 changed files with 126 additions and 26 deletions
Showing only changes of commit 3e01c9e80a - Show all commits

View File

@ -13,6 +13,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::predefinedLayouts; std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::predefinedLayouts;
SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState; SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState;
SHVertexInputState SHGraphicsPredefinedData::shadowMapVertexInputState;
std::vector<SHGraphicsPredefinedData::PerSystem> SHGraphicsPredefinedData::perSystemData; std::vector<SHGraphicsPredefinedData::PerSystem> SHGraphicsPredefinedData::perSystemData;
//SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::batchingSystemData; //SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::batchingSystemData;
@ -193,7 +195,7 @@ namespace SHADE
); );
} }
void SHGraphicsPredefinedData::InitDefaultVertexInputState(void) noexcept void SHGraphicsPredefinedData::InitPredefinedVertexInputState(void) noexcept
{ {
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // UVs at binding 1 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // UVs at binding 1
@ -201,13 +203,16 @@ namespace SHADE
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots) defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots)
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8 defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8
shadowMapVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D)});
shadowMapVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }, 4); // Transform at binding 4 - 7 (4 slots)
} }
void SHGraphicsPredefinedData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept void SHGraphicsPredefinedData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept
{ {
perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES)); perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES));
InitDescSetLayouts(logicalDevice); InitDescSetLayouts(logicalDevice);
InitDefaultVertexInputState(); InitPredefinedVertexInputState();
InitDescMappings(); InitDescMappings();
InitDummyPipelineLayouts (logicalDevice); InitDummyPipelineLayouts (logicalDevice);
} }
@ -231,6 +236,11 @@ namespace SHADE
} }
SHVertexInputState const& SHGraphicsPredefinedData::GetShadowMapViState(void) noexcept
{
return shadowMapVertexInputState;
}
SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept
{ {
return perSystemData[static_cast<uint32_t>(systemType)]; return perSystemData[static_cast<uint32_t>(systemType)];

View File

@ -58,6 +58,9 @@ namespace SHADE
//! Default vertex input state (used by everything). //! Default vertex input state (used by everything).
static SHVertexInputState defaultVertexInputState; static SHVertexInputState defaultVertexInputState;
//! vertex input state for shadow mapping
static SHVertexInputState shadowMapVertexInputState;
//! Predefined data for each type of system //! Predefined data for each type of system
static std::vector<PerSystem> perSystemData; static std::vector<PerSystem> perSystemData;
@ -73,7 +76,7 @@ namespace SHADE
static void InitDescMappings (void) noexcept; static void InitDescMappings (void) noexcept;
static void InitDummyPipelineLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept; static void InitDummyPipelineLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept; static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
static void InitDefaultVertexInputState (void) noexcept; static void InitPredefinedVertexInputState (void) noexcept;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -91,6 +94,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static std::vector<Handle<SHVkDescriptorSetLayout>> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept; static std::vector<Handle<SHVkDescriptorSetLayout>> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept;
static SHVertexInputState const& GetDefaultViState (void) noexcept; static SHVertexInputState const& GetDefaultViState (void) noexcept;
static SHVertexInputState const& GetShadowMapViState (void) noexcept;
static PerSystem const& GetSystemData (SystemType systemType) noexcept; static PerSystem const& GetSystemData (SystemType systemType) noexcept;
static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept; static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept;
//static PerSystem const& GetBatchingSystemData(void) noexcept; //static PerSystem const& GetBatchingSystemData(void) noexcept;

View File

@ -267,7 +267,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Shadow map pass will have no resources bound at first. Lighting system will add resources to the node. // Shadow map pass will have no resources bound at first. Lighting system will add resources to the node.
// It will initially also not have any subpasses since they will be added for each light that casts shadows. // It will initially also not have any subpasses since they will be added for each light that casts shadows.
auto shadowMapPassNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data(), {}, {}); //auto shadowMapPassNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data(), {}, {});
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* DEFERRED COMPOSITE NODE */ /* DEFERRED COMPOSITE NODE */
@ -761,16 +761,6 @@ namespace SHADE
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"); 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)
{ {
// Create new renderer for the light component and give it to the light component // Create new renderer for the light component and give it to the light component
@ -782,17 +772,30 @@ namespace SHADE
renderGraph->AddResource(resourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT}, resizeWidth, resizeHeight, vk::Format::eD24UnormS8Uint); renderGraph->AddResource(resourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT}, resizeWidth, resizeHeight, vk::Format::eD24UnormS8Uint);
// 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->GetNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data()); //auto shadowMapNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data());
shadowMapNode->RuntimeLinkResource(resourceName); auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data() + resourceName, {resourceName.c_str()}, SHGraphicsConstants::RenderGraphNodeNames::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", worldViewport, lightComp->GetRenderer()); auto newSubpass = shadowMapNode->RuntimeAddSubpass(resourceName + " Subpass", worldViewport, worldRenderer);
//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();
// Create pipeline from new renderpass and subpass if it's not created yet
if (!shadowMapPipeline)
{
SHPipelineLibrary tempLibrary{};
Handle<SHRenderGraphNode> rgNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data());
tempLibrary.Init(device);
tempLibrary.CreateGraphicsPipelines({ shadowMapVS, {} }, shadowMapNode->GetRenderpass(), newSubpass, SHGraphicsPredefinedData::GetShadowMapViState());
shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, {} });
}
newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline
return eventPtr->handle; return eventPtr->handle;
} }

View File

@ -1,14 +1,13 @@
#include "SHpch.h" #include "SHpch.h"
#include "SHPipelineLibrary.h" #include "SHPipelineLibrary.h"
#include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/RenderGraph/SHSubpass.h" #include "Graphics/RenderGraph/SHSubpass.h"
#include "Graphics/SHVkUtil.h" #include "Graphics/SHVkUtil.h"
namespace SHADE 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, SHVertexInputState const& viState/* = SHGraphicsPredefinedData::GetDefaultViState()*/) noexcept
{ {
std::vector<Handle<SHVkShaderModule>> modules{}; std::vector<Handle<SHVkShaderModule>> modules{};
if (vsFsPair.first) if (vsFsPair.first)
@ -27,7 +26,7 @@ namespace SHADE
// Create the pipeline and configure the default vertex input state // Create the pipeline and configure the default vertex input state
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass); auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsPredefinedData::GetDefaultViState()); newPipeline->GetPipelineState().SetVertexInputState(viState);
SHColorBlendState colorBlendState{}; SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE; colorBlendState.logic_op_enable = VK_FALSE;

View File

@ -3,6 +3,7 @@
#include <unordered_map> #include <unordered_map>
#include "Graphics/Shaders/SHVkShaderModule.h" #include "Graphics/Shaders/SHVkShaderModule.h"
#include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/Pipeline/SHVkPipeline.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
namespace SHADE namespace SHADE
{ {
@ -32,7 +33,8 @@ namespace SHADE
Handle<SHVkPipeline> CreateGraphicsPipelines ( Handle<SHVkPipeline> CreateGraphicsPipelines (
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
Handle<SHVkRenderpass> renderpass, Handle<SHVkRenderpass> renderpass,
Handle<SHSubpass> subpass Handle<SHSubpass> subpass,
SHVertexInputState const& viState = SHGraphicsPredefinedData::GetDefaultViState()
) noexcept; ) noexcept;
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept; Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept; bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;

View File

@ -195,7 +195,7 @@ namespace SHADE
return *this; return *this;
} }
void SHVertexInputState::AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs) noexcept void SHVertexInputState::AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs, uint32_t fixedAttributeLocation/* = static_cast<uint32_t>(-1)*/) noexcept
{ {
// add a binding and get ref to it // add a binding and get ref to it
bindings.emplace_back(); bindings.emplace_back();
@ -229,7 +229,8 @@ namespace SHADE
vertexAttrib.binding = static_cast<uint32_t>(bindings.size() - 1); vertexAttrib.binding = static_cast<uint32_t>(bindings.size() - 1);
//Attribute location. New index is simply + 1 of the previous. Starts from 0 obviously //Attribute location. New index is simply + 1 of the previous. Starts from 0 obviously
vertexAttrib.location = static_cast<uint32_t>(attributes.size () - 1); vertexAttrib.location = (fixedAttributeLocation != static_cast<uint32_t>(-1)) ? fixedAttributeLocation + i : static_cast<uint32_t>(attributes.size () - 1);
//vertexAttrib.location = static_cast<uint32_t>(attributes.size() - 1);
// Get the vkFormat associated with the SHAttribFormat // Get the vkFormat associated with the SHAttribFormat
vertexAttrib.format = format; vertexAttrib.format = format;

View File

@ -34,7 +34,7 @@ namespace SHADE
SHVertexInputState& operator= (SHVertexInputState const& rhs) noexcept; SHVertexInputState& operator= (SHVertexInputState const& rhs) noexcept;
SHVertexInputState& operator= (SHVertexInputState&& rhs) noexcept; SHVertexInputState& operator= (SHVertexInputState&& rhs) noexcept;
void AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs) noexcept; void AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs, uint32_t fixedAttributeLocation = static_cast<uint32_t>(-1)) noexcept;
friend class SHVkPipelineState; friend class SHVkPipelineState;
friend class SHVkPipeline; friend class SHVkPipeline;

View File

@ -275,6 +275,17 @@ namespace SHADE
} }
} }
void SHRenderGraph::ReindexNodes(void) noexcept
{
nodeIndexing.clear();
uint32_t i = 0;
for (auto& node : nodes)
{
nodeIndexing.emplace (node->name, i);
++i;
}
}
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -415,6 +426,65 @@ namespace SHADE
return node; return node;
} }
/***************************************************************************/
/*!
\brief
This function is purely used for dynamic nodes (if such a thing were to
exist in our architecture). In other words, don't use this function unless
the new node is fully standalone and does not rely or is a prereq of
other nodes.
\param nodeName
Name of new node
\param resourceInstruction
Resources for the node
\param nodeToAddAfter
The node to add the new node after.
\return
*/
/***************************************************************************/
Handle<SHRenderGraphNode> SHRenderGraph::AddNodeAfter(std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::string nodeToAddAfter) noexcept
{
if (nodeIndexing.contains(nodeName))
{
SHLOG_ERROR("Node already exists, cannot add node. ");
return {};
}
std::vector<SHAttachmentDescInitParams> descInitParams;
for (auto const& instruction : resourceInstruction)
{
// If the resource that the new node is requesting for exists, allow the graph to reference it
if (renderGraphStorage->graphResources->contains(instruction.resourceName))
{
descInitParams.push_back(
{
.resourceHdl = renderGraphStorage->graphResources->at(instruction.resourceName),
.dontClearOnLoad = instruction.dontClearOnLoad,
}
);
}
else
{
SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node.");
return{};
}
}
// get target node
auto targetNode = nodes.begin() + nodeIndexing.at(nodeToAddAfter);
auto node = nodes.insert(targetNode, renderGraphStorage->resourceHub->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::vector<Handle<SHRenderGraphNode>>()));
ReindexNodes ();
return *node;
}
void SHRenderGraph::AddRenderToSwapchainNode(std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept void SHRenderGraph::AddRenderToSwapchainNode(std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept
{ {
for (auto& node : predecessorNodes) for (auto& node : predecessorNodes)

View File

@ -55,6 +55,7 @@ namespace SHADE
void ConfigureRenderpasses (void) noexcept; void ConfigureRenderpasses (void) noexcept;
void ConfigureSubSystems (void) noexcept; void ConfigureSubSystems (void) noexcept;
void ConfigureFramebuffers (void) noexcept; void ConfigureFramebuffers (void) noexcept;
void ReindexNodes (void) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
@ -123,6 +124,12 @@ namespace SHADE
std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<ResourceInstruction> resourceInstruction,
std::initializer_list<std::string> predecessorNodes std::initializer_list<std::string> predecessorNodes
) noexcept; ) noexcept;
Handle<SHRenderGraphNode> AddNodeAfter
(
std::string nodeName,
std::initializer_list<ResourceInstruction> resourceInstruction,
std::string nodeToAddAfter
) noexcept;
void AddRenderToSwapchainNode void AddRenderToSwapchainNode
( (

View File

@ -365,6 +365,7 @@ namespace SHADE
, spDeps{ std::move(rhs.spDeps) } , spDeps{ std::move(rhs.spDeps) }
, nodeComputes{ std::move(rhs.nodeComputes) } , nodeComputes{ std::move(rhs.nodeComputes) }
, name { std::move(rhs.name) } , name { std::move(rhs.name) }
, ISelfHandle<SHRenderGraphNode>{std::move(rhs)}
{ {
rhs.renderpass = {}; rhs.renderpass = {};

View File

@ -77,6 +77,7 @@ namespace SHADE
, name { rhs.name } , name { rhs.name }
, viewport {rhs.viewport} , viewport {rhs.viewport}
, renderer {rhs.renderer} , renderer {rhs.renderer}
, companionSubpass {rhs.companionSubpass}
{ {
} }
@ -113,6 +114,7 @@ namespace SHADE
name = std::move(rhs.name); name = std::move(rhs.name);
renderer = rhs.renderer; renderer = rhs.renderer;
viewport = rhs.viewport; viewport = rhs.viewport;
companionSubpass = rhs.companionSubpass;
return *this; return *this;
@ -237,6 +239,7 @@ namespace SHADE
} }
else else
{ {
// if not bind pipeline for companion and and execute draw command
commandBuffer->BindPipeline(companionSubpass.pipeline); commandBuffer->BindPipeline(companionSubpass.pipeline);
companionSubpass.companion->superBatch->Draw(commandBuffer, frameIndex, false); companionSubpass.companion->superBatch->Draw(commandBuffer, frameIndex, false);
} }