20201015

Pixel-art-style Conway's game-of-life using a tile shader in WebGL

Implementation of Conway's game of life cellular automata with a retro-style shader. Added as example on webgpgpu Github.




Sketch of WebGL implementation:

  • Underlying cellular automata runs Conway's game of life
  • States as game tiles: new cells: small blue; live cells: blue; died: skulls
  • Life diffuses out coloring nearby areas
  • A single RGBA texture stores the game state. We render to/from this texture as a framebuffer.
  • Each color channel in [0,1] can be mapped to a [0,255] byte value
  • The green channel stores the game of life state
  • The blue channel stores the diffusing field
  • The red channel outputs a tile ID value that is passed to a tile shader to render the game


 The core of the code is implemented in this shader:


void main() {
    vec2 dx = vec2(1.0/game_size.x,0.0);
    vec2 dy = vec2(0.0,1.0/game_size.y);
    vec2  p = gl_FragCoord.xy/game_size;
    // Get neighborhood
    vec4 s00 = texture2D(game_state,p-dy-dx);
    vec4 s01 = texture2D(game_state,p-dy);
    vec4 s02 = texture2D(game_state,p-dy+dx);
    vec4 s10 = texture2D(game_state,p-dx);
    vec4 s11 = texture2D(game_state,p);
    vec4 s12 = texture2D(game_state,p+dx);
    vec4 s20 = texture2D(game_state,p+dy-dx);
    vec4 s21 = texture2D(game_state,p+dy);
    vec4 s22 = texture2D(game_state,p+dy+dx);
    // Current cell and neighborhood cell density count
    float cell = s11.g;
    float near = s00.g+s01.g+s02.g+s10.g+s12.g+s20.g+s21.g+s22.g;
    float next = (cell>0.5&&near>1.5&&near<3.5||near>2.5&&near<3.5)?1.0:0.0;
    // Diffusing state: average neighborhood with decay; add density if live
    float diffuse = (s01.b+s10.b+s11.b+s12.b+s21.b)*0.2;
    diffuse = max(diffuse*0.95,next);
    // Tile ID: 
    int id = 
        (cell>0.5&&next>0.5)? MATURE :
        (cell>0.5&&next<0.5)? DIED :
        (cell<0.5&&next>0.5)? NEWBORN :
        SHADES + int((1.0-diffuse)*16.0)+1;
    gl_FragColor = vec4(float(id)/256.0,next,diffuse,0.0);
}

No comments:

Post a Comment