particles_update.glsl 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #version 430 core
  2. struct particle_t {
  3. vec2 pos;
  4. vec2 dir;
  5. };
  6. struct cell_t {
  7. float pheromone;
  8. float result;
  9. int population;
  10. };
  11. uniform int map_width;
  12. uniform int map_height;
  13. uniform uint population;
  14. uniform float speed;
  15. uniform float steering;
  16. uniform float sensing_distance;
  17. uniform float sensing_angle;
  18. uniform float dt;
  19. layout(std430, binding = 1) coherent buffer particles_buffer
  20. {
  21. particle_t particles[];
  22. };
  23. layout(std430, binding = 2) coherent buffer map_buffer
  24. {
  25. cell_t map[];
  26. };
  27. vec2 rotate(vec2 v, float angle){
  28. float c = cos(angle);
  29. float s = sin(angle);
  30. return vec2(v.x * c - v.y * s, v.x * s + v.y * c);
  31. }
  32. vec2 ahead(vec2 at, vec2 dir, float d){
  33. return at + d * dir;
  34. }
  35. vec2 wrap_coord(vec2 v){
  36. return mod(v, vec2(map_width, map_height));
  37. }
  38. uint cell_id(vec2 v){
  39. ivec2 map_pos = ivec2(floor(v));
  40. return uint(map_pos.y * map_width + map_pos.x);
  41. }
  42. layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
  43. void main(){
  44. uint particle_id = gl_GlobalInvocationID.x;
  45. if(particle_id >= population){
  46. return;
  47. }
  48. // Update particle position
  49. particle_t p = particles[particle_id];
  50. particles[particle_id].pos = wrap_coord(p.pos + dt * speed * p.dir);
  51. // Count particle
  52. uint p_cell_id = cell_id(p.pos);
  53. atomicAdd(map[p_cell_id].population, 1);
  54. // Sense and turn
  55. vec2 look_ahead = wrap_coord(ahead(p.pos, p.dir, sensing_distance));
  56. vec2 look_left = wrap_coord(ahead(p.pos, rotate(p.dir, sensing_angle), sensing_distance));
  57. vec2 look_right = wrap_coord(ahead(p.pos, rotate(p.dir, -sensing_angle), sensing_distance));
  58. float pheromone_ahead = map[cell_id(look_ahead)].pheromone;
  59. float pheromone_left = map[cell_id(look_left )].pheromone;
  60. float pheromone_right = map[cell_id(look_right)].pheromone;
  61. if(pheromone_left > pheromone_ahead && pheromone_left > pheromone_right){
  62. particles[particle_id].dir = rotate(p.dir, steering * dt);
  63. }else if(pheromone_right > pheromone_ahead && pheromone_right > pheromone_left){
  64. particles[particle_id].dir = rotate(p.dir, -steering * dt);
  65. }
  66. }