mirror of
https://github.com/GarrettGunnell/God-Machine.git
synced 2025-10-19 14:43:16 +00:00
Encode upper left ui grid quadrant to byte array and pass as push constant to compute shader
This commit is contained in:
parent
057a4e1ca5
commit
bbf1224d7d
7 changed files with 97 additions and 44 deletions
|
@ -14,8 +14,10 @@ layout(binding = 1) uniform UniformBufferObject {
|
|||
};
|
||||
|
||||
layout(push_constant, std430) uniform Params {
|
||||
vec2 raster_size;
|
||||
vec2 seeds;
|
||||
uint64_t _UpperLeftMask;
|
||||
uint64_t _UpperRightMask;
|
||||
uint64_t _LowerLeftMask;
|
||||
uint64_t _LowerRightMask;
|
||||
};
|
||||
|
||||
float pseudo(vec2 v) {
|
||||
|
@ -26,8 +28,8 @@ float pseudo(vec2 v) {
|
|||
[numthreads(8, 8, 1)]
|
||||
void Seed() {
|
||||
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
|
||||
ivec2 size = ivec2(raster_size);
|
||||
if (uv.x >= size.x || uv.y >= size.y) return;
|
||||
|
||||
vec2 seeds = vec2(0.0, 0.0);
|
||||
|
||||
float seed = pseudo(vec2(float(uv.x) * 0.1 + seeds.x, float(uv.y) * 0.1 + seeds.x * 3));
|
||||
|
||||
|
@ -70,25 +72,29 @@ uint sum_uint_bits(uint64_t i) {
|
|||
[numthreads(8, 8, 1)]
|
||||
void Automaton() {
|
||||
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
|
||||
ivec2 size = ivec2(raster_size);
|
||||
if (uv.x >= size.x || uv.y >= size.y) return;
|
||||
|
||||
int cell = int(imageLoad(_AutomatonFrom, uv).r);
|
||||
|
||||
uint64_t top_row_mask = 18374686479671623680UL;
|
||||
uint64_t left_column_mask = 9259542123273814144UL;
|
||||
|
||||
// GAME OF LIFE
|
||||
// uint64_t upper_left_mask = 770;
|
||||
uint64_t upper_left_mask = 69540876599103UL;
|
||||
|
||||
// uint64_t upper_right_mask = 49216 & ~(left_column_mask);
|
||||
uint64_t upper_right_mask = 278163506396412UL & ~(left_column_mask);
|
||||
|
||||
// uint64_t lower_left_mask = 144959613005987840UL & ~(top_row_mask);
|
||||
uint64_t lower_left_mask = 4557430888798814208UL & ~(top_row_mask);
|
||||
|
||||
// uint64_t lower_right_mask = 4665729213955833856UL & ~(top_row_mask | left_column_mask);
|
||||
uint64_t lower_right_mask = 18229723555195256832UL & ~(top_row_mask | left_column_mask);
|
||||
|
||||
// BUGS
|
||||
// uint64_t upper_left_mask = 69540876599103UL;
|
||||
// uint64_t upper_right_mask = 278163506396412UL & ~(left_column_mask);
|
||||
// uint64_t lower_left_mask = 4557430888798814208UL & ~(top_row_mask);
|
||||
// uint64_t lower_right_mask = 18229723555195256832UL & ~(top_row_mask | left_column_mask);
|
||||
|
||||
uint64_t upper_left_mask = _UpperLeftMask;
|
||||
uint64_t upper_right_mask = _UpperRightMask & ~(left_column_mask);
|
||||
uint64_t lower_left_mask = _LowerLeftMask & ~(top_row_mask);
|
||||
uint64_t lower_right_mask = _LowerRightMask & ~(top_row_mask | left_column_mask);
|
||||
|
||||
|
||||
uint64_t upper_left_quadrant_bits = encode_tile_to_uint(uv) & upper_left_mask;
|
||||
uint64_t upper_right_quadrant_bits = encode_tile_to_uint(uv + ivec2(7, 0)) & upper_right_mask;
|
||||
|
@ -102,8 +108,8 @@ void Automaton() {
|
|||
neighbor_count += sum_uint_bits(lower_right_quadrant_bits);
|
||||
|
||||
|
||||
// for (int x = -neighborhood_radius; x <= neighborhood_radius; ++x) {
|
||||
// for (int y = -neighborhood_radius; y <= neighborhood_radius; ++y) {
|
||||
// for (int x = -1; x <= 1; ++x) {
|
||||
// for (int y = -1; y <= 1; ++y) {
|
||||
// if (x == 0 && y == 0) continue;
|
||||
|
||||
// ivec2 texcoords = uv + ivec2(x, y);
|
||||
|
@ -113,13 +119,13 @@ void Automaton() {
|
|||
// }
|
||||
// }
|
||||
|
||||
// if (neighbor_count <= 1) cell = 0;
|
||||
// if (neighbor_count == 3) cell = 1;
|
||||
// if (neighbor_count >= 4) cell = 0;
|
||||
if (neighbor_count <= 1) cell = 0;
|
||||
if (neighbor_count == 3) cell = 1;
|
||||
if (neighbor_count >= 4) cell = 0;
|
||||
|
||||
if (neighbor_count <= 33) cell = 0;
|
||||
if (34 <= neighbor_count && neighbor_count <= 45) cell = 1;
|
||||
if (58 <= neighbor_count && neighbor_count <= 121) cell = 0;
|
||||
// if (neighbor_count <= 33) cell = 0;
|
||||
// if (34 <= neighbor_count && neighbor_count <= 45) cell = 1;
|
||||
// if (58 <= neighbor_count && neighbor_count <= 121) cell = 0;
|
||||
|
||||
imageStore(_AutomatonTo, uv, vec4(cell));
|
||||
}
|
||||
|
@ -127,9 +133,6 @@ void Automaton() {
|
|||
[numthreads(8, 8, 1)]
|
||||
void Blit() {
|
||||
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
|
||||
ivec2 size = ivec2(raster_size);
|
||||
|
||||
if (uv.x >= size.x || uv.y >= size.y) return;
|
||||
|
||||
float automata = imageLoad(_AutomatonTo, uv / 2).r;
|
||||
|
||||
|
|
|
@ -4,6 +4,14 @@ class_name Neighborhood
|
|||
@export var spawn_range : Vector2i
|
||||
@export var stable_range : Vector2i
|
||||
|
||||
enum Quadrant { UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, LOWER_RIGHT }
|
||||
|
||||
var quadrant_strings : Array = Array([[], [], [], []])
|
||||
|
||||
var neighborhood_bytes : PackedByteArray = PackedByteArray()
|
||||
|
||||
func _init() -> void:
|
||||
neighborhood_bytes.resize(32)
|
||||
|
||||
func get_spawn_range() -> Vector2i:
|
||||
return spawn_range
|
||||
|
@ -13,9 +21,22 @@ func get_stable_range() -> Vector2i:
|
|||
return stable_range
|
||||
|
||||
|
||||
func add_to_spawn_range(v : Vector2i):
|
||||
func add_to_spawn_range(v : Vector2i) -> void:
|
||||
spawn_range = spawn_range + v
|
||||
|
||||
|
||||
func add_to_stable_range(v : Vector2i):
|
||||
stable_range = stable_range + v
|
||||
func add_to_stable_range(v : Vector2i) -> void:
|
||||
stable_range = stable_range + v
|
||||
|
||||
|
||||
func set_quadrant_strings(quadrant : Quadrant, byte_strings : Array) -> void:
|
||||
quadrant_strings[quadrant] = Array(byte_strings)
|
||||
|
||||
func encode_quadrant_byte(quadrant : Quadrant, value : int, byte_offset : int) -> void:
|
||||
var index = quadrant * 8 + byte_offset
|
||||
|
||||
neighborhood_bytes.encode_u8(index, value)
|
||||
|
||||
|
||||
func get_neighborhood_bytes() -> PackedByteArray:
|
||||
return neighborhood_bytes
|
|
@ -48,7 +48,7 @@ needs_motion_vectors = false
|
|||
needs_normal_roughness = false
|
||||
script = ExtResource("1_vlji8")
|
||||
pause = false
|
||||
update_speed = 0.05
|
||||
update_speed = 0.006
|
||||
exposure = Vector4(2, 1, 1, 1)
|
||||
metadata/_custom_type_script = "uid://drfxlavovcgta"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
extends AcerolaPanel
|
||||
|
||||
func on_pressed() -> void:
|
||||
get_node("../../.").encode_grid_to_bit_string()
|
||||
get_node("../../.").encode_grid_to_neighborhood_bytes()
|
||||
|
|
|
@ -28,6 +28,10 @@ var timer = 0.0
|
|||
var current_seed : int = 0
|
||||
var needs_seeding = true
|
||||
|
||||
var push_constant : PackedByteArray = PackedByteArray()
|
||||
|
||||
var neighborhood_wizard : Node
|
||||
|
||||
func _init():
|
||||
effect_callback_type = EFFECT_CALLBACK_TYPE_POST_TRANSPARENT
|
||||
rd = RenderingServer.get_rendering_device()
|
||||
|
@ -101,7 +105,10 @@ func _render_callback(p_effect_callback_type, p_render_data):
|
|||
reseed = false
|
||||
|
||||
# Vulkan has a feature known as push constants which are like uniform sets but for very small amounts of data
|
||||
var push_constant : PackedFloat32Array = PackedFloat32Array([size.x, size.y, current_seed, 0.0])
|
||||
push_constant = neighborhood_wizard.get_quadrant()
|
||||
# push_constant = PackedByteArray()
|
||||
|
||||
# push_constant.resize(16)
|
||||
|
||||
for view in range(render_scene_buffers.get_view_count()):
|
||||
var input_image = render_scene_buffers.get_color_layer(view)
|
||||
|
@ -114,7 +121,7 @@ func _render_callback(p_effect_callback_type, p_render_data):
|
|||
exposure_compute.set_texture(2, previous_generation)
|
||||
exposure_compute.set_texture(3, next_generation)
|
||||
exposure_compute.set_uniform_buffer(1, uniform_array)
|
||||
exposure_compute.set_push_constant(push_constant.to_byte_array())
|
||||
exposure_compute.set_push_constant(push_constant)
|
||||
|
||||
# Dispatch the compute kernel
|
||||
if (needs_seeding):
|
||||
|
@ -139,3 +146,6 @@ func set_seed(new_seed : int):
|
|||
|
||||
func get_world_texture() -> RID:
|
||||
return world_texture;
|
||||
|
||||
func set_push_constant(buffer : PackedByteArray):
|
||||
push_constant = buffer
|
||||
|
|
|
@ -3,6 +3,8 @@ class_name GameMaster
|
|||
|
||||
var automata_compositor_effect : CompositorEffect
|
||||
|
||||
var neighborhood_wizard : Node
|
||||
|
||||
var current_seed : int = 0
|
||||
|
||||
func _ready() -> void:
|
||||
|
@ -15,6 +17,9 @@ func _ready() -> void:
|
|||
|
||||
automata_compositor_effect = environment.compositor.compositor_effects[0]
|
||||
|
||||
neighborhood_wizard = root_node.get_node("Node3D/UI/Neighborhoods/Neighborhood 1")
|
||||
automata_compositor_effect.neighborhood_wizard = neighborhood_wizard
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
pass
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
extends Node
|
||||
class_name NeighborhoodWizard
|
||||
|
||||
var neighborhood : Neighborhood
|
||||
|
||||
var grid : TileMapLayer
|
||||
|
||||
var upper_left_quadrant : PackedByteArray
|
||||
|
||||
func _ready() -> void:
|
||||
neighborhood = Neighborhood.new()
|
||||
grid = get_node("Grid/Actual Grid")
|
||||
encode_grid_to_neighborhood_bytes()
|
||||
|
||||
|
||||
func get_spawn_range() -> Vector2i:
|
||||
|
@ -25,29 +29,39 @@ func add_to_stable_range(v : Vector2i) -> void:
|
|||
neighborhood.add_to_stable_range(v)
|
||||
|
||||
|
||||
func encode_grid_to_bit_string() -> void:
|
||||
var bit_string = ""
|
||||
var full_bit_string = ""
|
||||
func encode_grid_to_neighborhood_bytes() -> void:
|
||||
var byte_strings = Array()
|
||||
var byte_array = PackedByteArray()
|
||||
byte_array.resize(8)
|
||||
|
||||
# Top Left Quadrant
|
||||
var row = 0;
|
||||
for y in range(-7, 1):
|
||||
bit_string = ""
|
||||
for y in range(0, 8):
|
||||
var byte_string = ""
|
||||
for x in range(-7, 1):
|
||||
var grid_coord = Vector2i(x, y)
|
||||
var grid_coord = Vector2i(x, -y)
|
||||
|
||||
var cell = grid.get_cell_atlas_coords(grid_coord).x
|
||||
|
||||
bit_string += "0" if cell == 0 else "1"
|
||||
byte_string += "0" if cell == 0 else "1"
|
||||
|
||||
|
||||
print(bit_string + " -> " + str(bit_string.bin_to_int()))
|
||||
byte_array.encode_u8(row, bit_string.bin_to_int())
|
||||
row += 1
|
||||
full_bit_string += bit_string
|
||||
byte_strings.append(byte_string)
|
||||
neighborhood.encode_quadrant_byte(neighborhood.Quadrant.UPPER_LEFT, byte_string.bin_to_int(), y)
|
||||
byte_array.encode_u8(y, byte_string.bin_to_int())
|
||||
|
||||
|
||||
var full_byte_string = ""
|
||||
for i in range(0, 8):
|
||||
print(byte_strings[7 - i] + " -> " + str(byte_strings[7 - i].bin_to_int()))
|
||||
|
||||
full_byte_string += byte_strings[7 - i]
|
||||
|
||||
print(PackedInt64Array(byte_strings))
|
||||
print(byte_array)
|
||||
print(full_bit_string)
|
||||
print(neighborhood.get_neighborhood_bytes())
|
||||
|
||||
upper_left_quadrant = PackedByteArray(byte_array)
|
||||
|
||||
|
||||
func get_quadrant() -> PackedByteArray:
|
||||
return neighborhood.get_neighborhood_bytes()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue