#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; } }