Added as example on webgpgpu Github.
This is a cellular automata analogue of the model that we used for developmental retinal waves in this paper.
Key rules
- Vegetation "grows" occasionally (flip a coin to increment amount of trees)
- Fires have a small chance of starting spontaneously
- Intensity of ignited fires decay down to zero, at which point they leave ash
- Fires spread to adjacent cells with a probability that depends on their intensity
- Probability of a cell igniting given a fire is related to how much vegetation there is
Sketch of WebGL implementation:
- A single RGBA texture stores the game state
- Each color channel in [0,1] can be mapped to a [0,255] byte value
- A "noise" texture creates pseudorandom numbers
- The green channel stores the level of vegetation (BURNT,NONE,GRASS,SCRUB,TREE)
- The blue channel stores the intensity of the fire
- 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 s01 = texture2D(game_state,p-dy); vec4 s10 = texture2D(game_state,p-dx); vec4 s11 = texture2D(game_state,p); vec4 s12 = texture2D(game_state,p+dx); vec4 s21 = texture2D(game_state,p+dy); // Get noise vec4 n = texture2D(noise,p); // Trees emerge with some probablity float tree = s11.g + float(n.r<4.0/256.0)*0.1; // Fire burns out float fire = s11.b-1.0/18.0; // Fire spreads if there are trees to burn float PrFire = s01.b+s10.b+s12.b+s21.b; PrFire = PrFire*0.5+0.0005; float u = n.g+n.b/256.0; if (u<(PrFire*(tree-0.1))) {fire=9.0/10.0;} if (fire>0.0) tree=0.0; // Tile IDs for each state int id = (fire>0.0)? ONFIRE+int(fire*9.0): (tree>0.7)? TREE : (tree>0.4)? SCRUB : (tree>0.3)? GRASS : (tree>0.0)? NONE : BURNT; gl_FragColor = vec4(float(id)/255.0,tree,fire,0.0); }
No comments:
Post a Comment