The short version
- SVG feTurbulence is a filter primitive that generates Perlin noise, which you can use as grain, paper, clouds or a displacement source.
- The baseFrequency attribute sets the size of the noise: high values around 0.6 to 0.9 give fine grain, and low values around 0.01 to 0.05 give large soft clouds.
- type="fractalNoise" makes soft, even noise suited to grain and paper, while type="turbulence" makes sharper, rippled noise suited to marble and water.
- A small noise tile with stitchTiles="stitch", layered over a gradient at low opacity, adds texture and hides banding at very little cost.
- feTurbulence is expensive to compute over large areas, so render it once as a tile rather than animating it full screen.
On this page
SVG feTurbulence is a filter primitive that fills its region with Perlin noise. On its own the result is a field of coloured static; combined with other primitives it becomes film grain, paper fibre, clouds, marble or a source for warping shapes. You control it with five attributes: type, baseFrequency, numOctaves, seed and stitchTiles. Most textures on modern websites, including the grain on grainy gradients, start here.
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300">
<filter id="noise">
<feTurbulence type="fractalNoise" baseFrequency="0.75" numOctaves="3" stitchTiles="stitch" />
</filter>
<rect width="100%" height="100%" filter="url(#noise)" />
</svg>What each feTurbulence attribute does
typeturbulence (default) or fractalNoiseEffect
baseFrequencyValues
Effect
numOctavesValues
Effect
seedAny number, default 0Effect
stitchTilesValues
noStitch (default) or stitchEffect
baseFrequency is the one you will touch most. It is measured in cycles per user unit, so 0.8 packs features close together and 0.02 stretches them into slow clouds. Two values, such as baseFrequency="0.01 0.3", stretch the noise along one axis, which is how brushed metal and wood grain are faked.
Looks like
Use
Looks like
Use
Looks like
Use
Looks like
Use
Looks like
Use
type="fractalNoise"
- Soft, cloudlike, evenly spread
- Good for grain, paper and fog
- The usual choice for overlays
type="turbulence"
- Sharper with dark creases
- Good for marble, fire and water
- Looks busy as a full overlay
Recipe: grain over a gradient
The most useful thing feTurbulence does is add grain. A clean digital gradient bands into visible stripes, especially dark ones; light noise breaks those stripes up and makes the surface feel printed. The steps: make the noise, strip its colour, then lay it over the gradient at low strength.
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240">
<filter id="grain" x="0" y="0" width="100%" height="100%">
<feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="3" stitchTiles="stitch" result="noise" />
<feColorMatrix in="noise" type="saturate" values="0" />
</filter>
<rect width="100%" height="100%" filter="url(#grain)" />
</svg>Save that as grain.svg or inline it as a data URI, then tile it in a pseudo element above the gradient.
.hero {
position: relative;
isolation: isolate;
background: linear-gradient(160deg, #0f0b1e 0%, #312e81 55%, #6d28d9 100%);
}
.hero::after {
content: "";
position: absolute;
inset: 0;
z-index: -1;
background-image: url("/grain.svg");
background-size: 240px;
opacity: 0.12;
mix-blend-mode: overlay;
pointer-events: none;
}linear-gradient(160deg, #0f0b1e 0%, #312e81 55%, #6d28d9 100%)Recipe: paper texture
Paper is low frequency noise turned into relief by a light source. feDiffuseLighting treats the noise as a height map and lights it from one side, which produces the soft hills of a sheet of cotton paper.
<filter id="paper" x="0" y="0" width="100%" height="100%">
<feTurbulence type="fractalNoise" baseFrequency="0.04" numOctaves="5" result="noise" />
<feDiffuseLighting in="noise" lighting-color="#f7f1ea" surfaceScale="2" result="lit">
<feDistantLight azimuth="45" elevation="60" />
</feDiffuseLighting>
<feBlend in="SourceGraphic" in2="lit" mode="multiply" />
</filter>Pair it with warm off white grounds. Paper texture backgrounds has palettes that suit it.
Recipe: warped edges with feDisplacementMap
Noise can also move pixels. feDisplacementMap reads the noise and shifts each pixel of the source by up to scale units, which gives hand drawn lines, melting type and rippled water.
<filter id="wobble">
<feTurbulence type="turbulence" baseFrequency="0.02" numOctaves="2" seed="3" result="warp" />
<feDisplacementMap in="SourceGraphic" in2="warp" scale="10" xChannelSelector="R" yChannelSelector="G" />
</filter>
<text x="40" y="120" font-size="96" font-weight="700" filter="url(#wobble)">Wavy</text>Performance and browser behaviour
feTurbulence works in every current browser, but it is computed on the CPU in many of them and its cost grows with area and octaves. A 240 pixel tile is calculated once and repeated, which is cheap. A full screen filter on a live element is recalculated whenever the element repaints, which can be slow on phones.
- 1
Tile it
Render noise into a small SVG with
stitchTiles="stitch"and repeat it as a background image. - 2
Keep octaves low
numOctavesabove 4 rarely adds visible detail at grain sizes and costs every time. - 3
Avoid animating it
Animating
baseFrequencyorseedforces a full recalculation every frame. Shift a static tile with a transform instead. - 4
Check both themes
Grain that looks right on dark can look dirty on light. Tune opacity per theme, as in dark mode gradients.
For a CSS only take on the same idea, see CSS noise texture. And if you want grain without tuning filters at all, every Gradiently Mark carries its own grain and material as part of its recipe, rendered live at whatever size you design.
A Mark with grain built into its surface. The noise is part of the recipe, so it stays the same scale at every size.
Questions people ask
What does feTurbulence do in SVG?
It generates Perlin noise inside an SVG filter. You can show the noise directly as texture or feed it into other primitives such as feColorMatrix, feDiffuseLighting or feDisplacementMap.
What baseFrequency should I use for grain?
Try 0.7 to 0.9 with type fractalNoise and three octaves for fine film grain. Lower values make larger, softer features.
What is the difference between fractalNoise and turbulence?
fractalNoise is soft and even, good for grain and paper. turbulence has sharper creases and suits marble, fire or water effects.
Why does my SVG noise have visible seams when tiled?
Set stitchTiles="stitch" on feTurbulence and set the filter region to the full tile with x, y, width and height, so edges match and no soft border appears.
Is feTurbulence slow?
It can be on large areas or when animated, because it recalculates the noise on every repaint. A small static tile repeated as a background is cheap.
Written by Gradiently
The team behind Gradiently, a design tool built around Marks: living gradients that make everything you design look like yours.
See our profile