xxxxxxxxxx
70
precision mediump float;
// Pixel position
varying vec2 pos;
// Uniforms set by filterShader
uniform sampler2D filter_background; // contains the image being filtered
uniform vec2 filter_res; // contains the image resolution in pixels
float is_empty(vec3 col) {
// If cell is black, the sum of R, G, B is 0
// Therefore 1-sum = 1, and step returns 1
// If any channel has some colour, 1-sum < 1 and step returns 0
return step(1., 1. - (col.r + col.g + col.b));
}
vec3 get_cell(vec2 pos) {
return texture2D(filter_background, pos).rgb;
}
void main() {
// Figure out how far a pixel is
// Zero stored in z for swizzle convenience
vec3 normalRes = vec3(1./filter_res, 0.);
// Get colour of current pixel
vec3 curr = get_cell(pos);
vec3 left = get_cell(pos - normalRes.xz);
vec3 right = get_cell(pos + normalRes.xz);
vec3 up = get_cell(pos - normalRes.zy);
vec3 up_left = get_cell(pos - normalRes.xz + normalRes.zy);
vec3 up_right = get_cell(pos + normalRes.xy);
vec3 down = get_cell(pos + normalRes.zy);
vec3 down_left = get_cell(pos - normalRes.xy);
vec3 down_right = get_cell(pos + normalRes.xz - normalRes.zy);
float bottom_of_screen = step(0., pos.y);
float curr_empty = is_empty(curr);
float left_empty = is_empty(left);
float right_empty = is_empty(right);
float up_empty = is_empty(up);
float up_left_empty = is_empty(up_left);
float up_right_empty = is_empty(up_right);
float down_empty = is_empty(down);
float down_left_empty = is_empty(down_left);
float down_right_empty = is_empty(down_right);
float all_solid_below = 1. - step(1., down_empty + down_left_empty + down_right_empty);
vec3 col = (curr * all_solid_below) + // current colour if the cells below are solid
(1. - all_solid_below) * (
up * (1.-up_empty)
);
// Output the cell (white = alive, black = dead)
gl_FragColor = vec4(col, 1.);
}