mirror of
https://github.com/GarrettGunnell/God-Machine.git
synced 2025-10-19 14:43:16 +00:00
Multi neighborhood cellular automata
This commit is contained in:
parent
7221805bab
commit
b08bd4e627
4 changed files with 99 additions and 34 deletions
|
@ -9,16 +9,25 @@ layout(rgba8, set = 0, binding = 0) uniform image2D _RenderTarget;
|
|||
layout(r16f, set = 0, binding = 2) uniform image2D _AutomatonFrom;
|
||||
layout(r16f, set = 0, binding = 3) uniform image2D _AutomatonTo;
|
||||
|
||||
struct Neighborhood {
|
||||
uint64_t upper_left_mask;
|
||||
uint64_t upper_right_mask;
|
||||
uint64_t lower_left_mask;
|
||||
uint64_t lower_right_mask;
|
||||
};
|
||||
|
||||
layout(binding = 1) uniform UniformBufferObject {
|
||||
vec4 _Exposure;
|
||||
ivec4 _RuleRanges;
|
||||
ivec4 _RuleRanges2;
|
||||
ivec4 _RuleRanges3;
|
||||
ivec4 _RuleRanges4;
|
||||
};
|
||||
|
||||
layout(push_constant, std430) uniform Params {
|
||||
uint64_t _UpperLeftMask;
|
||||
uint64_t _UpperRightMask;
|
||||
uint64_t _LowerLeftMask;
|
||||
uint64_t _LowerRightMask;
|
||||
ivec4 _RuleRanges;
|
||||
Neighborhood _Neighborhood1;
|
||||
Neighborhood _Neighborhood2;
|
||||
Neighborhood _Neighborhood3;
|
||||
Neighborhood _Neighborhood4;
|
||||
};
|
||||
|
||||
float pseudo(vec2 v) {
|
||||
|
@ -91,22 +100,55 @@ void Automaton() {
|
|||
// 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_mask = _Neighborhood1.upper_left_mask;
|
||||
uint64_t upper_right_mask = _Neighborhood1.upper_right_mask & ~(left_column_mask);
|
||||
uint64_t lower_left_mask = _Neighborhood1.lower_left_mask & ~(top_row_mask);
|
||||
uint64_t lower_right_mask = _Neighborhood1.lower_right_mask & ~(top_row_mask | left_column_mask);
|
||||
|
||||
uint64_t upper_left_mask2 = _Neighborhood2.upper_left_mask;
|
||||
uint64_t upper_right_mask2 = _Neighborhood2.upper_right_mask & ~(left_column_mask);
|
||||
uint64_t lower_left_mask2 = _Neighborhood2.lower_left_mask & ~(top_row_mask);
|
||||
uint64_t lower_right_mask2 = _Neighborhood2.lower_right_mask & ~(top_row_mask | left_column_mask);
|
||||
|
||||
uint64_t upper_left_mask3 = _Neighborhood3.upper_left_mask;
|
||||
uint64_t upper_right_mask3 = _Neighborhood3.upper_right_mask & ~(left_column_mask);
|
||||
uint64_t lower_left_mask3 = _Neighborhood3.lower_left_mask & ~(top_row_mask);
|
||||
uint64_t lower_right_mask3 = _Neighborhood3.lower_right_mask & ~(top_row_mask | left_column_mask);
|
||||
|
||||
uint64_t upper_left_mask4 = _Neighborhood4.upper_left_mask;
|
||||
uint64_t upper_right_mask4 = _Neighborhood4.upper_right_mask & ~(left_column_mask);
|
||||
uint64_t lower_left_mask4 = _Neighborhood4.lower_left_mask & ~(top_row_mask);
|
||||
uint64_t lower_right_mask4 = _Neighborhood4.lower_right_mask & ~(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;
|
||||
uint64_t lower_left_quadrant_bits = encode_tile_to_uint(uv + ivec2(0, 7)) & lower_left_mask;
|
||||
uint64_t lower_right_quadrant_bits = encode_tile_to_uint(uv + ivec2(7, 7)) & lower_right_mask;
|
||||
uint64_t upper_left_quadrant_bits = encode_tile_to_uint(uv);
|
||||
uint64_t upper_right_quadrant_bits = encode_tile_to_uint(uv + ivec2(7, 0));
|
||||
uint64_t lower_left_quadrant_bits = encode_tile_to_uint(uv + ivec2(0, 7));
|
||||
uint64_t lower_right_quadrant_bits = encode_tile_to_uint(uv + ivec2(7, 7));
|
||||
|
||||
uint neighbor_count = 0;
|
||||
neighbor_count += sum_uint_bits(upper_left_quadrant_bits);
|
||||
neighbor_count += sum_uint_bits(upper_right_quadrant_bits);
|
||||
neighbor_count += sum_uint_bits(lower_left_quadrant_bits);
|
||||
neighbor_count += sum_uint_bits(lower_right_quadrant_bits);
|
||||
uint neighbor_count1 = 0;
|
||||
neighbor_count1 += sum_uint_bits(upper_left_quadrant_bits & upper_left_mask);
|
||||
neighbor_count1 += sum_uint_bits(upper_right_quadrant_bits & upper_right_mask);
|
||||
neighbor_count1 += sum_uint_bits(lower_left_quadrant_bits & lower_left_mask);
|
||||
neighbor_count1 += sum_uint_bits(lower_right_quadrant_bits & lower_right_mask);
|
||||
|
||||
uint neighbor_count2 = 0;
|
||||
neighbor_count2 += sum_uint_bits(upper_left_quadrant_bits & upper_left_mask2);
|
||||
neighbor_count2 += sum_uint_bits(upper_right_quadrant_bits & upper_right_mask2);
|
||||
neighbor_count2 += sum_uint_bits(lower_left_quadrant_bits & lower_left_mask2);
|
||||
neighbor_count2 += sum_uint_bits(lower_right_quadrant_bits & lower_right_mask2);
|
||||
|
||||
uint neighbor_count3 = 0;
|
||||
neighbor_count3 += sum_uint_bits(upper_left_quadrant_bits & upper_left_mask3);
|
||||
neighbor_count3 += sum_uint_bits(upper_right_quadrant_bits & upper_right_mask3);
|
||||
neighbor_count3 += sum_uint_bits(lower_left_quadrant_bits & lower_left_mask3);
|
||||
neighbor_count3 += sum_uint_bits(lower_right_quadrant_bits & lower_right_mask3);
|
||||
|
||||
uint neighbor_count4 = 0;
|
||||
neighbor_count4 += sum_uint_bits(upper_left_quadrant_bits & upper_left_mask4);
|
||||
neighbor_count4 += sum_uint_bits(upper_right_quadrant_bits & upper_right_mask4);
|
||||
neighbor_count4 += sum_uint_bits(lower_left_quadrant_bits & lower_left_mask4);
|
||||
neighbor_count4 += sum_uint_bits(lower_right_quadrant_bits & lower_right_mask4);
|
||||
|
||||
|
||||
// for (int x = -1; x <= 1; ++x) {
|
||||
|
@ -124,9 +166,34 @@ void Automaton() {
|
|||
// if (neighbor_count == 3) cell = 1;
|
||||
// if (neighbor_count >= 4) cell = 0;
|
||||
|
||||
if (_RuleRanges.x <= neighbor_count && neighbor_count <= _RuleRanges.y) { // Spawn
|
||||
|
||||
if (_RuleRanges.x <= neighbor_count1 && neighbor_count1 <= _RuleRanges.y) { // Spawn
|
||||
cell = 1;
|
||||
} else if (_RuleRanges.z <= neighbor_count && neighbor_count <= _RuleRanges.w) { // Stable
|
||||
} else if (_RuleRanges.z <= neighbor_count1 && neighbor_count1 <= _RuleRanges.w) { // Stable
|
||||
cell = cell;
|
||||
} else {
|
||||
cell = 0; // RIP
|
||||
}
|
||||
|
||||
if (_RuleRanges2.x <= neighbor_count2 && neighbor_count2 <= _RuleRanges2.y) { // Spawn
|
||||
cell = 1;
|
||||
} else if (_RuleRanges2.z <= neighbor_count2 && neighbor_count2 <= _RuleRanges2.w) { // Stable
|
||||
cell = cell;
|
||||
} else {
|
||||
cell = 0; // RIP
|
||||
}
|
||||
|
||||
if (_RuleRanges3.x <= neighbor_count3 && neighbor_count3 <= _RuleRanges3.y) { // Spawn
|
||||
cell = 1;
|
||||
} else if (_RuleRanges3.z <= neighbor_count3 && neighbor_count3 <= _RuleRanges3.w) { // Stable
|
||||
cell = cell;
|
||||
} else {
|
||||
cell = 0; // RIP
|
||||
}
|
||||
|
||||
if (_RuleRanges4.x <= neighbor_count4 && neighbor_count4 <= _RuleRanges4.y) { // Spawn
|
||||
cell = 1;
|
||||
} else if (_RuleRanges4.z <= neighbor_count4 && neighbor_count4 <= _RuleRanges4.w) { // Stable
|
||||
cell = cell;
|
||||
} else {
|
||||
cell = 0; // RIP
|
||||
|
@ -139,7 +206,7 @@ void Automaton() {
|
|||
void Blit() {
|
||||
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
float automata = imageLoad(_AutomatonTo, uv).r;
|
||||
float automata = imageLoad(_AutomatonTo, uv / 2).r;
|
||||
|
||||
imageStore(_RenderTarget, uv, vec4(automata, 0, 0, 1.0));
|
||||
}
|
|
@ -47,7 +47,7 @@ needs_motion_vectors = false
|
|||
needs_normal_roughness = false
|
||||
script = ExtResource("1_vlji8")
|
||||
pause = false
|
||||
update_speed = 0.025
|
||||
update_speed = 0.001
|
||||
exposure = Vector4(2, 1, 1, 1)
|
||||
metadata/_custom_type_script = "uid://drfxlavovcgta"
|
||||
|
||||
|
@ -100,8 +100,8 @@ blend_mode = 2
|
|||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_052nx"]
|
||||
shader = ExtResource("36_l2vhu")
|
||||
shader_parameter/first_color = Color(0.147984, 0.050227, 0.0839159, 1)
|
||||
shader_parameter/second_color = Color(0.743183, 0.702316, 0.71273, 1)
|
||||
shader_parameter/first_color = Color(0.120647, 0.229811, 0.120427, 1)
|
||||
shader_parameter/second_color = Color(0.449922, 0.532924, 0.299953, 1)
|
||||
|
||||
[node name="Node3D" type="Node3D"]
|
||||
|
||||
|
|
|
@ -106,17 +106,15 @@ func _render_callback(p_effect_callback_type, p_render_data):
|
|||
var automaton = GameMaster.get_active_automaton()
|
||||
if not automaton: return
|
||||
|
||||
var rule_ranges = automaton.get_rule_ranges()
|
||||
var neighborhood_bytes = automaton.get_neighorhood_bytes().slice(0, 32)
|
||||
|
||||
push_constant.append_array(neighborhood_bytes)
|
||||
push_constant.append_array(PackedInt32Array([rule_ranges[0], rule_ranges[1], rule_ranges[2], rule_ranges[3]]).to_byte_array())
|
||||
# print("neighborhood_bytes: ")
|
||||
# print(neighborhood_bytes)
|
||||
push_constant.append_array(automaton.get_neighorhood_bytes())
|
||||
|
||||
# print(push_constant)
|
||||
|
||||
for view in range(render_scene_buffers.get_view_count()):
|
||||
# Pack the exposure vector into a byte array
|
||||
var uniform_array = PackedFloat32Array([exposure.x, exposure.y, exposure.z, exposure.w]).to_byte_array()
|
||||
var uniform_array = PackedInt32Array(automaton.get_rule_ranges()).to_byte_array()
|
||||
|
||||
# ACompute handles uniform caching under the hood, as long as the exposure value doesn't change or the render target doesn't change, these functions will only do work once
|
||||
exposure_compute.set_texture(0, world_texture)
|
||||
|
|
|
@ -103,10 +103,10 @@ func encode_grid_to_neighborhood_bytes() -> void:
|
|||
byte_array.encode_u8(y + 7, byte_string.bin_to_int())
|
||||
|
||||
|
||||
for i in range(0, 8): print(byte_strings[7 - i])
|
||||
# for i in range(0, 8): print(byte_strings[7 - i])
|
||||
|
||||
print(byte_array)
|
||||
print(neighborhood.get_neighborhood_bytes())
|
||||
# print(byte_array)
|
||||
# print(neighborhood.get_neighborhood_bytes())
|
||||
|
||||
upper_left_quadrant = PackedByteArray(byte_array)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue