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 needUse
soft drifting clouds or smokeseededPlane around evolving around noiseField, then noiseTone
layered fractal detail with an anglefractalNoise
cells, scales or a cracked-earth lookworleyNoise
Voronoi cells with a fill and border linescellDistances with cellFill, cellBorders and borderOverlay
brushed metal or wood graingaborGrains inside unitized
rippling water interferencewaveletBands inside unitized
film grain or ditherpixelGrid around blueSpeckle
eroded terrain ridgeserosionRidges inside unitized
swirling flow, eddies and streamscurlSpeed
hairline scratches on a surfacescratchStreaks
a basis is −1 to 1 and the ramp wants 0–1unitized or signedTone
the standard contrast and balance slidersnoiseTone
a contrast slider where 1 means unchangedgainTone
two colors with no color-space proplinearPair
an organic wobble on an edge, radius or fillwaves, or organicWaves for a ready schedule
a wavy line, horizon or curtain pathwavyLine
flowing gradient ribbons between two pointsribbons closed by overRgb with backToP3 and tonePow
embossing the layer inside as stone or clothnoiseRelief 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

TypeWhat it is
ReliefBasisA height field noiseRelief can emboss a layer with.
RgbStageA color-only step for overRgb: takes a paint's rgb and returns new rgb.
WaveOne traveling sine wave, written as plain data.
WaveTermOne term of a wave schedule: a single wave, or several multiplied together.

Words