Grain belongs in the midtones

Adding uniform noise to a frame is the standard way to fake film, and it is the reason faked film usually reads as a dirty screen instead. Real grain has structure, and the structure is not subtle once you know to look for it.

Left: clean. Middle: uniform grain at a fixed amplitude. Right: amplitude following the exposure.

The middle panel has grain crawling all over the shadows. The right panel leaves the shadows almost clean, puts the most grain through the midtones, and eases off again in the highlight. That is where film actually puts it, and it is the difference between "shot on film" and "there is something wrong with this screen".

Why the midtones

Grain is a counting phenomenon. Film is a layer of silver halide crystals, and a given exposure develops some fraction of them. The visible grain is the statistical variation in which ones happened to develop.

In a deep shadow almost nothing developed, so there is very little variation to see. In a blown highlight nearly everything developed, so again there is little left to vary. The variance is largest in between, where roughly half the crystals flipped and the outcome is most uncertain. That is a binomial process, and its standard deviation goes as the square root of p(1-p):

float lum = luminance(color);
float amt = strength * sqrt(lum * (1.0 - lum));   // peaks at lum = 0.5

One sqrt, and the grain stops looking like an overlay.

Grain does not scale with your resolution

A grain is a physical object of a fixed size on the negative. Render it per-pixel and it becomes finer as your output gets bigger, so the same footage grains differently at 1080p and 4K, and a 4K master downsampled for delivery has almost no grain left at all.

float grainScale = resolutionHeight / 320.0;   // pick a reference height
vec2  gp = fragCoord / grainScale;             // sample at a FIXED size

Tie it to a reference height and it stays the same physical size at every output resolution, which is what actually matches the reference.

The two other details

Rules of thumb

  1. Amplitude follows sqrt(lum*(1-lum)). Peak in the midtones, near zero at both ends.
  2. Fix the grain size in physical units, not pixels, or it changes with resolution.
  3. Use noise with a cell size. White noise reads as digital, not film.
  4. Apply after the tonemap and grade, with the dither, at the very end.
  5. Animate it on the frame clock, not continuously, or it shimmers rather than flickers.

All 61 notes How to use them Credits