Backdrops · effect

StippleField

A stipple drawing where tone is how many marks there are, not how big.

ambient, watch the density drift

Paste into Claude Code, Cursor or any agent. Pinned to a tag, so it will not change under you.

Options

paper #fbfaf4

css colour

The paper behind the marks.

ink #36362f

css colour

The nib.

accent #c44400

css colour

A second nib, on a small share of the marks.

pitch 7

3 to 30

Cell size in CSS pixels. There is at most one mark per cell, so this is the spacing of the stipple rather than its weight. Laid out in pixels so the marks keep their size whatever shape the element is.

jitter 0.75

0 to 1

How far each mark is thrown off the centre of its cell. At 0 the marks sit on a grid and it stops being a stipple; at 1 they are anywhere in their cell and the grid is undetectable.

scale 1.6

0.2 to 8

Size of the tone field the marks follow. Lower is broader country with slower changes in density.

weight 0.19

0.05 to 0.45

Radius of a mark, measured in cells. Every mark is the same size, which is the point: an engraver has one nib. Past about 0.4 they touch at full density and it becomes a solid.

contrast 1.9

0.5 to 5

How hard the tone field pushes away from the midtone. Applied about 0.5, so raising it opens the field out rather than dragging the whole thing dark.

accentShare 0.06

0 to 0.5

Share of marks that take the second nib. Small: this is a second pass over a drawing, not a second drawing.

grain 0.4

0 to 1

Paper tooth under the marks.

period 18

2 to 120

Seconds for one loop of the drift. The tone field travels a closed circle through noise space, so it returns to exactly where it began and the loop is seamless.

What it needs

Dependencies
None at all
Browser
WEBGL2
Frame budget
~1.5 ms · 1 context
Pinned to
v0.10.0
  • Tone is carried by the number of marks rather than their size, which is what separates a stipple from a halftone: an engraver has one nib, so darker means more marks rather than fatter ones
  • Each mark is tested against the nine surrounding cells, because a mark thrown off centre crosses into its neighbour and testing only its own cell would slice it at the boundary
  • One WebGL2 context, one full-screen triangle, no buffers and no attributes
  • Nine cell tests per pixel, each a hash and a distance, plus four octaves of value noise for the tone field
  • Most cells fail the tone test and cost one hash, so the lighter the field the cheaper it is
  • Nothing is uploaded per frame. Only uniforms change