# Checkerboard Logic

*Task 2 of 4 · [Pixels from Scratch](https://gpu.rocks/learn/pixels-from-scratch-d2869039.md) · GPU.js Learn*

Smooth ramps become hard-edged patterns with two tools:
`Math.floor` to chop coordinates into cells, and the remainder operator
`%` to make the cells repeat. `Math.floor(this.thread.x / 16)` asks
*"which 16-pixel band am I in?"* — and `% 2` answers
*"odd or even?"*.

The starter already draws vertical stripes with exactly that trick. A checkerboard is
the same idea in both axes at once: compute a cell index for x *and* y, add them,
and take the parity of the sum — cells that touch on an edge always disagree.

## Goal

**Goal:** upgrade the stripes to an 8×8 checkerboard of 16-pixel cells —
paint `(cellX + cellY) % 2` into all three color channels.

## Requirements

- Keep the cells 16 pixels: `Math.floor(coordinate / 16)`
- Combine both axes: parity of `cellX + cellY`
- Pure black and white only — the parity (0 or 1) is the color

## Hint 1 — the second axis

Mirror the existing line for y:

```js
const cellY = Math.floor(this.thread.y / 16);
```

## Hint 2 — why the sum?

Moving one cell right changes `cellX` by 1; moving one cell up
changes `cellY` by 1. Either move flips the parity of
`cellX + cellY` — which is exactly what a checkerboard does. So:
`const v = (cellX + cellY) % 2;`

## Same idea elsewhere

Procedural patterns are a GPU staple: GLSL and WGSL shaders build checkers,
stripes and grids from `floor()` and `mod()` with no texture in
sight, and CUDA kernels lean on the same modular arithmetic on thread ids to stripe work
across blocks.

## Starter code

```js
// Modular arithmetic turns smooth coordinates into repeating patterns.
const gpu = new GPU({ mode });

const board = gpu.createKernel(function () {
  // Stripes: which 16-pixel column band is this thread in — odd or even?
  const cellX = Math.floor(this.thread.x / 16);
  const v = cellX % 2;
  // TODO: bring this.thread.y into it. A checkerboard flips parity every
  // 16 pixels vertically too — (cellX + cellY) is the trick.
  this.color(v, v, v, 1);
}, {
  output: [128, 128],
  graphical: true,
});

await board();
render(board.canvas);
```

---

Interactive version: https://gpu.rocks/learn/pixels-from-scratch-d2869039/2

[Previous task](https://gpu.rocks/learn/pixels-from-scratch-d2869039/1.md) · [Next task](https://gpu.rocks/learn/pixels-from-scratch-d2869039/3.md)
