particles_update.glsl 2.3 KB

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