Patterns & tiling
Repeating patterns you can color and animate: checkers, stripes, zigzags, rings, falling
streaks, and tiled lattices of squares, hexagons, triangles, bricks, truchet arcs, woven
threads and isometric cubes, plus the print-screen filters (halftone dots, CMYK plates and
dithering). Most pattern words return a mask: a number per pixel that is 1 on the pattern
and 0 off it. The lattice words also return a per-cell shade, a brightness factor around 1
that vary multiplies into a fill so every tile reads slightly different.
The lattice words share one coordinate system: cellFrame sets how many cells fit down the
canvas height and how far the lattice is rotated, and gridLines, hexLines,
triangleLines, truchetArcs, weaveThreads and isoCubeFaces draw inside it. The
free-standing words (checkerCells, stripeBands, ringWaves, dotLattice,
brickCourses) bring their own. Color a mask with strokeOver (fill where 0, stroke where 1,
in a chosen color space) or hang it under one color as alpha with withAlpha; the result goes
in paint:. The halftone and dither words are filters over the layer inside them and go in
effect:.
import {patterns} from 'shaders/std'
Reach for it when
| When you need | Use |
|---|---|
| a two-color checkerboard | checkerCells colored with strokeOver |
| stripes or chevrons that scroll | stripeBands, zigzagBands |
| rings rippling out from a point | ringWaves |
| rain or streaks falling across the canvas | fallingStreaks with withAlpha |
| a field of dots, optionally staggered or twinkling | dotLattice under withAlpha |
| grid lines, honeycombs or triangle lattices | cellFrame with gridLines, hexLines, triangleLines |
| every tile a slightly different brightness | vary with a lattice word's shade output |
| a brick wall | brickCourses |
| a maze of joined arcs | truchetArcs |
| a woven textile | weaveThreads |
| tumbling 3D cubes | isoCubeFaces with times, mixOf, opaque |
| a mapped size or thickness that should change per whole cell | sampleMapsAtCellCentres on the definition's mapSampleUVs field |
| a halftone dot screen over the layer inside | dotScreen |
| a four-color print with plate angles and misregistration | cmykPress with inkPlate |
| your own ink press inside a gather build | dotScreenMask, inkTransmission |
| one select prop that swaps whole effect recipes | chosenBy |
| a retro dither | pixelGrid, quantise, ditherInks |
| a color's alpha or RGB on its own | alphaOf, rgbOf |
Example
import {defineShader, p, patterns, transformColor, transformColorSpace, transformAngle, colorSpaceOptions} from 'shaders/std'
const {cellFrame, hexLines, strokeOver, vary} = patterns
// A honeycomb: hexagon lines in a rotatable lattice, each cell's fill lightened or darkened at random.
const field = hexLines({
frame: cellFrame({cells: p('cells'), rotation: p('rotation'), convention: 'clockwise'}),
thickness: p('thickness'),
softness: p('softness'),
variation: p('variation'),
})
export const Honeycomb = defineShader({
name: 'Honeycomb',
props: {
fill: {default: '#101828', transform: transformColor},
line: {default: '#f5d90a', transform: transformColor},
colorSpace: {default: 'linear', transform: transformColorSpace, compileTime: true, ui: {type: 'select', options: colorSpaceOptions}},
cells: {default: 8},
thickness: {default: 1},
rotation: {default: 0, transform: transformAngle},
softness: {default: 0},
variation: {default: 0.3},
},
paint: strokeOver({
fill: vary(p('fill'), field.shade),
stroke: p('line'),
mask: field.lines,
space: p('colorSpace'),
}),
})
Types
| Type | What it is |
|---|---|
CellFrameConvention | Which way a lattice's rows and rotation run. |
GatherStage | A value computed per pixel from the layer inside a gather effect, such as a dither level. |
InkPlateSpec | One ink plate of a cmykPress: which channel it prints, its screen-angle prop (degrees) and its ink-color prop. |
PaintSlot | What a pattern slot accepts: a prop p('name') or another pattern value. |
PatternPaint | A pattern value: something you place in paint: or hand to another pattern word, yielding a color or a mask per pixel. |
PixelGrid | The pixel grid a dither works on, from pixelGrid: the cell size prop, the cell coordinate coord, and source, the child's color sampled once per cell. |
ScatterOptions | What scatterPoint and scatterPoints take. |
ScatteredPoint | One scattered point: where it sits, the pixel's offset from it, and three random 0–1 values for its cell. |
Words
- strokeOverTwo colors mixed through a mask:
fillwhere the mask is 0,strokewhere it is 1. - withAlphaA color with its alpha replaced by a separately built mask.
- checkerCellsA checkerboard mask: 1 on one set of squares, 0 on the other, with clean edges at any size.
- stripeBandsA mask of straight parallel stripes that scroll with the layer's clock.
- zigzagBandsA mask of chevron (zigzag) stripes that scroll with the layer's clock.
- ringWavesA mask of concentric rings spreading out from a point, animated by the layer's clock.
- fallingStreaksStreaks that fall across the canvas in columns, each column at its own random speed.
- dotLatticeA mask of round dots on a square grid, with optional row stagger, drift and twinkle.
- cellFrameThe shared coordinate system of a tiled pattern: how many cells fit down the canvas height and how far the whole lattice is rotated.
- gridLinesSquare grid lines drawn in a
cellFrame, plus a per-cell shade for the fill. - hexLinesHoneycomb lines (pointy-top hexagons) drawn in a
cellFrame, plus a per-cell shade. - triangleLinesA lattice of equilateral triangles drawn in a
cellFrame, with rows that can drift. - brickCoursesA brick wall: staggered rows with mortar gaps, optional rotation and per-row drift.
- truchetArcsA maze of quarter-circle arcs, two per tile, flipped at random so they join into flowing curves.
- weaveThreadsTwo sets of threads woven over and under each other, returned as a finished color.
- isoCubeFacesTumbling blocks: three shaded rhombus faces per hexagon that read as a field of 3D cubes.
- varyA color lightened or darkened per cell by a shade factor, alpha untouched.
- sampleMapsAtCellCentresMakes map-driven props change per whole cell instead of per pixel, so a mapped dot size or line thickness grows cell by cell rather than being cut off mid-cell.
- timesThe product of two values: a mask scaled by a prop, an RGB dimmed by a shade, two masks combined.
- mixOfA straight blend from one value to another by an amount from 0 to 1.
- alphaOfThe alpha channel of a color, as a number per pixel.
- rgbOfThe RGB channels of a color, without its alpha.
- opaqueAn RGB value finished as a fully opaque color.
- dotScreenA classic halftone filter: the layer inside it redrawn as a grid of dots that grow where it is bright.
- cmykPressA four-color print filter: the layer inside it separated into ink plates, each screened into dots at its own angle and laid down on paper in order.
- inkPlateDeclares one ink plate for
cmykPress. - dotScreenMaskThe dot coverage of one halftone screen: 1 inside a dot, 0 between, with the dot size set by an ink amount.
- inkTransmissionHow much light passes one ink plate: white where the dot mask is 0, the ink color where it is 1.
- chosenByPicks one whole effect recipe from a select prop, decided when the shader compiles.
- pixelGridThe pixel grid of a dither: the layer inside it chopped into square cells of a given size.
- quantiseReduces each grid cell of the layer inside to 0 or 1 using a dither pattern.
- ditherInksA dither filter: colors the 0/1 levels from
quantise, either with two colors of your own or with darkened and brightened versions of the layer's own pixels. - scatterPointOne random point in each cell of a square grid: the classic scatter for glitter, stars, dust and sparkles.
- scatterPointsThe scattered points of the four grid cells nearest the pixel, so anything drawn up to half a cell from its point shows whole, never clipped at a cell edge.