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
9 changed files with 92 additions and 41 deletions
Showing only changes of commit 9538636af6 - Show all commits

View File

@ -175,6 +175,12 @@ namespace SHADE
writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
writeInfo.descImageInfos[i].imageLayout = layout;
}
// Rest is not used, so it doesn't matter what's in them, we just want to pacify Vulkan
for (uint32_t i = imageViewsAndSamplers.size(); i < writeInfo.descImageInfos.size(); ++i)
{
writeInfo.descImageInfos[i].sampler = std::get<Handle<SHVkSampler>>(imageViewsAndSamplers.back())->GetVkSampler();
}
}
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& imageViewAndSampler, uint32_t descIndex) noexcept

View File

@ -183,35 +183,43 @@ namespace SHADE
/*if (!extensionsSupported)
SHUtil::ReportWarning("Some of the required extensions cannot be found on the physical device. ");*/
vk::PhysicalDeviceFeatures features{}; // ADD MORE FEATURES HERE IF NEEDED
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature
{
.shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
.descriptorBindingPartiallyBound = VK_TRUE,
.descriptorBindingVariableDescriptorCount = VK_TRUE,
.runtimeDescriptorArray = VK_TRUE,
};
vk::PhysicalDeviceRobustness2FeaturesEXT robustFeatures
{
.nullDescriptor = VK_TRUE,
};
robustFeatures.pNext = &descIndexingFeature;
vk::PhysicalDeviceFeatures2 features{}; // ADD MORE FEATURES HERE IF NEEDED
// point and lines fill mode
features.fillModeNonSolid = VK_TRUE;
features.samplerAnisotropy = VK_TRUE;
features.multiDrawIndirect = VK_TRUE;
features.independentBlend = VK_TRUE;
features.features.fillModeNonSolid = VK_TRUE;
features.features.samplerAnisotropy = VK_TRUE;
features.features.multiDrawIndirect = VK_TRUE;
features.features.independentBlend = VK_TRUE;
features.features.wideLines = VK_TRUE;
// for wide lines
features.wideLines = true;
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{};
descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
descIndexingFeature.shaderSampledImageArrayNonUniformIndexing = true;
descIndexingFeature.descriptorBindingPartiallyBound = true;
descIndexingFeature.runtimeDescriptorArray = true;
features.pNext = &robustFeatures;
// Prepare to create the device
vk::DeviceCreateInfo deviceCreateInfo
{
.pNext = &descIndexingFeature,
.pNext = &features,
.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size()),
.pQueueCreateInfos = queueCreateInfos.data(),
.enabledLayerCount = 0, // deprecated and ignored
.ppEnabledLayerNames = nullptr, // deprecated and ignored
.enabledExtensionCount = !extensionsSupported ? 0 : static_cast<uint32_t>(requiredExtensions.size()),
.ppEnabledExtensionNames = !extensionsSupported ? nullptr : requiredExtensions.data(),
.pEnabledFeatures = &features
//.pEnabledFeatures = &features
};
// Actually create the device

View File

