mirror of
https://github.com/GarrettGunnell/God-Machine.git
synced 2025-10-19 14:43:16 +00:00
140 lines
No EOL
3.9 KiB
Text
140 lines
No EOL
3.9 KiB
Text
#kernel Seed
|
|
#kernel Automaton
|
|
#kernel Blit
|
|
|
|
#extension GL_ARB_gpu_shader_int64 : require
|
|
|
|
|
|
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;
|
|
|
|
layout(binding = 1) uniform UniformBufferObject {
|
|
vec4 _Exposure;
|
|
};
|
|
|
|
layout(push_constant, std430) uniform Params {
|
|
uint64_t _UpperLeftMask;
|
|
uint64_t _UpperRightMask;
|
|
uint64_t _LowerLeftMask;
|
|
uint64_t _LowerRightMask;
|
|
};
|
|
|
|
float pseudo(vec2 v) {
|
|
v = fract(v/128.)*128. + vec2(-64.340622, -72.465622);
|
|
return fract(dot(v.xyx * v.xyy, vec3(20.390625, 60.703125, 2.4281209)));
|
|
}
|
|
|
|
[numthreads(8, 8, 1)]
|
|
void Seed() {
|
|
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
|
|
|
|
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));
|
|
|
|
if (seed < 0.75) seed = 0.0;
|
|
else seed = 1.0;
|
|
|
|
imageStore(_AutomatonFrom, uv, vec4(seed));
|
|
}
|
|
|
|
|
|
uint64_t encode_tile_to_uint(ivec2 uv) {
|
|
uint64_t tile_bits = 0;
|
|
|
|
for (int y = 0; y < 8; ++y) {
|
|
for (int x = 0; x < 8; ++x) {
|
|
uint bit_index = x + y * 8; // Convert to 1D index in 64 bit uint
|
|
|
|
ivec2 world_coords = uv + ivec2(-x, -y);
|
|
uint64_t cell_value = int(imageLoad(_AutomatonFrom, world_coords % 512).r);
|
|
|
|
tile_bits |= (cell_value << bit_index);
|
|
}
|
|
}
|
|
|
|
return tile_bits;
|
|
}
|
|
|
|
uint sum_uint_bits(uint64_t i) {
|
|
uint sum = 0;
|
|
|
|
while (i != 0) {
|
|
sum += uint(i & 1);
|
|
i >>= 1;
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
|
|
[numthreads(8, 8, 1)]
|
|
void Automaton() {
|
|
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
|
|
|
|
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_right_mask = 49216 & ~(left_column_mask);
|
|
// uint64_t lower_left_mask = 144959613005987840UL & ~(top_row_mask);
|
|
// uint64_t lower_right_mask = 4665729213955833856UL & ~(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;
|
|
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;
|
|
|
|
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);
|
|
|
|
|
|
// 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);
|
|
// texcoords = texcoords % 512;
|
|
|
|
// neighbor_count += int(imageLoad(_AutomatonFrom, texcoords).r);
|
|
// }
|
|
// }
|
|
|
|
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;
|
|
|
|
imageStore(_AutomatonTo, uv, vec4(cell));
|
|
}
|
|
|
|
[numthreads(8, 8, 1)]
|
|
void Blit() {
|
|
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
|
|
|
|
float automata = imageLoad(_AutomatonTo, uv / 2).r;
|
|
|
|
imageStore(_RenderTarget, uv, vec4(automata, 0, 0, 1.0));
|
|
} |