#version 450 #extension GL_ARB_separate_shader_objects : enable struct Object { mat4 model; float explosion_start_time; float explosion_duration; bool deleted; }; layout (binding = 0) uniform UniformBufferObject { mat4 view; mat4 proj; float cur_time; } ubo; layout(binding = 1) readonly buffer StorageBufferObject { Object objects[]; } sbo; layout(location = 0) in vec3 particle_start_velocity; layout(location = 1) in float particle_start_time; layout(location = 2) in uint obj_index; layout(location = 0) out float opacity; void main() { mat4 model = sbo.objects[obj_index].model; float explosion_start_time = sbo.objects[obj_index].explosion_start_time; float explosion_duration = sbo.objects[obj_index].explosion_duration; bool deleted = sbo.objects[obj_index].deleted; float t = ubo.cur_time - explosion_start_time - particle_start_time; if (t < 0.0) { opacity = 0.0; } else { // Need to find out the last time this particle was at the origin // If that is greater than the duration, hide the particle float cur = floor(t / explosion_duration); float end = floor((explosion_duration - particle_start_time) / explosion_duration); if (cur > end) { opacity = 0.0; } else { opacity = 1.0 - (t / explosion_duration); } } if (deleted) { gl_Position = vec4(0.0, 0.0, 2.0, 1.0); } else { // this is the center of the explosion vec3 p = vec3(0.0, 0.0, 0.0); // allow time to loop around so particle emitter keeps going p += normalize(particle_start_velocity) * mod(t, explosion_duration) / explosion_duration * 0.3; gl_Position = ubo.proj * ubo.view * model * vec4(p, 1.0); } gl_PointSize = 10.0; // size in pixels }