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
12 changed files with 144 additions and 19 deletions
Showing only changes of commit 19f9b67550 - Show all commits

View File

@ -0,0 +1,21 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
//#include "ShaderDescriptorDefinitions.glsl"
layout(location = 0) in vec3 aVertexPos;
layout(set = 1, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 projMat;
} cameraData;
void main()
{
// clip space for rendering
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
}

View File

@ -10,5 +10,8 @@ namespace SHADE
{ {
//! We need to get the light component and initialize the relevant variables. //! We need to get the light component and initialize the relevant variables.
EntityID lightEntity; EntityID lightEntity;
//! Generate a renderer for the light component
bool generateRenderer;
}; };
} }

View File

@ -46,6 +46,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h" #include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
#include "Events/SHEvent.h" #include "Events/SHEvent.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Input/SHInputManager.h"
namespace SHADE namespace SHADE
{ {
@ -400,7 +401,7 @@ namespace SHADE
postOffscreenRenderSubSystem->Init(device, renderGraph->GetRenderGraphResource("Scene"), descPool); postOffscreenRenderSubSystem->Init(device, renderGraph->GetRenderGraphResource("Scene"), descPool);
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>(); lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
lightingSubSystem->Init(device, descPool, samplerCache.GetSampler (device, SHVkSamplerParams lightingSubSystem->Init(device, descPool, &resourceManager, samplerCache.GetSampler (device, SHVkSamplerParams
{ {
// nothing for now // nothing for now
}) })
@ -557,6 +558,15 @@ namespace SHADE
#endif #endif
} }
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::B))
{
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
for (auto& comp : lightComps)
{
comp.SetEnableShadow(true);
}
}
renderGraph->Begin(frameIndex); renderGraph->Begin(frameIndex);
auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex); auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex);
@ -746,18 +756,26 @@ namespace SHADE
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);
if (EVENT_DATA->generateRenderer)
{
// Create new renderer for the light component and give it to the light component
Handle<SHRenderer> newRenderer = resourceManager.Create<SHRenderer>(device, swapchain->GetNumImages(), descPool, SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC);
lightComp->SetRenderer (newRenderer);
}
// Add the shadow map resource to the graph // Add the shadow map resource to the graph
renderGraph->AddResource(resourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE}, 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); shadowMapNode->RuntimeLinkResource(resourceName);
// Add a subpass to render to that shadow map // Add a subpass to render to that shadow map
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);
// regenerate the node // regenerate the node
//shadowMapNode->RuntimeStandaloneRegenerate(); shadowMapNode->RuntimeStandaloneRegenerate();
return eventPtr->handle; return eventPtr->handle;
} }

View File

@ -18,9 +18,9 @@ of DigiPen Institute of Technology is prohibited.
// Project Includes // Project Includes
#include "SHCamera.h" #include "SHCamera.h"
#include "Resource/SHHandle.h" #include "Resource/SHHandle.h"
#include "Graphics/RenderGraph/SHRenderGraph.h"
#include "Math/SHMath.h" #include "Math/SHMath.h"
#include <vector> #include <vector>
#include "Graphics/Pipeline/SHPipelineType.h"
namespace SHADE namespace SHADE
{ {

View File

@ -2,6 +2,7 @@
#include "SHLightComponent.h" #include "SHLightComponent.h"
#include "Graphics/Events/SHGraphicsEvents.h" #include "Graphics/Events/SHGraphicsEvents.h"
#include "Events/SHEventManager.hpp" #include "Events/SHEventManager.hpp"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
namespace SHADE namespace SHADE
{ {
@ -14,6 +15,7 @@ namespace SHADE
//indexInBuffer = std::numeric_limits<uint32_t>::max(); //indexInBuffer = std::numeric_limits<uint32_t>::max();
isActive = true; isActive = true;
//Unbind(); //Unbind();
renderer = {};
} }
@ -116,11 +118,17 @@ namespace SHADE
// Create new event and broadcast it // Create new event and broadcast it
SHLightEnableShadowEvent newEvent; SHLightEnableShadowEvent newEvent;
newEvent.lightEntity = GetEID(); newEvent.lightEntity = GetEID();
newEvent.generateRenderer = static_cast<bool>(!renderer);
SHEventManager::BroadcastEvent<SHLightEnableShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT); SHEventManager::BroadcastEvent<SHLightEnableShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT);
} }
} }
void SHLightComponent::SetRenderer(Handle<SHRenderer> newRenderer) noexcept
{
renderer = newRenderer;
}
SHLightData const& SHLightComponent::GetLightData(void) const noexcept SHLightData const& SHLightComponent::GetLightData(void) const noexcept
{ {
return lightData; return lightData;
@ -172,6 +180,11 @@ namespace SHADE
return lightData.strength; return lightData.strength;
} }
Handle<SHRenderer> SHLightComponent::GetRenderer(void) const noexcept
{
return renderer;
}
} }
RTTR_REGISTRATION RTTR_REGISTRATION

View File

