home/ atoms/ grid-wrap-around-modulo

Wrapping edge-cell neighbor lookups with the modulo operator creates a toroidal grid topology that prevents out-of-bounds buffer access

In a cellular automaton, cells at the grid boundary have fewer than 8 neighbors unless you define wrap-around. The standard approach treats the grid as a torus: the left edge’s neighbors include the right edge’s cells. In WGSL, apply the modulo operator to both coordinates in the cell-index function: (cell.y % gridHeight) * gridWidth + (cell.x % gridWidth). This also prevents out-of-bounds reads (undefined behavior). For u32 arithmetic, subtracting 1 from 0 wraps to a very large number — modulo-based indexing is essential rather than clamping.

Examples

fn cellIndex(cell: vec2u) -> u32 {
  return (cell.y % u32(grid.y)) * u32(grid.x) + (cell.x % u32(grid.x));
}
// When cell.x == 0 and we compute cell.x-1: u32 underflows to ~4B; % grid.x wraps to rightmost column

Assessment

Why does subtracting 1 from a u32 value of 0 produce a very large number rather than -1? How does the modulo in cellIndex handle this correctly for left-edge cells?

“By using the `%` operator to wrap the cell X and Y when it extends past the grid size”
corpus · your-first-webgpu-app-google-codelab · chunk 23