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:
Brandon Mak 2022-10-26 22:40:04 +08:00
parent 43ea33cabf
commit 6e9f54987f
13 changed files with 175 additions and 87 deletions

View File

@ -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;
}
}
}

View File

@ -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,

View File

@ -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;
/***************************************************************************/
/*!

View File

@ -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

View File

@ -28,7 +28,7 @@ namespace SHADE
material = {};
oldMaterial = {};
lightLayer = 0;
lightLayer = 1;
}
void SHRenderable::OnDestroy()

View File

@ -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)

View File

@ -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 */
/*-----------------------------------------------------------------------*/

View File

@ -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.

View File

@ -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.

View File

@ -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.