mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-12-01 00:21:50 +00:00
8228146ac0
I realized I'd need to get the particle counts out to the draw commands somehow, and this seemed to be the most natural way.
105 lines
2.5 KiB
Text
105 lines
2.5 KiB
Text
#version 450
|
|
|
|
layout (constant_id = 0) const int MaxParticles = 2048;
|
|
|
|
layout (local_size_x = 1, local_size_y = 1) in;
|
|
|
|
struct Particle {
|
|
vec4 pos;
|
|
vec4 vel;
|
|
vec4 color;
|
|
float tex;
|
|
float ramp;
|
|
float scale;
|
|
float live;
|
|
};
|
|
|
|
struct Parameters {
|
|
vec4 drag; // [dx, dy, dz, grav scale]
|
|
vec4 ramp; // [rate, max, alpha rate, scale rate]
|
|
};
|
|
|
|
layout(std140, set = 0, binding = 0) buffer InStates {
|
|
Particle particles[];
|
|
} inState;
|
|
|
|
layout(std140, set = 0, binding = 1) buffer InParameters {
|
|
Parameters parameters[];
|
|
} inParameters;
|
|
|
|
//doubles as VkDrawIndirectCommand
|
|
layout(std140, set = 0, binding = 2) buffer InSystem {
|
|
uint vertexCount;
|
|
uint particleCount; //instanceCount
|
|
uint firstVertex;
|
|
uint firstInstance;
|
|
} inSystem;
|
|
|
|
layout(std140, set = 1, binding = 0) buffer OutStates {
|
|
Particle particles[];
|
|
} outStates;
|
|
|
|
layout(std140, set = 1, binding = 1) buffer OutParameters {
|
|
Parameters parameters[];
|
|
} outParameters;
|
|
|
|
//doubles as VkDrawIndirectCommand
|
|
layout(std140, set = 1, binding = 2) buffer OutSystem {
|
|
uint vertexCount;
|
|
uint particleCount; //instanceCount
|
|
uint firstVertex;
|
|
uint firstInstance;
|
|
} outSystem;
|
|
|
|
layout(std140, set = 2, binding = 0) buffer NewStates {
|
|
Particle particles[];
|
|
} newStates;
|
|
|
|
layout(std140, set = 2, binding = 1) buffer NewParameters {
|
|
Parameters parameters[];
|
|
} newParameters;
|
|
|
|
//doubles as VkDrawIndirectCommand
|
|
layout(std140, set = 2, binding = 2) buffer NewSystem {
|
|
uint vertexCount;
|
|
uint particleCount; //instanceCount
|
|
uint firstVertex;
|
|
uint firstInstance;
|
|
} newSystem;
|
|
|
|
bool
|
|
is_dead (in Particle part, in Parameters parm)
|
|
{
|
|
if (part.live <= 0) {
|
|
return true;
|
|
}
|
|
if (part.ramp >= parm.ramp.y || part.color.a <= 0 || part.scale <= 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void
|
|
main ()
|
|
{
|
|
uint j = 0;
|
|
// compact existing partles removing dead particles
|
|
for (uint i = 0; i < inSystem.particleCount; i++) {
|
|
if (is_dead (inState.particles[i], inParameters.parameters[i])) {
|
|
continue;
|
|
}
|
|
outStates.particles[j] = inState.particles[i];
|
|
outParameters.parameters[j] = inParameters.parameters[i];
|
|
j++;
|
|
}
|
|
// inject any new particles that aren't DOA
|
|
for (uint i = 0; i < newSystem.particleCount && j < MaxParticles; i++) {
|
|
if (is_dead (inState.particles[i], inParameters.parameters[i])) {
|
|
continue;
|
|
}
|
|
outStates.particles[j] = newStates.particles[i];
|
|
outParameters.parameters[j] = newParameters.parameters[i];
|
|
j++;
|
|
}
|
|
outSystem.particleCount = j;
|
|
}
|