Patterns
A pattern is a pure WGSL function that maps a UV point to a mask in
[0, 1] (or richer per-cell info, like the hex grid below). Tile a UV
surface with one of these and you have stripes, dots, hex grids, weaves
and bricks — no textures, no vertex buffers, no allocations. The mask is
already anti-aliased, so it composes cleanly with SDFs, noise, and
post-processing.
Every entry below is a single pure WGSL function in the registry. Pull one into a composition by slug, then call it from your fragment stage:
let main = r#"@fragment fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { let m = dots(in.uv, 12.0, 0.25, 0.02); let bg = vec3<f32>(0.10, 0.12, 0.18); let fg = vec3<f32>(0.95, 0.65, 0.40); return vec4<f32>(mix(bg, fg, m), 1.0);}"#;let shader = Shader::new(&["pattern/dots", main])?;Each preview below renders the pattern directly across the frame and mixes a muted background against a single accent. Tune the parameters to your own scene; the registry shape is just the function.
Staggered running-bond brick grid. cells controls bricks per UV unit
on each axis, mortar is the mortar half-width as a fraction of a cell,
and fw is the smoothing width. Returns 1 inside a brick body, 0 on
mortar lines.
fn brick(uv: vec2<f32>, cells: vec2<f32>, mortar: f32, fw: f32) -> f32
chevron
Section titled “chevron”V-shaped stripes. period is the vertical spacing between V-tips and
slant controls how far each V leans horizontally. fw smooths the
stripe edges.
fn chevron(uv: vec2<f32>, period: f32, slant: f32, fw: f32) -> f32
Circular dots on a square grid. cells is the number of dots per UV
unit, radius is the dot radius in cell units (so 0.5 exactly tiles),
and fw is the anti-aliasing width.
fn dots(uv: vec2<f32>, cells: f32, radius: f32, fw: f32) -> f32
hexgrid
Section titled “hexgrid”Hexagonal tiling helper. Returns a vec3<f32> whose .x is the distance
to the nearest hex edge (use it as a line mask) and whose .yz is an
integer-valued hex id you can hash for per-cell colour.
fn hexgrid(uv: vec2<f32>, scale: f32) -> vec3<f32>
stripes
Section titled “stripes”Straight stripes in any direction. direction is normalised inside the
function. period is the stripe period in UV units, duty is the
fraction of each period that is “on” (0.5 for equal stripes), and fw
anti-aliases the edges.
fn stripes(uv: vec2<f32>, direction: vec2<f32>, period: f32, duty: f32, fw: f32) -> f32
trigrid
Section titled “trigrid”Triangular grid line mask. scale controls cells per UV unit,
thickness is the line width as a fraction of a cell, and fw smooths
the line edges. Returns 1 on a line and 0 inside a cell.
fn trigrid(uv: vec2<f32>, scale: f32, thickness: f32, fw: f32) -> f32
truchet
Section titled “truchet”Truchet tiles with a randomly-rotated quarter-arc per cell, producing woven-looking curves. Returns the unsigned distance to the nearest arc; threshold it for a line mask, or smooth-step a thicker band for ribbons.
fn truchet(uv: vec2<f32>, scale: f32) -> f32
Simple over/under weave pattern. cells is the thread density per UV
unit, and fw smooths the ridge/valley boundary. Returns a soft mask in
[0, 1] you can mix between a warp and a weft colour.
fn weave(uv: vec2<f32>, cells: f32, fw: f32) -> f32
Wavy zebra stripes driven by a sine of (uv.x + uv.y * warp + phase).
freq is stripes per UV unit, warp adds a diagonal skew, phase
shifts the wave (animate it for motion), and fw smooths the edges.
fn zebra(uv: vec2<f32>, freq: f32, warp: f32, phase: f32, fw: f32) -> f32