From 8fac6fd9113f20a8edbc6e2f14b24509dd8c87f8 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Mon, 13 Mar 2023 22:23:15 +0800 Subject: [PATCH] Particles WIP --- Assets/Scenes/Scene2.shade | 11 +++ SHADE_Engine/src/Common/SHAllComponents.h | 1 + .../Inspector/SHEditorComponentView.hpp | 6 +- .../Inspector/SHEditorInspector.cpp | 7 ++ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 15 +++- .../MiddleEnd/Interface/SHGraphicsSystem.h | 2 + .../Particles/SHParticleEmitterComponent.cpp | 40 +++++++++- .../Particles/SHParticleEmitterComponent.h | 14 +++- .../Particles/SHParticleSubSystem.cpp | 78 ++++++++++++++----- .../MiddleEnd/Particles/SHParticleSubSystem.h | 2 +- .../RenderGraph/SHRenderGraphNode.cpp | 12 +++ .../Graphics/RenderGraph/SHRenderGraphNode.h | 8 ++ .../src/Serialization/SHSerialization.cpp | 2 + 13 files changed, 169 insertions(+), 29 deletions(-) diff --git a/Assets/Scenes/Scene2.shade b/Assets/Scenes/Scene2.shade index c45d8b51..704d2028 100644 --- a/Assets/Scenes/Scene2.shade +++ b/Assets/Scenes/Scene2.shade @@ -145,4 +145,15 @@ End Alpha: 1 "Color Eval Rate ": 0.192000002 IsActive: true + 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: ~ \ No newline at end of file diff --git a/SHADE_Engine/src/Common/SHAllComponents.h b/SHADE_Engine/src/Common/SHAllComponents.h index ee900736..32efee1f 100644 --- a/SHADE_Engine/src/Common/SHAllComponents.h +++ b/SHADE_Engine/src/Common/SHAllComponents.h @@ -15,3 +15,4 @@ #include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h" #include "AudioSystem/SHAudioListenerComponent.h" #include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h" +#include "Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h" \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 388667a3..8f4e6f47 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -822,7 +822,11 @@ namespace SHADE { 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); }); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index f331f499..e9da2f09 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -26,6 +26,7 @@ #include "SHEditorComponentView.h" #include "AudioSystem/SHAudioListenerComponent.h" #include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h" +#include "Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h" #include "Camera/SHCameraSystem.h" #include "FRC/SHFramerateController.h" @@ -188,6 +189,10 @@ namespace SHADE { DrawComponent(trajectoryComponent); } + if (auto particleComponent = SHComponentManager::GetComponent_s(eid)) + { + DrawComponent(particleComponent); + } ImGui::Separator(); // Render Scripts SHScriptEngine* scriptEngine = static_cast(SHSystemManager::GetSystem()); @@ -204,6 +209,7 @@ namespace SHADE DrawAddComponentButton(eid); DrawAddComponentButton(eid); DrawAddComponentButton(eid); + DrawAddComponentButton(eid); // Components that require Transforms @@ -213,6 +219,7 @@ namespace SHADE DrawAddComponentWithEnforcedComponentButton(eid); DrawAddComponentWithEnforcedComponentButton(eid); DrawAddComponentWithEnforcedComponentButton(eid); + //DrawAddComponentWithEnforcedComponentButton(eid); ImGui::EndMenu(); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 59813cd3..b34eb8de 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -48,6 +48,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Input/SHInputManager.h" #include "Assets/Events/SHAssetManagerEvents.h" +#include "Graphics/MiddleEnd/Particles/SHParticleSubSystem.h" namespace SHADE { @@ -170,7 +171,8 @@ namespace SHADE static constexpr AssetID TRAJECTORY_FS = 45635685; trajectoryFS = SHResourceManager::LoadOrGet(TRAJECTORY_FS); static constexpr AssetID SHADOW_BLUR_CS = 38004013; shadowMapBlurCS = SHResourceManager::LoadOrGet(SHADOW_BLUR_CS); static constexpr AssetID PARTICLE_VS = 35035037; particleVS = SHResourceManager::LoadOrGet(PARTICLE_VS); - static constexpr AssetID PARTICLE_EMIT_CS = 42509714; particleEmitCS = SHResourceManager::LoadOrGet(PARTICLE_EMIT_CS); + static constexpr AssetID PARTICLE_FS = 42509714; particleFS = SHResourceManager::LoadOrGet(PARTICLE_FS); + static constexpr AssetID PARTICLE_EMIT_CS = 49959611; particleEmitCS = SHResourceManager::LoadOrGet(PARTICLE_EMIT_CS); static constexpr AssetID PARTICLE_UPDATE_CS = 36260925; particleUpdateCS = SHResourceManager::LoadOrGet(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 vfxSubpass = vfxPass->AddSubpass(SHGraphicsConstants::RenderGraphEntityNames::VFX_SUBPASS.data(), worldViewport, worldRenderer); + vfxPass->AddPreBeginFunction([=](Handle cmdBuffer, uint32_t frameIndex) + { + particleSubSystem->Run(cmdBuffer, frameIndex); + }); vfxSubpass->AddColorOutput("Scene"); vfxSubpass->AddDepthOutput("Depth Buffer"); vfxSubpass->AddExteriorDrawCalls([=](Handle cmdBuffer, Handle renderer, uint32_t frameIndex) { trajectoryRenderingSubSystem->Render(cmdBuffer, renderer, frameIndex); + //particleSubSystem->Render(cmdBuffer, renderer, frameIndex); }); /*-----------------------------------------------------------------------*/ @@ -497,6 +504,12 @@ namespace SHADE trajectoryRenderingSubSystem = resourceManager.Create(); + auto vfxPass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::VFX_PASS.data()); + + // particle sub system initialization + particleSubSystem = resourceManager.Create(); + 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()); trajectoryRenderingSubSystem->Init(device, vfxNode->GetRenderpass(), vfxNode->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::VFX_SUBPASS), trajectoryVS, trajectoryFS); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index a199464c..2627415c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -59,6 +59,7 @@ namespace SHADE class SHMaterialInstance; class SHMousePickSystem; class SHTextRenderingSubSystem; + class SHParticleSubSystem; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -527,6 +528,7 @@ namespace SHADE Handle lightingSubSystem; Handle textRenderingSubSystem; Handle trajectoryRenderingSubSystem; + Handle particleSubSystem; Handle ssaoStorage; uint32_t resizeWidth = 1; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp index c7dca2a0..8a652381 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp @@ -20,24 +20,56 @@ namespace SHADE toEmit = true; } - void SHParticleEmitterComponent::SetEmissionCount(float count) noexcept + void SHParticleEmitterComponent::SetEmissionCount(uint32_t count) noexcept { emissionCount = count; } - bool SHParticleEmitterComponent::SetPassive(bool flag) noexcept + void SHParticleEmitterComponent::SetPassive(bool flag) noexcept { 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; } - bool SHParticleEmitterComponent::GetPassive(void) noexcept + bool SHParticleEmitterComponent::GetPassive(void) const noexcept { 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; + + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h index 7b519e85..ac2556b1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h @@ -105,11 +105,17 @@ namespace SHADE void Emit (void) noexcept; - void SetEmissionCount (float count) noexcept; - bool SetPassive (bool flag) noexcept; + void SetEmissionCount (uint32_t count) 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; - bool GetPassive (void) noexcept; + uint32_t GetEmissionCount (void) const noexcept; + bool GetPassive (void) const noexcept; + float GetEmissionInterval (void) const noexcept; + float GetMinLife (void) const noexcept; + float GetMaxLife (void) const noexcept; friend class SHParticleSubSystem; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp index 95e9818f..5141112e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp @@ -10,23 +10,29 @@ #include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h" #include "Math/Transform/SHTransformComponent.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 { 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(sizeof(vk::DrawIndirectCommand)); - uint32_t sizeofUint = static_cast(sizeof(uint32_t)); - // TODO: temporary only. - static constexpr uint32_t NUM_PARTICLES = 500; + static constexpr uint32_t NUM_PARTICLES = 5; comp.maxParticles = NUM_PARTICLES; + uint32_t sizeofUint = static_cast(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 - uint32_t const PARTICLE_FRAME_CHUNK_SIZE = (particleStructAligned * comp.maxParticles); + uint32_t const PARTICLE_FRAME_CHUNK_SIZE = particleChunkStructAligned; // 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 // 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 // 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); // 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 std::array indirectCommands{}; @@ -60,7 +66,7 @@ namespace SHADE } // 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; // 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 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_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_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; @@ -110,8 +123,8 @@ namespace SHADE offsets[DYOFF_INDEX_EMITTER] = i * emitterStructAligned; offsets[DYOFF_INDEX_PARTICLE_INPUT] = inputOffset; offsets[DYOFF_INDEX_PARTICLE_OUTPUT] = outputOffset; - offsets[DYOFF_INDEX_INDICES_DATA] = i * sizeofUint * comp.maxParticles; - offsets[DYOFF_INDEX_DRAW_DATA] = i * sizeofIndirectCmd; + offsets[DYOFF_INDEX_INDICES_DATA] = i * indicesDataAligned; + offsets[DYOFF_INDEX_DRAW_DATA] = i * sizeofIndirectCmdAligned; } } @@ -140,7 +153,6 @@ namespace SHADE // reset instance count to 0 comp.drawCallData->WriteToMemory (&ZERO, sizeof(uint32_t), 0, instanceCountOffset); - // bind the descriptor sets required for emitting particles 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.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 { .shaderModules = {emitCS}, @@ -231,6 +270,7 @@ namespace SHADE emittingPipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(emitPlParams); emittingPipelineData.pipeline = logicalDevice->CreateComputePipeline(emittingPipelineData.pipelineLayout); + emittingPipelineData.pipeline->ConstructPipeline(); SHPipelineLayoutParams defaultUpdatePlParams { @@ -240,7 +280,7 @@ namespace SHADE defaultUpdatePipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(defaultUpdatePlParams); defaultUpdatePipelineData.pipeline = logicalDevice->CreateComputePipeline(defaultUpdatePipelineData.pipelineLayout); - + defaultUpdatePipelineData.pipeline->ConstructPipeline(); /*-----------------------------------------------------------------------*/ /* OTHER INITIALIZATION */ @@ -248,8 +288,10 @@ namespace SHADE SHComponentManager::CreateComponentSparseSet(); } - void SHParticleSubSystem::Run(Handle cmdBuffer, uint32_t frameIndex, float dt) noexcept + void SHParticleSubSystem::Run(Handle cmdBuffer, uint32_t frameIndex) noexcept { + float dt = static_cast(SHFrameRateController::GetRawDeltaTime()); + auto& emitters = SHComponentManager::GetDense(); auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::PARTICLE_RENEDERING); @@ -346,7 +388,7 @@ namespace SHADE /* AFTER UPDATING, RENDER PARTICLES */ /*-----------------------------------------------------------------------*/ // 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, {}); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h index 9003f169..73404e3d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h @@ -86,7 +86,7 @@ namespace SHADE public: void Init(Handle device, Handle inDescPool, Handle compatibleRenderpass, Handle subpass, Handle VS, Handle FS, Handle emitCS, Handle defaultUpdateCS) noexcept; - void Run(Handle cmdBuffer, uint32_t frameIndex, float dt) noexcept; + void Run(Handle cmdBuffer, uint32_t frameIndex) noexcept; void Render(Handle cmdBuffer, Handle renderer, uint32_t frameIndex) noexcept; void Exit(void) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 53363a63..4a89290a 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -372,6 +372,7 @@ namespace SHADE , ISelfHandle{std::move(rhs)} , dynamicIsActive {rhs.dynamicIsActive} , isDynamic {rhs.isDynamic} + , preBeginFuncs{std::move(rhs.preBeginFuncs)} { rhs.renderpass = {}; @@ -399,6 +400,7 @@ namespace SHADE name = std::move(rhs.name); dynamicIsActive = rhs.dynamicIsActive; isDynamic = rhs.isDynamic; + preBeginFuncs = std::move(rhs.preBeginFuncs); rhs.renderpass = {}; @@ -493,6 +495,11 @@ namespace SHADE return nodeCompute; } + void SHRenderGraphNode::AddPreBeginFunction(PreBeginFunction const& func) noexcept + { + preBeginFuncs.push_back(func); + } + /***************************************************************************/ /*! @@ -664,6 +671,11 @@ namespace SHADE void SHRenderGraphNode::Execute(Handle commandBuffer, Handle descPool, uint32_t frameIndex) noexcept { + for (auto& func : preBeginFuncs) + { + func(commandBuffer, frameIndex); + } + if (renderpass) { uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 971a84ae..72494b6a 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -27,6 +27,10 @@ namespace SHADE class SH_API SHRenderGraphNode : public ISelfHandle { + public: + using PreBeginFunction = std::function, uint32_t)>; + + private: /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ @@ -74,6 +78,9 @@ namespace SHADE //! of drawing objects on the image (i.e. compute). std::vector> nodeComputes; + //! Calls before renderpass begins + std::vector preBeginFuncs; + //! Whether or not the node has finished execution bool executed; @@ -118,6 +125,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ Handle AddSubpass(std::string subpassName, Handle viewport, Handle renderer) noexcept; Handle AddNodeCompute(std::string nodeName, Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings = {}, uint32_t variableDescCount = 0, float numWorkGroupScale = 1.0f) noexcept; + void AddPreBeginFunction (PreBeginFunction const& func) noexcept; void Execute(Handle commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; Handle GetOrCreatePipeline(std::pair, Handle> const& vsFsPair, Handle subpass) noexcept; diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index b6455935..2451414d 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -248,6 +248,7 @@ namespace SHADE AddComponentToComponentNode(components, eid); AddComponentToComponentNode(components, eid); AddComponentToComponentNode(components, eid); + AddComponentToComponentNode(components, eid); node[ComponentsNode] = components; @@ -398,5 +399,6 @@ namespace SHADE SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); + SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); } }