@ -3,9 +3,11 @@
#include <rttr/registration> #include <rttr/registration>
#include "ECS_Base/Components/SHComponent.h" #include "ECS_Base/Components/SHComponent.h"
#include "SHLightData.h" #include "SHLightData.h"
#include "Resource/SHHandle.h"
namespace SHADE namespace SHADE
{ {
class SHRenderer;
class SH_API SHLightComponent final : public SHComponent class SH_API SHLightComponent final : public SHComponent
{ {
@ -14,6 +16,9 @@ namespace SHADE
//! GPU depends on the type of the light. //! GPU depends on the type of the light.
SHLightData lightData; SHLightData lightData;
//! Renderer to calculate light world to projection matrix
Handle<SHRenderer> renderer;
//! Since the lighting system is gonna be self contained and light weight, we store this //! Since the lighting system is gonna be self contained and light weight, we store this
//! so that we only write this to the CPU buffer when this light component change, we don't //! so that we only write this to the CPU buffer when this light component change, we don't
//! rewrite everything. However we still write to the GPU buffer when everything changes. //! rewrite everything. However we still write to the GPU buffer when everything changes.
@ -49,6 +54,7 @@ namespace SHADE
//void SetBound (uint32_t inIndexInBuffer) noexcept; //void SetBound (uint32_t inIndexInBuffer) noexcept;
void SetStrength (float value) noexcept; // serialized void SetStrength (float value) noexcept; // serialized
void SetEnableShadow (bool flag) noexcept; void SetEnableShadow (bool flag) noexcept;
void SetRenderer (Handle<SHRenderer> newRenderer) noexcept;
SHLightData const& GetLightData (void) const noexcept; SHLightData const& GetLightData (void) const noexcept;
@ -61,6 +67,7 @@ namespace SHADE
//bool GetBound (void) const noexcept; //bool GetBound (void) const noexcept;
//uint32_t GetIndexInBuffer (void) const noexcept; //uint32_t GetIndexInBuffer (void) const noexcept;
float GetStrength (void) const noexcept; float GetStrength (void) const noexcept;
Handle<SHRenderer> GetRenderer (void) const noexcept;
RTTR_ENABLE() RTTR_ENABLE()
}; };
} }

View File

@ -13,6 +13,9 @@
#include "Graphics/Images/SHVkImageView.h" #include "Graphics/Images/SHVkImageView.h"
#include "Graphics/MiddleEnd/Textures/SHVkSamplerCache.h" #include "Graphics/MiddleEnd/Textures/SHVkSamplerCache.h"
#include "Graphics/Images/SHVkSampler.h" #include "Graphics/Images/SHVkSampler.h"
#include "Graphics/Events/SHGraphicsEvents.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
#include "Math/Transform/SHTransformComponent.h"
namespace SHADE namespace SHADE
{ {
@ -373,6 +376,27 @@ namespace SHADE
} }
SHMatrix SHLightingSubSystem::GetViewMatrix(SHLightComponent* lightComp) noexcept
{
SHTransformComponent* transform = SHComponentManager::GetComponent<SHTransformComponent>(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));
case SH_LIGHT_TYPE::POINT:
return {};
case SH_LIGHT_TYPE::SPOT:
return {};
case SH_LIGHT_TYPE::AMBIENT:
return {};
case SH_LIGHT_TYPE::NUM_TYPES:
return {};
default:
return {};
}
}
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -383,11 +407,12 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHLightingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, Handle<SHVkSampler> inShadowMapSampler) noexcept void SHLightingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, SHResourceHub* rh, Handle<SHVkSampler> inShadowMapSampler) noexcept
{ {
SHComponentManager::CreateComponentSparseSet<SHLightComponent>(); SHComponentManager::CreateComponentSparseSet<SHLightComponent>();
logicalDevice = device; logicalDevice = device;
resourceHub = rh;
uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES); uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES);
#pragma region LIGHTING #pragma region LIGHTING
@ -496,6 +521,14 @@ namespace SHADE
// Light is now updated in the container // Light is now updated in the container
//light.ClearDirtyFlag(); //light.ClearDirtyFlag();
} }
if (auto renderer = light.GetRenderer())
{
//SHMatrix orthoMatrix = SHMatrix::OrthographicRH()
renderer->UpdateDataManual (frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicRH(80.0f, 80.0f, 0.01f, 10000.0f));
}
} }
// Write data to GPU // Write data to GPU
@ -561,7 +594,7 @@ namespace SHADE
// Update descriptor set // Update descriptor set
static constexpr uint32_t SHADOW_MAP_DESC_SET_INDEX = 0; static constexpr uint32_t SHADOW_MAP_DESC_SET_INDEX = 0;
uint32_t const SHADOW_MAP_DESC_ARRAY_INDEX = shadowMapImageSamplers.size() - 1; uint32_t const SHADOW_MAP_DESC_ARRAY_INDEX = static_cast<uint32_t>(shadowMapImageSamplers.size()) - 1u;
shadowMapDescriptorSet->ModifyWriteDescImage shadowMapDescriptorSet->ModifyWriteDescImage
( (
SHADOW_MAP_DESC_SET_INDEX, SHADOW_MAP_DESC_SET_INDEX,

View File

@ -178,6 +178,10 @@ namespace SHADE
//! to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) //! to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
std::vector<vk::ImageMemoryBarrier> shadowMapMemoryBarriers; std::vector<vk::ImageMemoryBarrier> shadowMapMemoryBarriers;
//! Resource hub from Graphics System
SHResourceHub* resourceHub;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -185,13 +189,14 @@ namespace SHADE
void ComputeDynamicOffsets (void) noexcept; void ComputeDynamicOffsets (void) noexcept;
void ResetNumLights (void) noexcept; void ResetNumLights (void) noexcept;
void UpdateShadowMapDesc (void) noexcept; void UpdateShadowMapDesc (void) noexcept;
SHMatrix GetViewMatrix (SHLightComponent* lightComp) noexcept;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, Handle<SHVkSampler> inShadowMapSampler) noexcept; void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, SHResourceHub* rh, Handle<SHVkSampler> inShadowMapSampler) noexcept;
void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept; void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept;
void Exit (void) noexcept; void Exit (void) noexcept;
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept; void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept;

