Improved particles and trajectory rendering #430
|
@ -157,15 +157,17 @@
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
IsActive: true
|
IsActive: true
|
||||||
classSHADE::SHParticleEmitterComponent:
|
classSHADE::SHParticleEmitterComponent:
|
||||||
Emission Count: 1
|
Emission Count: 7
|
||||||
Is Passive: true
|
Is Passive: true
|
||||||
Emission Interval: 0.200000003
|
Emission Interval: 0.0939999968
|
||||||
Min Life: 2
|
Min Life: 2
|
||||||
Max Life: 3
|
Max Life: 3
|
||||||
Minimum Speed: 3
|
Minimum Speed: 3
|
||||||
Maximum Speed: 6
|
Maximum Speed: 6
|
||||||
Minimum Size: 0
|
Minimum Size: 0
|
||||||
Maximum Size: 0.5
|
Maximum Size: 0.5
|
||||||
Angular Ranges And Offset: {x: 0, y: 0, z: 0, w: 0}
|
Angular Ranges And Offset: {x: 0.699999988, y: 0.469999999, z: 0, w: 0}
|
||||||
|
Rotation Speed: 0
|
||||||
|
Texture Asset ID: 63456868
|
||||||
IsActive: true
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
|
@ -1,5 +1,7 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
#define PI 3.14159265f
|
||||||
|
|
||||||
layout(local_size_x = 128) in;
|
layout(local_size_x = 128) in;
|
||||||
|
|
||||||
struct EmitterParameters
|
struct EmitterParameters
|
||||||
|
@ -7,14 +9,15 @@ struct EmitterParameters
|
||||||
vec4 angularRangesAndOffsets;
|
vec4 angularRangesAndOffsets;
|
||||||
float minSpeed;
|
float minSpeed;
|
||||||
float maxSpeed;
|
float maxSpeed;
|
||||||
float padding[2];
|
float rotationSpeed;
|
||||||
|
uint textureIndex;
|
||||||
vec4 lifeAndSizeRange; // min life, max life, min size, max size
|
vec4 lifeAndSizeRange; // min life, max life, min size, max size
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParticleData
|
struct ParticleData
|
||||||
{
|
{
|
||||||
vec4 position;
|
vec4 position;
|
||||||
vec4 rotation;
|
vec4 orientationSpeedDecay;
|
||||||
vec4 velocity;
|
vec4 velocity;
|
||||||
vec4 acceleration;
|
vec4 acceleration;
|
||||||
vec4 scaleAndDecay;
|
vec4 scaleAndDecay;
|
||||||
|
@ -149,8 +152,18 @@ void main()
|
||||||
particle.scaleAndDecay.x = particleSize;
|
particle.scaleAndDecay.x = particleSize;
|
||||||
particle.scaleAndDecay.z = particleSize;
|
particle.scaleAndDecay.z = particleSize;
|
||||||
|
|
||||||
particle.rotation = vec4 (5.0f);
|
// Set the texture for the particle
|
||||||
|
particle.textureIndex = emitterParams.data.textureIndex;
|
||||||
|
|
||||||
|
// Set orientation and rotation speed
|
||||||
|
if (emitterParams.data.rotationSpeed != 0.0f)
|
||||||
|
particle.orientationSpeedDecay = vec4 (rand(seed) * PI, emitterParams.data.rotationSpeed, 0.0f, 0.0f);
|
||||||
|
else
|
||||||
|
particle.orientationSpeedDecay = vec4 (0.0f);
|
||||||
|
|
||||||
|
|
||||||
particle.acceleration = vec4 (0.01f);
|
particle.acceleration = vec4 (0.01f);
|
||||||
|
|
||||||
|
|
||||||
inputParticles.data[index] = particle;
|
inputParticles.data[index] = particle;
|
||||||
}
|
}
|
Binary file not shown.
|
@ -13,7 +13,7 @@ struct DrawArraysIndirectArgs
|
||||||
struct ParticleData
|
struct ParticleData
|
||||||
{
|
{
|
||||||
vec4 position;
|
vec4 position;
|
||||||
vec4 rotation;
|
vec4 orientationSpeedDecay;
|
||||||
vec4 velocity;
|
vec4 velocity;
|
||||||
vec4 acceleration;
|
vec4 acceleration;
|
||||||
vec4 scaleAndDecay;
|
vec4 scaleAndDecay;
|
||||||
|
|
Binary file not shown.
|
@ -1,15 +1,26 @@
|
||||||
#version 460 core
|
#version 460 core
|
||||||
|
#extension GL_EXT_nonuniform_qualifier : require
|
||||||
|
|
||||||
layout (location = 0) out vec4 fragColor;
|
layout (location = 0) out vec4 fragColor;
|
||||||
|
|
||||||
|
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
|
||||||
|
|
||||||
// between shader stages
|
// between shader stages
|
||||||
layout(location = 0) in struct
|
layout(location = 0) in struct
|
||||||
{
|
{
|
||||||
vec2 uv; // location = 0
|
vec2 uv; // location = 0
|
||||||
|
|
||||||
} In;
|
} In;
|
||||||
|
|
||||||
|
// material stuff
|
||||||
|
layout(location = 1) flat in struct
|
||||||
|
{
|
||||||
|
uint textureIndex;
|
||||||
|
} InFlat;
|
||||||
|
|
||||||
|
|
||||||
void main ()
|
void main ()
|
||||||
{
|
{
|
||||||
fragColor = vec4 (1.0f);
|
fragColor = vec4 (texture(textures [nonuniformEXT(InFlat.textureIndex)], In.uv));
|
||||||
|
if (fragColor.a < 0.01f)
|
||||||
|
discard;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -19,7 +19,7 @@ struct GenericData
|
||||||
struct ParticleData
|
struct ParticleData
|
||||||
{
|
{
|
||||||
vec4 position;
|
vec4 position;
|
||||||
vec4 rotation;
|
vec4 orientationSpeedDecay;
|
||||||
vec4 velocity;
|
vec4 velocity;
|
||||||
vec4 acceleration;
|
vec4 acceleration;
|
||||||
vec4 scaleAndDecay;
|
vec4 scaleAndDecay;
|
||||||
|
@ -56,9 +56,14 @@ layout (std430, set = 2, binding = 4) coherent restrict buffer IndicesData
|
||||||
layout(location = 0) out struct
|
layout(location = 0) out struct
|
||||||
{
|
{
|
||||||
vec2 uv; // location = 0
|
vec2 uv; // location = 0
|
||||||
|
|
||||||
} Out;
|
} Out;
|
||||||
|
|
||||||
|
// material stuff
|
||||||
|
layout(location = 1) out struct
|
||||||
|
{
|
||||||
|
uint textureIndex; // location = 1
|
||||||
|
} OutFlat;
|
||||||
|
|
||||||
vec2 CreateQuad (in uint vertexID)
|
vec2 CreateQuad (in uint vertexID)
|
||||||
{
|
{
|
||||||
uint b = 1 << vertexID;
|
uint b = 1 << vertexID;
|
||||||
|
@ -90,6 +95,7 @@ void main()
|
||||||
vec3 viewUp = normalize(vec3 (cameraData.viewMat[0][1], cameraData.viewMat[1][1], cameraData.viewMat[2][1]));
|
vec3 viewUp = normalize(vec3 (cameraData.viewMat[0][1], cameraData.viewMat[1][1], cameraData.viewMat[2][1]));
|
||||||
|
|
||||||
particlePos = particle.position.xyz + (viewRight * particlePos.x * particleScaleData.x) + (viewUp * particlePos.y * particleScaleData.y);
|
particlePos = particle.position.xyz + (viewRight * particlePos.x * particleScaleData.x) + (viewUp * particlePos.y * particleScaleData.y);
|
||||||
|
OutFlat.textureIndex = particle.textureIndex;
|
||||||
|
|
||||||
gl_Position = cameraData.vpMat * vec4(particlePos, 1.0f);
|
gl_Position = cameraData.vpMat * vec4(particlePos, 1.0f);
|
||||||
}
|
}
|
Binary file not shown.
|
@ -811,6 +811,8 @@ namespace SHADE
|
||||||
if (!component)
|
if (!component)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
|
||||||
ImGui::PushID(SHFamilyID<SHComponent>::GetID<SHParticleEmitterComponent>());
|
ImGui::PushID(SHFamilyID<SHComponent>::GetID<SHParticleEmitterComponent>());
|
||||||
|
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
|
@ -860,6 +862,47 @@ namespace SHADE
|
||||||
comp->SetMaxSpeed(val);
|
comp->SetMaxSpeed(val);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
SHEditorWidgets::DragFloat("Rotation Speed",
|
||||||
|
[comp = component]()
|
||||||
|
{
|
||||||
|
return comp->GetMaxSpeed();
|
||||||
|
},
|
||||||
|
[comp = component](float val)
|
||||||
|
{
|
||||||
|
comp->SetMaxSpeed(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
SHEditorWidgets::DragInt("Texture Index",
|
||||||
|
[comp = component]()
|
||||||
|
{
|
||||||
|
return comp->GetTextureAssetID();
|
||||||
|
},
|
||||||
|
[comp = component](AssetID val)
|
||||||
|
{
|
||||||
|
comp->SetTextureAssetID(val);
|
||||||
|
});
|
||||||
|
if (SHDragDrop::BeginTarget())
|
||||||
|
{
|
||||||
|
if (AssetID* payload = SHDragDrop::AcceptPayload<AssetID>(SHDragDrop::DRAG_RESOURCE))
|
||||||
|
{
|
||||||
|
Handle<SHTexture> texture = SHResourceManager::LoadOrGet<SHTexture>(*payload);
|
||||||
|
gfxSystem->BuildTextures();
|
||||||
|
|
||||||
|
if (texture)
|
||||||
|
{
|
||||||
|
component->SetTextureIndex(texture->TextureArrayIndex);
|
||||||
|
component->SetTextureAssetID(*payload);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[] Attempted to load invalid texture! Texture for particle not set. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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); });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,21 @@ namespace SHADE
|
||||||
cpuEmitterData.maxSpeed = speed;
|
cpuEmitterData.maxSpeed = speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHParticleEmitterComponent::SetRotationSpeed(float speed) noexcept
|
||||||
|
{
|
||||||
|
cpuEmitterData.rotationSpeed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHParticleEmitterComponent::SetTextureIndex(uint32_t index) noexcept
|
||||||
|
{
|
||||||
|
cpuEmitterData.textureIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHParticleEmitterComponent::SetTextureAssetID(AssetID id)
|
||||||
|
{
|
||||||
|
textureAssetID = id;
|
||||||
|
}
|
||||||
|
|
||||||
void SHParticleEmitterComponent::SetMinSize(float size) noexcept
|
void SHParticleEmitterComponent::SetMinSize(float size) noexcept
|
||||||
{
|
{
|
||||||
cpuEmitterData.lifeAndSizeRange.z = size;
|
cpuEmitterData.lifeAndSizeRange.z = size;
|
||||||
|
@ -113,6 +128,21 @@ namespace SHADE
|
||||||
return cpuEmitterData.maxSpeed;
|
return cpuEmitterData.maxSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float SHParticleEmitterComponent::GetRotationSpeed(void) const noexcept
|
||||||
|
{
|
||||||
|
return cpuEmitterData.rotationSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SHParticleEmitterComponent::GetTextureIndex(void) const noexcept
|
||||||
|
{
|
||||||
|
return cpuEmitterData.textureIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetID SHParticleEmitterComponent::GetTextureAssetID(void) const noexcept
|
||||||
|
{
|
||||||
|
return textureAssetID;
|
||||||
|
}
|
||||||
|
|
||||||
float SHParticleEmitterComponent::GetMinSize(void) const noexcept
|
float SHParticleEmitterComponent::GetMinSize(void) const noexcept
|
||||||
{
|
{
|
||||||
return cpuEmitterData.lifeAndSizeRange.z;
|
return cpuEmitterData.lifeAndSizeRange.z;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "Math/Vector/SHVec4.h"
|
#include "Math/Vector/SHVec4.h"
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
|
#include <Assets/SHAssetMacros.h>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -25,7 +26,11 @@ namespace SHADE
|
||||||
//! Maximum starting velocity
|
//! Maximum starting velocity
|
||||||
float maxSpeed;
|
float maxSpeed;
|
||||||
|
|
||||||
float padding[2];
|
//! Rotational speed of the quad
|
||||||
|
float rotationSpeed;
|
||||||
|
|
||||||
|
//! Texture used by the particle
|
||||||
|
uint32_t textureIndex;
|
||||||
|
|
||||||
//! Spawn lifetime and size range (min and max)
|
//! Spawn lifetime and size range (min and max)
|
||||||
SHVec4 lifeAndSizeRange;
|
SHVec4 lifeAndSizeRange;
|
||||||
|
@ -104,6 +109,9 @@ namespace SHADE
|
||||||
//! For all the dynamic SSBOs in the descriptor set
|
//! For all the dynamic SSBOs in the descriptor set
|
||||||
std::array<std::array<uint32_t, 5>, SHGraphicsConstants::NUM_FRAME_BUFFERS> dynamicOffsets{};
|
std::array<std::array<uint32_t, 5>, SHGraphicsConstants::NUM_FRAME_BUFFERS> dynamicOffsets{};
|
||||||
|
|
||||||
|
//! For the emitter to use to give particles their texture
|
||||||
|
AssetID textureAssetID;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void OnCreate(void) override final;
|
void OnCreate(void) override final;
|
||||||
void OnDestroy(void) override final;
|
void OnDestroy(void) override final;
|
||||||
|
@ -118,6 +126,9 @@ namespace SHADE
|
||||||
void SetAngularRangesAndOffsets (SHVec4 const& ranges) noexcept;
|
void SetAngularRangesAndOffsets (SHVec4 const& ranges) noexcept;
|
||||||
void SetMinSpeed (float speed) noexcept;
|
void SetMinSpeed (float speed) noexcept;
|
||||||
void SetMaxSpeed (float speed) noexcept;
|
void SetMaxSpeed (float speed) noexcept;
|
||||||
|
void SetRotationSpeed (float speed) noexcept;
|
||||||
|
void SetTextureIndex (uint32_t index) noexcept;
|
||||||
|
void SetTextureAssetID (AssetID id);
|
||||||
void SetMinSize (float size) noexcept;
|
void SetMinSize (float size) noexcept;
|
||||||
void SetMaxSize (float size) noexcept;
|
void SetMaxSize (float size) noexcept;
|
||||||
|
|
||||||
|
@ -130,6 +141,9 @@ namespace SHADE
|
||||||
SHVec4 const& GetAngularRangesAndOffsets (void) const noexcept;
|
SHVec4 const& GetAngularRangesAndOffsets (void) const noexcept;
|
||||||
float GetMinSpeed (void) const noexcept;
|
float GetMinSpeed (void) const noexcept;
|
||||||
float GetMaxSpeed (void) const noexcept;
|
float GetMaxSpeed (void) const noexcept;
|
||||||
|
float GetRotationSpeed (void) const noexcept;
|
||||||
|
uint32_t GetTextureIndex (void) const noexcept;
|
||||||
|
AssetID GetTextureAssetID (void) const noexcept;
|
||||||
float GetMinSize (void) const noexcept;
|
float GetMinSize (void) const noexcept;
|
||||||
float GetMaxSize (void) const noexcept;
|
float GetMaxSize (void) const noexcept;
|
||||||
|
|
||||||
|
|
|
@ -200,9 +200,9 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// ...copy assign barriers on heap
|
// ...copy assign barriers on heap
|
||||||
preUpdateBarriers[EMITTER_INDEX * 3] = inputParticleDataBarrierPreUpdate;
|
preUpdateBarriers.push_back(inputParticleDataBarrierPreUpdate);
|
||||||
preUpdateBarriers[(EMITTER_INDEX * 3) + 1] = freelistDataBarrierPreUpdate;
|
preUpdateBarriers.push_back(freelistDataBarrierPreUpdate);
|
||||||
preUpdateBarriers[(EMITTER_INDEX * 3) + 2] = indicesDataBarrierPreUpdate;
|
preUpdateBarriers.push_back(indicesDataBarrierPreUpdate);
|
||||||
|
|
||||||
// make new barrier on stack...
|
// make new barrier on stack...
|
||||||
vk::BufferMemoryBarrier outputParticleDataBarrierPostUpdate
|
vk::BufferMemoryBarrier outputParticleDataBarrierPostUpdate
|
||||||
|
@ -235,9 +235,9 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// ...copy assign barriers on heap
|
// ...copy assign barriers on heap
|
||||||
postUpdateBarriers[EMITTER_INDEX * 3] = outputParticleDataBarrierPostUpdate;
|
postUpdateBarriers.push_back(outputParticleDataBarrierPostUpdate);
|
||||||
postUpdateBarriers[(EMITTER_INDEX * 3) + 1] = indicesDataBarrierPostUpdate;
|
postUpdateBarriers.push_back(indicesDataBarrierPostUpdate);
|
||||||
postUpdateBarriers[(EMITTER_INDEX * 3) + 2] = drawDataBarrierPostUpdate;
|
postUpdateBarriers.push_back(drawDataBarrierPostUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHParticleSubSystem::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 SHParticleSubSystem::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
|
||||||
|
@ -334,15 +334,15 @@ namespace SHADE
|
||||||
// Every emitter will have its own barrier for its particle data and freelist data. Indices data is not needed since
|
// Every emitter will have its own barrier for its particle data and freelist data. Indices data is not needed since
|
||||||
// it's mainly used in update and rendering so a barrier for it is NOT needed here.
|
// it's mainly used in update and rendering so a barrier for it is NOT needed here.
|
||||||
std::vector<vk::BufferMemoryBarrier> preUpdateBarriers{};
|
std::vector<vk::BufferMemoryBarrier> preUpdateBarriers{};
|
||||||
preUpdateBarriers.resize(emitters.size() * 3);
|
preUpdateBarriers.reserve(emitters.size() * 3);
|
||||||
|
|
||||||
// After we invoke the updates for the emitters, we need to make sure all particles and indices data are done updating
|
// After we invoke the updates for the emitters, we need to make sure all particles and indices data are done updating
|
||||||
// before we issue them for rendering.
|
// before we issue them for rendering.
|
||||||
std::vector<vk::BufferMemoryBarrier> postUpdateBarriers{};
|
std::vector<vk::BufferMemoryBarrier> postUpdateBarriers{};
|
||||||
postUpdateBarriers.resize(emitters.size() * 3);
|
postUpdateBarriers.reserve(emitters.size() * 3);
|
||||||
|
|
||||||
std::vector<vk::BufferMemoryBarrier> preDrawBarriers{};
|
std::vector<vk::BufferMemoryBarrier> preDrawBarriers{};
|
||||||
preDrawBarriers.resize(emitters.size());
|
preDrawBarriers.reserve(emitters.size());
|
||||||
|
|
||||||
|
|
||||||
// If we wanted to be VERY safe, a barrier would be good here to make sure output particles have finish reading input particles in
|
// If we wanted to be VERY safe, a barrier would be good here to make sure output particles have finish reading input particles in
|
||||||
|
@ -364,6 +364,8 @@ namespace SHADE
|
||||||
waitFence->Wait(true);
|
waitFence->Wait(true);
|
||||||
|
|
||||||
for (auto& emitter : emitters)
|
for (auto& emitter : emitters)
|
||||||
|
{
|
||||||
|
if (emitter.isActive)
|
||||||
{
|
{
|
||||||
if (!emitter.initialized)
|
if (!emitter.initialized)
|
||||||
InitializeComponent(emitter);
|
InitializeComponent(emitter);
|
||||||
|
@ -399,10 +401,14 @@ namespace SHADE
|
||||||
|
|
||||||
// Emitter will emit once and stop emitting next frame (unless specified before reaching here to do so).
|
// Emitter will emit once and stop emitting next frame (unless specified before reaching here to do so).
|
||||||
emitter.toEmit = false;
|
emitter.toEmit = false;
|
||||||
|
}
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// issue the barrier to wait
|
// issue the barrier to wait
|
||||||
|
if (!preUpdateBarriers.empty())
|
||||||
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader | vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eDrawIndirect, vk::PipelineStageFlagBits::eComputeShader, {}, {}, preUpdateBarriers, {});
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader | vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eDrawIndirect, vk::PipelineStageFlagBits::eComputeShader, {}, {}, preUpdateBarriers, {});
|
||||||
|
|
||||||
|
|
||||||
|
@ -417,13 +423,16 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& emitter : emitters)
|
for (auto& emitter : emitters)
|
||||||
{
|
{
|
||||||
|
if (emitter.isActive)
|
||||||
UpdateCompoennt(cmdBuffer, emitter, frameIndex);
|
UpdateCompoennt(cmdBuffer, emitter, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* 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.
|
||||||
|
if (!postUpdateBarriers.empty())
|
||||||
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eDrawIndirect | vk::PipelineStageFlagBits::eVertexShader, {}, {}, postUpdateBarriers, {});
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eDrawIndirect | vk::PipelineStageFlagBits::eVertexShader, {}, {}, postUpdateBarriers, {});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -456,6 +465,8 @@ namespace SHADE
|
||||||
|
|
||||||
// TODO: Issue barrier for output particle data. Semaphore should also be issued outside in SHGraphicsSystem
|
// TODO: Issue barrier for output particle data. Semaphore should also be issued outside in SHGraphicsSystem
|
||||||
for (auto& emitter : emitters)
|
for (auto& emitter : emitters)
|
||||||
|
{
|
||||||
|
if (emitter.isActive)
|
||||||
{
|
{
|
||||||
// bind the descriptor sets required for emitting particles
|
// bind the descriptor sets required for emitting particles
|
||||||
cmdBuffer->BindDescriptorSet(emitter.particleDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, mappings.at(SHPredefinedDescriptorTypes::PARTICLES), emitter.dynamicOffsets[frameIndex]);
|
cmdBuffer->BindDescriptorSet(emitter.particleDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, mappings.at(SHPredefinedDescriptorTypes::PARTICLES), emitter.dynamicOffsets[frameIndex]);
|
||||||
|
@ -463,6 +474,7 @@ namespace SHADE
|
||||||
RenderComponent(cmdBuffer, emitter, frameIndex);
|
RenderComponent(cmdBuffer, emitter, frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHParticleSubSystem::Exit(void) noexcept
|
void SHParticleSubSystem::Exit(void) noexcept
|
||||||
|
|
|
@ -514,6 +514,8 @@ namespace YAML
|
||||||
static constexpr std::string_view MAX_SIZE_TAG = "Maximum Size";
|
static constexpr std::string_view MAX_SIZE_TAG = "Maximum Size";
|
||||||
static constexpr std::string_view MIN_SPEED_TAG = "Minimum Speed";
|
static constexpr std::string_view MIN_SPEED_TAG = "Minimum Speed";
|
||||||
static constexpr std::string_view MAX_SPEED_TAG = "Maximum Speed";
|
static constexpr std::string_view MAX_SPEED_TAG = "Maximum Speed";
|
||||||
|
static constexpr std::string_view ROTATION_SPEED_TAG = "Rotation Speed";
|
||||||
|
static constexpr std::string_view TEXTURE_ASSET_ID_TAG = "Texture Asset ID";
|
||||||
|
|
||||||
static YAML::Node encode(SHParticleEmitterComponent const& rhs)
|
static YAML::Node encode(SHParticleEmitterComponent const& rhs)
|
||||||
{
|
{
|
||||||
|
@ -528,11 +530,15 @@ namespace YAML
|
||||||
node[MIN_SIZE_TAG.data()] = rhs.GetMinSize();
|
node[MIN_SIZE_TAG.data()] = rhs.GetMinSize();
|
||||||
node[MAX_SIZE_TAG.data()] = rhs.GetMaxSize();
|
node[MAX_SIZE_TAG.data()] = rhs.GetMaxSize();
|
||||||
node[ANGULAR_RANGES_OFFSET_TAG.data()] = rhs.GetAngularRangesAndOffsets();
|
node[ANGULAR_RANGES_OFFSET_TAG.data()] = rhs.GetAngularRangesAndOffsets();
|
||||||
|
node[ROTATION_SPEED_TAG.data()] = rhs.GetRotationSpeed();
|
||||||
|
node[TEXTURE_ASSET_ID_TAG.data()] = rhs.GetTextureAssetID();
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
static bool decode(YAML::Node const& node, SHParticleEmitterComponent& rhs)
|
static bool decode(YAML::Node const& node, SHParticleEmitterComponent& rhs)
|
||||||
{
|
{
|
||||||
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
|
||||||
if (node[EMISSION_COUNT_TAG.data()].IsDefined())
|
if (node[EMISSION_COUNT_TAG.data()].IsDefined())
|
||||||
rhs.SetEmissionCount(node[EMISSION_COUNT_TAG.data()].as<uint32_t>());
|
rhs.SetEmissionCount(node[EMISSION_COUNT_TAG.data()].as<uint32_t>());
|
||||||
|
|
||||||
|
@ -560,6 +566,20 @@ namespace YAML
|
||||||
if (node[MAX_SIZE_TAG.data()].IsDefined())
|
if (node[MAX_SIZE_TAG.data()].IsDefined())
|
||||||
rhs.SetMaxSize(node[MAX_SIZE_TAG.data()].as<float>());
|
rhs.SetMaxSize(node[MAX_SIZE_TAG.data()].as<float>());
|
||||||
|
|
||||||
|
if (node[ROTATION_SPEED_TAG.data()].IsDefined())
|
||||||
|
rhs.SetRotationSpeed(node[ROTATION_SPEED_TAG.data()].as<float>());
|
||||||
|
|
||||||
|
if (node[TEXTURE_ASSET_ID_TAG.data()].IsDefined())
|
||||||
|
{
|
||||||
|
AssetID id = node[TEXTURE_ASSET_ID_TAG.data()].as<AssetID>();
|
||||||
|
|
||||||
|
Handle<SHTexture> texture = SHResourceManager::LoadOrGet<SHTexture>(id);
|
||||||
|
gfxSystem->BuildTextures();
|
||||||
|
|
||||||
|
rhs.SetTextureIndex(texture->TextureArrayIndex);
|
||||||
|
rhs.SetTextureAssetID(id);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue