From 15639ff098608b7c92d9a97f133b56d67369250c Mon Sep 17 00:00:00 2001 From: Kasper Date: Fri, 1 Aug 2025 22:46:57 +0300 Subject: [PATCH] I think it is in some kind of working state now --- shaders/agents_cs.glsl | 37 ++++++++++++++++++++++--------------- shaders/decay_cs.glsl | 11 ++++++----- slime_simulation.gd | 40 +++++++++++++++++++++++++++------------- slime_simulation.tscn | 7 ++++--- 4 files changed, 59 insertions(+), 36 deletions(-) diff --git a/shaders/agents_cs.glsl b/shaders/agents_cs.glsl index 686d56d..c41699f 100644 --- a/shaders/agents_cs.glsl +++ b/shaders/agents_cs.glsl @@ -7,8 +7,8 @@ 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]; + vec2 positions[1024]; + float headings[1024]; } agent_buffer; layout(push_constant, std430) uniform Params { @@ -19,9 +19,17 @@ layout(push_constant, std430) uniform Params { const float SPEED = 1.0; -void main() { +vec2 loop_position(vec2 pos) { + int width = params.texture_size.x; + int height = params.texture_size.y; + if (pos.x > width) pos.x = mod(pos.x, width); + if (pos.y > height) pos.y = mod(pos.y, height); + if (pos.x < 0) pos.x = width - pos.x; + if (pos.y < 0) pos.y = height - pos.y; + return pos; +} - ivec2 size = ivec2(params.texture_size.x - 1, params.texture_size.y - 1); +void main() { uint id = gl_GlobalInvocationID.x; vec2 position = agent_buffer.positions[id]; @@ -36,35 +44,34 @@ void main() { vec2 forward_detect_dir = vec2(cos(heading), sin(heading)); float sd = params.sensor_distance; - vec2 left_detect_pos = position + left_detect_dir * sd; - vec2 right_detect_pos = position + right_detect_dir * sd; - vec2 forward_detect_pos = position + forward_detect_dir * sd; - - left_detect_pos = mod(left_detect_pos, size); - right_detect_pos = mod(right_detect_pos, size); - forward_detect_pos = mod(forward_detect_pos, size); + 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 { pos += forward_detect_dir * SPEED; } - pos = mod(pos, size); + pos = loop_position(pos); agent_buffer.positions[id] = pos; + agent_buffer.headings[id] = new_heading; - ivec2 uv = ivec2(pos); - float current_v = imageLoad(current_trail, uv).r; + float current_v = imageLoad(current_trail, ivec2(pos)).r; float new_v = current_v + 0.3; vec4 result = vec4(new_v, new_v, new_v, 1.0); - imageStore(output_trail, uv, result); + imageStore(output_trail, ivec2(pos), result); } diff --git a/shaders/decay_cs.glsl b/shaders/decay_cs.glsl index 3a5221e..e3326b9 100644 --- a/shaders/decay_cs.glsl +++ b/shaders/decay_cs.glsl @@ -20,9 +20,11 @@ float get_dissipation_from(ivec2 uv) { return v * params.dissipation_factor; } -void store_value(ivec2 uv, vec4 v) { - imageStore(output_image, uv, v); -} +// ivec2 loop_position(vec2 pos) { +// int width = params.texture_size.x; +// int height = params.texture_size.y; +// return ivec2(mod(pos + params.texture_size, params.texture_size)); +// } // The code we want to execute in each invocation void main() { @@ -31,7 +33,6 @@ void main() { ivec2 uv = ivec2(gl_GlobalInvocationID.xy); ivec2 tl = ivec2(0, 0); - ivec2 up_uv = clamp(uv - ivec2(0, 1), tl, size); ivec2 down_uv = clamp(uv + ivec2(0, 1), tl, size); ivec2 left_uv = clamp(uv - ivec2(1, 0), tl, size); @@ -51,7 +52,7 @@ void main() { new_v += get_dissipation_from(left_uv); - new_v = clamp(new_v, 0, 1); + // new_v = clamp(new_v, 0, 1); vec4 result = vec4(new_v, new_v, new_v, 1.0); imageStore(output_image, uv, result); diff --git a/slime_simulation.gd b/slime_simulation.gd index 3132c02..ed97e52 100644 --- a/slime_simulation.gd +++ b/slime_simulation.gd @@ -12,7 +12,7 @@ extends Node2D @onready var mesh := $MeshInstance2D ## Needs to be changed from the shader as well -const AGENTS: int = 4096 +const AGENTS: int = 1024 var texture: Texture2DRD var next_texture: int = 0 @@ -31,7 +31,14 @@ func _process(_delta: float) -> void: texture.texture_rd_rid = texture_rds[next_texture] RenderingServer.call_on_render_thread( - _render_process.bind(next_texture, texture_size, decay_factor, dissipation_factor, sensor_angle, sensor_distance) + _render_process.bind( + next_texture, + texture_size, + decay_factor, + dissipation_factor, + sensor_angle, + sensor_distance + ) ) @@ -96,9 +103,8 @@ func _initialize_compute_code(with_texture_size: Vector2i) -> void: var agent_angles := PackedFloat32Array() # This must match what is set in the shader, if fixed size for n in AGENTS: - var new_position: Vector2 = Vector2( - rng.randf_range(0, with_texture_size.x), - rng.randf_range(0, with_texture_size.y) + var new_position := Vector2( + rng.randf_range(0, with_texture_size.x), rng.randf_range(0, with_texture_size.y) ) agent_positions.push_back(new_position) agent_angles.push_back(rng.randf_range(0, TAU)) @@ -106,8 +112,7 @@ func _initialize_compute_code(with_texture_size: Vector2i) -> void: var agent_data := PackedByteArray(agent_positions.to_byte_array()) agent_data.append_array(agent_angles.to_byte_array()) agent_buffer = rd.storage_buffer_create( - agent_data.size(), agent_data, 0, - RenderingDevice.BUFFER_CREATION_AS_STORAGE_BIT + agent_data.size(), agent_data, 0, RenderingDevice.BUFFER_CREATION_AS_STORAGE_BIT ) # Create trail texture @@ -127,7 +132,6 @@ func _initialize_compute_code(with_texture_size: Vector2i) -> void: | RenderingDevice.TEXTURE_USAGE_CAN_COPY_TO_BIT ) - var agent_uniforms: Array[RDUniform] = [] for i in 2: texture_rds[i] = rd.texture_create(tf, RDTextureView.new(), []) @@ -142,7 +146,7 @@ func _initialize_compute_code(with_texture_size: Vector2i) -> void: txtr_uniform_1.binding = 0 txtr_uniform_1.add_id(texture_rds[0]) agent_uniforms.append(txtr_uniform_1) - + var txtr_uniform_2 := RDUniform.new() txtr_uniform_2.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE txtr_uniform_2.binding = 1 @@ -153,11 +157,22 @@ func _initialize_compute_code(with_texture_size: Vector2i) -> void: uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER uniform.binding = 2 uniform.add_id(agent_buffer) - agent_sets[0] = rd.uniform_set_create([txtr_uniform_1, txtr_uniform_2, uniform], agent_shader, 0) - agent_sets[1] = rd.uniform_set_create([txtr_uniform_2, txtr_uniform_1, uniform], agent_shader, 0) + agent_sets[0] = rd.uniform_set_create( + [txtr_uniform_1, txtr_uniform_2, uniform], agent_shader, 0 + ) + agent_sets[1] = rd.uniform_set_create( + [txtr_uniform_2, txtr_uniform_1, uniform], agent_shader, 0 + ) -func _render_process(with_next_texture: int, tex_size: Vector2i, decay_fctr: float, dissipation_fctr: float, snsr_angle: float, snsr_distance: float) -> void: +func _render_process( + with_next_texture: int, + tex_size: Vector2i, + decay_fctr: float, + dissipation_fctr: float, + snsr_angle: float, + snsr_distance: float +) -> void: var next_set := texture_sets[with_next_texture] var current_set := texture_sets[(with_next_texture - 1) % 2] @@ -168,7 +183,6 @@ func _render_process(with_next_texture: int, tex_size: Vector2i, decay_fctr: flo push_constant.push_back(snsr_angle) push_constant.push_back(snsr_distance) - var agent_compute_list := rd.compute_list_begin() rd.compute_list_bind_compute_pipeline(agent_compute_list, agent_pipeline) rd.compute_list_bind_uniform_set(agent_compute_list, agent_sets[with_next_texture], 0) diff --git a/slime_simulation.tscn b/slime_simulation.tscn index a341f8d..5e01d5c 100644 --- a/slime_simulation.tscn +++ b/slime_simulation.tscn @@ -15,9 +15,10 @@ shader_parameter/trail_tex = SubResource("Texture2DRD_pxe3a") script = ExtResource("1_pxe3a") texture_size = Vector2i(1152, 648) decay_factor = 0.75 -dissipation_factor = 0.04 -sensor_angle = 27.0 -sensor_distance = 5.0 +dissipation_factor = 0.06 +sensor_angle = 8.0 +sensor_distance = 20.0 +rng_seed = 8008 [node name="MeshInstance2D" type="MeshInstance2D" parent="."] self_modulate = Color(0.581022, 0.701395, 0.890748, 1)