Improved particles and trajectory rendering #430

Merged
Xenosas1337 merged 19 commits from SP3-1-Rendering into main 2023-03-20 16:55:29 +08:00
13 changed files with 145 additions and 180 deletions
Showing only changes of commit 32ef4d8c55 - Show all commits

View File

@ -158,15 +158,14 @@
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: 1, y: 1, z: 0}
Maximum Velocity: {x: 2, y: 2, z: 0}
Minimum Size: 1
Maximum Size: 3
Is Passive: true
Emission Interval: 0.200000003
Min Life: 2
Max Life: 3
Minimum Speed: 3
Maximum Speed: 6
Minimum Size: 0
Maximum Size: 0.5
Angular Ranges And Offset: {x: 0, y: 0, z: 0, w: 0}
IsActive: true
Scripts: ~

View File

@ -4,10 +4,10 @@ layout(local_size_x = 128) in;
struct EmitterParameters
{
vec4 angularMin;
vec4 angularMax;
vec4 minVel;
vec4 maxVel;
vec4 angularRangesAndOffsets;
float minSpeed;
float maxSpeed;
float padding[2];
vec4 lifeAndSizeRange; // min life, max life, min size, max size
};
@ -107,6 +107,9 @@ void main()
{
uint emitterInvocationIndex = gl_GlobalInvocationID.x;
vec4 emitterPosition = emitterPushConstant.emitterPosition;
vec4 angularRangesAndOffsets = emitterParams.data.angularRangesAndOffsets;
float minSpeed = emitterParams.data.minSpeed;
float maxSpeed = emitterParams.data.maxSpeed;
if (emitterInvocationIndex >= emitterPushConstant.emissionCount)
return;
@ -127,15 +130,24 @@ void main()
// emit particle from emitter position
particle.position = vec4 (emitterPosition.xyz, 1.0f);
vec2 eulerAngles = vec2 (rand(seed) * angularRangesAndOffsets.x + angularRangesAndOffsets.z,
rand(seed) * angularRangesAndOffsets.y + angularRangesAndOffsets.w);
// Set its velocity
particle.velocity = emitterParams.data.minVel;
particle.velocity.xyz = vec3 (cos(eulerAngles.x) * cos(eulerAngles.y),
sin(eulerAngles.x) * cos(eulerAngles.y),
sin(eulerAngles.y));
particle.velocity *= map (rand (seed), 0.0f, 1.0f, minSpeed.x, maxSpeed.x);
// 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);
float particleSize = map (rand(seed), 0.0f, 1.0f, emitterParams.data.lifeAndSizeRange.z, emitterParams.data.lifeAndSizeRange.w);
// Set size of particle
particle.scaleAndDecay.x = emitterParams.data.lifeAndSizeRange.z;
particle.scaleAndDecay.z = emitterParams.data.lifeAndSizeRange.z;
particle.scaleAndDecay.x = particleSize;
particle.scaleAndDecay.z = particleSize;
particle.rotation = vec4 (5.0f);
particle.acceleration = vec4 (0.01f);

View File

@ -119,23 +119,23 @@ void main()
if (particle.life > 0.0f)
{
// update position from velocity
// particle.position += particle.velocity * genericDataBuffer.data.dt;
// particle.life -= genericDataBuffer.data.dt;
particle.position += particle.velocity * genericDataBuffer.data.dt;
particle.life -= genericDataBuffer.data.dt;
if (particle.life < 0.0f || particle.scaleAndDecay.x < 0.0f || particle.scaleAndDecay.y < 0.0f)
{
particle.life = 0.0f;
particle.position.x = 99999.0f;
particle.position.x = 9999.0f;
outputParticles.data[index] = particle;
freelist.freeIndices[atomicAdd(freelist.freeCount, 1)] = int (index);
return;
}
outputParticles.data[index] = particle;
uint drawIndex = atomicAdd (indirectArgs.instanceCount, 1);
indices[drawIndex] = index;
// indirectArgs.instanceCount = 1;
}
outputParticles.data[index] = particle;
}

View File

