Implemented Shadow maps (still needs improvement) #314
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 aVertexPos;
|
layout(location = 0) in vec3 aVertexPos;
|
||||||
|
layout(location = 4) in mat4 worldTransform;
|
||||||
|
|
||||||
layout(set = 1, binding = 0) uniform CameraData
|
layout(set = 1, binding = 0) uniform CameraData
|
||||||
{
|
{
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: ShadowMap_VS
|
||||||
|
ID: 44646107
|
||||||
|
Type: 2
|
|
@ -551,7 +551,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* SHBatch - Usage Functions */
|
/* SHBatch - Usage Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
|
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline/* = true*/)
|
||||||
{
|
{
|
||||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
{
|
{
|
||||||
|
@ -566,7 +566,10 @@ namespace SHADE
|
||||||
// Bind all required objects before drawing
|
// Bind all required objects before drawing
|
||||||
static std::array<uint32_t, 1> dynamicOffset{ 0 };
|
static std::array<uint32_t, 1> dynamicOffset{ 0 };
|
||||||
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
||||||
cmdBuffer->BindPipeline(pipeline);
|
|
||||||
|
if (bindBatchPipeline)
|
||||||
|
cmdBuffer->BindPipeline(pipeline);
|
||||||
|
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
|
||||||
if (matPropsDescSet[frameIndex])
|
if (matPropsDescSet[frameIndex])
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace SHADE
|
||||||
void UpdateTransformBuffer(uint32_t frameIndex);
|
void UpdateTransformBuffer(uint32_t frameIndex);
|
||||||
void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
|
void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
|
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
|
|
@ -107,12 +107,12 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline /*= true*/) noexcept
|
||||||
{
|
{
|
||||||
// Build all batches
|
// Build all batches
|
||||||
for (auto& batch : batches)
|
for (auto& batch : batches)
|
||||||
{
|
{
|
||||||
batch.Draw(cmdBuffer, frameIndex);
|
batch.Draw(cmdBuffer, frameIndex, bindBatchPipeline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace SHADE
|
||||||
void Clear() noexcept;
|
void Clear() noexcept;
|
||||||
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
|
|
@ -127,6 +127,8 @@ namespace SHADE
|
||||||
|
|
||||||
SHFreetypeInstance::Init();
|
SHFreetypeInstance::Init();
|
||||||
|
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_VS.glsl", false);
|
||||||
|
|
||||||
// Load Built In Shaders
|
// Load Built In Shaders
|
||||||
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
||||||
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
|
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
|
||||||
|
@ -140,6 +142,8 @@ namespace SHADE
|
||||||
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
|
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
|
||||||
static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS);
|
static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS);
|
||||||
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS);
|
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS);
|
||||||
|
static constexpr AssetID SHADOW_MAP_VS = 44646107; shadowMapVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_MAP_VS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitRenderGraph(void) noexcept
|
void SHGraphicsSystem::InitRenderGraph(void) noexcept
|
||||||
|
@ -752,9 +756,20 @@ namespace SHADE
|
||||||
// we need to wait for the device to finish using the graph first
|
// we need to wait for the device to finish using the graph first
|
||||||
device->WaitIdle();
|
device->WaitIdle();
|
||||||
|
|
||||||
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightEnableShadowEvent>*>(eventPtr.get())->data;
|
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightEnableShadowEvent>*>(eventPtr.get())->data;
|
||||||
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);
|
||||||
|
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)
|
if (EVENT_DATA->generateRenderer)
|
||||||
{
|
{
|
||||||
|
@ -773,6 +788,7 @@ namespace SHADE
|
||||||
// Add a subpass to render to that shadow map
|
// 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_STENCIL);
|
newSubpass->AddDepthOutput(resourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
|
||||||
|
newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline
|
||||||
|
|
||||||
// regenerate the node
|
// regenerate the node
|
||||||
shadowMapNode->RuntimeStandaloneRegenerate();
|
shadowMapNode->RuntimeStandaloneRegenerate();
|
||||||
|
|
|
@ -464,6 +464,7 @@ namespace SHADE
|
||||||
Handle<SHVkShaderModule> textFS;
|
Handle<SHVkShaderModule> textFS;
|
||||||
Handle<SHVkShaderModule> renderToSwapchainVS;
|
Handle<SHVkShaderModule> renderToSwapchainVS;
|
||||||
Handle<SHVkShaderModule> renderToSwapchainFS;
|
Handle<SHVkShaderModule> renderToSwapchainFS;
|
||||||
|
Handle<SHVkShaderModule> shadowMapVS;
|
||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
Handle<SHFont> testFont;
|
Handle<SHFont> testFont;
|
||||||
|
@ -478,6 +479,7 @@ namespace SHADE
|
||||||
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
|
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
|
||||||
Handle<SHVkPipeline> debugDrawFilledPipeline;
|
Handle<SHVkPipeline> debugDrawFilledPipeline;
|
||||||
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
|
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
|
||||||
|
Handle<SHVkPipeline> shadowMapPipeline; // initialized only when a shadow map is needed
|
||||||
|
|
||||||
// Built-In Textures
|
// Built-In Textures
|
||||||
Handle<SHTexture> defaultTexture;
|
Handle<SHTexture> defaultTexture;
|
||||||
|
|
|
@ -378,11 +378,10 @@ namespace SHADE
|
||||||
|
|
||||||
SHMatrix SHLightingSubSystem::GetViewMatrix(SHLightComponent* lightComp) noexcept
|
SHMatrix SHLightingSubSystem::GetViewMatrix(SHLightComponent* lightComp) noexcept
|
||||||
{
|
{
|
||||||
SHTransformComponent* transform = SHComponentManager::GetComponent<SHTransformComponent>(lightComp->GetEID());
|
|
||||||
switch (lightComp->GetLightData().type)
|
switch (lightComp->GetLightData().type)
|
||||||
{
|
{
|
||||||
case SH_LIGHT_TYPE::DIRECTIONAL:
|
case SH_LIGHT_TYPE::DIRECTIONAL:
|
||||||
return SHMatrix::LookAtRH(transform->GetLocalPosition(), lightComp->GetLightData().position, SHVec3(0.0f, 1.0f, 0.0f));
|
return SHMatrix::LookAtRH(lightComp->GetLightData().position, lightComp->GetLightData().position + lightComp->GetLightData().direction, SHVec3(0.0f, 1.0f, 0.0f));
|
||||||
case SH_LIGHT_TYPE::POINT:
|
case SH_LIGHT_TYPE::POINT:
|
||||||
return {};
|
return {};
|
||||||
case SH_LIGHT_TYPE::SPOT:
|
case SH_LIGHT_TYPE::SPOT:
|
||||||
|
|
|
@ -10,9 +10,15 @@ 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) noexcept
|
||||||
{
|
{
|
||||||
|
std::vector<Handle<SHVkShaderModule>> modules{};
|
||||||
|
if (vsFsPair.first)
|
||||||
|
modules.push_back(vsFsPair.first);
|
||||||
|
if (vsFsPair.second)
|
||||||
|
modules.push_back(vsFsPair.second);
|
||||||
|
|
||||||
SHPipelineLayoutParams params
|
SHPipelineLayoutParams params
|
||||||
{
|
{
|
||||||
.shaderModules = {vsFsPair.first, vsFsPair.second},
|
.shaderModules = std::move (modules),
|
||||||
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
|
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,69 +19,71 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
{
|
{
|
||||||
// References for convenience
|
if (shaderModule)
|
||||||
auto const& reflectedData = shaderModule->GetReflectedData();
|
|
||||||
auto const& pcInfo = reflectedData.GetPushConstantInfo();
|
|
||||||
|
|
||||||
// If a push constant block exists for the shader module
|
|
||||||
if (pcInfo.memberCount != 0)
|
|
||||||
{
|
{
|
||||||
bool exists = false;
|
// References for convenience
|
||||||
|
auto const& reflectedData = shaderModule->GetReflectedData();
|
||||||
|
auto const& pcInfo = reflectedData.GetPushConstantInfo();
|
||||||
|
|
||||||
// Check if push constant block already exists
|
// If a push constant block exists for the shader module
|
||||||
for (uint32_t i = 0; i < pcInfos.size(); ++i)
|
if (pcInfo.memberCount != 0)
|
||||||
{
|
{
|
||||||
// If there is a block with the same name, member count and size
|
bool exists = false;
|
||||||
if (std::strcmp(pcInfos[i]->name, pcInfo.name) == 0 && pcInfos[i]->memberCount == pcInfo.memberCount && pcInfos[i]->size == pcInfo.size)
|
|
||||||
|
// Check if push constant block already exists
|
||||||
|
for (uint32_t i = 0; i < pcInfos.size(); ++i)
|
||||||
{
|
{
|
||||||
// We just take the existing pc range we built earlier, and allow it to be accessed in potentially other shader stages
|
// If there is a block with the same name, member count and size
|
||||||
vkPcRanges[i].stageFlags |= shaderModule->GetShaderStageFlagBits();
|
if (std::strcmp(pcInfos[i]->name, pcInfo.name) == 0 && pcInfos[i]->memberCount == pcInfo.memberCount && pcInfos[i]->size == pcInfo.size)
|
||||||
|
{
|
||||||
|
// We just take the existing pc range we built earlier, and allow it to be accessed in potentially other shader stages
|
||||||
|
vkPcRanges[i].stageFlags |= shaderModule->GetShaderStageFlagBits();
|
||||||
|
|
||||||
// Set flag and stop checking
|
// Set flag and stop checking
|
||||||
exists = true;
|
exists = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the block doesn't exist yet
|
|
||||||
if (!exists)
|
|
||||||
{
|
|
||||||
// Loop through all member variables of the new push constant block
|
|
||||||
for (uint32_t i = 0; i < pcInfo.memberCount; ++i)
|
|
||||||
{
|
|
||||||
std::string variableName;
|
|
||||||
variableName.reserve(50);
|
|
||||||
variableName += pcInfo.name;
|
|
||||||
variableName += ".";
|
|
||||||
variableName += pcInfo.members[i].name;
|
|
||||||
|
|
||||||
// Add the variable's offset info to the interface
|
|
||||||
pushConstantInterface.AddOffset(std::move(variableName), startOffset + pcInfo.members[i].offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New push constant range
|
// If the block doesn't exist yet
|
||||||
vk::PushConstantRange newRange;
|
if (!exists)
|
||||||
|
{
|
||||||
|
// Loop through all member variables of the new push constant block
|
||||||
|
for (uint32_t i = 0; i < pcInfo.memberCount; ++i)
|
||||||
|
{
|
||||||
|
std::string variableName;
|
||||||
|
variableName.reserve(50);
|
||||||
|
variableName += pcInfo.name;
|
||||||
|
variableName += ".";
|
||||||
|
variableName += pcInfo.members[i].name;
|
||||||
|
|
||||||
// set offset and size
|
// Add the variable's offset info to the interface
|
||||||
newRange.offset = startOffset;
|
pushConstantInterface.AddOffset(std::move(variableName), startOffset + pcInfo.members[i].offset);
|
||||||
newRange.size = pcInfo.size;
|
}
|
||||||
|
|
||||||
// Stage flags will be whatever shader stage of the shader that contains the push constant block
|
// New push constant range
|
||||||
newRange.stageFlags = shaderModule->GetShaderStageFlagBits();
|
vk::PushConstantRange newRange;
|
||||||
|
|
||||||
// Add to the list foe checking later
|
// set offset and size
|
||||||
pcInfos.push_back(&pcInfo);
|
newRange.offset = startOffset;
|
||||||
|
newRange.size = pcInfo.size;
|
||||||
|
|
||||||
// For pipeline layout to consume
|
// Stage flags will be whatever shader stage of the shader that contains the push constant block
|
||||||
vkPcRanges.push_back(newRange);
|
newRange.stageFlags = shaderModule->GetShaderStageFlagBits();
|
||||||
|
|
||||||
// Next push constant block will start next to the previous push constant block
|
// Add to the list foe checking later
|
||||||
startOffset += pcInfo.size;
|
pcInfos.push_back(&pcInfo);
|
||||||
|
|
||||||
|
// For pipeline layout to consume
|
||||||
|
vkPcRanges.push_back(newRange);
|
||||||
|
|
||||||
|
// Next push constant block will start next to the previous push constant block
|
||||||
|
startOffset += pcInfo.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
stageFlags |= shaderModule->GetShaderStageFlagBits();
|
||||||
}
|
}
|
||||||
|
|
||||||
stageFlags |= shaderModule->GetShaderStageFlagBits();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// After all the sizes of the push constant blocks have been added, record the size in the interface
|
// After all the sizes of the push constant blocks have been added, record the size in the interface
|
||||||
|
@ -132,6 +134,9 @@ namespace SHADE
|
||||||
//! Now we take descriptor set info from all shaders and prepare some bindings for the descriptor set
|
//! Now we take descriptor set info from all shaders and prepare some bindings for the descriptor set
|
||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
{
|
{
|
||||||
|
if (!shaderModule)
|
||||||
|
continue;
|
||||||
|
|
||||||
auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo();
|
auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo();
|
||||||
auto const& reflectedSets = descBindingInfo.GetReflectedSets();
|
auto const& reflectedSets = descBindingInfo.GetReflectedSets();
|
||||||
|
|
||||||
|
@ -326,11 +331,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
for (auto& mod : shaderModules)
|
for (auto& mod : shaderModules)
|
||||||
{
|
{
|
||||||
mod->AddCallback([this]()
|
if (mod)
|
||||||
{
|
{
|
||||||
RecreateIfNeeded();
|
mod->AddCallback([this]() { RecreateIfNeeded(); });
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecreateIfNeeded ();
|
RecreateIfNeeded ();
|
||||||
|
|
|
@ -229,8 +229,17 @@ namespace SHADE
|
||||||
if (renderer)
|
if (renderer)
|
||||||
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
|
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
|
||||||
|
|
||||||
// Draw all the batches
|
// If companion subpass is not a valid handle, render super batch normally
|
||||||
superBatch->Draw(commandBuffer, frameIndex);
|
if (!companionSubpass.companion)
|
||||||
|
{
|
||||||
|
// Draw all the batches
|
||||||
|
superBatch->Draw(commandBuffer, frameIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
commandBuffer->BindPipeline(companionSubpass.pipeline);
|
||||||
|
companionSubpass.companion->superBatch->Draw(commandBuffer, frameIndex, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw all the exterior draw calls
|
// Draw all the exterior draw calls
|
||||||
|
|
Loading…
Reference in New Issue