暂无描述

particle.comp 1.8KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #version 450
  2. #extension GL_ARB_separate_shader_objects : enable
  3. #extension GL_ARB_shading_language_420pack : enable
  4. struct Particle
  5. {
  6. vec2 pos;
  7. vec2 vel;
  8. vec4 gradientPos;
  9. };
  10. // Binding 0 : Position storage buffer
  11. layout(std140, binding = 0) buffer Pos
  12. {
  13. Particle particles[ ];
  14. };
  15. layout (local_size_x = 256) in;
  16. layout (binding = 1) uniform UBO
  17. {
  18. float deltaT;
  19. float destX;
  20. float destY;
  21. int particleCount;
  22. } ubo;
  23. vec2 attraction(vec2 pos, vec2 attractPos)
  24. {
  25. vec2 delta = attractPos - pos;
  26. const float damp = 0.5;
  27. float dDampedDot = dot(delta, delta) + damp;
  28. float invDist = 1.0f / sqrt(dDampedDot);
  29. float invDistCubed = invDist*invDist*invDist;
  30. return delta * invDistCubed * 0.0035;
  31. }
  32. vec2 repulsion(vec2 pos, vec2 attractPos)
  33. {
  34. vec2 delta = attractPos - pos;
  35. float targetDistance = sqrt(dot(delta, delta));
  36. return delta * (1.0 / (targetDistance * targetDistance * targetDistance)) * -0.000035;
  37. }
  38. void main()
  39. {
  40. // Current SSBO index
  41. uint index = gl_GlobalInvocationID.x;
  42. // Don't try to write beyond particle count
  43. if (index >= ubo.particleCount)
  44. return;
  45. // Read position and velocity
  46. vec2 vVel = particles[index].vel.xy;
  47. vec2 vPos = particles[index].pos.xy;
  48. vec2 destPos = vec2(ubo.destX, ubo.destY);
  49. vec2 delta = destPos - vPos;
  50. float targetDistance = sqrt(dot(delta, delta));
  51. vVel += repulsion(vPos, destPos.xy) * 0.05;
  52. // Move by velocity
  53. vPos += vVel * ubo.deltaT;
  54. // collide with boundary
  55. if ((vPos.x < -1.0) || (vPos.x > 1.0) || (vPos.y < -1.0) || (vPos.y > 1.0))
  56. vVel = (-vVel * 0.1) + attraction(vPos, destPos) * 12;
  57. else
  58. particles[index].pos.xy = vPos;
  59. // Write back
  60. particles[index].vel.xy = vVel;
  61. particles[index].gradientPos.x += 0.02 * ubo.deltaT;
  62. if (particles[index].gradientPos.x > 1.0)
  63. particles[index].gradientPos.x -= 1.0;
  64. }