#[compute] #version 450 // Invocations in the (x, y, z) dimension layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; layout(r32f, binding = 0) uniform restrict readonly image2D current_trail; layout(r32f, binding = 1) uniform restrict writeonly image2D output_trail; layout(binding = 2) restrict buffer AgentBuffer { vec2 positions[1024 * 1024]; float headings[1024 * 1024]; } agent_buffer; layout(push_constant, std430) uniform Params { vec2 texture_size; float sensor_angle; float sensor_distance; } params; const float SPEED = 1.0; float random(vec2 coords) { return fract(sin(dot(coords.xy, vec2(12.9898,78.233))) * 43758.5453); } vec2 loop_position(vec2 pos) { return mod(pos, params.texture_size); } void main() { uint id = gl_GlobalInvocationID.x; vec2 position = agent_buffer.positions[id]; float heading = agent_buffer.headings[id]; float current_v = imageLoad(current_trail, ivec2(position)).r; float sa = params.sensor_angle; float left_heading = heading - sa; float right_heading = heading + sa; vec2 left_detect_dir = vec2(cos(left_heading), sin(left_heading)); vec2 right_detect_dir = vec2(cos(right_heading), sin(right_heading)); vec2 forward_detect_dir = vec2(cos(heading), sin(heading)); float sd = params.sensor_distance; vec2 left_detect_pos = loop_position(position + left_detect_dir * sd); vec2 right_detect_pos = loop_position(position + right_detect_dir * sd); vec2 forward_detect_pos = loop_position(position + forward_detect_dir * sd); float left = imageLoad(current_trail, ivec2(left_detect_pos)).r; float right = imageLoad(current_trail, ivec2(right_detect_pos)).r; float forward = imageLoad(current_trail, ivec2(forward_detect_pos)).r; vec2 pos = position; float new_heading = heading; if (left > forward && left > right) { pos += left_detect_dir * SPEED; new_heading = left_heading; } else if (right > forward && right > left) { pos += right_detect_dir * SPEED; new_heading = right_heading; } else if (forward < left && forward < right) { // uuugh float r = random(pos); if (r < 0.5) { pos += right_detect_dir * SPEED; new_heading = right_heading; } else { pos += left_detect_dir * SPEED; new_heading = left_heading; } } else { pos += forward_detect_dir * SPEED; } pos = mod(pos, params.texture_size); agent_buffer.positions[id] = pos; agent_buffer.headings[id] = new_heading; float new_v = current_v + 0.3; if (new_v > 1.0) new_v = 1.0; vec4 result = vec4(new_v, new_v, new_v, 1.0); imageStore(output_trail, ivec2(pos), result); }