Particles WIP

This commit is contained in:
Brandon Mak 2023-03-13 22:23:15 +08:00
parent 2f4a316a09
commit 8fac6fd911
13 changed files with 169 additions and 29 deletions

View File

@ -146,3 +146,14 @@
"Color Eval Rate ": 0.192000002 "Color Eval Rate ": 0.192000002
IsActive: true IsActive: true
Scripts: ~ Scripts: ~
- EID: 7
Name: ParticleTest
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
IsActive: true
Scripts: ~

View File

@ -15,3 +15,4 @@
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h" #include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
#include "AudioSystem/SHAudioListenerComponent.h" #include "AudioSystem/SHAudioListenerComponent.h"
#include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h" #include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h"
#include "Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h"

View File

@ -822,7 +822,11 @@ namespace SHADE
{ {
DrawContextMenu(component); DrawContextMenu(component);
SHEditorWidgets::DragFloat("Emission Count", [comp = component]() {return comp->GetEmissionCount(); }, [comp = component](float count) {comp->SetEmissionCount(count);}); SHEditorWidgets::DragInt("Emission Count", [comp = component]() {return comp->GetEmissionCount(); }, [comp = component](uint32_t count) {comp->SetEmissionCount(count);});
SHEditorWidgets::DragFloat("Emission Interval", [comp = component]() {return comp->GetEmissionInterval(); }, [comp = component](float interval) {comp->SetEmissionInterval(interval); });
SHEditorWidgets::DragFloat("Min Life", [comp = component]() {return comp->GetMinLife(); }, [comp = component](float val) {comp->SetMinLife(val); });
SHEditorWidgets::DragFloat("Max Life", [comp = component]() {return comp->GetMaxLife(); }, [comp = component](float val) {comp->SetMaxLife(val); });
SHEditorWidgets::CheckBox("Is Passive", [comp = component]() {return comp->GetPassive(); }, [comp = component](bool flag) {comp->SetPassive(flag); }); SHEditorWidgets::CheckBox("Is Passive", [comp = component]() {return comp->GetPassive(); }, [comp = component](bool flag) {comp->SetPassive(flag); });
} }

View File

@ -26,6 +26,7 @@
#include "SHEditorComponentView.h" #include "SHEditorComponentView.h"
#include "AudioSystem/SHAudioListenerComponent.h" #include "AudioSystem/SHAudioListenerComponent.h"
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h" #include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
#include "Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h"
#include "Camera/SHCameraSystem.h" #include "Camera/SHCameraSystem.h"
#include "FRC/SHFramerateController.h" #include "FRC/SHFramerateController.h"
@ -188,6 +189,10 @@ namespace SHADE
{ {
DrawComponent(trajectoryComponent); DrawComponent(trajectoryComponent);
} }
if (auto particleComponent = SHComponentManager::GetComponent_s<SHParticleEmitterComponent>(eid))
{
DrawComponent(particleComponent);
}
ImGui::Separator(); ImGui::Separator();
// Render Scripts // Render Scripts
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>()); SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
@ -204,6 +209,7 @@ namespace SHADE
DrawAddComponentButton<SHToggleButtonComponent>(eid); DrawAddComponentButton<SHToggleButtonComponent>(eid);
DrawAddComponentButton<SHSliderComponent>(eid); DrawAddComponentButton<SHSliderComponent>(eid);
DrawAddComponentButton<SHTrajectoryRenderableComponent>(eid); DrawAddComponentButton<SHTrajectoryRenderableComponent>(eid);
DrawAddComponentButton<SHParticleEmitterComponent>(eid);
// Components that require Transforms // Components that require Transforms
@ -213,6 +219,7 @@ namespace SHADE
DrawAddComponentWithEnforcedComponentButton<SHTextRenderableComponent, SHTransformComponent>(eid); DrawAddComponentWithEnforcedComponentButton<SHTextRenderableComponent, SHTransformComponent>(eid);
DrawAddComponentWithEnforcedComponentButton<SHAnimatorComponent, SHTransformComponent, SHRenderable>(eid); DrawAddComponentWithEnforcedComponentButton<SHAnimatorComponent, SHTransformComponent, SHRenderable>(eid);
DrawAddComponentWithEnforcedComponentButton<SHAudioListenerComponent, SHTransformComponent>(eid); DrawAddComponentWithEnforcedComponentButton<SHAudioListenerComponent, SHTransformComponent>(eid);
//DrawAddComponentWithEnforcedComponentButton<SHParticleEmitterComponent, SHTransformComponent>(eid);
ImGui::EndMenu(); ImGui::EndMenu();
} }