@ -193,17 +193,17 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
// Initialize world render graph
renderGraph->Init("World Render Graph", device, swapchain, &resourceManager, renderContextCmdPools);
renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
//worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second);
renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
renderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
renderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second);
renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second);
renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
renderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
renderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, true, windowDims.first, windowDims.second);
/*-----------------------------------------------------------------------*/
/* MAIN NODE */
@ -766,21 +766,18 @@ namespace SHADE
}
// Add the shadow map resource to the graph
renderGraph->AddResource(resourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT}, resizeWidth, resizeHeight, vk::Format::eD32Sfloat);
renderGraph->AddResource(resourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT}, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat);
// 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->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + resourceName, {resourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::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, lightComp->GetRenderer());
newSubpass->AddDepthOutput(resourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH);
// regenerate the node
shadowMapNode->RuntimeStandaloneRegenerate();
// Create pipeline from new renderpass and subpass if it's not created yet
if (!shadowMapPipeline)
{
@ -1110,6 +1107,7 @@ namespace SHADE
mousePickSubSystem->HandleResize();
postOffscreenRenderSubSystem->HandleResize();
//lightingSubSystem->HandleResize(renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()));
worldViewport->SetWidth(static_cast<float>(resizeWidth));
worldViewport->SetHeight(static_cast<float>(resizeHeight));

View File

@ -16,6 +16,7 @@
#include "Graphics/Events/SHGraphicsEvents.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
namespace SHADE
{
@ -594,7 +595,8 @@ namespace SHADE
uint32_t SHLightingSubSystem::AddShadowMap(Handle<SHRenderGraphResource> newShadowMap, EntityID lightEntity) noexcept
{
// Add to container of shadow maps
shadowMaps.emplace(lightEntity, newShadowMap);
shadowMapIndexing.emplace(lightEntity, shadowMaps.size());
shadowMaps.emplace_back(newShadowMap);
// Just use the image view stored in the resource
Handle<SHVkImageView> const NEW_IMAGE_VIEW = newShadowMap->GetImageView();
@ -650,6 +652,28 @@ namespace SHADE
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers);
}
//void SHLightingSubSystem::HandleResize(Handle<SHRenderGraphNodeCompute> compute) noexcept
//{
// uint32_t const NUM_SHADOW_MAPS = static_cast<uint32_t>(shadowMaps.size());
// for (uint32_t i = 0; i < NUM_SHADOW_MAPS; ++i)
// {
// // Just use the image view stored in the resource
// Handle<SHVkImageView> const NEW_IMAGE_VIEW = shadowMaps[i]->GetImageView();
// // set new image view
// std::get<Handle<SHVkImageView>>(shadowMapImageSamplers[i]) = NEW_IMAGE_VIEW;
// // Set image for barrier
// shadowMapMemoryBarriers[i].image = shadowMaps[i]->GetImage()->GetVkImage();
// }
// if (NUM_SHADOW_MAPS > 0)
// {
// // modify descriptors in render graph node compute
// compute->ModifyWriteDescImageComputeResource (SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, shadowMapImageSamplers);
// }
//}
Handle<SHVkDescriptorSetGroup> SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept
{
return lightingDataDescSet;

View File

@ -23,6 +23,7 @@ namespace SHADE
class SHSamplerCache;
class SHVkImageView;
class SHVkSampler;
class SHRenderGraphNodeCompute;
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
struct SHDirectionalLightData
@ -72,7 +73,8 @@ namespace SHADE
public:
using DynamicOffsetArray = std::array<std::vector<uint32_t>, static_cast<uint32_t>(SHGraphicsConstants::NUM_FRAME_BUFFERS)>;
static constexpr uint32_t MAX_SHADOWS = 200;
static constexpr uint32_t SHADOW_MAP_WIDTH = 1024;
static constexpr uint32_t SHADOW_MAP_HEIGHT = 1024;
private:
class PerTypeData
@ -172,9 +174,11 @@ namespace SHADE
//! Handle to sampler that all shadow map descriptors will use
Handle<SHVkSampler> shadowMapSampler;
//std::vector<Handle<SHRenderGraphResource>> shadowMaps;
//! For indexing shadow maps
std::unordered_map<EntityID, uint32_t> shadowMapIndexing;
//! Shadow maps for every light that casts a shadow Order here doesn't matter. We just want to store it
std::unordered_map<EntityID, Handle<SHRenderGraphResource>> shadowMaps;
std::vector<Handle<SHRenderGraphResource>> shadowMaps;
//! Descriptor sets required to be given to the compute shader for shadow calculation. This will be a descriptor array.
//! It will also be preallocated.
@ -211,6 +215,7 @@ namespace SHADE
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept;
uint32_t AddShadowMap (Handle<SHRenderGraphResource> newShadowMap, EntityID lightEntity) noexcept;
void PrepareShadowMapsForRead (Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
//void HandleResize (Handle<SHRenderGraphNodeCompute> compute) noexcept;
//void RemoveShadowMap (uint32_t index) noexcept;
/*-----------------------------------------------------------------------*/

View File

@ -54,7 +54,7 @@ namespace SHADE
*/
/***************************************************************************/
void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, bool resizeWithWindow, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
{
// If we set to
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
@ -64,7 +64,7 @@ namespace SHADE
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
}
auto resource = renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags);
auto resource = renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags, resizeWithWindow);
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
}
@ -616,8 +616,11 @@ namespace SHADE
// resize resources
for (auto& [name, resource] : *renderGraphStorage->graphResources)
{
if (!renderGraphStorage->nonOwningResourceInitialLayouts.contains (resource.GetId().Raw))
resource->HandleResize(newWidth, newHeight);
if (resource->resizeWithWindow)
{
if (!renderGraphStorage->nonOwningResourceInitialLayouts.contains (resource.GetId().Raw))
resource->HandleResize(newWidth, newHeight);
}
}
for (auto& node : nodes)

View File

@ -102,6 +102,7 @@ namespace SHADE
(
std::string resourceName,
std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags,
bool resizeWithWindow = true,
uint32_t w = static_cast<uint32_t>(-1),
uint32_t h = static_cast<uint32_t>(-1),
vk::Format format = vk::Format::eB8G8R8A8Unorm,

View File

@ -78,7 +78,7 @@ namespace SHADE
*/
/***************************************************************************/
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags, bool inResizeWithWindow) noexcept
: graphStorage{renderGraphStorage}
, resourceTypeFlags{ }
, resourceFormat{ format }
@ -88,6 +88,7 @@ namespace SHADE
, height{ h }
, mipLevels{ levels }
, resourceName{ name }
, resizeWithWindow { inResizeWithWindow }
{
// If the resource type is an arbitrary image and not swapchain image
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)
@ -210,6 +211,7 @@ namespace SHADE
, imageAspectFlags{ rhs.imageAspectFlags }
, graphStorage{rhs.graphStorage}
, infoTracker {std::move (rhs.infoTracker)}
, resizeWithWindow{rhs.resizeWithWindow}
{
}
@ -242,7 +244,8 @@ namespace SHADE
mipLevels = rhs.mipLevels;
imageAspectFlags = rhs.imageAspectFlags;
graphStorage = rhs.graphStorage;
infoTracker = std::move(infoTracker);
infoTracker = std::move(rhs.infoTracker);
resizeWithWindow = rhs.resizeWithWindow;
return *this;
}

View File

@ -96,11 +96,14 @@ namespace SHADE
//! For tracking resource states in stages of the render graphs
Handle<InfoTracker> infoTracker;
//! Whether or not to resize (recreate vulkan image) when window resizes
bool resizeWithWindow;
public:
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags, bool inResizeWithWindow) noexcept;
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
~SHRenderGraphResource(void) noexcept;