@ -74,24 +74,22 @@ void main()
ParticleData particle = outputParticles.data[indices[gl_InstanceIndex]];
vec3 normalized = normalize (particle.velocity.xyz);
float angle = atan (normalized.y, normalized.x);
float angle = 1.1f;
// float angle = atan (normalized.y, normalized.x);
vec2 particleScaleData = particle.scaleAndDecay.xz; // x and y
mat4 localModel = mat4 (1.0f);
localModel[0][0] = 1.0f;
localModel[1][1] = 1.0f;
// localModel[0][0] = particleScaleData.x;
// localModel[1][1] = particleScaleData.y;
mat4 rotate = mat4(1.0f);
mat3 rotate = mat3 (1.0f);
rotate[0][0] = cos(angle);
rotate[0][1] = sin(angle);
rotate[1][0] = -sin(angle);
rotate[1][1] = cos(angle);
// localModel = rotate * localModel;
localModel[3] = vec4 (particle.position.xyz, 1.0f);
// gl_Position = cameraData.vpMat * localModel * vec4(vertexPos, 1.0f);
gl_Position = vec4(vertexPos, 1.0f);
vec3 particlePos = rotate * vertexPos;
vec3 viewRight = normalize (vec3 (cameraData.viewMat[0][0], cameraData.viewMat[1][0], cameraData.viewMat[2][0]));
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);
gl_Position = cameraData.vpMat * vec4(particlePos, 1.0f);
}

Binary file not shown.

View File

@ -827,46 +827,37 @@ namespace SHADE
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("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::DragFloat("Max Size", [comp = component]() {return comp->GetMaxSize(); }, [comp = component](float val) {comp->SetMaxSize(val); });
SHEditorWidgets::DragVec3("Angular Min", {"x", "y", "z"},
SHEditorWidgets::DragVec4("Angles and Offsets", {"yaw", "pitch", "yaw off", "pitch off"},
[comp = component]()
{
return comp->GetAngularMin();
return comp->GetAngularRangesAndOffsets();
},
[comp = component](SHVec3 const& val)
[comp = component](SHVec4 const& val)
{
comp->SetAngularMin(val);
comp->SetAngularRangesAndOffsets(val);
});
SHEditorWidgets::DragVec3("Angular Max", { "x", "y", "z" },
SHEditorWidgets::DragFloat("Min Speed",
[comp = component]()
{
return comp->GetAngularMax();
return comp->GetMinSpeed();
},
[comp = component](SHVec3 const& val)
[comp = component](float val)
{
comp->SetAngularMax(val);
comp->SetMinSpeed(val);
});
SHEditorWidgets::DragVec3("Min Vel", { "x", "y", "z" },
SHEditorWidgets::DragFloat("Max Speed",
[comp = component]()
{
return comp->GetMinVelocity();
return comp->GetMaxSpeed();
},
[comp = component](SHVec3 const& val)
[comp = component](float val)
{
comp->SetMinVelocity(val);
});
SHEditorWidgets::DragVec3("Max Vel", { "x", "y", "z" },
[comp = component]()
{
return comp->GetMaxVelocity();
},
[comp = component](SHVec3 const& val)
{
comp->SetMaxVelocity(val);
comp->SetMaxSpeed(val);
});
SHEditorWidgets::CheckBox("Is Passive", [comp = component]() {return comp->GetPassive(); }, [comp = component](bool flag) {comp->SetPassive(flag); });

View File

@ -46,24 +46,20 @@ namespace SHADE
cpuEmitterData.lifeAndSizeRange.y = val;
}
void SHParticleEmitterComponent::SetAngularMin(SHVec3 const& min) noexcept
void SHParticleEmitterComponent::SetAngularRangesAndOffsets(SHVec4 const& ranges) noexcept
{
cpuEmitterData.angularMin = SHVec4 (min);
cpuEmitterData.angularRangesAndOffsets = SHVec4 (ranges);
}
void SHParticleEmitterComponent::SetAngularMax(SHVec3 const& max) noexcept
void SHParticleEmitterComponent::SetMinSpeed(float speed) noexcept
{
cpuEmitterData.angularMax = SHVec4(max);
cpuEmitterData.minSpeed = speed;
}
void SHParticleEmitterComponent::SetMinVelocity(SHVec3 const& vel) noexcept
void SHParticleEmitterComponent::SetMaxSpeed(float speed) noexcept
{
cpuEmitterData.minVel = vel;
}
void SHParticleEmitterComponent::SetMaxVelocity(SHVec3 const& vel) noexcept
{
cpuEmitterData.maxVel = vel;
cpuEmitterData.maxSpeed = speed;
}
void SHParticleEmitterComponent::SetMinSize(float size) noexcept
@ -102,19 +98,19 @@ namespace SHADE
}
SHVec3 SHParticleEmitterComponent::GetAngularMin(void) const noexcept
SHVec4 const& SHParticleEmitterComponent::GetAngularRangesAndOffsets(void) const noexcept
{
return SHVec3 (cpuEmitterData.angularMin.x, cpuEmitterData.angularMin.y, cpuEmitterData.angularMin.z);
return cpuEmitterData.angularRangesAndOffsets;
}
SHVec3 SHParticleEmitterComponent::GetMinVelocity(void) const noexcept
float SHParticleEmitterComponent::GetMinSpeed(void) const noexcept
{
return SHVec3(cpuEmitterData.minVel.x, cpuEmitterData.minVel.y, cpuEmitterData.minVel.z);
return cpuEmitterData.minSpeed;
}
SHVec3 SHParticleEmitterComponent::GetMaxVelocity(void) const noexcept
float SHParticleEmitterComponent::GetMaxSpeed(void) const noexcept
{
return SHVec3(cpuEmitterData.maxVel.x, cpuEmitterData.maxVel.y, cpuEmitterData.maxVel.z);
return cpuEmitterData.maxSpeed;
}
float SHParticleEmitterComponent::GetMinSize(void) const noexcept
@ -127,9 +123,5 @@ namespace SHADE
return cpuEmitterData.lifeAndSizeRange.w;
}
SHVec3 SHParticleEmitterComponent::GetAngularMax(void) const noexcept
{
return SHVec3(cpuEmitterData.angularMax.x, cpuEmitterData.angularMax.y, cpuEmitterData.angularMax.z);
}
}

