SVG Grain Texture: Keep Noise Inside Your Artwork
Add SVG grain with feTurbulence, keep monochrome noise inside SourceAlpha, tune it at two sizes, and preserve a clean path master for other destinations.
On this page
To add grain to an SVG illustration, generate noise with feTurbulence, turn it into a faint monochrome overlay, and composite that overlay inside SourceAlpha. Merge it over SourceGraphic so the original fill stays visible. This adds a rendered texture while leaving the artwork's path geometry intact.
A bare noise primitive gives a different result: it fills its filter primitive subregion, rather than following the shape's outline. That is why a leaf can become a rectangular noise patch. MDN's feTurbulence reference documents that behavior.
For a web illustration, the useful deliverables are a textured display version and a clean master. Grain produced by this filter is not a collection of editable dots or cutting contours.
Separate the shape from the surface treatment
Start with a simple filled path that already looks right without grain. Fix its outline, gaps, and color before adding the effect. A filter will not repair that geometry.
The three states below explain the boundary problem:
| Version | What the filter outputs | When to use it |
|---|---|---|
| Plain shape | The original filled path | Editing and a clean master |
| Bare noise | A rectangular generated image in the filter region | Inspecting the noise source, rather than delivering the motif |
| Contained grain | Original artwork plus monochrome noise limited by its alpha | A textured browser display version |

SourceGraphic supplies the element being filtered. SourceAlpha supplies its alpha channel. The filter operates on an image of the artwork; it does not rewrite the path commands. These inputs and the filter graph are defined in the W3C Filter Effects specification.
If your starting artwork already has transparent areas, those areas affect the containment too. SourceAlpha follows the actual rendered opacity, not a guessed outer bounding box.
Copy a complete SVG grain example
Save this as an .svg file and open it in a browser. It contains one original leaf path, a deterministic noise seed, a dark overlay, and the explicit containment step. The diagonal opening is part of the path, so it remains transparent in the textured version.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
<defs>
<filter id="grain" x="-10%" y="-10%" width="120%" height="120%"
color-interpolation-filters="sRGB">
<feTurbulence type="fractalNoise" baseFrequency="0.65"
numOctaves="2" seed="8" result="noise"/>
<feColorMatrix in="noise" type="matrix" values="0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0.28 0" result="ink"/>
<feComposite in="ink" in2="SourceAlpha" operator="in" result="inside"/>
<feMerge>
<feMergeNode in="SourceGraphic"/>
<feMergeNode in="inside"/>
</feMerge>
</filter>
</defs>
<path d="M36 142C40 70 104 26 164 30C164 100 120 150 60 156L38 180L28 170L52 146C80 112 112 78 146 46C104 78 74 110 54 140Z" fill="#e76b50" filter="url(#grain)"/>
</svg>The filter has four jobs:
feTurbulencecreates the noise and names itnoise.- The matrix sets red, green, and blue to zero. Its last row multiplies the noise's alpha by
0.28, creating a faint black overlay calledink. feCompositewithoperator="in"keeps that overlay whereSourceAlphaexists.feMergedraws the original artwork first and the contained overlay above it.
The MDN feColorMatrix reference explains how the five-column matrix transforms color and alpha. Here it changes the noise image, not the leaf's fill. The MDN feComposite reference explains the in operation used to restrict the overlay to the second input.
The value 0.28 is a starting point for this coral leaf, not a universal grain setting. Lower it if the texture dulls the artwork; raise it if the grain disappears at the intended display size. Black overlay grain darkens the fill. It will not create visible pale speckles on a black motif.
For the color and alpha operations used to recolor existing artwork, see the separate feColorMatrix guide. For hardening an existing transparent edge, see SVG alpha thresholds. Neither operation supplies the generated noise source used here.
Check the result at the size people will see
We made three versions of this original path: no filter, a filter containing only the noise primitive, and the complete contained-grain graph above. We inspected the rendered versions in Chrome at 120 × 120 and 360 × 360 CSS pixels, with the same 0 0 200 200 viewBox.
| Check | 120-pixel version | 360-pixel version |
|---|---|---|
| Plain master | Smooth coral leaf, transparent opening | Same outline and opening |
| Bare noise | Rectangular noise replaces the visible motif | Rectangular noise remains visible beyond the leaf silhouette |
| Contained grain | Faint texture inside the leaf | More visible texture, with opening and surrounding area clear |
The browser DOM contained one path in every specimen. All six d attributes were identical. That establishes the limit of this example: the rendered surface changed, and no speck paths were added. It is an authored browser fixture, not output from PerfectVector or a native vector editor.
A larger preview helps inspect the effect, but the smaller version decides whether the artwork still reads. Keep both sizes in your review. Increasing display size with the same viewBox also changes the apparent scale of the texture; do not assume one preview represents every use.
Tune the grain one control at a time
For a small web card illustration, start with the values in the example. Then change one parameter, compare the same two display sizes, and keep a copy of the version you preferred.
| Control | What to decide | Practical check |
|---|---|---|
baseFrequency | Coarser or finer variation in SVG coordinates | Try 0.25 beside 0.65; inspect at the actual display size |
numOctaves | How many layers of noise detail to combine | Compare 1 and 2 before adding more detail |
seed | Which noise realization to use | Keep it fixed while comparing other settings |
| Matrix alpha multiplier | How strongly the black overlay darkens the fill | Compare 0.15 and 0.28 on the same artwork |
| Filter region | The rectangle available to the filter graph | Fix missing output without using the rectangle as a substitute for alpha containment |
baseFrequency accepts one value for both axes or two values for horizontal and vertical frequency. The MDN baseFrequency reference documents that distinction. Start with one value for this leaf; unequal values are a deliberate choice for directional texture.
numOctaves controls the number of noise octaves, as described in the MDN numOctaves reference. Extra octaves are not extra vector paths. Use them only if they improve the visible surface at the size you need.
The example sets color-interpolation-filters="sRGB" explicitly. Keep that setting unchanged while comparing your candidates so a change in color processing does not confuse the grain comparison.
Fix a rectangle, missing fill, or dirty edge
The texture makes a rectangular patch. Inspect the final output of the filter. If it ends with feTurbulence, it is returning the noise image. Restore the matrix, the SourceAlpha composite, and the merge. Enlarging the filter rectangle will only give uncontained noise more room.
The leaf's color disappears. Check that the first merge node uses SourceGraphic. A final inside result alone contains the dark overlay, not the original coral fill. Also check spelling and capitalization of each named result and in reference.
Noise remains in a transparent opening. Confirm the second composite input is SourceAlpha, not the rectangular noise or an opaque background. Apply the filter to the artwork you want textured. Including an opaque background in the filtered group changes the alpha input.
Part of the output is cropped. Check x, y, width, and height on the filter. These set the available filter region, as described in the MDN filter reference. The example gives modest extra room. A wider region cannot repair a missing containment step, and it does not fix clipping imposed by a separate container.
The small artwork looks muddy. Reduce overlay alpha first, then compare frequency and octave count. If the texture still harms the silhouette, deliver the clean version at that size.
Keep a clean master for delivery
For the unfiltered master, remove filter="url(#grain)" from the path and remove the now-unused filter definition. Preserve the path's d, its fill, and the viewBox. Open that file separately and confirm the leaf and opening match the original clean version.
For a web app, check the textured version in the browsers and exact embedding method you will ship. If you repeat this inline SVG on one page, give each filter a unique ID and update its url(#...) reference. The standalone example uses one ID because it contains one instance.
For a destination that needs an exact raster appearance, export a raster preview at the required size and inspect it there. For a workflow that needs editable or cuttable geometry, hand over the clean paths and clarify that the grain is a display effect. Do not describe filter noise as vector specks, and do not promise that a downstream editor, PDF exporter, or cutter reproduces it. Test the actual destination.
If you deliberately need individually editable specks, that is a separate geometry task. It also needs a cleanup decision; see why an SVG has too many nodes before tracing texture into a mass of tiny contours. Preserving grain from a raster painting is another starting problem, covered in watercolor to vector.
When vectorization helps
If the clean motif survives only as a PNG or JPG, convert that source into editable SVG artwork before adding a browser filter. Inspect the recovered silhouette and opening in the clean version first. PerfectVector supplies the raster-to-vector step; the procedural grain graph in this guide is a separate SVG treatment you add afterward.
Already have the path-based master? Use it directly. A second conversion is unnecessary for the filter job. The image vectorization guide explains that source-recovery step if you need it.
FAQ
Why does feTurbulence create a rectangle instead of following my shape? The noise fills its filter primitive subregion. Composite it inside SourceAlpha and merge it over SourceGraphic to confine the overlay to the artwork while preserving its fill.
Does SVG grain add nodes to my path? This filter does not add speck paths. In the original browser fixture, all six specimens retained one path with identical d data; the filter changed the rendered surface.
Which grain settings should I start with? For the original leaf example, start with fractalNoise, baseFrequency 0.65, two octaves, seed 8, and a black overlay alpha multiplier of 0.28. Compare at the real display size and adjust one setting at a time.
Can I use the grain effect as a cutting file? The generated texture is not editable cutting geometry. Keep a separate unfiltered path master and check the geometry in the actual cutting workflow.
Sources
- MDN: feTurbulence — Noise generation and the primitive subregion.
- W3C: Filter primitive tree — SourceGraphic, SourceAlpha, and filter image processing.
- MDN: feColorMatrix — Color and alpha matrix operations.
- MDN: feComposite — Containment using the in operator.
- MDN: baseFrequency — One-axis and two-axis frequency values.
- MDN: numOctaves — Noise detail layers.
- MDN: filter — Filter-region attributes.
If your web illustration needs a clean master recovered from raster, start with image-to-vector conversion, review the paths, and add grain to a separate display copy.
More from the blog

FontForge SVG Import: Turn Drawn Shapes Into Glyph Outlines
Import SVG artwork into a FontForge glyph slot, then check contours, baseline, scale, and spacing. Learn what tracing provides and what still needs font design.

How to Evaluate Vector Trace Quality: A Scorecard
Use a 12-point scorecard to judge edge fidelity, negative space, color, node efficiency, editability, and whether an SVG works in its final destination.
