#version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable struct Particle { vec4 pos; vec4 col; vec4 vel; }; // Binding 0 : Position storage buffer layout(std140, binding = 0) buffer Pos { Particle particles[ ]; }; layout (local_size_x = 16, local_size_y = 16) in; layout (binding = 1) uniform UBO { float deltaT; float destX; float destY; int particleCount; } ubo; vec3 attraction(vec3 pos, vec3 attractPos) { vec3 delta = attractPos - pos; const float damp = 0.5; float dDampedDot = dot(delta, delta) + damp; float invDist = 1.0f / sqrt(dDampedDot); float invDistCubed = invDist*invDist*invDist; return delta * invDistCubed * 0.00035; } void main() { // Current SSBO index uint index = gl_GlobalInvocationID.x; // Don't try to write beyond particle count if (index >= ubo.particleCount) return; // Read position and velocity vec3 vPos = particles[index].pos.xyz; vec3 vVel = particles[index].vel.xyz; vec3 destPos = vec3(ubo.destX, ubo.destY, 0.0); // Calculate new velocity depending on attraction point vVel += attraction(vPos, destPos.xyz); // Move by velocity vPos += vVel * ubo.deltaT; if ((vPos.x < -1.0) || (vPos.x > 1.0)) vVel.x -= vVel.x; // Write back particles[index].pos.xyz = vPos; particles[index].vel.xyz = vVel; }