View File

@ -743,9 +743,9 @@ namespace SHADE
resourceAttachmentMapping->try_emplace(newResource.GetId().Raw, attachmentDescriptions.size() - 1); resourceAttachmentMapping->try_emplace(newResource.GetId().Raw, attachmentDescriptions.size() - 1);
} }
void SHRenderGraphNode::RuntimeAddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept Handle<SHSubpass> SHRenderGraphNode::RuntimeAddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept
{ {
AddSubpass(std::move (subpassName), viewport, renderer); return AddSubpass(std::move (subpassName), viewport, renderer);
} }
/***************************************************************************/ /***************************************************************************/

View File

@ -117,7 +117,7 @@ namespace SHADE
// Runtime functions that don't affect the renderpass // Runtime functions that don't affect the renderpass
void RuntimeLinkResource(std::string resourceName) noexcept; void RuntimeLinkResource(std::string resourceName) noexcept;
void RuntimeAddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept; Handle<SHSubpass> RuntimeAddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept;
void RuntimeStandaloneRegenerate (void) noexcept; void RuntimeStandaloneRegenerate (void) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/

View File

@ -443,6 +443,12 @@ namespace SHADE
subpassIndex = index; subpassIndex = index;
} }
void SHSubpass::SetCompanionSubpass(Handle<SHSubpass> companion, Handle<SHVkPipeline> pipeline) noexcept
{
companionSubpass.companion = companion;
companionSubpass.pipeline = pipeline;
}
/***************************************************************************/ /***************************************************************************/
/*! /*!

View File

@ -21,12 +21,23 @@ namespace SHADE
class SHVkSampler; class SHVkSampler;
class SHRenderer; class SHRenderer;
class SHViewport; class SHViewport;
class SHVkPipeline;
class SH_API SHSubpass : public ISelfHandle<SHSubpass> class SH_API SHSubpass : public ISelfHandle<SHSubpass>
{ {
public: public:
using ExteriorDrawCallFunction = std::function<void(Handle<SHVkCommandBuffer>, Handle<SHRenderer>, uint32_t)>; using ExteriorDrawCallFunction = std::function<void(Handle<SHVkCommandBuffer>, Handle<SHRenderer>, uint32_t)>;
// Allows for subpasses to run using a companions data
struct CompanionSubpass
{
// subpass whose data will be borrowed to draw
Handle<SHSubpass> companion;
// Pipeline that will be used for all the draw calls from all batches of the companion subpass
Handle<SHVkPipeline> pipeline;
};
private: private:
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
@ -94,6 +105,9 @@ namespace SHADE
// For identifying subpasses // For identifying subpasses
std::string name; std::string name;
//! Optional component to a companion subpass. If the subpass handle of this object
//! is valid, the subpass will be drawn using this companion's data.
CompanionSubpass companionSubpass;
private: private:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -133,13 +147,18 @@ namespace SHADE
void CreateInputDescriptors (void) noexcept; void CreateInputDescriptors (void) noexcept;
void UpdateWriteDescriptors (void) noexcept; void UpdateWriteDescriptors (void) noexcept;
/*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */
/*-----------------------------------------------------------------------*/
private: private:
/*-----------------------------------------------------------------------*/
/* PRIVATE GETTERS AND SETTERS */
/*-----------------------------------------------------------------------*/
void SetIndex (uint32_t index) noexcept; void SetIndex (uint32_t index) noexcept;
public: public:
/*-----------------------------------------------------------------------*/
/* PUBLIC SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
void SetCompanionSubpass (Handle<SHSubpass> companion, Handle<SHVkPipeline> pipeline) noexcept;
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept; Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
SHSubPassIndex GetIndex() const noexcept; SHSubPassIndex GetIndex() const noexcept;
Handle<SHSuperBatch> GetSuperBatch(void) const noexcept; Handle<SHSuperBatch> GetSuperBatch(void) const noexcept;