Implemented Shadow maps (still needs improvement) #314
|
@ -13,6 +13,8 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::predefinedLayouts;
|
||||
SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState;
|
||||
SHVertexInputState SHGraphicsPredefinedData::shadowMapVertexInputState;
|
||||
|
||||
std::vector<SHGraphicsPredefinedData::PerSystem> SHGraphicsPredefinedData::perSystemData;
|
||||
|
||||
//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_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(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
|
||||
|
||||
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
|
||||
{
|
||||
perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES));
|
||||
InitDescSetLayouts(logicalDevice);
|
||||
InitDefaultVertexInputState();
|
||||
InitPredefinedVertexInputState();
|
||||
InitDescMappings();
|
||||
InitDummyPipelineLayouts (logicalDevice);
|
||||
}
|
||||
|
@ -231,6 +236,11 @@ namespace SHADE
|
|||
}
|
||||
|
||||
|
||||
SHVertexInputState const& SHGraphicsPredefinedData::GetShadowMapViState(void) noexcept
|
||||
{
|
||||
return shadowMapVertexInputState;
|
||||
}
|
||||
|
||||
SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept
|
||||
{
|
||||
return perSystemData[static_cast<uint32_t>(systemType)];
|
||||
|
|
|
@ -58,6 +58,9 @@ namespace SHADE
|
|||
//! Default vertex input state (used by everything).
|
||||
static SHVertexInputState defaultVertexInputState;
|
||||
|
||||
//! vertex input state for shadow mapping
|
||||
static SHVertexInputState shadowMapVertexInputState;
|
||||
|
||||
//! Predefined data for each type of system
|
||||
static std::vector<PerSystem> perSystemData;
|
||||
|
||||
|
@ -73,7 +76,7 @@ namespace SHADE
|
|||
static void InitDescMappings (void) noexcept;
|
||||
static void InitDummyPipelineLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||
static void InitDefaultVertexInputState (void) noexcept;
|
||||
static void InitPredefinedVertexInputState (void) noexcept;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
@ -91,6 +94,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
static std::vector<Handle<SHVkDescriptorSetLayout>> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept;
|
||||
static SHVertexInputState const& GetDefaultViState (void) noexcept;
|
||||
static SHVertexInputState const& GetShadowMapViState (void) noexcept;
|
||||
static PerSystem const& GetSystemData (SystemType systemType) noexcept;
|
||||
static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept;
|
||||
//static PerSystem const& GetBatchingSystemData(void) noexcept;
|
||||
|
|
|
@ -267,7 +267,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
// 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.
|
||||
auto shadowMapPassNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data(), {}, {});
|
||||
//auto shadowMapPassNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data(), {}, {});
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* DEFERRED COMPOSITE NODE */
|
||||
|
@ -760,16 +760,6 @@ namespace SHADE
|
|||
auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(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)
|
||||
{
|
||||
|
@ -782,16 +772,29 @@ namespace SHADE
|
|||
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.
|
||||
auto shadowMapNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data());
|
||||
shadowMapNode->RuntimeLinkResource(resourceName);
|
||||
//auto shadowMapNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphNodeNames::SHADOW_MAP_PASS.data());
|
||||
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
|
||||
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->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline
|
||||
|
||||
// regenerate the node
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHPipelineLibrary.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
|
||||
#include "Graphics/RenderGraph/SHSubpass.h"
|
||||
#include "Graphics/SHVkUtil.h"
|
||||
|
||||
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{};
|
||||
if (vsFsPair.first)
|
||||
|
@ -27,7 +26,7 @@ namespace SHADE
|
|||
|
||||
// Create the pipeline and configure the default vertex input state
|
||||
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
|
||||
newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsPredefinedData::GetDefaultViState());
|
||||
newPipeline->GetPipelineState().SetVertexInputState(viState);
|
||||
|
||||
SHColorBlendState colorBlendState{};
|
||||
colorBlendState.logic_op_enable = VK_FALSE;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <unordered_map>
|
||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||
#include "Graphics/Pipeline/SHVkPipeline.h"
|
||||
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -32,7 +33,8 @@ namespace SHADE
|
|||
Handle<SHVkPipeline> CreateGraphicsPipelines (
|
||||
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
||||
Handle<SHVkRenderpass> renderpass,
|
||||
Handle<SHSubpass> subpass
|
||||
Handle<SHSubpass> subpass,
|
||||
SHVertexInputState const& viState = SHGraphicsPredefinedData::GetDefaultViState()
|
||||
) noexcept;
|
||||
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||
|
|
|
@ -195,7 +195,7 @@ namespace SHADE
|
|||
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
|
||||
bindings.emplace_back();
|
||||
|
@ -228,8 +228,9 @@ namespace SHADE
|
|||
// The binding for that attribute description is index of the new binding created earlier in this function
|
||||
vertexAttrib.binding = static_cast<uint32_t>(bindings.size() - 1);
|
||||
|
||||
// Attribute location. New index is simply + 1 of the previous. Starts from 0 obviously
|
||||
vertexAttrib.location = static_cast<uint32_t>(attributes.size () - 1);
|
||||
//Attribute location. New index is simply + 1 of the previous. Starts from 0 obviously
|
||||
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
|
||||
vertexAttrib.format = format;
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace SHADE
|
|||
SHVertexInputState& operator= (SHVertexInputState const& 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 SHVkPipeline;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\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
|
||||
{
|
||||
for (auto& node : predecessorNodes)
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace SHADE
|
|||
void ConfigureRenderpasses (void) noexcept;
|
||||
void ConfigureSubSystems (void) noexcept;
|
||||
void ConfigureFramebuffers (void) noexcept;
|
||||
void ReindexNodes (void) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER VARIABLES */
|
||||
|
@ -123,6 +124,12 @@ namespace SHADE
|
|||
std::initializer_list<ResourceInstruction> resourceInstruction,
|
||||
std::initializer_list<std::string> predecessorNodes
|
||||
) noexcept;
|
||||
Handle<SHRenderGraphNode> AddNodeAfter
|
||||
(
|
||||
std::string nodeName,
|
||||
std::initializer_list<ResourceInstruction> resourceInstruction,
|
||||
std::string nodeToAddAfter
|
||||
) noexcept;
|
||||
|
||||
void AddRenderToSwapchainNode
|
||||
(
|
||||
|
|
|
@ -365,6 +365,7 @@ namespace SHADE
|
|||
, spDeps{ std::move(rhs.spDeps) }
|
||||
, nodeComputes{ std::move(rhs.nodeComputes) }
|
||||
, name { std::move(rhs.name) }
|
||||
, ISelfHandle<SHRenderGraphNode>{std::move(rhs)}
|
||||
|
||||
{
|
||||
rhs.renderpass = {};
|
||||
|
|
|
@ -77,6 +77,7 @@ namespace SHADE
|
|||
, name { rhs.name }
|
||||
, viewport {rhs.viewport}
|
||||
, renderer {rhs.renderer}
|
||||
, companionSubpass {rhs.companionSubpass}
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -113,6 +114,7 @@ namespace SHADE
|
|||
name = std::move(rhs.name);
|
||||
renderer = rhs.renderer;
|
||||
viewport = rhs.viewport;
|
||||
companionSubpass = rhs.companionSubpass;
|
||||
|
||||
|
||||
return *this;
|
||||
|
@ -237,6 +239,7 @@ namespace SHADE
|
|||
}
|
||||
else
|
||||
{
|
||||
// if not bind pipeline for companion and and execute draw command
|
||||
commandBuffer->BindPipeline(companionSubpass.pipeline);
|
||||
companionSubpass.companion->superBatch->Draw(commandBuffer, frameIndex, false);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue