Improved particles and trajectory rendering #430
|
@ -22,18 +22,18 @@
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 1
|
- EID: 1
|
||||||
Name: Raccoon
|
Name: Raccoon
|
||||||
IsActive: true
|
IsActive: false
|
||||||
NumberOfChildren: 1
|
NumberOfChildren: 1
|
||||||
Components:
|
Components:
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: 0, y: 0.201105013, z: 0}
|
Translate: {x: 0, y: 0.201105013, z: 0}
|
||||||
Rotate: {x: 0.00523597933, y: -2.96353412, z: -6.40293041e-10}
|
Rotate: {x: 0.00523597933, y: -2.96353412, z: -6.40293041e-10}
|
||||||
Scale: {x: 1.00000191, y: 1, z: 1.00000191}
|
Scale: {x: 1.00000191, y: 1, z: 1.00000191}
|
||||||
IsActive: true
|
IsActive: false
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 149697411
|
Mesh: 149697411
|
||||||
Material: 126974645
|
Material: 126974645
|
||||||
IsActive: true
|
IsActive: false
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 3
|
- EID: 3
|
||||||
Name: Bag
|
Name: Bag
|
||||||
|
@ -87,18 +87,18 @@
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 5
|
- EID: 5
|
||||||
Name: Floor
|
Name: Floor
|
||||||
IsActive: true
|
IsActive: false
|
||||||
NumberOfChildren: 0
|
NumberOfChildren: 0
|
||||||
Components:
|
Components:
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: 0, y: 0.0810000002, z: 0}
|
Translate: {x: 0, y: 0.0810000002, z: 0}
|
||||||
Rotate: {x: -1.57079625, y: 0, z: -0}
|
Rotate: {x: -1.57079625, y: 0, z: -0}
|
||||||
Scale: {x: 50, y: 49.9999924, z: 49.9999924}
|
Scale: {x: 50, y: 49.9999924, z: 49.9999924}
|
||||||
IsActive: true
|
IsActive: false
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 141771688
|
Mesh: 141771688
|
||||||
Material: 124370424
|
Material: 124370424
|
||||||
IsActive: true
|
IsActive: false
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 6
|
- EID: 6
|
||||||
Name: TrajectoryTest
|
Name: TrajectoryTest
|
||||||
|
@ -156,4 +156,17 @@
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
IsActive: true
|
IsActive: true
|
||||||
|
classSHADE::SHParticleEmitterComponent:
|
||||||
|
Emission Count: 1
|
||||||
|
Is Passive: false
|
||||||
|
Emission Interval: 3
|
||||||
|
Min Life: 7
|
||||||
|
Max Life: 20
|
||||||
|
Angular Min: {x: 2.29999995, y: 1.70000005, z: 2.9000001}
|
||||||
|
Angular Max: {x: 0, y: 0, z: 0}
|
||||||
|
Minimum Velocity: {x: 2, y: 3, z: 4}
|
||||||
|
Maximum Velocity: {x: 0, y: 0, z: 0}
|
||||||
|
Minimum Size: 5
|
||||||
|
Maximum Size: 10
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
|
@ -6,6 +6,8 @@ struct EmitterParameters
|
||||||
{
|
{
|
||||||
vec4 angularMin;
|
vec4 angularMin;
|
||||||
vec4 angularMax;
|
vec4 angularMax;
|
||||||
|
vec4 minVel;
|
||||||
|
vec4 maxVel;
|
||||||
vec4 lifeAndSizeRange; // min life, max life, min size, max size
|
vec4 lifeAndSizeRange; // min life, max life, min size, max size
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,6 +111,7 @@ void main()
|
||||||
if (emitterInvocationIndex >= emitterPushConstant.emissionCount)
|
if (emitterInvocationIndex >= emitterPushConstant.emissionCount)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Freecount will start at max particles. Here we subtract every time we emit.
|
||||||
int freelistIndex = atomicAdd (freelist.freeCount, -1) - 1;
|
int freelistIndex = atomicAdd (freelist.freeCount, -1) - 1;
|
||||||
if (freelistIndex < 0)
|
if (freelistIndex < 0)
|
||||||
atomicAdd (freelist.freeCount, 1);
|
atomicAdd (freelist.freeCount, 1);
|
||||||
|
@ -124,9 +127,18 @@ void main()
|
||||||
// emit particle from emitter position
|
// emit particle from emitter position
|
||||||
particle.position = vec4 (emitterPosition.xyz, 1.0f);
|
particle.position = vec4 (emitterPosition.xyz, 1.0f);
|
||||||
|
|
||||||
// randomize life value that ranges from minLife to maxLife
|
// Set its velocity
|
||||||
particle.life = map (rand(seed), -1.0f, 1.0f, emitterParams.data.lifeAndSizeRange.x, emitterParams.data.lifeAndSizeRange.y);
|
particle.velocity = emitterParams.data.minVel;
|
||||||
|
|
||||||
|
// randomize life value that ranges from minLife to maxLife
|
||||||
|
particle.life = map (rand(seed), 0.0f, 1.0f, emitterParams.data.lifeAndSizeRange.x, emitterParams.data.lifeAndSizeRange.y);
|
||||||
|
|
||||||
|
// Set size of particle
|
||||||
|
particle.scaleAndDecay.x = emitterParams.data.lifeAndSizeRange.z;
|
||||||
|
particle.scaleAndDecay.y = emitterParams.data.lifeAndSizeRange.z;
|
||||||
|
|
||||||
|
particle.rotation = vec4 (5.0f);
|
||||||
|
particle.acceleration = vec4 (0.01f);
|
||||||
|
|
||||||
inputParticles.data[index] = particle;
|
inputParticles.data[index] = particle;
|
||||||
}
|
}
|
Binary file not shown.
|
@ -826,6 +826,48 @@ namespace SHADE
|
||||||
SHEditorWidgets::DragFloat("Emission Interval", [comp = component]() {return comp->GetEmissionInterval(); }, [comp = component](float interval) {comp->SetEmissionInterval(interval); });
|
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("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::DragFloat("Max Life", [comp = component]() {return comp->GetMaxLife(); }, [comp = component](float val) {comp->SetMaxLife(val); });
|
||||||
|
SHEditorWidgets::DragFloat("Min Size", [comp = component]() {return comp->GetMinSize(); }, [comp = component](float val) {comp->SetMinSize(val); });
|
||||||
|
SHEditorWidgets::DragFloat("Man Size", [comp = component]() {return comp->GetMaxSize(); }, [comp = component](float val) {comp->SetMaxSize(val); });
|
||||||
|
|
||||||
|
SHEditorWidgets::DragVec3("Angular Min", {"x", "y", "z"},
|
||||||
|
[comp = component]()
|
||||||
|
{
|
||||||
|
return comp->GetAngularMin();
|
||||||
|
},
|
||||||
|
[comp = component](SHVec3 const& val)
|
||||||
|
{
|
||||||
|
comp->SetAngularMin(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
SHEditorWidgets::DragVec3("Angular Max", { "x", "y", "z" },
|
||||||
|
[comp = component]()
|
||||||
|
{
|
||||||
|
return comp->GetAngularMax();
|
||||||
|
},
|
||||||
|
[comp = component](SHVec3 const& val)
|
||||||
|
{
|
||||||
|
comp->SetAngularMax(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
SHEditorWidgets::DragVec3("Min Vel", { "x", "y", "z" },
|
||||||
|
[comp = component]()
|
||||||
|
{
|
||||||
|
return comp->GetMinVelocity();
|
||||||
|
},
|
||||||
|
[comp = component](SHVec3 const& val)
|
||||||
|
{
|
||||||
|
comp->SetMinVelocity(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
SHEditorWidgets::DragVec3("Max Vel", { "x", "y", "z" },
|
||||||
|
[comp = component]()
|
||||||
|
{
|
||||||
|
return comp->GetMaxVelocity();
|
||||||
|
},
|
||||||
|
[comp = component](SHVec3 const& val)
|
||||||
|
{
|
||||||
|
comp->SetMaxVelocity(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); });
|
||||||
|
|
||||||
|
|
|
@ -361,7 +361,7 @@ namespace SHADE
|
||||||
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);
|
particleSubSystem->Render(cmdBuffer, renderer, frameIndex);
|
||||||
});
|
});
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -46,6 +46,36 @@ namespace SHADE
|
||||||
cpuEmitterData.lifeAndSizeRange.y = val;
|
cpuEmitterData.lifeAndSizeRange.y = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHParticleEmitterComponent::SetAngularMin(SHVec3 const& min) noexcept
|
||||||
|
{
|
||||||
|
cpuEmitterData.angularMin = SHVec4 (min);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHParticleEmitterComponent::SetAngularMax(SHVec3 const& max) noexcept
|
||||||
|
{
|
||||||
|
cpuEmitterData.angularMax = SHVec4(max);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHParticleEmitterComponent::SetMinVelocity(SHVec3 const& vel) noexcept
|
||||||
|
{
|
||||||
|
cpuEmitterData.minVel = vel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHParticleEmitterComponent::SetMaxVelocity(SHVec3 const& vel) noexcept
|
||||||
|
{
|
||||||
|
cpuEmitterData.maxVel = vel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHParticleEmitterComponent::SetMinSize(float size) noexcept
|
||||||
|
{
|
||||||
|
cpuEmitterData.lifeAndSizeRange.z = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHParticleEmitterComponent::SetMaxSize(float size) noexcept
|
||||||
|
{
|
||||||
|
cpuEmitterData.lifeAndSizeRange.w = size;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t SHParticleEmitterComponent::GetEmissionCount(void) const noexcept
|
uint32_t SHParticleEmitterComponent::GetEmissionCount(void) const noexcept
|
||||||
{
|
{
|
||||||
return emissionCount;
|
return emissionCount;
|
||||||
|
@ -72,4 +102,34 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHVec3 SHParticleEmitterComponent::GetAngularMin(void) const noexcept
|
||||||
|
{
|
||||||
|
return SHVec3 (cpuEmitterData.angularMin.x, cpuEmitterData.angularMin.y, cpuEmitterData.angularMin.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHParticleEmitterComponent::GetMinVelocity(void) const noexcept
|
||||||
|
{
|
||||||
|
return SHVec3(cpuEmitterData.minVel.x, cpuEmitterData.minVel.y, cpuEmitterData.minVel.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHParticleEmitterComponent::GetMaxVelocity(void) const noexcept
|
||||||
|
{
|
||||||
|
return SHVec3(cpuEmitterData.maxVel.x, cpuEmitterData.maxVel.y, cpuEmitterData.maxVel.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHParticleEmitterComponent::GetMinSize(void) const noexcept
|
||||||
|
{
|
||||||
|
return cpuEmitterData.lifeAndSizeRange.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHParticleEmitterComponent::GetMaxSize(void) const noexcept
|
||||||
|
{
|
||||||
|
return cpuEmitterData.lifeAndSizeRange.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHParticleEmitterComponent::GetAngularMax(void) const noexcept
|
||||||
|
{
|
||||||
|
return SHVec3(cpuEmitterData.angularMax.x, cpuEmitterData.angularMax.y, cpuEmitterData.angularMax.z);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,6 +22,12 @@ namespace SHADE
|
||||||
//! Maximum emitting angular range
|
//! Maximum emitting angular range
|
||||||
SHVec4 angularMax;
|
SHVec4 angularMax;
|
||||||
|
|
||||||
|
//! minimum starting velocity
|
||||||
|
SHVec4 minVel;
|
||||||
|
|
||||||
|
//! Maximum starting velocity
|
||||||
|
SHVec4 maxVel;
|
||||||
|
|
||||||
//! Spawn lifetime and size range (min and max)
|
//! Spawn lifetime and size range (min and max)
|
||||||
SHVec4 lifeAndSizeRange;
|
SHVec4 lifeAndSizeRange;
|
||||||
};
|
};
|
||||||
|
@ -110,12 +116,25 @@ namespace SHADE
|
||||||
void SetEmissionInterval (float interval) noexcept;
|
void SetEmissionInterval (float interval) noexcept;
|
||||||
void SetMinLife (float val) noexcept;
|
void SetMinLife (float val) noexcept;
|
||||||
void SetMaxLife (float val) noexcept;
|
void SetMaxLife (float val) noexcept;
|
||||||
|
void SetAngularMin (SHVec3 const& min) noexcept;
|
||||||
|
void SetAngularMax (SHVec3 const& max) noexcept;
|
||||||
|
void SetMinVelocity (SHVec3 const& vel) noexcept;
|
||||||
|
void SetMaxVelocity (SHVec3 const& vel) noexcept;
|
||||||
|
void SetMinSize (float size) noexcept;
|
||||||
|
void SetMaxSize (float size) noexcept;
|
||||||
|
|
||||||
uint32_t GetEmissionCount (void) const noexcept;
|
|
||||||
bool GetPassive (void) const noexcept;
|
uint32_t GetEmissionCount (void) const noexcept;
|
||||||
float GetEmissionInterval (void) const noexcept;
|
bool GetPassive (void) const noexcept;
|
||||||
float GetMinLife (void) const noexcept;
|
float GetEmissionInterval (void) const noexcept;
|
||||||
float GetMaxLife (void) const noexcept;
|
float GetMinLife (void) const noexcept;
|
||||||
|
float GetMaxLife (void) const noexcept;
|
||||||
|
SHVec3 GetAngularMax (void) const noexcept;
|
||||||
|
SHVec3 GetAngularMin (void) const noexcept;
|
||||||
|
SHVec3 GetMinVelocity (void) const noexcept;
|
||||||
|
SHVec3 GetMaxVelocity (void) const noexcept;
|
||||||
|
float GetMinSize (void) const noexcept;
|
||||||
|
float GetMaxSize (void) const noexcept;
|
||||||
|
|
||||||
friend class SHParticleSubSystem;
|
friend class SHParticleSubSystem;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace SHADE
|
||||||
uint32_t sizeofUint = static_cast<uint32_t>(sizeof(uint32_t));
|
uint32_t sizeofUint = static_cast<uint32_t>(sizeof(uint32_t));
|
||||||
uint32_t sizeofIndirectCmdAligned = logicalDevice->PadSSBOSize(sizeof(vk::DrawIndirectCommand));
|
uint32_t sizeofIndirectCmdAligned = logicalDevice->PadSSBOSize(sizeof(vk::DrawIndirectCommand));
|
||||||
uint32_t emitterStructAligned = logicalDevice->PadSSBOSize(sizeof (SHParticleEmitterComponent::GPUEmitterStruct));
|
uint32_t emitterStructAligned = logicalDevice->PadSSBOSize(sizeof (SHParticleEmitterComponent::GPUEmitterStruct));
|
||||||
uint32_t particleChunkStructAligned = logicalDevice->PadSSBOSize(sizeof (SHParticleEmitterComponent::GPUParticleStruct) * comp.maxParticles);
|
uint32_t particleChunkStructAligned = logicalDevice->PadSSBOSize(sizeof (SHParticleEmitterComponent::GPUParticleStruct)) * comp.maxParticles;
|
||||||
uint32_t indicesDataAligned = logicalDevice->PadSSBOSize(sizeofUint * comp.maxParticles);
|
uint32_t indicesDataAligned = logicalDevice->PadSSBOSize(sizeofUint * comp.maxParticles);
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,9 +36,11 @@ namespace SHADE
|
||||||
|
|
||||||
// Buffer Initialization
|
// Buffer Initialization
|
||||||
{
|
{
|
||||||
// count, value
|
// count, value. Initialize free count to max particles and indices to particle indices
|
||||||
std::vector<uint32_t> freelistInit(comp.maxParticles + 1, 0);
|
std::vector<uint32_t> freelistInit(comp.maxParticles + 1, 0);
|
||||||
freelistInit[0] = comp.maxParticles;
|
freelistInit[0] = comp.maxParticles;
|
||||||
|
for (uint32_t i = 0; i < comp.maxParticles; ++i)
|
||||||
|
freelistInit[i + 1] = i;
|
||||||
|
|
||||||
// Particle emitter buffer. Multiple copies, Host-visible mapped. We want multiple copies because we'll be writing to it from the CPU. We don't want to do that while the GPU
|
// Particle emitter buffer. Multiple copies, Host-visible mapped. We want multiple copies because we'll be writing to it from the CPU. We don't want to do that while the GPU
|
||||||
// is using it during compute operations so we write to another portion.
|
// is using it during compute operations so we write to another portion.
|
||||||
|
@ -89,10 +91,10 @@ namespace SHADE
|
||||||
|
|
||||||
// After buffers are created, we want to populate all bindings(6) with the buffers
|
// After buffers are created, we want to populate all bindings(6) with the buffers
|
||||||
set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_EMITTER_DATA, { &comp.emitterData, 1 }, 0, emitterStructAligned);
|
set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_EMITTER_DATA, { &comp.emitterData, 1 }, 0, emitterStructAligned);
|
||||||
set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_INPUT_DATA, { &comp.particleData, 1 }, 0, PARTICLE_FRAME_CHUNK_SIZE); // input and output will be th same until we bind using dynamic offsets
|
set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_INPUT_DATA, { &comp.particleData, 1 }, 0, particleChunkStructAligned); // input and output will be th same until we bind using dynamic offsets
|
||||||
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, particleChunkStructAligned);
|
||||||
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, indicesDataAligned);
|
||||||
set->ModifyWriteDescBuffer(PARTICLE_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::PARTICLE_DRAW_DATA, { &comp.drawCallData, 1 }, 0, sizeofIndirectCmdAligned);
|
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_EMITTER_DATA);
|
||||||
|
@ -139,6 +141,8 @@ namespace SHADE
|
||||||
cmdBuffer->SetPushConstantVariable("EmitterPushConstant.emitterPosition", transform->GetWorldPosition(), SH_PIPELINE_TYPE::COMPUTE);
|
cmdBuffer->SetPushConstantVariable("EmitterPushConstant.emitterPosition", transform->GetWorldPosition(), SH_PIPELINE_TYPE::COMPUTE);
|
||||||
cmdBuffer->SetPushConstantVariable("EmitterPushConstant.emissionCount", comp.emissionCount, SH_PIPELINE_TYPE::COMPUTE);
|
cmdBuffer->SetPushConstantVariable("EmitterPushConstant.emissionCount", comp.emissionCount, SH_PIPELINE_TYPE::COMPUTE);
|
||||||
|
|
||||||
|
cmdBuffer->SubmitPushConstants(SH_PIPELINE_TYPE::COMPUTE);
|
||||||
|
|
||||||
// emit particles
|
// emit particles
|
||||||
cmdBuffer->ComputeDispatch((comp.emissionCount / EMITTER_WORKGROUP_SIZE) + 1, 1, 1);
|
cmdBuffer->ComputeDispatch((comp.emissionCount / EMITTER_WORKGROUP_SIZE) + 1, 1, 1);
|
||||||
}
|
}
|
||||||
|
@ -388,17 +392,24 @@ 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, {});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHParticleSubSystem::Render(Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex) noexcept
|
void SHParticleSubSystem::Render(Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
auto& emitters = SHComponentManager::GetDense<SHParticleEmitterComponent>();
|
auto& emitters = SHComponentManager::GetDense<SHParticleEmitterComponent>();
|
||||||
|
auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::PARTICLE_RENEDERING);
|
||||||
|
|
||||||
|
// bind the pipeline for updating
|
||||||
|
cmdBuffer->BindPipeline(renderingPipelineData.pipeline);
|
||||||
|
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
|
// bind the descriptor sets required for emitting particles
|
||||||
|
cmdBuffer->BindDescriptorSet(emitter.particleDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, mappings.at(SHPredefinedDescriptorTypes::PARTICLES), emitter.dynamicOffsets[frameIndex]);
|
||||||
|
|
||||||
RenderComponent(cmdBuffer, emitter, frameIndex);
|
RenderComponent(cmdBuffer, emitter, frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,6 +311,7 @@ namespace SHADE
|
||||||
AddComponentID<SHUIComponent>(componentIDList, componentsNode);
|
AddComponentID<SHUIComponent>(componentIDList, componentsNode);
|
||||||
AddComponentID<SHAudioListenerComponent>(componentIDList, componentsNode);
|
AddComponentID<SHAudioListenerComponent>(componentIDList, componentsNode);
|
||||||
AddComponentID<SHTrajectoryRenderableComponent>(componentIDList, componentsNode);
|
AddComponentID<SHTrajectoryRenderableComponent>(componentIDList, componentsNode);
|
||||||
|
AddComponentID<SHParticleEmitterComponent>(componentIDList, componentsNode);
|
||||||
|
|
||||||
return componentIDList;
|
return componentIDList;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
||||||
#include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h"
|
#include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h"
|
||||||
#include "Physics/Collision/Shapes/SHCapsule.h"
|
#include "Physics/Collision/Shapes/SHCapsule.h"
|
||||||
|
#include <Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
@ -35,6 +36,9 @@ namespace YAML
|
||||||
struct HasYAMLConv<SHAnimatorComponent> : std::true_type {};
|
struct HasYAMLConv<SHAnimatorComponent> : std::true_type {};
|
||||||
template<>
|
template<>
|
||||||
struct HasYAMLConv<SHTrajectoryRenderableComponent> : std::true_type {};
|
struct HasYAMLConv<SHTrajectoryRenderableComponent> : std::true_type {};
|
||||||
|
template<>
|
||||||
|
struct HasYAMLConv<SHParticleEmitterComponent> : std::true_type {};
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct convert<SHVec4>
|
struct convert<SHVec4>
|
||||||
|
@ -497,4 +501,75 @@ namespace YAML
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHParticleEmitterComponent>
|
||||||
|
{
|
||||||
|
static constexpr std::string_view EMISSION_COUNT_TAG = "Emission Count";
|
||||||
|
static constexpr std::string_view IS_PASSIVE_TAG = "Is Passive";
|
||||||
|
static constexpr std::string_view EMISSION_INTERVAL_TAG = "Emission Interval";
|
||||||
|
static constexpr std::string_view MIN_LIFE_TAG = "Min Life";
|
||||||
|
static constexpr std::string_view MAX_LIFE_TAG = "Max Life";
|
||||||
|
static constexpr std::string_view ANGULAR_MIN_TAG = "Angular Min";
|
||||||
|
static constexpr std::string_view ANGULAR_MAX_TAG = "Angular Max";
|
||||||
|
static constexpr std::string_view MIN_VEL_TAG = "Minimum Velocity";
|
||||||
|
static constexpr std::string_view MAX_VEL_TAG = "Maximum Velocity";
|
||||||
|
static constexpr std::string_view MIN_SIZE_TAG = "Minimum Size";
|
||||||
|
static constexpr std::string_view MAX_SIZE_TAG = "Maximum Size";
|
||||||
|
|
||||||
|
static YAML::Node encode(SHParticleEmitterComponent const& rhs)
|
||||||
|
{
|
||||||
|
YAML::Node node;
|
||||||
|
node[EMISSION_COUNT_TAG.data()] = rhs.GetEmissionCount();
|
||||||
|
node[IS_PASSIVE_TAG.data()] = rhs.GetPassive();
|
||||||
|
node[EMISSION_INTERVAL_TAG.data()] = rhs.GetEmissionInterval();
|
||||||
|
node[MIN_LIFE_TAG.data()] = rhs.GetMinLife();
|
||||||
|
node[MAX_LIFE_TAG.data()] = rhs.GetMaxLife();
|
||||||
|
node[ANGULAR_MIN_TAG.data()] = rhs.GetAngularMin();
|
||||||
|
node[ANGULAR_MAX_TAG.data()] = rhs.GetAngularMax();
|
||||||
|
node[MIN_VEL_TAG.data()] = rhs.GetMinVelocity();
|
||||||
|
node[MAX_VEL_TAG.data()] = rhs.GetMaxVelocity();
|
||||||
|
node[MIN_SIZE_TAG.data()] = rhs.GetMinSize();
|
||||||
|
node[MAX_SIZE_TAG.data()] = rhs.GetMaxSize();
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(YAML::Node const& node, SHParticleEmitterComponent& rhs)
|
||||||
|
{
|
||||||
|
if (node[EMISSION_COUNT_TAG.data()].IsDefined())
|
||||||
|
rhs.SetEmissionCount(node[EMISSION_COUNT_TAG.data()].as<uint32_t>());
|
||||||
|
|
||||||
|
if (node[IS_PASSIVE_TAG.data()].IsDefined())
|
||||||
|
rhs.SetPassive(node[IS_PASSIVE_TAG.data()].as<bool>());
|
||||||
|
|
||||||
|
if (node[EMISSION_INTERVAL_TAG.data()].IsDefined())
|
||||||
|
rhs.SetEmissionInterval(node[EMISSION_INTERVAL_TAG.data()].as<float>());
|
||||||
|
|
||||||
|
if (node[MIN_LIFE_TAG.data()].IsDefined())
|
||||||
|
rhs.SetMinLife(node[MIN_LIFE_TAG.data()].as<float>());
|
||||||
|
|
||||||
|
if (node[MAX_LIFE_TAG.data()].IsDefined())
|
||||||
|
rhs.SetMaxLife(node[MAX_LIFE_TAG.data()].as<float>());
|
||||||
|
|
||||||
|
if (node[ANGULAR_MIN_TAG.data()].IsDefined())
|
||||||
|
rhs.SetAngularMin(node[ANGULAR_MIN_TAG.data()].as<SHVec3>());
|
||||||
|
|
||||||
|
if (node[ANGULAR_MAX_TAG.data()].IsDefined())
|
||||||
|
rhs.SetAngularMax(node[ANGULAR_MAX_TAG.data()].as<SHVec3>());
|
||||||
|
|
||||||
|
if (node[MIN_VEL_TAG.data()].IsDefined())
|
||||||
|
rhs.SetMinVelocity(node[MIN_VEL_TAG.data()].as<SHVec3>());
|
||||||
|
|
||||||
|
if (node[MAX_VEL_TAG.data()].IsDefined())
|
||||||
|
rhs.SetMaxVelocity(node[MAX_VEL_TAG.data()].as<SHVec3>());
|
||||||
|
|
||||||
|
if (node[MIN_SIZE_TAG.data()].IsDefined())
|
||||||
|
rhs.SetMinSize(node[MIN_SIZE_TAG.data()].as<float>());
|
||||||
|
|
||||||
|
if (node[MAX_SIZE_TAG.data()].IsDefined())
|
||||||
|
rhs.SetMaxSize(node[MAX_SIZE_TAG.data()].as<float>());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue