void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    ivec3 xyz = to3d(ivec2(fragCoord));

    if (xyz.x >= int(Size) || xyz.y >= int(Size) || xyz.z >= int(Size))
    {
        fragColor = vec4(0);
        return;
    }

    if (iFrame == 0)
    {
        fragColor = vec4( step(0.99, sin(fragCoord.x * 4.0 * fragCoord.y)) );
        return;
    }

    if (iFrame % 32 != 0)
    {
        fragColor = texture(iChannel0, fragCoord/iResolution.xy);
        return;
    }

    int c = 0;
    for (int x = -1; x < 2; x++)
    for (int y = -1; y < 2; y++)
    for (int z = -1; z < 2; z++)
    {
        if (x == 0 && y == 0 && z == 0)
            continue;

        c += int(texelFetch(iChannel0, to2d(to3d(ivec2(fragCoord)) + ivec3(x,y,z)), 0).r);
    }

    int m = int(texelFetch(iChannel0, to2d(to3d(ivec2(fragCoord))), 0).r);

    vec3 live = vec3(0);
    if (m == 1 && (c == 5 || c == 6) || c == 4)
        live = vec3(1);

    fragColor = vec4(live, 1);
}
