Search across packages, versions, files, declarations, and comments. Use multiple terms to narrow results (AND), and add @vertex, @fragment, or @compute to filter by shader stage.
1// The shader reads the previous frame's state from the `input` texture, and writes the new state of
2// each pixel to the `output` texture. The textures are flipped each step to progress the
3// simulation.
4// Two textures are needed for the game of life as each pixel of step N depends on the state of its
5// neighbors at step N-1.
7@group(0) @binding(0) var input: texture_storage_2d<rgba32float, read>;
9@group(0) @binding(1) var output: texture_storage_2d<rgba32float, write>;
11@group(0) @binding(2) var<uniform> config: GameOfLifeUniforms;
13struct GameOfLifeUniforms {
14 alive_color: vec4<f32>,
17fn hash(value: u32) -> u32 {
18 var state = value;
19 state = state ^ 2747636419u;
20 state = state * 2654435769u;
21 state = state ^ (state >> 16u);
22 state = state * 2654435769u;
23 state = state ^ (state >> 16u);
24 state = state * 2654435769u;
25 return state;
28fn randomFloat(value: u32) -> f32 {
29 return f32(hash(value)) / 4294967295.0;
32@compute @workgroup_size(8, 8, 1)
33fn init(@builtin(global_invocation_id) invocation_id: vec3<u32>) {
34 let location = vec2<i32>(i32(invocation_id.x), i32(invocation_id.y));
36 let randomNumber = randomFloat((invocation_id.y << 16u) | invocation_id.x);
37 let alive = randomNumber > 0.9;
38 // Use alpha channel to keep track of cell's state
39 let color = vec4(config.alive_color.rgb, f32(alive));
41 textureStore(output, location, color);
44fn is_alive(location: vec2<i32>, offset_x: i32, offset_y: i32) -> i32 {
45 let value: vec4<f32> = textureLoad(input, location + vec2<i32>(offset_x, offset_y));
46 return i32(value.a);
49fn count_alive(location: vec2<i32>) -> i32 {
50 return is_alive(location, -1, -1) +
51 is_alive(location, -1, 0) +
52 is_alive(location, -1, 1) +
53 is_alive(location, 0, -1) +
54 is_alive(location, 0, 1) +
55 is_alive(location, 1, -1) +
56 is_alive(location, 1, 0) +
57 is_alive(location, 1, 1);
60@compute @workgroup_size(8, 8, 1)
61fn update(@builtin(global_invocation_id) invocation_id: vec3<u32>) {
62 let location = vec2<i32>(i32(invocation_id.x), i32(invocation_id.y));
64 let n_alive = count_alive(location);
66 var alive: bool;
67 if (n_alive == 3) {
68 alive = true;
69 } else if (n_alive == 2) {
70 let currently_alive = is_alive(location, 0, 0);
71 alive = bool(currently_alive);
72 } else {
73 alive = false;
74 }
75 let color = vec4(config.alive_color.rgb, f32(alive));
77 textureStore(output, location, color);
Contents