fragmentShader = `
uniform sampler2D u_texture;
uniform vec2 u_size;
uniform float u_time;
int state_from_color(vec3 col) {
${col_arr_str}
for (int i = 0; i < ${number_of_states}; i++) {
float d = distance(colors[i] / 255.0, col);
if (d < 0.0001) return i;
}
return -1;
}
vec3 color_from_state(const int state) {
${col_arr_str}
// this is an ugly hack. Can't index with state as it is not constant
for (int i = 0; i < ${number_of_states}; i++) {
if (i == state) return colors[i] / 255.0;
}
}
void main() {
vec2 position = gl_FragCoord.xy;
vec4 c = texture2D(u_texture, position / u_size);
int c_state = state_from_color(c.xyz);
int opp_state = c_state + 1;
if (opp_state >= ${number_of_states}) opp_state -= ${number_of_states};
int counter = 0;
for (int dx = -int(${size_of_neighborhood / 2}); dx <= int(${
size_of_neighborhood / 2
}); ++dx) {
for (int dy = -int(${size_of_neighborhood / 2}); dy <= int(${
size_of_neighborhood / 2
}); ++dy) {
if (dx == 0 && dy == 0) continue;
vec4 n = texture2D(u_texture, (position + vec2(dx,dy)) / u_size);
int n_state = state_from_color(n.xyz);
if (n_state == opp_state) {
counter++;
}
}
}
vec4 next_col = c;
if (counter >= ${n}) {
vec3 val = color_from_state(opp_state).xyz;
next_col = vec4(val, 1.0);
}
gl_FragColor = next_col;
}
`