I've been playing with shadertoy a bit, and here is a lil demo. It's probably not the best way to do it, code suggestions welcome.
https://www.shadertoy.com/view/dtlBRM
Here's most of the code for reference:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// fetch neighbor values from last frame, loop back onto screen if off screen
mat3 n;
n[0][0] = texelFetch(iChannel0, ivec2(mod(vec2(fragCoord) + vec2(-1., -1.), iResolution.xy)), 0).g;
n[1][0] = texelFetch(iChannel0, ivec2(mod(vec2(fragCoord) + vec2(0., -1.), iResolution.xy)), 0).g;
n[2][0] = texelFetch(iChannel0, ivec2(mod(vec2(fragCoord) + vec2(1., -1.), iResolution.xy)), 0).g;
n[0][1] = texelFetch(iChannel0, ivec2(mod(vec2(fragCoord) + vec2(-1., 0.), iResolution.xy)), 0).g;
n[1][1] = texelFetch(iChannel0, ivec2(mod(vec2(fragCoord) + vec2(0., 0.), iResolution.xy)), 0).g;
n[2][1] = texelFetch(iChannel0, ivec2(mod(vec2(fragCoord) + vec2(1., 0.), iResolution.xy)), 0).g;
n[0][2] = texelFetch(iChannel0, ivec2(mod(vec2(fragCoord) + vec2(-1., 1.), iResolution.xy)), 0).g;
n[1][2] = texelFetch(iChannel0, ivec2(mod(vec2(fragCoord) + vec2(0., 1.), iResolution.xy)), 0).g;
n[2][2] = texelFetch(iChannel0, ivec2(mod(vec2(fragCoord) + vec2(1., 1.), iResolution.xy)), 0).g;
// sum of neighbors
float sum = n[0][0] + n[1][0] + n[2][0] +
n[0][1] + n[2][1] +
n[0][2] + n[1][2] + n[2][2];
if(n[1][1] == 0.) {
if(sum == 3.) {
// if dead and has 3 neighbors, come alive
fragColor = vec4(0., 1., 0., 1.);
} else {
// otherwise stay dead
fragColor = vec4(0., 0., 0., 1.);
}
} else {
if(sum == 2. || sum == 3.) {
// if alive and has 2 or 3 neighbors, stay alive
fragColor = vec4(0., 1., 0., 1.);
} else {
// otherwise, die
fragColor = vec4(0., 0., 0., 1.);
}
}
}