-
Notifications
You must be signed in to change notification settings - Fork 1
/
slime.gd
120 lines (88 loc) · 4.13 KB
/
slime.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
extends Sprite2D
#region Simulation Parameters
var screen_size := Vector2i(1280, 720)
var working_screen_size := screen_size
var simulation_speed := 1.0
var blur_speed := 6.0
var decay_speed := 0.5
var agent_speed := 30.0
var agent_turn_speed := 4.0
var agent_lookahead := 40.0
var agent_fov := deg_to_rad(30.0)
var agent_trail := 2.0
var agent_sensor_extend := 1.0
var player_enabled := false
var player_trail := 2.0
var player_trail_radius := 50.0
#endregion
var agent_compute_shader: ComputeHelper
var texture_compute_shader: ComputeHelper
var agent_shader_groups: Vector3i
var texture_shader_groups: Vector3i
var input_texture: ImageUniform
var halfway_texture: SharedImageUniform
var output_texture: SharedImageUniform
var agent_parameters_buffer: StorageBufferUniform
var agent_buffer: StorageBufferUniform
var texture_parameters_buffer: StorageBufferUniform
func _ready() -> void:
RenderingServer.call_on_render_thread(initialize_compute_shaders)
func _process(delta : float) -> void:
RenderingServer.call_on_render_thread(update_compute_shaders.bind(delta * simulation_speed))
func _exit_tree() -> void:
RenderingServer.call_on_render_thread(end_compute_shaders)
func initialize_compute_shaders() -> void:
var screen_radius := minf(screen_size.x, screen_size.y) / 2.0
var screen_center := screen_size / 2.0
$Player.position = screen_center
$Agents.start_agent_creation(screen_radius, screen_center, screen_size)
var agent_params := PackedFloat32Array([0.0]).to_byte_array()
var texture_params := PackedFloat32Array([0.0]).to_byte_array()
var image := Image.create(screen_size.x, screen_size.y, false, Image.FORMAT_RGBAF)
image.fill(Color.BLACK)
agent_compute_shader = ComputeHelper.create("res://slime/agent_compute.glsl")
texture_compute_shader = ComputeHelper.create("res://slime/texture_compute.glsl")
input_texture = ImageUniform.create(image)
halfway_texture = SharedImageUniform.create(input_texture)
output_texture = SharedImageUniform.create(input_texture)
texture.texture_rd_rid = input_texture.texture
agent_shader_groups = Vector3i($Agents.number_of_agents / 64, 1, 1)
texture_shader_groups = Vector3i(screen_size.x / 16, screen_size.y / 16, 1)
agent_parameters_buffer = StorageBufferUniform.create(agent_params)
texture_parameters_buffer = StorageBufferUniform.create(texture_params)
agent_buffer = StorageBufferUniform.create($Agents.get_created_agents())
agent_compute_shader.add_uniform_array([agent_parameters_buffer, agent_buffer, input_texture, halfway_texture])
texture_compute_shader.add_uniform_array([texture_parameters_buffer, halfway_texture, output_texture])
func update_compute_shaders(delta: float) -> void:
if player_enabled:
$Player.movement(delta)
var agent_params := PackedFloat32Array([
randf(), working_screen_size.x, working_screen_size.y, agent_speed * delta, agent_turn_speed * delta,
agent_lookahead, agent_fov, agent_trail * delta, agent_sensor_extend
]).to_byte_array()
agent_parameters_buffer.update_data(agent_params)
agent_compute_shader.run(agent_shader_groups)
ComputeHelper.sync()
var texture_params := PackedFloat32Array([
blur_speed * delta, decay_speed * delta, player_trail_radius, player_trail * float(player_enabled),
$Player.position.x, $Player.position.y
]).to_byte_array()
texture_parameters_buffer.update_data(texture_params)
texture_compute_shader.run(texture_shader_groups)
func reset_simulation() -> void:
var screen_radius := minf(screen_size.x, screen_size.y) / 2.0
var screen_center := screen_size / 2.0
$Player.position = screen_center
$Agents.start_agent_creation(screen_radius, screen_center, screen_size)
var image := Image.create(screen_size.x, screen_size.y, false, Image.FORMAT_RGBAF)
image.fill(Color.BLACK)
texture.texture_rd_rid = RID()
input_texture.update_image(image)
agent_shader_groups = Vector3i($Agents.number_of_agents / 64, 1, 1)
texture_shader_groups = Vector3i(screen_size.x / 16, screen_size.y / 16, 1)
working_screen_size = screen_size
texture.texture_rd_rid = input_texture.texture
agent_buffer.update_data($Agents.get_created_agents())
func end_compute_shaders() -> void:
agent_compute_shader.free()
texture_compute_shader.free()