nuclear-plant-sim/assets/shader/particles.comp

82 lines
1.9 KiB
Plaintext

#include "header.glsl"
#include "random.glsl"
layout (local_size_x = 1, local_size_y = 64, local_size_z = 1) in;
struct VertType {
vec4 pos;
vec4 colour;
vec2 screen_offset;
vec2 uv;
int texid;
};
struct ParticleType {
vec4 pos;
vec4 vel;
vec4 acc;
vec4 colour;
float random_pos;
float random_vel;
float random_time;
float time_start;
float duration;
float size;
int texid;
int seed;
};
layout (binding = SSBO_PARTICLES_IN) readonly buffer ParticleBufferIn {
ParticleType particles_in[];
};
layout (binding = SSBO_PARTICLES_OUT) writeonly buffer ParticleBufferOut {
VertType vertices_out[];
};
layout (binding = SSBO_PARTICLES_LOOKUP) readonly buffer ParticleLookupIn {
int lookup_in[];
};
layout (binding = UBO_PARTICLES_INFO) uniform ParticleInfo {
float p_time;
int p_size;
};
const vec2 QUADS[4] = {
vec2(0, 0),
vec2(1, 0),
vec2(0, 1),
vec2(1, 1)
};
void main() {
ParticleType p = particles_in[lookup_in[gl_GlobalInvocationID.x]];
int n = p.seed;
rand_mix(n, int(gl_GlobalInvocationID.y));
float t_total = p.duration + p.random_time * (rand_float(n)*2-1);
float t = clamp(p_time - p.time_start, 0, t_total);
float t_ratio = t / t_total;
vec3 vel = p.vel.xyz + normalize(rand_vec3(n)*2-1) * p.random_vel;
vec4 pos = vec4(p.pos.xyz + normalize(rand_vec3(n)*2-1) * p.random_pos + (vel + 0.5 * p.acc.xyz * t) * t, 1);
vec4 colour = vec4(p.colour.rgb, p.colour.a * (1 - t_ratio));
pos.z *= (pos.z > 0 ? 1 : 0);
mat2 uv = mat2(rand_vec2(n), rand_vec2(n));
uv = mat2(min(uv[0], uv[1]), max(uv[0], uv[1]));
uint v_id = (gl_GlobalInvocationID.x * gl_WorkGroupSize.y * p_size + gl_GlobalInvocationID.y) * 4;
for(int i = 0; i < 4; i++) {
vertices_out[v_id+i].pos = pos;
vertices_out[v_id+i].colour = colour;
vertices_out[v_id+i].screen_offset = (QUADS[i]*2-1) * p.size;
vertices_out[v_id+i].uv = QUADS[i] * (uv[1] - uv[0]) + uv[0];
vertices_out[v_id+i].texid = p.texid;
}
}