Advertisement
JontePonte

2D particle life shader

Oct 10th, 2024
17
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.10 KB | None | 0 0
  1. #pragma kernel CSMain
  2.  
  3. struct Particle
  4. {
  5. float posX;
  6. float posY;
  7. float velX;
  8. float velY;
  9. int type;
  10. };
  11.  
  12. RWTexture2D<float4> Result;
  13. RWStructuredBuffer<Particle> particles;
  14. StructuredBuffer<float> attractionMatrix;
  15.  
  16. float deltaTime;
  17. float maxDist;
  18. float forceFactor;
  19. float frictionFactor;
  20.  
  21. uint resolution;
  22. uint particleCount;
  23.  
  24. float Force(float dist, float attraction)
  25. {
  26. const float beta = 0.3;
  27.  
  28. if (dist < beta)
  29. {
  30. return dist / beta - 1;
  31. }
  32. else if (beta < dist && dist < 1)
  33. {
  34. return attraction * (1 - abs(2 * dist - 1 - beta) / (1 - beta));
  35. }
  36. else
  37. {
  38. return 0;
  39. }
  40. }
  41.  
  42. float4 GetParticleColor(uint type)
  43. {
  44. if(type == 0)
  45. return float4(1, 0, 0, 1);
  46. else if(type == 1)
  47. return float4(0, 0, 1, 1);
  48. else if(type == 2)
  49. return float4(1, 0.92, 0.016, 1);
  50. else if(type == 3)
  51. return float4(0, 1, 0, 1);
  52. else if(type == 4)
  53. return float4(0, 1, 1, 1);
  54. else if (type == 5)
  55. return float4(1, 0, 1, 1);
  56. else
  57. return float4(1, 1, 1, 1);
  58. }
  59.  
  60. [numthreads(64,1,1)]
  61. void CSMain (uint3 id : SV_DispatchThreadID)
  62. {
  63. particles[id.x].posX += particles[id.x].velX * deltaTime;
  64. particles[id.x].posY += particles[id.x].velY * deltaTime;
  65.  
  66. float2 totalForce = float2(0, 0);
  67. uint thisType = particles[id.x].type;
  68.  
  69. uint res = resolution - maxDist;
  70.  
  71. for(uint i = 0; i < particleCount; i++)
  72. {
  73. if(i == id.x) { continue; }
  74.  
  75. uint targetType = particles[i].type;
  76.  
  77. float diffX = particles[i].posX - particles[id.x].posX;
  78. float diffY = particles[i].posY - particles[id.x].posY;
  79.  
  80. // Adiust for wrap-around to find shortest path
  81. if (abs(diffX) > (float)(resolution / 2))
  82. {
  83. diffX -= resolution * sign(diffX);
  84. }
  85.  
  86. if (abs(diffY) > (float)(resolution / 2))
  87. {
  88. diffY -= resolution * sign(diffY);
  89. }
  90.  
  91.  
  92. float dist = length(float2(diffX, diffY));
  93.  
  94. if(dist > 0 && dist < maxDist)
  95. {
  96. float force = Force(dist / maxDist, attractionMatrix[thisType + (targetType * 6)]);
  97.  
  98. totalForce += float2(diffX / dist * force, diffY / dist * force);
  99. }
  100. }
  101.  
  102. totalForce *= maxDist * forceFactor;
  103.  
  104. // Apply friction and update velocity
  105. particles[id.x].velX *= frictionFactor;
  106. particles[id.x].velY *= frictionFactor;
  107.  
  108. particles[id.x].velX += totalForce.x * deltaTime;
  109. particles[id.x].velY += totalForce.y * deltaTime;
  110.  
  111. // Apply wrap-around to position
  112. if(particles[id.x].posX >= (float)resolution) { particles[id.x].posX -= resolution; }
  113. if(particles[id.x].posY >= (float)resolution) { particles[id.x].posY -= resolution; }
  114. if(particles[id.x].posX < 0.0) { particles[id.x].posX += resolution; }
  115. if(particles[id.x].posY < 0.0) { particles[id.x].posY += resolution; }
  116.  
  117. int x = (uint)particles[id.x].posX;
  118. int y = (uint)particles[id.x].posY;
  119.  
  120. Result[int2(x, y)] = GetParticleColor(thisType);
  121. }
  122.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement