Noise
Words for grainy, cloudy, cellular and streaked surfaces: the textures behind clouds, film
grain, stone, water and brushed metal. Read a noise recipe from the inside out, in four
steps. A basis is the raw pattern, one number per point (gaborGrains, curlSpeed,
blueSpeckle, or a noiseField from paint). A framing decides where on the canvas the
basis is sampled and how big it is: seededPlane for almost everything, pixelGrid for
patterns that live on pixels. A tone word turns the raw number into a 0–1 ramp position
with contrast and balance controls: noiseTone for a 0–1 basis, signedTone for a −1 to 1
one, or unitized to convert first. A ramp closes it: rampOver with stops or
linearPair gives the field color.
Each basis is either signed (−1 to 1) or unit (0 to 1); its comment says which. Signed
bases go through unitized or signedTone, unit bases straight into noiseTone. Bases
that move read the layer's clock, so declare animatedTime: {speed: 'speed'} on the
definition. fractalNoise and worleyNoise are complete paints that do all four steps
for you. The wave words (waves, wavyLine) are expressions rather than fields, for
recipes written as a paint: (params) => … function. noiseRelief is the one filter here:
it embosses the layer inside instead of painting.
import {noise} from 'shaders/std'
Reach for it when
| When you need | Use |
|---|---|
| soft drifting clouds or smoke | seededPlane around evolving around noiseField, then noiseTone |
| layered fractal detail with an angle | fractalNoise |
| cells, scales or a cracked-earth look | worleyNoise |
| Voronoi cells with a fill and border lines | cellDistances with cellFill, cellBorders and borderOverlay |
| brushed metal or wood grain | gaborGrains inside unitized |
| rippling water interference | waveletBands inside unitized |
| film grain or dither | pixelGrid around blueSpeckle |
| eroded terrain ridges | erosionRidges inside unitized |
| swirling flow, eddies and streams | curlSpeed |
| hairline scratches on a surface | scratchStreaks |
| a basis is −1 to 1 and the ramp wants 0–1 | unitized or signedTone |
| the standard contrast and balance sliders | noiseTone |
| a contrast slider where 1 means unchanged | gainTone |
| two colors with no color-space prop | linearPair |
| an organic wobble on an edge, radius or fill | waves, or organicWaves for a ready schedule |
| a wavy line, horizon or curtain path | wavyLine |
| flowing gradient ribbons between two points | ribbons closed by overRgb with backToP3 and tonePow |
| embossing the layer inside as stone or cloth | noiseRelief with reliefBases |
Example
import {defineShader, p, noise, paint, transformColor, transformColorSpace, colorSpaceOptions} from 'shaders/std'
const {seededPlane, gaborGrains, unitized, noiseTone} = noise
const {rampOver, stops} = paint
// Brushed metal: oriented sine grains (a signed basis) framed on a zoomable plane,
// converted to 0–1, toned with contrast and balance, and read through the color ramp.
export const BrushedMetal = defineShader({
name: 'BrushedMetal',
animatedTime: {speed: 'speed'},
props: {
colorA: {default: '#f4f4f5', transform: transformColor},
colorB: {default: '#27272a', transform: transformColor},
colorSpace: {default: 'oklab', transform: transformColorSpace, compileTime: true, ui: {type: 'select', options: colorSpaceOptions}},
scale: {default: 1.5},
frequency: {default: 8},
seed: {default: 0},
contrast: {default: 0},
balance: {default: 0},
speed: {default: 0.5},
},
paint: rampOver(
noiseTone(
seededPlane(unitized(gaborGrains({frequency: p('frequency')})), {scale: p('scale'), seed: p('seed')}),
{contrast: p('contrast'), balance: p('balance')},
),
stops(p('colorSpace')),
),
})
Types
| Type | What it is |
|---|---|
ReliefBasis | A height field noiseRelief can emboss a layer with. |
RgbStage | A color-only step for overRgb: takes a paint's rgb and returns new rgb. |
Wave | One traveling sine wave, written as plain data. |
WaveTerm | One term of a wave schedule: a single wave, or several multiplied together. |
Words
- seededPlaneFrames a field on a zoomable plane: how big the pattern is and where it starts.
- evolvingMakes a 3D noise basis morph in place over time instead of sliding across the canvas.
- noiseToneThe standard contrast and balance controls of a noise texture, turning a 0–1 field into the ramp position.
- unitizedTurns a signed field (−1 to 1) into a unit field (0 to 1).
- signedToneContrast and balance for a signed field (−1 to 1), applied before it is squashed to 0–1.
- gainToneContrast as a multiplier and balance as a shift over a 0–1 field, not flipped.
- gaborGrainsOriented sine grains: short striped patches, each facing a random way, like brushed metal or wood grain.
- waveletBandsRotating bands of wavelets: layered ripples that turn against each other, a watery interference look.
- curlSpeedHow fast a swirling flow moves at each point: soft eddies and streams that morph in place.
- erosionRidgesTerrain eroded by water: sharp branching ridges with gullies running off them.
- scratchStreaksFine hairline scratches, like a scuffed surface, flickering on the layer's clock.
- pixelGridFrames a field on the pixel grid: one value per block of
graindevice pixels. - blueSpeckleFine, even speckle with no clumps: blue noise, one random value per pixel block.
- scaledPlaneFrames a field on the aspect-corrected canvas plane, zoomed by a plain multiplier.
- linearPairA two-color palette mixed in linear RGB, for a definition with no color-space prop.
- fractalNoiseA complete fractal-noise paint: layered simplex noise that morphs over time, read through the color ramp.
- worleyNoiseA complete cellular-noise paint: distances to drifting cell points, read through the color ramp.
- transformWorleyModeThe
transformfor aworleyNoisemodeprop: maps'f1','f2','f2MinusF1','f1PlusF2'or'f1TimesF2'to the number the paint reads. - transformWorleyDistanceThe
transformfor aworleyNoisedistanceprop: maps'euclidean','manhattan'or'chebyshev'to the number the paint reads. - cellDistancesDistances from each pixel to its nearest two cell points, as
(d1, d2): the raw material for Voronoi fills and borders. - cellFillA 0–1 fill for each cell: 0 at the cell's point, 1 at its boundary, whatever the cell size.
- cellBordersA mask of the lines between cells: 0 on a boundary, 1 inside a cell.
- borderOverlayDraws a color over a paint wherever a mask falls to 0, keeping the paint's alpha.
- wavesOverlapping traveling sine waves from a schedule written as data: the organic wobble behind blob edges, water lines and drifting fills.
- wavyLineThe height of an animated wavy line at a point along it: a stack of traveling sines.
- organicWavesA ready-made
wavesschedule from three knobs, for when you have no hand-tuned constants. - ribbonsFlowing gradient-colored ribbons between two points: the Strands look.
- overRgbRuns color-only steps over a paint, in order, leaving its alpha alone.
- backToP3Brings
ribbonscolor from its working color space back to display color. - tonePowA gentle lift of the mid-tones (rgb to the power 0.85), as an
overRgbstep. - noiseReliefEmbosses the layer inside with a textured surface: the child is slightly distorted, then lit by a height field so it reads as carved stone or woven cloth.
- reliefBasesThe height fields
noiseReliefaccepts:stone(marbled stone) andwool(interwoven fibres). - reliefBases.stoneMarbled stone height field.
- reliefBases.woolInterwoven fibrous fabric height field.