Prepared light global desc set layout data and render graph resources
- Fixed material padding - Lighting desc sets now have a buffer at binding 0 to store light counts. - Added position, normals, albedo resources in render graph
This commit is contained in:
parent
43ea33cabf
commit
6e9f54987f
|
@ -180,7 +180,8 @@ namespace SHADE
|
|||
{
|
||||
SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!");
|
||||
}
|
||||
propsCurrPtr += singleMatPropAlignedSize;
|
||||
//propsCurrPtr += singleMatPropAlignedSize;
|
||||
propsCurrPtr += singleMatPropSize;
|
||||
}
|
||||
|
||||
// Transfer to GPU
|
||||
|
@ -302,7 +303,7 @@ namespace SHADE
|
|||
{
|
||||
singleMatPropSize = SHADER_INFO->GetBytesRequired();
|
||||
singleMatPropAlignedSize = device->PadSSBOSize(static_cast<uint32_t>(singleMatPropSize));
|
||||
matPropTotalBytes = numTotalElements * singleMatPropAlignedSize;
|
||||
matPropTotalBytes = numTotalElements * singleMatPropSize;
|
||||
if (matPropsDataSize < matPropTotalBytes)
|
||||
{
|
||||
matPropsData.reset(new char[matPropTotalBytes]);
|
||||
|
@ -361,7 +362,8 @@ namespace SHADE
|
|||
{
|
||||
SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!");
|
||||
}
|
||||
propsCurrPtr += singleMatPropAlignedSize;
|
||||
//propsCurrPtr += singleMatPropAlignedSize;
|
||||
propsCurrPtr += singleMatPropSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,36 +47,35 @@ namespace SHADE
|
|||
// For global data (generic data and textures)
|
||||
Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,{ genericDataBinding, texturesBinding });
|
||||
|
||||
|
||||
std::vector<SHVkDescriptorSetLayout::Binding> lightBindings{};
|
||||
for (uint32_t i = 0; i < SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); ++i)
|
||||
|
||||
// This is the binding we use to count the lights (binding 0)
|
||||
lightBindings.push_back(SHVkDescriptorSetLayout::Binding
|
||||
{
|
||||
.Type = vk::DescriptorType::eUniformBufferDynamic,
|
||||
.Stage = vk::ShaderStageFlagBits::eCompute,
|
||||
.BindPoint = 0,
|
||||
.DescriptorCount = 1,
|
||||
|
||||
});
|
||||
|
||||
for (uint32_t i = 1; i <= SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); ++i)
|
||||
{
|
||||
lightBindings.push_back (SHVkDescriptorSetLayout::Binding
|
||||
{
|
||||
.Type = vk::DescriptorType::eStorageBufferDynamic,
|
||||
.Stage = vk::ShaderStageFlagBits::eFragment,
|
||||
.Stage = vk::ShaderStageFlagBits::eCompute,
|
||||
.BindPoint = i,
|
||||
.DescriptorCount = 1,
|
||||
});
|
||||
}
|
||||
//SHVkDescriptorSetLayout::Binding pointLightBinding
|
||||
//{
|
||||
// .Type = vk::DescriptorType::eStorageBufferDynamic,
|
||||
// .Stage = vk::ShaderStageFlagBits::eFragment,
|
||||
// .BindPoint = SHGraphicsConstants::DescriptorSetBindings::POINT_LIGHT_DATA,
|
||||
// .DescriptorCount = 1,
|
||||
//};
|
||||
|
||||
//SHVkDescriptorSetLayout::Binding spotLightBinding
|
||||
//{
|
||||
// .Type = vk::DescriptorType::eStorageBufferDynamic,
|
||||
// .Stage = vk::ShaderStageFlagBits::eFragment,
|
||||
// .BindPoint = SHGraphicsConstants::DescriptorSetBindings::SPOT_LIGHT_DATA,
|
||||
// .DescriptorCount = 1,
|
||||
//};
|
||||
|
||||
// For Dynamic global data (lights)
|
||||
Handle<SHVkDescriptorSetLayout> dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings);
|
||||
|
||||
|
||||
SHVkDescriptorSetLayout::Binding cameraDataBinding
|
||||
{
|
||||
.Type = vk::DescriptorType::eUniformBufferDynamic,
|
||||
|
|
|
@ -94,32 +94,14 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
static constexpr uint32_t IMAGE_AND_SAMPLERS_DATA = 1;
|
||||
|
||||
///***************************************************************************/
|
||||
///*!
|
||||
// \brief
|
||||
// DescriptorSet binding for directional lights.
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
DescriptorSet binding for combined image sampler data.
|
||||
|
||||
//*/
|
||||
///***************************************************************************/
|
||||
//static constexpr uint32_t DIRECTIONAL_LIGHT_DATA = 0;
|
||||
|
||||
///***************************************************************************/
|
||||
///*!
|
||||
// \brief
|
||||
// DescriptorSet binding for directional lights.
|
||||
|
||||
//*/
|
||||
///***************************************************************************/
|
||||
//static constexpr uint32_t POINT_LIGHT_DATA = 1;
|
||||
|
||||
///***************************************************************************/
|
||||
///*!
|
||||
// \brief
|
||||
// DescriptorSet binding for directional lights.
|
||||
|
||||
//*/
|
||||
///***************************************************************************/
|
||||
//static constexpr uint32_t SPOT_LIGHT_DATA = 2;
|
||||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t LIGHTING_COUNT = 0;
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
|
|
@ -127,15 +127,20 @@ namespace SHADE
|
|||
shaderSourceLibrary.LoadShader(2, "KirschCs.glsl", SH_SHADER_TYPE::COMPUTE, true);
|
||||
shaderSourceLibrary.LoadShader(3, "PureCopyCs.glsl", SH_SHADER_TYPE::COMPUTE, true);
|
||||
|
||||
shaderSourceLibrary.LoadShader(4, "DeferredCompositeCs.glsl", SH_SHADER_TYPE::COMPUTE, true);
|
||||
|
||||
|
||||
shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary);
|
||||
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
|
||||
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
|
||||
auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl");
|
||||
auto pureCopy = shaderModuleLibrary.GetShaderModule("PureCopyCs.glsl");
|
||||
auto deferredComposite = shaderModuleLibrary.GetShaderModule("DeferredCompositeCs.glsl");
|
||||
cubeVS->Reflect();
|
||||
cubeFS->Reflect();
|
||||
greyscale->Reflect();
|
||||
pureCopy->Reflect();
|
||||
deferredComposite->Reflect();
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
||||
|
@ -176,26 +181,45 @@ namespace SHADE
|
|||
|
||||
// Initialize world render graph
|
||||
worldRenderGraph->Init(device, swapchain);
|
||||
worldRenderGraph->AddResource("Scene Pre-Process", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||
worldRenderGraph->AddResource("Position", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||
worldRenderGraph->AddResource("Normals", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||
worldRenderGraph->AddResource("Albedo", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||
worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||
worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||
worldRenderGraph->AddResource("Light Layer Indices", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||
|
||||
auto gBufferNode = worldRenderGraph->AddNode("G-Buffer",
|
||||
{
|
||||
"Position",
|
||||
"Entity ID",
|
||||
"Light Layer Indices",
|
||||
"Normals",
|
||||
"Albedo",
|
||||
"Depth Buffer",
|
||||
"Scene"
|
||||
},
|
||||
{}); // no predecessors
|
||||
|
||||
auto gBufferNode = worldRenderGraph->AddNode("G-Buffer", { "Light Layer Indices", "Entity ID", "Depth Buffer", "Scene", "Scene Pre-Process"}, {}); // no predecessors
|
||||
auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write");
|
||||
gBufferSubpass->AddColorOutput("Scene Pre-Process");
|
||||
gBufferSubpass->AddColorOutput("Position");
|
||||
gBufferSubpass->AddColorOutput("Entity ID");
|
||||
gBufferSubpass->AddColorOutput("Light Layer Indices");
|
||||
gBufferSubpass->AddColorOutput("Normals");
|
||||
gBufferSubpass->AddColorOutput("Albedo");
|
||||
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
|
||||
|
||||
//// kirsch
|
||||
//auto kirschShader = shaderModuleLibrary.GetShaderModule("KirschCs.glsl");
|
||||
//gBufferNode->AddNodeCompute(kirschShader, { "Scene Pre-Process", "Scene" });
|
||||
//gBufferNode->AddNodeCompute(kirschShader, { "Position", "Scene" });
|
||||
|
||||
// copy
|
||||
auto pureCopyShader = shaderModuleLibrary.GetShaderModule("PureCopyCs.glsl");
|
||||
gBufferNode->AddNodeCompute(pureCopyShader, { "Scene Pre-Process", "Scene" });
|
||||
//// copy
|
||||
//auto pureCopyShader = shaderModuleLibrary.GetShaderModule("PureCopyCs.glsl");
|
||||
//gBufferNode->AddNodeCompute(pureCopyShader, { "Position", "Scene" });
|
||||
|
||||
// deferred composite
|
||||
auto deferredCompositeShader = shaderModuleLibrary.GetShaderModule("DeferredCompositeCs.glsl");
|
||||
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Albedo", "Scene" });
|
||||
|
||||
|
||||
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, {"G-Buffer"}); // no predecessors
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace SHADE
|
|||
material = {};
|
||||
oldMaterial = {};
|
||||
|
||||
lightLayer = 0;
|
||||
lightLayer = 1;
|
||||
}
|
||||
|
||||
void SHRenderable::OnDestroy()
|
||||
|
|
|
@ -76,8 +76,8 @@ namespace SHADE
|
|||
// boilerplate
|
||||
intermediateData = nullptr;
|
||||
|
||||
// initialize alignment
|
||||
lightDataAlignmentSize = logicalDevice->PadSSBOSize(GetLightTypeSize(type));
|
||||
// Get data required for struct
|
||||
lightDataSize = GetLightTypeSize(type);
|
||||
|
||||
// So create some data!
|
||||
Expand(logicalDevice);
|
||||
|
@ -94,7 +94,7 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
void SHLightingSubSystem::PerTypeData::Expand(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
||||
{
|
||||
if (lightDataAlignmentSize == 0)
|
||||
if (lightDataSize == 0)
|
||||
{
|
||||
SHLOG_ERROR ("One of the types of lights have not been accounted for. Make sure lightDataAlignmentSize is not nullptr.");
|
||||
return;
|
||||
|
@ -111,10 +111,12 @@ namespace SHADE
|
|||
numLights = 0;
|
||||
|
||||
// Initialize the data for lights
|
||||
intermediateData = std::make_unique<uint8_t[]>(lightDataAlignmentSize * maxLights);
|
||||
intermediateData = std::make_unique<uint8_t[]>(lightDataSize * maxLights);
|
||||
|
||||
lightDataAlignedSize = logicalDevice->PadSSBOSize(lightDataSize * maxLights);
|
||||
|
||||
// We want to initialize 3 times the amount of data required.
|
||||
dataBuffer = logicalDevice->CreateBuffer(maxLights * lightDataAlignmentSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, maxLights * lightDataAlignmentSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
||||
dataBuffer = logicalDevice->CreateBuffer(lightDataAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightDataAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -122,24 +124,27 @@ namespace SHADE
|
|||
uint32_t const OLD_MAX_LIGHTS = maxLights;
|
||||
|
||||
// before we increase the number of lights, create space to store old data.
|
||||
std::unique_ptr<uint8_t[]> oldData = std::make_unique<uint8_t[]>(lightDataAlignmentSize * OLD_MAX_LIGHTS);
|
||||
std::unique_ptr<uint8_t[]> oldData = std::make_unique<uint8_t[]>(lightDataSize * OLD_MAX_LIGHTS);
|
||||
|
||||
// copy data over.
|
||||
std::memcpy (oldData.get(), intermediateData.get(), lightDataAlignmentSize * OLD_MAX_LIGHTS);
|
||||
std::memcpy (oldData.get(), intermediateData.get(), lightDataSize * OLD_MAX_LIGHTS);
|
||||
|
||||
// now we start to expand....
|
||||
|
||||
// double space for lights
|
||||
maxLights *= 2;
|
||||
|
||||
// calculate total + padding
|
||||
lightDataAlignedSize = logicalDevice->PadSSBOSize(lightDataSize * maxLights);
|
||||
|
||||
// destroy old data and initialize container for double the amount of data.
|
||||
intermediateData = std::make_unique<uint8_t[]>(lightDataAlignmentSize * maxLights);
|
||||
intermediateData = std::make_unique<uint8_t[]>(lightDataSize * maxLights);
|
||||
|
||||
// copy old data to new container
|
||||
std::memcpy(intermediateData.get(), oldData.get(), lightDataAlignmentSize * OLD_MAX_LIGHTS);
|
||||
std::memcpy(intermediateData.get(), oldData.get(), lightDataSize * OLD_MAX_LIGHTS);
|
||||
|
||||
// Resize the GPU buffer. TODO: Replace with Resize no copy here
|
||||
dataBuffer->ResizeReplace(maxLights * lightDataAlignmentSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, oldData.get(), lightDataAlignmentSize * OLD_MAX_LIGHTS);
|
||||
dataBuffer->ResizeReplace(maxLights * lightDataAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, oldData.get(), lightDataAlignedSize * OLD_MAX_LIGHTS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -187,7 +192,12 @@ namespace SHADE
|
|||
|
||||
uint32_t SHLightingSubSystem::PerTypeData::GetAlignmentSize(void) const noexcept
|
||||
{
|
||||
return lightDataAlignmentSize;
|
||||
return lightDataAlignedSize;
|
||||
}
|
||||
|
||||
uint32_t SHLightingSubSystem::PerTypeData::GetDataSize(void) const noexcept
|
||||
{
|
||||
return lightDataSize;
|
||||
}
|
||||
|
||||
uint32_t SHLightingSubSystem::PerTypeData::GetNumLights(void) const noexcept
|
||||
|
@ -231,7 +241,7 @@ namespace SHADE
|
|||
// Now that the container is big enough, bind the new light
|
||||
|
||||
// Get address of write location
|
||||
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignmentSize * numLights);
|
||||
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataSize * numLights);
|
||||
|
||||
// Write the light data to address
|
||||
WriteLightToAddress(writeLocation, unboundLight);
|
||||
|
@ -257,7 +267,7 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
void SHLightingSubSystem::PerTypeData::ModifyLight(SHLightComponent* lightComp) noexcept
|
||||
{
|
||||
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignmentSize * lightComp->GetIndexInBuffer());
|
||||
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataSize * lightComp->GetIndexInBuffer());
|
||||
WriteLightToAddress(writeLocation, lightComp);
|
||||
}
|
||||
|
||||
|
@ -266,7 +276,7 @@ namespace SHADE
|
|||
if (intermediateData)
|
||||
{
|
||||
// we want to write to the offset of the current frame
|
||||
dataBuffer->WriteToMemory(intermediateData.get(), lightDataAlignmentSize * numLights, 0, lightDataAlignmentSize * maxLights * frameIndex);
|
||||
dataBuffer->WriteToMemory(intermediateData.get(), lightDataSize * numLights, 0, lightDataSize * maxLights * frameIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,12 +297,12 @@ namespace SHADE
|
|||
|
||||
// We bind the buffer with the correct desc set binding
|
||||
lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS,
|
||||
binding,
|
||||
binding + 1, // we want to +1 here because the first binding is reserved for count
|
||||
{ &buffer, 1 },
|
||||
0,
|
||||
perTypeData[binding].GetAlignmentSize() * perTypeData[binding].GetMaxLights());
|
||||
perTypeData[binding].GetDataSize() * perTypeData[binding].GetMaxLights());
|
||||
|
||||
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, binding);
|
||||
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, binding + 1); // +1 here, same reason. see above
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -307,11 +317,13 @@ namespace SHADE
|
|||
{
|
||||
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||
{
|
||||
for (uint32_t j = 0; j < dynamicOffsets.size(); ++j)
|
||||
dynamicOffsets[i][0] = i * lightCountsAlignedSize;
|
||||
// Even if the first binding is a count, we want to account for that too
|
||||
for (uint32_t j = 1; j < static_cast<uint32_t>(dynamicOffsets.size()); ++j)
|
||||
{
|
||||
auto const& typeData = perTypeData[j];
|
||||
{
|
||||
dynamicOffsets[i][j] = j * typeData.GetAlignmentSize() * typeData.GetMaxLights();
|
||||
dynamicOffsets[i][j] = j * typeData.GetAlignmentSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -346,11 +358,23 @@ namespace SHADE
|
|||
// initialize all the data first. We add more lights here as we add more types.
|
||||
perTypeData[i].InitializeData(logicalDevice, static_cast<SH_LIGHT_TYPE>(i));
|
||||
UpdateDescSet(i);
|
||||
|
||||
// no lights at first
|
||||
lightCountsData[i] = 0;
|
||||
}
|
||||
|
||||
lightCountsAlignedSize = sizeof (uint32_t) * NUM_LIGHT_TYPES;
|
||||
lightCountsAlignedSize = logicalDevice->PadUBOSize(lightCountsAlignedSize);
|
||||
|
||||
// Create the GPU buffer to hold light count
|
||||
lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
||||
|
||||
lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, {&lightCountsBuffer, 1}, 0, sizeof (uint32_t) * NUM_LIGHT_TYPES);
|
||||
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT);
|
||||
|
||||
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||
{
|
||||
dynamicOffsets[i].resize(NUM_LIGHT_TYPES);
|
||||
dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,6 +390,8 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
void SHLightingSubSystem::Run(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||
{
|
||||
static uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES);
|
||||
|
||||
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
|
||||
bool expanded = false;
|
||||
for (auto& light : lightComps)
|
||||
|
@ -377,6 +403,9 @@ namespace SHADE
|
|||
if (!light.GetBound())
|
||||
{
|
||||
perTypeData[enumValue].AddLight(logicalDevice, &light, expanded);
|
||||
|
||||
// add to light count
|
||||
++lightCountsData[enumValue];
|
||||
}
|
||||
|
||||
// if there was modification to the light data
|
||||
|
@ -396,6 +425,8 @@ namespace SHADE
|
|||
data.WriteToGPU(frameIndex);
|
||||
}
|
||||
|
||||
lightCountsBuffer->WriteToMemory(lightCountsData.data(), lightCountsData.size() * sizeof (uint32_t), 0, lightCountsAlignedSize * frameIndex);
|
||||
|
||||
// If any of the buffers got expanded, the descriptor set is invalid because the expanded buffer
|
||||
// is a new buffer. If some expansion was detected, update descriptor sets.
|
||||
if (expanded)
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace SHADE
|
|||
class SHVkCommandBuffer;
|
||||
|
||||
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
||||
struct SHDirectionalLightData
|
||||
struct SHDirectionalLightData
|
||||
{
|
||||
//! Direction of the light
|
||||
SHVec3 direction;
|
||||
|
@ -53,8 +53,11 @@ namespace SHADE
|
|||
//! Capacity of the container.
|
||||
uint32_t maxLights;
|
||||
|
||||
//! SSBOs need to be aligned. This is to pad lighting structs
|
||||
uint32_t lightDataAlignmentSize;
|
||||
//! SSBOs need to be aligned. This is to pad descriptor offset
|
||||
uint32_t lightDataAlignedSize;
|
||||
|
||||
//! size needed to store 1 struct object
|
||||
uint32_t lightDataSize;
|
||||
|
||||
//! type of the light. Will be used later when we want to expand
|
||||
SH_LIGHT_TYPE lightType;
|
||||
|
@ -87,6 +90,7 @@ namespace SHADE
|
|||
static uint32_t GetLightTypeSize (SH_LIGHT_TYPE type) noexcept;
|
||||
Handle<SHVkBuffer> GetDataBuffer (void) const noexcept;
|
||||
uint32_t GetAlignmentSize (void) const noexcept;
|
||||
uint32_t GetDataSize (void) const noexcept;
|
||||
uint32_t GetNumLights (void) const noexcept;
|
||||
uint32_t GetMaxLights (void) const noexcept;
|
||||
};
|
||||
|
@ -105,6 +109,15 @@ namespace SHADE
|
|||
//! Container to store dynamic offsets for binding descriptor sets
|
||||
std::array<std::vector<uint32_t>, static_cast<uint32_t>(SHGraphicsConstants::NUM_FRAME_BUFFERS)> dynamicOffsets;
|
||||
|
||||
//! holds the data that represents how many lights are in the scene
|
||||
std::array<uint32_t, static_cast<uint32_t>(SH_LIGHT_TYPE::NUM_TYPES)> lightCountsData;
|
||||
|
||||
//! GPU buffer to hold lightCountData
|
||||
Handle<SHVkBuffer> lightCountsBuffer;
|
||||
|
||||
//! For padding in the buffer
|
||||
uint32_t lightCountsAlignedSize;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#version 450
|
||||
|
||||
struct DirectionalLightStruct
|
||||
{
|
||||
vec3 direction;
|
||||
uint isActive;
|
||||
uint cullingMask;
|
||||
vec4 diffuseColor;
|
||||
};
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 16) in;
|
||||
layout(set = 4, binding = 0, rgba8) uniform image2D inputImage;
|
||||
layout(set = 4, binding = 1, rgba8) uniform image2D targetImage;
|
||||
|
||||
layout(set = 1, binding = 0) buffer DirectionalLightData
|
||||
{
|
||||
DirectionalLightStruct dLightData[];
|
||||
} DirLightData;
|
||||
|
||||
void main()
|
||||
{
|
||||
// convenient variables
|
||||
ivec2 globalThread = ivec2(gl_GlobalInvocationID);
|
||||
|
||||
vec3 color = imageLoad (inputImage, globalThread).rgb;
|
||||
|
||||
// store result into result image
|
||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(color, 1.0f));
|
||||
|
||||
}
|
Binary file not shown.
|
@ -13,13 +13,14 @@ struct MatPropData
|
|||
|
||||
layout(location = 0) in struct
|
||||
{
|
||||
vec4 vertColor;
|
||||
vec2 uv;
|
||||
vec4 vertPos; // location 0
|
||||
vec2 uv; // location = 1
|
||||
vec4 normal; // location = 2
|
||||
|
||||
} In;
|
||||
|
||||
// material stuff
|
||||
layout(location = 2) flat in struct
|
||||
layout(location = 3) flat in struct
|
||||
{
|
||||
int materialIndex;
|
||||
uint eid;
|
||||
|
@ -34,16 +35,18 @@ layout (set = 3, binding = 0) buffer MaterialProperties // For materials
|
|||
MatPropData data[];
|
||||
} MatProp;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
layout(location = 0) out vec4 position;
|
||||
layout(location = 1) out uint outEntityID;
|
||||
layout(location = 2) out uint lightLayerIndices;
|
||||
layout(location = 3) out vec4 normals;
|
||||
layout(location = 4) out vec4 albedo;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) +
|
||||
MatProp.data[In2.materialIndex].color / MatProp.data[In2.materialIndex].alpha;
|
||||
position = In.vertPos;
|
||||
normals = In.normal;
|
||||
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) + MatProp.data[In2.materialIndex].color / MatProp.data[In2.materialIndex].alpha;
|
||||
|
||||
outEntityID = In2.eid;
|
||||
lightLayerIndices = In2.lightLayerIndex;
|
||||
//outColor = vec4 (1.0f);
|
||||
}
|
Binary file not shown.
|
@ -14,13 +14,14 @@ layout(location = 8) in uvec2 integerData;
|
|||
|
||||
layout(location = 0) out struct
|
||||
{
|
||||
vec4 vertColor; // location 0
|
||||
vec4 vertPos; // location 0
|
||||
vec2 uv; // location = 1
|
||||
vec4 normal; // location = 2
|
||||
|
||||
} Out;
|
||||
|
||||
// material stuff
|
||||
layout(location = 2) out struct
|
||||
layout(location = 3) out struct
|
||||
{
|
||||
int materialIndex;
|
||||
uint eid;
|
||||
|
@ -36,10 +37,13 @@ layout(set = 2, binding = 0) uniform CameraData
|
|||
|
||||
void main()
|
||||
{
|
||||
Out.uv = aUV;
|
||||
|
||||
Out2.materialIndex = gl_InstanceIndex;
|
||||
Out2.eid = integerData[0];
|
||||
Out2.lightLayerIndex = integerData[1];
|
||||
|
||||
Out.vertPos = worldTransform * vec4(aVertexPos, 1.0f);
|
||||
Out.uv = aUV;
|
||||
Out.normal = vec4 (aNormal, 1.0f);
|
||||
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
||||
Out.vertColor = vec4 (aVertexPos, 1.0f);
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue