first try with compute shading

This commit is contained in:
Henrik Neumann 2025-03-02 11:08:22 +01:00
parent 641b069cb0
commit dbd4f668aa
3 changed files with 137 additions and 1 deletions

View File

@ -0,0 +1,34 @@
#[compute]
#version 450
// Speicher für FlowField-Daten
layout(std430, set = 0, binding = 0) buffer FlowFieldBuffer {
vec2 flow_field[];
};
// Zielposition und Grid-Daten
layout(push_constant) uniform Params {
vec2 target_pos;
float cell_size;
int grid_size_x;
int grid_size_z;
};
void main(){
uint x = gl_GlobalInvocationID.x;
uint z = gl_GlobalInvocationID.y;
if (x >= grid_size_x || z >= grid_size_z) return;
int index = int(z * grid_size_x + x);
// Zellzentrum berechnen
vec2 cell_center = vec2(x, z) * cell_size + vec2(cell_size * 0.5);
// Richtung zum Ziel berechnen
vec2 direction = normalize(target_pos - cell_center);
// Ergebnis in FlowField speichern
flow_field[index] = direction;
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://bf4mkjohkqpox"
path="res://.godot/imported/flow_field_compute.glsl-51e5023d4249c63dbf26c3aa62523e13.res"
[deps]
source_file="res://swarm_engine/flow_field_navigation/flow_field_compute.glsl"
dest_files=["res://.godot/imported/flow_field_compute.glsl-51e5023d4249c63dbf26c3aa62523e13.res"]
[params]

View File

@ -39,8 +39,54 @@ var flow_direction_list: Array[Vector2] = []
var half_size_x: float
var half_size_z: float
var rd: RenderingDevice
var shader: RID
var pipeline: RID
var flow_field_buffer: RID
var flow_field_data: PackedVector2Array
func _ready() -> void:
#var rendering_device := RenderingServer.create_local_rendering_device()
#var shader_file := load("res://swarm_engine/flow_field_navigation/flow_field_compute.glsl")
#var shader_spirv: RDShaderSPIRV = shader_file.get_spirv()
#var shader_RID := rendering_device.shader_create_from_spirv(shader_spirv)
#
#var center_array: PackedVector3Array
#for x in range(grid_size_x):
#for z in range(grid_size_z):
#center_array.append(_get_cell_center_with_coordinates(x,z))
#
#var center_byte_array = center_array.to_byte_array()
#var storage_buffer_RID = rendering_device.storage_buffer_create(center_byte_array.size(), center_byte_array)
#
#var uniform := RDUniform.new()
#uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER
#uniform.binding = 0
#uniform.add_id(storage_buffer_RID)
#var uniform_set_RID := rendering_device.uniform_set_create([uniform], shader_RID, 0)
#
#var pipeline_RID := rendering_device.compute_pipeline_create(shader_RID)
#var compute_list_id := rendering_device.compute_list_begin()
#
#rendering_device.compute_list_bind_compute_pipeline(compute_list_id, pipeline_RID)
#rendering_device.compute_list_bind_uniform_set(compute_list_id, uniform_set_RID, 0)
#rendering_device.compute_list_dispatch(compute_list_id, 1, 1, 1)
#rendering_device.compute_list_end()
#rendering_device.submit()
#rd = RenderingServer.get_rendering_device()
#
## Compute Shader laden
#var shader_file = load("res://swarm_engine/flow_field_navigation/flow_field_compute.glsl")
#shader = rd.shader_create_from_spirv(shader_file.get_spirv())
#pipeline = rd.compute_pipeline_create(shader)
#
## Speicher für FlowField erstellen
#var buffer_size = grid_size_x * grid_size_z * 8 # Vector2 -> 2 floats = 8 Bytes pro Eintrag
#flow_field_buffer = rd.storage_buffer_create(buffer_size)
#flow_field_data.resize(grid_size_x * grid_size_z)
#
for x in range(grid_size_x):
for z in range(grid_size_z):
flow_direction_list.append(Vector2(0.0, 0.0))
@ -49,10 +95,52 @@ func _ready() -> void:
func _process(delta: float) -> void:
#_update_gpu_flow_field()
_update_flow_field()
_draw_debug()
func _update_gpu_flow_field():
if not target:
return
# Push-Constants für Shader setzen
var push_constants = PackedByteArray()
push_constants.append_array(PackedByteArray([
target.position.x,
target.position.z,
cell_size,
float(grid_size_x),
float(grid_size_z)
]))
# GPU Command erstellen
var compute_list = rd.compute_list_begin()
rd.compute_list_bind_compute_pipeline(compute_list, pipeline)
rd.compute_list_bind_storage_buffer(compute_list, flow_field_buffer, 0, 0)
rd.compute_list_set_push_constant(compute_list, push_constants, 0)
rd.compute_list_dispatch(compute_list, grid_size_x, grid_size_z, 1)
rd.compute_list_end()
# GPU Berechnung starten
rd.submit()
rd.sync()
# Daten von der GPU zurückholen
var buffer_data = rd.buffer_get_data(flow_field_buffer)
var output = buffer_data.to_float32_array()
# 2D-Array für FlowField initialisieren
flow_direction_list = []
for x in range(grid_size_x):
flow_direction_list.append([]) # Erstellt leere Arrays für jede X-Spalte
# Konvertiere die 1D-GPU-Daten in ein 2D-Array
for z in range(grid_size_z):
for x in range(grid_size_x):
var index = (z * grid_size_x + x) * 2 # 2 Floats pro Vector2
var flow_vector = Vector2(output[index], output[index + 1])
flow_direction_list[index] = flow_vector
func _update_flow_field():
if target != null:
for x in range(grid_size_x):