mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-12-11 05:11:16 +00:00
d9b0ee22e6
I don't yet know whether they actually work (not rendering yet), but the system isn't locking up, and shutdown is clean, so at least resources are handled correctly.
108 lines
2.7 KiB
Text
108 lines
2.7 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 OutStates {
|
|
Particle particles[];
|
|
} outStates;
|
|
|
|
layout(std140, set = 0, binding = 1) buffer OutParameters {
|
|
Parameters parameters[];
|
|
} outParameters;
|
|
|
|
//doubles as VkDrawIndirectCommand
|
|
layout(std140, set = 0, binding = 2) buffer OutSystem {
|
|
uint vertexCount;
|
|
uint particleCount; //instanceCount
|
|
uint firstVertex;
|
|
uint firstInstance;
|
|
} outSystem;
|
|
|
|
layout(std140, set = 1, binding = 0) buffer InStates {
|
|
Particle particles[];
|
|
} inStates;
|
|
|
|
layout(std140, set = 1, binding = 1) buffer InParameters {
|
|
Parameters parameters[];
|
|
} inParameters;
|
|
|
|
//doubles as VkDrawIndirectCommand
|
|
layout(std140, set = 1, binding = 2) buffer InSystem {
|
|
uint vertexCount;
|
|
uint particleCount; //instanceCount
|
|
uint firstVertex;
|
|
uint firstInstance;
|
|
} inSystem;
|
|
|
|
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 (inStates.particles[i], inParameters.parameters[i])) {
|
|
continue;
|
|
}
|
|
outStates.particles[j] = inStates.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 (newStates.particles[i], newParameters.parameters[i])) {
|
|
continue;
|
|
}
|
|
outStates.particles[j] = newStates.particles[i];
|
|
outParameters.parameters[j] = newParameters.parameters[i];
|
|
j++;
|
|
}
|
|
outSystem.vertexCount = newSystem.vertexCount;
|
|
outSystem.particleCount = j;
|
|
outSystem.firstVertex = newSystem.firstVertex;
|
|
outSystem.firstInstance = newSystem.firstInstance;
|
|
}
|