View File

@ -16,17 +16,16 @@ namespace SHADE
private:
struct GPUEmitterStruct
{
//! Minimum emitting angular range
SHVec4 angularMin;
//! Maximum emitting angular range
SHVec4 angularMax;
//! Angular ranges of emission
SHVec4 angularRangesAndOffsets;
//! minimum starting velocity
SHVec4 minVel;
float minSpeed;
//! Maximum starting velocity
SHVec4 maxVel;
float maxSpeed;
float padding[2];
//! Spawn lifetime and size range (min and max)
SHVec4 lifeAndSizeRange;
@ -111,30 +110,28 @@ namespace SHADE
void Emit (void) 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;
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;
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;
void SetAngularRangesAndOffsets (SHVec4 const& ranges) noexcept;
void SetMinSpeed (float speed) noexcept;
void SetMaxSpeed (float speed) noexcept;
void SetMinSize (float size) noexcept;
void SetMaxSize (float size) 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;
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;
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;
SHVec4 const& GetAngularRangesAndOffsets (void) const noexcept;
float GetMinSpeed (void) const noexcept;
float GetMaxSpeed (void) const noexcept;
float GetMinSize (void) const noexcept;
float GetMaxSize (void) const noexcept;
friend class SHParticleSubSystem;

View File

@ -23,7 +23,7 @@ namespace SHADE
void SHParticleSubSystem::InitializeComponent(SHParticleEmitterComponent& comp) noexcept
{
// TODO: temporary only.
static constexpr uint32_t NUM_PARTICLES = 5;
static constexpr uint32_t NUM_PARTICLES = 2000;
comp.maxParticles = NUM_PARTICLES;
uint32_t sizeofUint = static_cast<uint32_t>(sizeof(uint32_t));
@ -166,34 +166,46 @@ namespace SHADE
//cmdBuffer->DrawArrays(4, 1, 0, 0);
}
void SHParticleSubSystem::PreparePrePostUpdateBarriers(std::vector<vk::BufferMemoryBarrier>& preUpdateBarriers, std::vector<vk::BufferMemoryBarrier>& postUpdateBarriers, std::vector<vk::BufferMemoryBarrier>& preDrawBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept
void SHParticleSubSystem::PreparePrePostUpdateBarriers(std::vector<vk::BufferMemoryBarrier>& preUpdateBarriers, std::vector<vk::BufferMemoryBarrier>& postUpdateBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept
{
// pre-update particles data barrier. Note that this is for input because we want the input to be available before we use it.
vk::BufferMemoryBarrier particleDataBarrier
vk::BufferMemoryBarrier inputParticleDataBarrierPreUpdate
{
.srcAccessMask = vk::AccessFlagBits::eShaderWrite,
.srcAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite,
.dstAccessMask = vk::AccessFlagBits::eShaderRead,
.buffer = emitter.particleData->GetVkBuffer(),
.offset = emitter.dynamicOffsets[FRAME_INDEX][DYOFF_INDEX_PARTICLE_INPUT],
.size = emitter.chunkSize
};
// pre-update free list data barrier
vk::BufferMemoryBarrier freelistDataBarrier
// pre-update free list data barrier.
vk::BufferMemoryBarrier freelistDataBarrierPreUpdate
{
.srcAccessMask = vk::AccessFlagBits::eShaderWrite,
.dstAccessMask = vk::AccessFlagBits::eShaderRead,
.srcAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite,
.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite,
.buffer = emitter.freelistData->GetVkBuffer(),
.offset = 0, // Only 1 copy of freelist data, so offset is at 0
.size = static_cast<uint32_t>(sizeof (uint32_t)) * (emitter.maxParticles + 1)
};
// pre update indices data barrier.
vk::BufferMemoryBarrier indicesDataBarrierPreUpdate
{
.srcAccessMask = vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead,
.dstAccessMask = vk::AccessFlagBits::eShaderWrite,
.buffer = emitter.indicesData->GetVkBuffer(),
.offset = emitter.dynamicOffsets[FRAME_INDEX][DYOFF_INDEX_INDICES_DATA],
.size = static_cast<uint32_t>(sizeof(uint32_t)) * emitter.maxParticles
};
// ...copy assign barriers on heap
preUpdateBarriers[EMITTER_INDEX * 2] = particleDataBarrier;
preUpdateBarriers[(EMITTER_INDEX * 2) + 1] = freelistDataBarrier;
preUpdateBarriers[EMITTER_INDEX * 3] = inputParticleDataBarrierPreUpdate;
preUpdateBarriers[(EMITTER_INDEX * 3) + 1] = freelistDataBarrierPreUpdate;
preUpdateBarriers[(EMITTER_INDEX * 3) + 2] = indicesDataBarrierPreUpdate;
// make new barrier on stack...
vk::BufferMemoryBarrier particleDataBarrierPost
vk::BufferMemoryBarrier outputParticleDataBarrierPostUpdate
{
.srcAccessMask = vk::AccessFlagBits::eShaderWrite,
.dstAccessMask = vk::AccessFlagBits::eShaderRead,
@ -203,7 +215,7 @@ namespace SHADE
};
// make new barrier on stack...
vk::BufferMemoryBarrier indicesDataBarrier
vk::BufferMemoryBarrier indicesDataBarrierPostUpdate
{
.srcAccessMask = vk::AccessFlagBits::eShaderWrite,
.dstAccessMask = vk::AccessFlagBits::eShaderRead,
@ -213,9 +225,9 @@ namespace SHADE
};
// make new barrier on stack...
vk::BufferMemoryBarrier drawDataBarrier
vk::BufferMemoryBarrier drawDataBarrierPostUpdate
{
.srcAccessMask = vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eMemoryWrite,
.srcAccessMask = vk::AccessFlagBits::eShaderWrite,
.dstAccessMask = vk::AccessFlagBits::eIndirectCommandRead,
.buffer = emitter.drawCallData->GetVkBuffer(),
.offset = emitter.dynamicOffsets[FRAME_INDEX][DYOFF_INDEX_DRAW_DATA],
@ -223,9 +235,9 @@ namespace SHADE
};
// ...copy assign barriers on heap
postUpdateBarriers[EMITTER_INDEX * 2] = particleDataBarrierPost;
postUpdateBarriers[(EMITTER_INDEX * 2) + 1] = indicesDataBarrier;
preDrawBarriers[EMITTER_INDEX] = drawDataBarrier;
postUpdateBarriers[EMITTER_INDEX * 3] = outputParticleDataBarrierPostUpdate;
postUpdateBarriers[(EMITTER_INDEX * 3) + 1] = indicesDataBarrierPostUpdate;
postUpdateBarriers[(EMITTER_INDEX * 3) + 2] = 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
@ -322,12 +334,12 @@ namespace SHADE
// 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.
std::vector<vk::BufferMemoryBarrier> preUpdateBarriers{};
preUpdateBarriers.resize(emitters.size() * 2);
preUpdateBarriers.resize(emitters.size() * 3);
// 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.
std::vector<vk::BufferMemoryBarrier> postUpdateBarriers{};
postUpdateBarriers.resize(emitters.size() * 2);
postUpdateBarriers.resize(emitters.size() * 3);
std::vector<vk::BufferMemoryBarrier> preDrawBarriers{};
preDrawBarriers.resize(emitters.size());
@ -340,8 +352,6 @@ namespace SHADE
/* BEGIN EMITTING PARTICES */
/*-----------------------------------------------------------------------*/
// TODO: Might need to issue a barrier here for input particle data
// bind the pipeline for emitting particles
cmdBuffer->BindPipeline(emittingPipelineData.pipeline);
@ -385,7 +395,7 @@ namespace SHADE
}
// prepare barriers
PreparePrePostUpdateBarriers(preUpdateBarriers, postUpdateBarriers, preDrawBarriers, emitter, i, frameIndex);
PreparePrePostUpdateBarriers(preUpdateBarriers, postUpdateBarriers, emitter, i, frameIndex);
// Emitter will emit once and stop emitting next frame (unless specified before reaching here to do so).
emitter.toEmit = false;
@ -393,7 +403,7 @@ namespace SHADE
}
// issue the barrier to wait
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eComputeShader, {}, {}, preUpdateBarriers, {});
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader | vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eDrawIndirect, vk::PipelineStageFlagBits::eComputeShader, {}, {}, preUpdateBarriers, {});
@ -414,39 +424,13 @@ 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::eDrawIndirect, {}, {}, preDrawBarriers, {});
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eDrawIndirect | vk::PipelineStageFlagBits::eVertexShader, {}, {}, postUpdateBarriers, {});
}
void SHParticleSubSystem::ResetInstanceCounts(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{
auto& emitters = SHComponentManager::GetDense<SHParticleEmitterComponent>();
std::vector<vk::BufferMemoryBarrier> preResetBarriers{};
preResetBarriers.resize(emitters.size());
uint32_t i = 0;
for (auto& emitter : emitters)
{
if (emitter.initialized)
{
// pre-update particles data barrier. Note that this is for input because we want the input to be available before we use it.
vk::BufferMemoryBarrier drawDataHostWriteBarrier
{
.srcAccessMask = vk::AccessFlagBits::eIndirectCommandRead | vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite,
.dstAccessMask = vk::AccessFlagBits::eMemoryWrite | vk::AccessFlagBits::eHostWrite,
.buffer = emitter.drawCallData->GetVkBuffer(),
.offset = emitter.dynamicOffsets[frameIndex][DYOFF_INDEX_DRAW_DATA],
.size = static_cast<uint32_t>(sizeof(vk::DrawIndirectCommand))
};
preResetBarriers[i] = drawDataHostWriteBarrier;
}
++i;
}
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eDrawIndirect, vk::PipelineStageFlagBits::eHost, {}, {}, preResetBarriers, {});
for (auto& emitter : emitters)
{

View File

@ -82,7 +82,7 @@ namespace SHADE
void UpdateCompoennt(Handle<SHVkCommandBuffer> cmdBuffer, SHParticleEmitterComponent& comp, uint32_t frameIndex) noexcept;
void RenderComponent(Handle<SHVkCommandBuffer> cmdBuffer, SHParticleEmitterComponent& comp, uint32_t frameIndex) noexcept;
void PreparePrePostUpdateBarriers (std::vector<vk::BufferMemoryBarrier>& preUpdateBarriers, std::vector<vk::BufferMemoryBarrier>& postUpdateBarriers, std::vector<vk::BufferMemoryBarrier>& preDrawBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept;
void PreparePrePostUpdateBarriers (std::vector<vk::BufferMemoryBarrier>& preUpdateBarriers, std::vector<vk::BufferMemoryBarrier>& postUpdateBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept;
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;

View File

@ -509,12 +509,11 @@ namespace YAML
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 ANGULAR_RANGES_OFFSET_TAG = "Angular Ranges And Offset";
static constexpr std::string_view MIN_SIZE_TAG = "Minimum 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 MAX_SPEED_TAG = "Maximum Speed";
static YAML::Node encode(SHParticleEmitterComponent const& rhs)
{
@ -524,12 +523,11 @@ namespace YAML
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_SPEED_TAG.data()] = rhs.GetMinSpeed();
node[MAX_SPEED_TAG.data()] = rhs.GetMaxSpeed();
node[MIN_SIZE_TAG.data()] = rhs.GetMinSize();
node[MAX_SIZE_TAG.data()] = rhs.GetMaxSize();
node[ANGULAR_RANGES_OFFSET_TAG.data()] = rhs.GetAngularRangesAndOffsets();
return node;
}
@ -550,20 +548,14 @@ namespace YAML
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_RANGES_OFFSET_TAG.data()].IsDefined())
rhs.SetAngularRangesAndOffsets(node[ANGULAR_RANGES_OFFSET_TAG.data()].as<SHVec4>());
if (node[ANGULAR_MAX_TAG.data()].IsDefined())
rhs.SetAngularMax(node[ANGULAR_MAX_TAG.data()].as<SHVec3>());
if (node[MIN_SPEED_TAG.data()].IsDefined())
rhs.SetMinSpeed(node[MIN_SPEED_TAG.data()].as<float>());
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_SPEED_TAG.data()].IsDefined())
rhs.SetMaxSpeed (node[MAX_SPEED_TAG.data()].as<float>());
if (node[MAX_SIZE_TAG.data()].IsDefined())
rhs.SetMaxSize(node[MAX_SIZE_TAG.data()].as<float>());