View File

@ -48,6 +48,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Input/SHInputManager.h" #include "Input/SHInputManager.h"
#include "Assets/Events/SHAssetManagerEvents.h" #include "Assets/Events/SHAssetManagerEvents.h"
#include "Graphics/MiddleEnd/Particles/SHParticleSubSystem.h"
namespace SHADE namespace SHADE
{ {
@ -170,7 +171,8 @@ namespace SHADE
static constexpr AssetID TRAJECTORY_FS = 45635685; trajectoryFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TRAJECTORY_FS); static constexpr AssetID TRAJECTORY_FS = 45635685; trajectoryFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TRAJECTORY_FS);
static constexpr AssetID SHADOW_BLUR_CS = 38004013; shadowMapBlurCS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_BLUR_CS); static constexpr AssetID SHADOW_BLUR_CS = 38004013; shadowMapBlurCS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_BLUR_CS);
static constexpr AssetID PARTICLE_VS = 35035037; particleVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(PARTICLE_VS); static constexpr AssetID PARTICLE_VS = 35035037; particleVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(PARTICLE_VS);
static constexpr AssetID PARTICLE_EMIT_CS = 42509714; particleEmitCS = SHResourceManager::LoadOrGet<SHVkShaderModule>(PARTICLE_EMIT_CS); static constexpr AssetID PARTICLE_FS = 42509714; particleFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(PARTICLE_FS);
static constexpr AssetID PARTICLE_EMIT_CS = 49959611; particleEmitCS = SHResourceManager::LoadOrGet<SHVkShaderModule>(PARTICLE_EMIT_CS);
static constexpr AssetID PARTICLE_UPDATE_CS = 36260925; particleUpdateCS = SHResourceManager::LoadOrGet<SHVkShaderModule>(PARTICLE_UPDATE_CS); static constexpr AssetID PARTICLE_UPDATE_CS = 36260925; particleUpdateCS = SHResourceManager::LoadOrGet<SHVkShaderModule>(PARTICLE_UPDATE_CS);
} }
@ -350,11 +352,16 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
auto vfxPass = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::VFX_PASS.data(), { "Scene", "Depth Buffer" }, { SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data() }); auto vfxPass = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::VFX_PASS.data(), { "Scene", "Depth Buffer" }, { SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data() });
auto vfxSubpass = vfxPass->AddSubpass(SHGraphicsConstants::RenderGraphEntityNames::VFX_SUBPASS.data(), worldViewport, worldRenderer); auto vfxSubpass = vfxPass->AddSubpass(SHGraphicsConstants::RenderGraphEntityNames::VFX_SUBPASS.data(), worldViewport, worldRenderer);
vfxPass->AddPreBeginFunction([=](Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
{
particleSubSystem->Run(cmdBuffer, frameIndex);
});
vfxSubpass->AddColorOutput("Scene"); vfxSubpass->AddColorOutput("Scene");
vfxSubpass->AddDepthOutput("Depth Buffer"); vfxSubpass->AddDepthOutput("Depth Buffer");
vfxSubpass->AddExteriorDrawCalls([=](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex) vfxSubpass->AddExteriorDrawCalls([=](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
{ {
trajectoryRenderingSubSystem->Render(cmdBuffer, renderer, frameIndex); trajectoryRenderingSubSystem->Render(cmdBuffer, renderer, frameIndex);
//particleSubSystem->Render(cmdBuffer, renderer, frameIndex);
}); });
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -497,6 +504,12 @@ namespace SHADE
trajectoryRenderingSubSystem = resourceManager.Create<SHTrajectoryRenderingSubSystem>(); trajectoryRenderingSubSystem = resourceManager.Create<SHTrajectoryRenderingSubSystem>();
auto vfxPass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::VFX_PASS.data());
// particle sub system initialization
particleSubSystem = resourceManager.Create<SHParticleSubSystem>();
particleSubSystem->Init(device, descPool, vfxPass->GetRenderpass(), vfxPass->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::VFX_SUBPASS), particleVS, particleFS, particleEmitCS, particleUpdateCS);
auto vfxNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::VFX_PASS.data()); auto vfxNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::VFX_PASS.data());
trajectoryRenderingSubSystem->Init(device, vfxNode->GetRenderpass(), vfxNode->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::VFX_SUBPASS), trajectoryVS, trajectoryFS); trajectoryRenderingSubSystem->Init(device, vfxNode->GetRenderpass(), vfxNode->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::VFX_SUBPASS), trajectoryVS, trajectoryFS);

View File

@ -59,6 +59,7 @@ namespace SHADE
class SHMaterialInstance; class SHMaterialInstance;
class SHMousePickSystem; class SHMousePickSystem;
class SHTextRenderingSubSystem; class SHTextRenderingSubSystem;
class SHParticleSubSystem;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -527,6 +528,7 @@ namespace SHADE
Handle<SHLightingSubSystem> lightingSubSystem; Handle<SHLightingSubSystem> lightingSubSystem;
Handle<SHTextRenderingSubSystem> textRenderingSubSystem; Handle<SHTextRenderingSubSystem> textRenderingSubSystem;
Handle<SHTrajectoryRenderingSubSystem> trajectoryRenderingSubSystem; Handle<SHTrajectoryRenderingSubSystem> trajectoryRenderingSubSystem;
Handle<SHParticleSubSystem> particleSubSystem;
Handle<SHSSAO> ssaoStorage; Handle<SHSSAO> ssaoStorage;
uint32_t resizeWidth = 1; uint32_t resizeWidth = 1;

View File

@ -20,24 +20,56 @@ namespace SHADE
toEmit = true; toEmit = true;
} }
void SHParticleEmitterComponent::SetEmissionCount(float count) noexcept void SHParticleEmitterComponent::SetEmissionCount(uint32_t count) noexcept
{ {
emissionCount = count; emissionCount = count;
} }
bool SHParticleEmitterComponent::SetPassive(bool flag) noexcept void SHParticleEmitterComponent::SetPassive(bool flag) noexcept
{ {
isPassive = flag; isPassive = flag;
} }
float SHParticleEmitterComponent::GetEmissionCount(void) noexcept void SHParticleEmitterComponent::SetEmissionInterval(float interval) noexcept
{
emissionInterval = interval;
timeBeforeEmission = emissionInterval;
}
void SHParticleEmitterComponent::SetMinLife(float val) noexcept
{
cpuEmitterData.lifeAndSizeRange.x = val;
}
void SHParticleEmitterComponent::SetMaxLife(float val) noexcept
{
cpuEmitterData.lifeAndSizeRange.y = val;
}
uint32_t SHParticleEmitterComponent::GetEmissionCount(void) const noexcept
{ {
return emissionCount; return emissionCount;
} }
bool SHParticleEmitterComponent::GetPassive(void) noexcept bool SHParticleEmitterComponent::GetPassive(void) const noexcept
{ {
return isPassive; return isPassive;
} }
float SHParticleEmitterComponent::GetEmissionInterval(void) const noexcept
{
return emissionInterval;
}
float SHParticleEmitterComponent::GetMinLife(void) const noexcept
{
return cpuEmitterData.lifeAndSizeRange.x;
}
float SHParticleEmitterComponent::GetMaxLife(void) const noexcept
{
return cpuEmitterData.lifeAndSizeRange.y;
}
} }

View File

@ -105,11 +105,17 @@ namespace SHADE
void Emit (void) noexcept; void Emit (void) noexcept;
void SetEmissionCount (float count) noexcept; void SetEmissionCount (uint32_t count) noexcept;
bool SetPassive (bool flag) noexcept; void SetPassive (bool flag) noexcept;
void SetEmissionInterval (float interval) noexcept;
void SetMinLife (float val) noexcept;
void SetMaxLife (float val) noexcept;
float GetEmissionCount (void) noexcept; uint32_t GetEmissionCount (void) const noexcept;
bool GetPassive (void) noexcept; bool GetPassive (void) const noexcept;
float GetEmissionInterval (void) const noexcept;
float GetMinLife (void) const noexcept;
float GetMaxLife (void) const noexcept;
friend class SHParticleSubSystem; friend class SHParticleSubSystem;

View File

@ -10,23 +10,29 @@
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h" #include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Buffers/SHVkBuffer.h"
#include "FRC/SHFramerateController.h"
#include "Graphics/Pipeline/SHVkPipeline.h"
#include "Graphics/RenderGraph/SHSubpass.h"
#include "Graphics/SHVkUtil.h"
namespace SHADE namespace SHADE
{ {
void SHParticleSubSystem::InitializeComponent(SHParticleEmitterComponent& comp) noexcept void SHParticleSubSystem::InitializeComponent(SHParticleEmitterComponent& comp) noexcept
{ {
uint32_t emitterStructAligned = logicalDevice->PadSSBOSize(sizeof (SHParticleEmitterComponent::GPUEmitterStruct));
uint32_t particleStructAligned = logicalDevice->PadUBOSize(sizeof (SHParticleEmitterComponent::GPUParticleStruct));
uint32_t sizeofIndirectCmd = static_cast<uint32_t>(sizeof(vk::DrawIndirectCommand));
uint32_t sizeofUint = static_cast<uint32_t>(sizeof(uint32_t));
// TODO: temporary only. // TODO: temporary only.
static constexpr uint32_t NUM_PARTICLES = 500; static constexpr uint32_t NUM_PARTICLES = 5;
comp.maxParticles = NUM_PARTICLES; comp.maxParticles = NUM_PARTICLES;
uint32_t sizeofUint = static_cast<uint32_t>(sizeof(uint32_t));
uint32_t sizeofIndirectCmdAligned = logicalDevice->PadSSBOSize(sizeof(vk::DrawIndirectCommand));
uint32_t emitterStructAligned = logicalDevice->PadSSBOSize(sizeof (SHParticleEmitterComponent::GPUEmitterStruct));
uint32_t particleChunkStructAligned = logicalDevice->PadSSBOSize(sizeof (SHParticleEmitterComponent::GPUParticleStruct) * comp.maxParticles);
uint32_t indicesDataAligned = logicalDevice->PadSSBOSize(sizeofUint * comp.maxParticles);
// offset into the buffer for input and output // offset into the buffer for input and output
uint32_t const PARTICLE_FRAME_CHUNK_SIZE = (particleStructAligned * comp.maxParticles); uint32_t const PARTICLE_FRAME_CHUNK_SIZE = particleChunkStructAligned;
// Buffer Initialization // Buffer Initialization
{ {
@ -40,14 +46,14 @@ namespace SHADE
// buffer for particle data: pure GPU memory, no transfers, no flags. We want to triple buffer this so that we can submit work to the GPU // buffer for particle data: pure GPU memory, no transfers, no flags. We want to triple buffer this so that we can submit work to the GPU
// without having to wait for rendering to finish reading the data // without having to wait for rendering to finish reading the data
comp.particleData = logicalDevice->CreateBuffer(SHGraphicsConstants::NUM_FRAME_BUFFERS * particleStructAligned * NUM_PARTICLES, nullptr, 0, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, {}); comp.particleData = logicalDevice->CreateBuffer(SHGraphicsConstants::NUM_FRAME_BUFFERS * particleChunkStructAligned, nullptr, 0, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, {});
// Buffer for freelist data. 1 copy only, host-visible mapped. We only need 1 copy because it is only required in compute. If it was used or read in another // Buffer for freelist data. 1 copy only, host-visible mapped. We only need 1 copy because it is only required in compute. If it was used or read in another
// stage we would need more copies. // stage we would need more copies.
comp.freelistData = logicalDevice->CreateBuffer(sizeofUint * (comp.maxParticles + 1), freelistInit.data(), sizeofUint * (comp.maxParticles + 1), vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT); comp.freelistData = logicalDevice->CreateBuffer(sizeofUint * (comp.maxParticles + 1), freelistInit.data(), sizeofUint * (comp.maxParticles + 1), vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT);
// Buffer for indices. NUM_FRAME_BUFFERS copies since it's used in rendering. host-visible mapped. // Buffer for indices. NUM_FRAME_BUFFERS copies since it's used in rendering. host-visible mapped.
comp.indicesData = logicalDevice->CreateBuffer(sizeofUint * comp.maxParticles, nullptr, 0, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT); comp.indicesData = logicalDevice->CreateBuffer(SHGraphicsConstants::NUM_FRAME_BUFFERS * indicesDataAligned, nullptr, 0, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT);
// Draw call data will not be tampered with after this initialization except for one variable: instanceCount, which will be modified from compute shader // Draw call data will not be tampered with after this initialization except for one variable: instanceCount, which will be modified from compute shader
std::array<vk::DrawIndirectCommand, SHGraphicsConstants::NUM_FRAME_BUFFERS> indirectCommands{}; std::array<vk::DrawIndirectCommand, SHGraphicsConstants::NUM_FRAME_BUFFERS> indirectCommands{};
@ -60,7 +66,7 @@ namespace SHADE
} }
// buffer to store draw call data. Non-indexed, host-visible mapped, triple buffered. // buffer to store draw call data. Non-indexed, host-visible mapped, triple buffered.
comp.drawCallData = logicalDevice->CreateBuffer(SHGraphicsConstants::NUM_FRAME_BUFFERS * sizeofIndirectCmd, indirectCommands.data(), SHGraphicsConstants::NUM_FRAME_BUFFERS * sizeofIndirectCmd, vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndirectBuffer, VMA_MEMORY_USAGE_AUTO, VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT); comp.drawCallData = logicalDevice->CreateBuffer(SHGraphicsConstants::NUM_FRAME_BUFFERS * sizeofIndirectCmdAligned, indirectCommands.data(), SHGraphicsConstants::NUM_FRAME_BUFFERS * sizeofIndirectCmdAligned, vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndirectBuffer, VMA_MEMORY_USAGE_AUTO, VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT);
} }
@ -73,7 +79,7 @@ namespace SHADE
static constexpr uint32_t PARTICLE_DATA_SET_INDEX = 0; static constexpr uint32_t PARTICLE_DATA_SET_INDEX = 0;
// Variable desc counts, all ignored anyway (This is required but its a dumb interface. You can only blame yourself, Brandon. ) // Variable desc counts, all ignored anyway (This is required but its a dumb interface. You can only blame yourself, Brandon. )
std::vector const VARIABLE_COUNTS = {0u,0u,0u,0u,0u}; std::vector const VARIABLE_COUNTS = {0u};
// allocate new desc set // allocate new desc set
comp.particleDescriptorSet = descPool->Allocate(descSetLayout, VARIABLE_COUNTS); comp.particleDescriptorSet = descPool->Allocate(descSetLayout, VARIABLE_COUNTS);
@ -87,7 +93,14 @@ namespace SHADE
set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_OUTPUT_DATA, { &comp.particleData, 1 }, 0, PARTICLE_FRAME_CHUNK_SIZE); set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_OUTPUT_DATA, { &comp.particleData, 1 }, 0, PARTICLE_FRAME_CHUNK_SIZE);
set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_FREELIST_DATA, { &comp.freelistData, 1 }, 0, sizeofUint * (comp.maxParticles + 1)); set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_FREELIST_DATA, { &comp.freelistData, 1 }, 0, sizeofUint * (comp.maxParticles + 1));
set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_INDICES_DATA, { &comp.indicesData, 1 }, 0, sizeofUint * (comp.maxParticles)); set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_INDICES_DATA, { &comp.indicesData, 1 }, 0, sizeofUint * (comp.maxParticles));
set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_DRAW_DATA, { &comp.drawCallData, 1 }, 0, sizeofIndirectCmd); set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_DRAW_DATA, { &comp.drawCallData, 1 }, 0, sizeofIndirectCmdAligned);
set->UpdateDescriptorSetBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_EMITTER_DATA);
set->UpdateDescriptorSetBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_INPUT_DATA);
set->UpdateDescriptorSetBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_OUTPUT_DATA);
set->UpdateDescriptorSetBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_FREELIST_DATA);
set->UpdateDescriptorSetBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_INDICES_DATA);
set->UpdateDescriptorSetBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_DRAW_DATA);
} }
comp.initialized = true; comp.initialized = true;
@ -110,8 +123,8 @@ namespace SHADE
offsets[DYOFF_INDEX_EMITTER] = i * emitterStructAligned; offsets[DYOFF_INDEX_EMITTER] = i * emitterStructAligned;
offsets[DYOFF_INDEX_PARTICLE_INPUT] = inputOffset; offsets[DYOFF_INDEX_PARTICLE_INPUT] = inputOffset;
offsets[DYOFF_INDEX_PARTICLE_OUTPUT] = outputOffset; offsets[DYOFF_INDEX_PARTICLE_OUTPUT] = outputOffset;
offsets[DYOFF_INDEX_INDICES_DATA] = i * sizeofUint * comp.maxParticles; offsets[DYOFF_INDEX_INDICES_DATA] = i * indicesDataAligned;
offsets[DYOFF_INDEX_DRAW_DATA] = i * sizeofIndirectCmd; offsets[DYOFF_INDEX_DRAW_DATA] = i * sizeofIndirectCmdAligned;
} }
} }
@ -140,7 +153,6 @@ namespace SHADE
// reset instance count to 0 // reset instance count to 0
comp.drawCallData->WriteToMemory (&ZERO, sizeof(uint32_t), 0, instanceCountOffset); comp.drawCallData->WriteToMemory (&ZERO, sizeof(uint32_t), 0, instanceCountOffset);
// bind the descriptor sets required for emitting particles // bind the descriptor sets required for emitting particles
cmdBuffer->BindDescriptorSet(comp.particleDescriptorSet, SH_PIPELINE_TYPE::COMPUTE, mappings.at(SHPredefinedDescriptorTypes::PARTICLES), comp.dynamicOffsets[frameIndex]); cmdBuffer->BindDescriptorSet(comp.particleDescriptorSet, SH_PIPELINE_TYPE::COMPUTE, mappings.at(SHPredefinedDescriptorTypes::PARTICLES), comp.dynamicOffsets[frameIndex]);
@ -223,6 +235,33 @@ namespace SHADE
renderingPipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(plParams); renderingPipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(plParams);
renderingPipelineData.pipeline = logicalDevice->CreateGraphicsPipeline(renderingPipelineData.pipelineLayout, nullptr, compatibleRenderpass, subpass); renderingPipelineData.pipeline = logicalDevice->CreateGraphicsPipeline(renderingPipelineData.pipelineLayout, nullptr, compatibleRenderpass, subpass);
SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE;
colorBlendState.logic_op = vk::LogicOp::eCopy;
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
colorBlendState.attachments.reserve(subpassColorReferences.size());
for (auto& att : subpassColorReferences)
{
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
{
.blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(att.attachment)),
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd,
.srcAlphaBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstAlphaBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.alphaBlendOp = vk::BlendOp::eAdd,
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
}
);
}
renderingPipelineData.pipeline->GetPipelineState().SetColorBlenState(colorBlendState);
renderingPipelineData.pipeline->ConstructPipeline();
SHPipelineLayoutParams emitPlParams SHPipelineLayoutParams emitPlParams
{ {
.shaderModules = {emitCS}, .shaderModules = {emitCS},
@ -231,6 +270,7 @@ namespace SHADE
emittingPipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(emitPlParams); emittingPipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(emitPlParams);
emittingPipelineData.pipeline = logicalDevice->CreateComputePipeline(emittingPipelineData.pipelineLayout); emittingPipelineData.pipeline = logicalDevice->CreateComputePipeline(emittingPipelineData.pipelineLayout);
emittingPipelineData.pipeline->ConstructPipeline();
SHPipelineLayoutParams defaultUpdatePlParams SHPipelineLayoutParams defaultUpdatePlParams
{ {
@ -240,7 +280,7 @@ namespace SHADE
defaultUpdatePipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(defaultUpdatePlParams); defaultUpdatePipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(defaultUpdatePlParams);
defaultUpdatePipelineData.pipeline = logicalDevice->CreateComputePipeline(defaultUpdatePipelineData.pipelineLayout); defaultUpdatePipelineData.pipeline = logicalDevice->CreateComputePipeline(defaultUpdatePipelineData.pipelineLayout);
defaultUpdatePipelineData.pipeline->ConstructPipeline();
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* OTHER INITIALIZATION */ /* OTHER INITIALIZATION */
@ -248,8 +288,10 @@ namespace SHADE
SHComponentManager::CreateComponentSparseSet<SHParticleEmitterComponent>(); SHComponentManager::CreateComponentSparseSet<SHParticleEmitterComponent>();
} }
void SHParticleSubSystem::Run(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, float dt) noexcept void SHParticleSubSystem::Run(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{ {
float dt = static_cast<float>(SHFrameRateController::GetRawDeltaTime());
auto& emitters = SHComponentManager::GetDense<SHParticleEmitterComponent>(); auto& emitters = SHComponentManager::GetDense<SHParticleEmitterComponent>();
auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::PARTICLE_RENEDERING); auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::PARTICLE_RENEDERING);
@ -346,7 +388,7 @@ namespace SHADE
/* AFTER UPDATING, RENDER PARTICLES */ /* AFTER UPDATING, RENDER PARTICLES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// issue the barrier to wait for output particles to be done updating and indices data to finish being modified. // issue the barrier to wait for output particles to be done updating and indices data to finish being modified.
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eComputeShader, {}, {}, postUpdateBarriers, {}); //cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eComputeShader, {}, {}, postUpdateBarriers, {});
} }

View File

@ -86,7 +86,7 @@ namespace SHADE
public: public:
void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> inDescPool, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkShaderModule> VS, Handle<SHVkShaderModule> FS, Handle<SHVkShaderModule> emitCS, Handle<SHVkShaderModule> defaultUpdateCS) noexcept; void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> inDescPool, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkShaderModule> VS, Handle<SHVkShaderModule> FS, Handle<SHVkShaderModule> emitCS, Handle<SHVkShaderModule> defaultUpdateCS) noexcept;
void Run(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, float dt) noexcept; void Run(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
void Render(Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex) noexcept; void Render(Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex) noexcept;
void Exit(void) noexcept; void Exit(void) noexcept;

View File

@ -372,6 +372,7 @@ namespace SHADE
, ISelfHandle<SHRenderGraphNode>{std::move(rhs)} , ISelfHandle<SHRenderGraphNode>{std::move(rhs)}
, dynamicIsActive {rhs.dynamicIsActive} , dynamicIsActive {rhs.dynamicIsActive}
, isDynamic {rhs.isDynamic} , isDynamic {rhs.isDynamic}
, preBeginFuncs{std::move(rhs.preBeginFuncs)}
{ {
rhs.renderpass = {}; rhs.renderpass = {};
@ -399,6 +400,7 @@ namespace SHADE
name = std::move(rhs.name); name = std::move(rhs.name);
dynamicIsActive = rhs.dynamicIsActive; dynamicIsActive = rhs.dynamicIsActive;
isDynamic = rhs.isDynamic; isDynamic = rhs.isDynamic;
preBeginFuncs = std::move(rhs.preBeginFuncs);
rhs.renderpass = {}; rhs.renderpass = {};
@ -493,6 +495,11 @@ namespace SHADE
return nodeCompute; return nodeCompute;
} }
void SHRenderGraphNode::AddPreBeginFunction(PreBeginFunction const& func) noexcept
{
preBeginFuncs.push_back(func);
}
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -664,6 +671,11 @@ namespace SHADE
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
{ {
for (auto& func : preBeginFuncs)
{
func(commandBuffer, frameIndex);
}
if (renderpass) if (renderpass)
{ {
uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0; uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0;

View File

@ -27,6 +27,10 @@ namespace SHADE
class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode> class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
{ {
public:
using PreBeginFunction = std::function<void(Handle<SHVkCommandBuffer>, uint32_t)>;
private: private:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
@ -74,6 +78,9 @@ namespace SHADE
//! of drawing objects on the image (i.e. compute). //! of drawing objects on the image (i.e. compute).
std::vector<Handle<SHRenderGraphNodeCompute>> nodeComputes; std::vector<Handle<SHRenderGraphNodeCompute>> nodeComputes;
//! Calls before renderpass begins
std::vector<PreBeginFunction> preBeginFuncs;
//! Whether or not the node has finished execution //! Whether or not the node has finished execution
bool executed; bool executed;
@ -118,6 +125,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
Handle<SHSubpass> AddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept; Handle<SHSubpass> AddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept;
Handle<SHRenderGraphNodeCompute> AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, uint32_t variableDescCount = 0, float numWorkGroupScale = 1.0f) noexcept; Handle<SHRenderGraphNodeCompute> AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, uint32_t variableDescCount = 0, float numWorkGroupScale = 1.0f) noexcept;
void AddPreBeginFunction (PreBeginFunction const& func) noexcept;
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept; void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept; Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;

View File

@ -248,6 +248,7 @@ namespace SHADE
AddComponentToComponentNode<SHUIComponent>(components, eid); AddComponentToComponentNode<SHUIComponent>(components, eid);
AddComponentToComponentNode<SHAudioListenerComponent>(components, eid); AddComponentToComponentNode<SHAudioListenerComponent>(components, eid);
AddComponentToComponentNode<SHTrajectoryRenderableComponent>(components, eid); AddComponentToComponentNode<SHTrajectoryRenderableComponent>(components, eid);
AddComponentToComponentNode<SHParticleEmitterComponent>(components, eid);
node[ComponentsNode] = components; node[ComponentsNode] = components;
@ -398,5 +399,6 @@ namespace SHADE
SHSerializationHelper::InitializeComponentFromNode<SHUIComponent>(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode<SHUIComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHAudioListenerComponent>(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode<SHAudioListenerComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHTrajectoryRenderableComponent>(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode<SHTrajectoryRenderableComponent>(componentsNode, eid);
SHSerializationHelper::InitializeComponentFromNode<SHParticleEmitterComponent>(componentsNode, eid);
} }
} }