Pattern Repetition

15 / 15
Learn how to create repetitive geometric patterns, including grid systems, random variations, and animation effects

This tutorial divides the canvas into an 8×8 grid, then draws a randomly rotated circle, square, or cross in each cell — cycling through the three types based on cell position:

Let's walk through the core mechanics.


Grid coordinates: floor and fract working together

floor(grid) gives integer cell IDs — which row, which column.

fract(grid) gives the local coordinate within a cell — a 0–1 range measured from the cell's bottom-left corner.

This is the standard template for tiled patterns: use floor to identify "which cell am I in?" and fract to draw inside each cell.


hash assigns a random value per cell

This is a common hash function — it maps the integer cell ID (x, y) to a pseudo-random value between 0 and 1. The same cell always returns the same value, but neighboring cells return very different ones.

This random value offsets each cell's rotation start angle, so they don't all spin in sync.


mod cycles through pattern types

Adding column and row IDs then taking mod 3 gives 0, 1, or 2 — used to cycle through circle, square, and cross patterns.


Try changing it

ChangeEffect
Set gridSize from 8.0 to 4.0Larger cells, shapes are clearer
Change 0.5 in rotation = u_time * 0.5 + ... to 2.0Rotation speeds up
Change mod(..., 3.0) to mod(..., 2.0)Only circles and squares, no crosses
Set all three colors to the same valueDifferent shapes, uniform color

Exercise

In the exercise, use fract(uv * repeatCount) as the tiling coordinate, draw a cross pattern inside each cell, and finish with a dynamic blend between the cross and a circle shape.

Answer Breakdown

fract(uv * 5.0) tiles the canvas into a 5×5 grid. Subtracting vec2(0.5) re-centers each cell's coordinate at 0.

For the cross: step(-w, v) * step(v, w) returns 1 only within the -w to +w band. Taking max of the horizontal and vertical bands produces the cross shape.

For the circle: smoothstep(0.25, 0.2, dist) returns 1 when the distance is under 0.2 and 0 when over 0.25, giving a smooth circular edge.

mix(cross, circle, switchTime) switches between the two using a time-driven factor. switchTime oscillates with sin(u_time * 0.5).

Try setting repeatCount to 8.0 for a denser grid.

GLSL Code Editor

Correct Code Preview

Current Code Preview