I think it is in some kind of working state now

This commit is contained in:
2025-08-01 22:46:57 +03:00
parent e2f1c8c13a
commit 15639ff098
4 changed files with 59 additions and 36 deletions

View File

@@ -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 = 0) uniform restrict readonly image2D current_trail;
layout(r32f, binding = 1) uniform restrict writeonly image2D output_trail; layout(r32f, binding = 1) uniform restrict writeonly image2D output_trail;
layout(binding = 2) restrict buffer AgentBuffer { layout(binding = 2) restrict buffer AgentBuffer {
vec2 positions[1024*1024]; vec2 positions[1024];
float headings[1024*1024]; float headings[1024];
} agent_buffer; } agent_buffer;
layout(push_constant, std430) uniform Params { layout(push_constant, std430) uniform Params {
@@ -19,9 +19,17 @@ layout(push_constant, std430) uniform Params {
const float SPEED = 1.0; 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; uint id = gl_GlobalInvocationID.x;
vec2 position = agent_buffer.positions[id]; vec2 position = agent_buffer.positions[id];
@@ -36,35 +44,34 @@ void main() {
vec2 forward_detect_dir = vec2(cos(heading), sin(heading)); vec2 forward_detect_dir = vec2(cos(heading), sin(heading));
float sd = params.sensor_distance; float sd = params.sensor_distance;
vec2 left_detect_pos = position + left_detect_dir * sd; vec2 left_detect_pos = loop_position(position + left_detect_dir * sd);
vec2 right_detect_pos = position + right_detect_dir * sd; vec2 right_detect_pos = loop_position(position + right_detect_dir * sd);
vec2 forward_detect_pos = position + forward_detect_dir * sd; vec2 forward_detect_pos = loop_position(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);
float left = imageLoad(current_trail, ivec2(left_detect_pos)).r; float left = imageLoad(current_trail, ivec2(left_detect_pos)).r;
float right = imageLoad(current_trail, ivec2(right_detect_pos)).r; float right = imageLoad(current_trail, ivec2(right_detect_pos)).r;
float forward = imageLoad(current_trail, ivec2(forward_detect_pos)).r; float forward = imageLoad(current_trail, ivec2(forward_detect_pos)).r;
vec2 pos = position; vec2 pos = position;
float new_heading = heading;
if (left > forward && left > right) { if (left > forward && left > right) {
pos += left_detect_dir * SPEED; pos += left_detect_dir * SPEED;
new_heading = left_heading;
} else if (right > forward && right > left) { } else if (right > forward && right > left) {
pos += right_detect_dir * SPEED; pos += right_detect_dir * SPEED;
new_heading = right_heading;
} else { } else {
pos += forward_detect_dir * SPEED; pos += forward_detect_dir * SPEED;
} }
pos = mod(pos, size); pos = loop_position(pos);
agent_buffer.positions[id] = pos; agent_buffer.positions[id] = pos;
agent_buffer.headings[id] = new_heading;
ivec2 uv = ivec2(pos); float current_v = imageLoad(current_trail, ivec2(pos)).r;
float current_v = imageLoad(current_trail, uv).r;
float new_v = current_v + 0.3; float new_v = current_v + 0.3;
vec4 result = vec4(new_v, new_v, new_v, 1.0); vec4 result = vec4(new_v, new_v, new_v, 1.0);
imageStore(output_trail, uv, result); imageStore(output_trail, ivec2(pos), result);
} }

View File

@@ -20,9 +20,11 @@ float get_dissipation_from(ivec2 uv) {
return v * params.dissipation_factor; return v * params.dissipation_factor;
} }
void store_value(ivec2 uv, vec4 v) { // ivec2 loop_position(vec2 pos) {
imageStore(output_image, uv, v); // 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 // The code we want to execute in each invocation
void main() { void main() {
@@ -31,7 +33,6 @@ void main() {
ivec2 uv = ivec2(gl_GlobalInvocationID.xy); ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
ivec2 tl = ivec2(0, 0); ivec2 tl = ivec2(0, 0);
ivec2 up_uv = clamp(uv - ivec2(0, 1), tl, size); ivec2 up_uv = clamp(uv - ivec2(0, 1), tl, size);
ivec2 down_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); 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 += 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); vec4 result = vec4(new_v, new_v, new_v, 1.0);
imageStore(output_image, uv, result); imageStore(output_image, uv, result);

View File

@@ -12,7 +12,7 @@ extends Node2D
@onready var mesh := $MeshInstance2D @onready var mesh := $MeshInstance2D
## Needs to be changed from the shader as well ## Needs to be changed from the shader as well
const AGENTS: int = 4096 const AGENTS: int = 1024
var texture: Texture2DRD var texture: Texture2DRD
var next_texture: int = 0 var next_texture: int = 0
@@ -31,7 +31,14 @@ func _process(_delta: float) -> void:
texture.texture_rd_rid = texture_rds[next_texture] texture.texture_rd_rid = texture_rds[next_texture]
RenderingServer.call_on_render_thread( 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() var agent_angles := PackedFloat32Array()
# This must match what is set in the shader, if fixed size # This must match what is set in the shader, if fixed size
for n in AGENTS: for n in AGENTS:
var new_position: Vector2 = Vector2( var new_position := Vector2(
rng.randf_range(0, with_texture_size.x), rng.randf_range(0, with_texture_size.x), rng.randf_range(0, with_texture_size.y)
rng.randf_range(0, with_texture_size.y)
) )
agent_positions.push_back(new_position) agent_positions.push_back(new_position)
agent_angles.push_back(rng.randf_range(0, TAU)) 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()) var agent_data := PackedByteArray(agent_positions.to_byte_array())
agent_data.append_array(agent_angles.to_byte_array()) agent_data.append_array(agent_angles.to_byte_array())
agent_buffer = rd.storage_buffer_create( agent_buffer = rd.storage_buffer_create(
agent_data.size(), agent_data, 0, agent_data.size(), agent_data, 0, RenderingDevice.BUFFER_CREATION_AS_STORAGE_BIT
RenderingDevice.BUFFER_CREATION_AS_STORAGE_BIT
) )
# Create trail texture # Create trail texture
@@ -127,7 +132,6 @@ func _initialize_compute_code(with_texture_size: Vector2i) -> void:
| RenderingDevice.TEXTURE_USAGE_CAN_COPY_TO_BIT | RenderingDevice.TEXTURE_USAGE_CAN_COPY_TO_BIT
) )
var agent_uniforms: Array[RDUniform] = [] var agent_uniforms: Array[RDUniform] = []
for i in 2: for i in 2:
texture_rds[i] = rd.texture_create(tf, RDTextureView.new(), []) 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.binding = 0
txtr_uniform_1.add_id(texture_rds[0]) txtr_uniform_1.add_id(texture_rds[0])
agent_uniforms.append(txtr_uniform_1) agent_uniforms.append(txtr_uniform_1)
var txtr_uniform_2 := RDUniform.new() var txtr_uniform_2 := RDUniform.new()
txtr_uniform_2.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE txtr_uniform_2.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
txtr_uniform_2.binding = 1 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.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER
uniform.binding = 2 uniform.binding = 2
uniform.add_id(agent_buffer) uniform.add_id(agent_buffer)
agent_sets[0] = rd.uniform_set_create([txtr_uniform_1, txtr_uniform_2, uniform], agent_shader, 0) agent_sets[0] = rd.uniform_set_create(
agent_sets[1] = rd.uniform_set_create([txtr_uniform_2, txtr_uniform_1, uniform], agent_shader, 0) [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 next_set := texture_sets[with_next_texture]
var current_set := texture_sets[(with_next_texture - 1) % 2] 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_angle)
push_constant.push_back(snsr_distance) push_constant.push_back(snsr_distance)
var agent_compute_list := rd.compute_list_begin() var agent_compute_list := rd.compute_list_begin()
rd.compute_list_bind_compute_pipeline(agent_compute_list, agent_pipeline) 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) rd.compute_list_bind_uniform_set(agent_compute_list, agent_sets[with_next_texture], 0)

View File

@@ -15,9 +15,10 @@ shader_parameter/trail_tex = SubResource("Texture2DRD_pxe3a")
script = ExtResource("1_pxe3a") script = ExtResource("1_pxe3a")
texture_size = Vector2i(1152, 648) texture_size = Vector2i(1152, 648)
decay_factor = 0.75 decay_factor = 0.75
dissipation_factor = 0.04 dissipation_factor = 0.06
sensor_angle = 27.0 sensor_angle = 8.0
sensor_distance = 5.0 sensor_distance = 20.0
rng_seed = 8008
[node name="MeshInstance2D" type="MeshInstance2D" parent="."] [node name="MeshInstance2D" type="MeshInstance2D" parent="."]
self_modulate = Color(0.581022, 0.701395, 0.890748, 1) self_modulate = Color(0.581022, 0.701395, 0.890748, 1)