Filtering

Filtering and Resampling

What Nuke's filters really are: kernels, ringing, aliasing, concatenation, upscaling and dither

Math in Nuke, the series: Merge & Premultiplication · The Grade Node · ColorCorrect · Saturation, Hue & HSV · Keying · Despill · Matching Colour & Light · Edge Extend · Lin, Log & Gamma · Filtering & Resampling · Edge Detection · Vectors · Trigonometry · Expressions & Curves

Every Transform, Reformat, CornerPin, STMap and LensDistortion has a filter menu with twelve names. Most compositors pick cubic, Lanczos when they want sharp, impulse for data, and never look further. Behind the names there are exact mathematical functions, and I measured them in Nuke 17: I scaled a single white pixel by 8 with each filter and read the shape it left. This page shows what came out, and what those shapes do to images: ringing, aliasing, softness, banding.



Useful Links



Index



01. Pixels are samples

An image is a grid of numbers measured at the pixel centres. As soon as you move it by 0.3 pixels, rotate it or scale it, the new pixels fall between the old ones, and their value has to be invented from the neighbours. A filter is the rule for that invention, a weight that depends on the distance:

new value = Σ old pixeli × k(distancei)     with Σ k = 1

The function k is the kernel. Its shape decides everything: how soft the result is, whether edges get halos, whether fine patterns survive a downscale. It's the same idea as a convolution, with the kernel evaluated at fractional distances.



02. The cubic family, measured

Seven of Nuke's filters are the same formula with two different numbers. In 1988 Mitchell and Netravali described a family of cubic kernels with two parameters, B and C:

|x| < 1:   [ (12 − 9B − 6C)|x|³ + (−18 + 12B + 6C)|x|² + (6 − 2B) ] / 6
1 ≤ |x| < 2:   [ (−B − 6C)|x|³ + (6B + 30C)|x|² + (−12B − 48C)|x| + (8B + 24C) ] / 6

I fitted every measured kernel to it. These fit exactly (zero error):

Nuke filterBCcharacter
cubic00smooth, no negative lobes, radius 1
Keys00.5the classic "Catmull-Rom", mild sharpening
Simon00.75sharper
Rifman01sharpest of the cubics
Mitchell1/31/3the compromise recommended by the paper
Parzen10the cubic B-spline: soft, no ringing
notch1.5−0.25very soft, kills fine patterns
-2-101200.51distance from the pixel (pixels)weightimpulse (nearest)linearcubic: B 0, C 0Parzen: B 1, C 0notch: B 1.5, C -0.25
The smooth kernels. impulse is a box (nearest neighbour), linear a tent, cubic a smooth hump that is zero at the neighbouring pixels.
-2-101200.51distance from the pixel (pixels)weightMitchell: B 1/3, C 1/3Keys: B 0, C 0.5Simon: B 0, C 0.75Rifman: B 0, C 1
The sharpening cubics: the bigger C, the deeper the negative lobes around 1.4 pixels, the sharper the result.

B is the blur: it widens the kernel and lowers its peak. C is the sharpening: it digs the negative lobes. And there's a difference worth knowing: kernels that are exactly 1 at distance 0 and 0 at every other whole pixel (impulse, linear, cubic, Keys, Simon, Rifman, Lanczos) interpolate: if a transform happens to land on whole pixels, the image comes back untouched. Mitchell (0.89 at the centre), Parzen (0.67) and notch (0.5) approximate: they soften the image even when it doesn't move.



03. Lanczos and sinc4

The ideal interpolator is the sinc function, sin(πx) / (πx), but it never ends. Lanczos cuts it with a wider sinc as a window:

Lanczosa(x) = sinc(x) × sinc(x / a)    for |x| < a

The measurement clears up the names: Nuke's Lanczos4 is Lanczos with a = 2 (it uses 4 pixels across), Lanczos6 is a = 3 (6 pixels across). The number counts the pixels, not the radius. sinc4 is its own shape: it reaches 0 at one and two pixels, with the deepest negative lobes of all (−0.21): the sharpest filter in the menu, and the one with the most ringing.

-3-2-1012300.51distance from the pixel (pixels)weightLanczos4 = Lanczos, radius 2Lanczos6 = Lanczos, radius 3sinc4, as measured
Lanczos4 and Lanczos6 against the formula with a = 2 and a = 3, and sinc4 as measured.


04. Negative lobes and ringing

Negative weights are what makes a filter sharp: they subtract a bit of the neighbours and steepen the edges. The price is ringing: next to a strong edge the filter overshoots, a dark ring next to a bright edge, a bright ring next to a dark one. In scene linear, where a highlight can be 20 times brighter than the surroundings, the overshoot is 20 times bigger and goes below zero:

cubic: no ring
cubic
Rifman: a dark ring
Rifman
Lanczos6: dark and bright rings
Lanczos6
sinc4: a strong dark ring
sinc4

A 4 × 4 highlight of value 20 on a 0.05 background, scaled up 9 times. Shown through x / (1 + x) so the highlight fits on screen; values below 0 are drawn darker than the background. Only cubic stays clean.

That's why cubic is a safe default for CG with hot highlights, and why the sharp filters are better on plates, where values stay in a narrower range and a little sharpness is welcome.



05. Upscaling

An eye from the Tears of Steel plate, scaled up 6 times with six filters:

impulse
impulse: blocks
linear
linear: soft, slightly diamond-shaped
cubic
cubic
Mitchell
Mitchell: the softest
Rifman
Rifman: sharp, dark halos
Lanczos6
Lanczos6: sharp, some ringing

No filter adds detail that isn't there: interpolation only chooses between softness and halos. Smarter upscales use more knowledge about images. My own Upscale gizmo combines three ideas: it works in YCbCr, sharpening the luminance and blurring the chroma, because the eye sees detail in brightness and much less in colour; it uses Nuke's TVIScale, which upscales by minimising the total variation, so it keeps edges sharp without inventing ringing; and it ends with a tiny antialiasing kernel to soften the staircases. Machine learning upscalers go further and actually guess the missing detail.



06. Downscaling and aliasing

Shrinking is the dangerous direction. A grid can only hold details down to two pixels per cycle (the Nyquist limit); anything finer doesn't disappear, it folds into false, coarser patterns: moiré, crawling stripes, jagged edges. A zone plate, rings that get finer towards the edges, shows it at once:

The centre of the zone plate at full size
the original (centre, full size)
Reduced 4 times with impulse: false rings everywhere
÷4, impulse: false rings everywhere
Reduced with cubic
÷4, cubic
Reduced with Lanczos6
÷4, Lanczos6

Impulse just picks one pixel every four: everything finer than the new grid aliases. The other filters widen their kernel when the image shrinks, so they average the details away before sampling: the fine rings become a flat grey, which is the correct answer. If you must use impulse (data passes, IDs), blur first by about the scale factor:

Blur 6 then impulse: clean
blur 6, then ÷4 with impulse: clean


07. Concatenation: filter once

Every filter softens a little. Nuke avoids filtering twice when it can: consecutive Transform-type nodes are concatenated, their matrices multiplied into one (see the Transform matrix page), and the image is resampled once. Put a colour node between them and the chain breaks: every Transform filters on its own.

Original
original
Ten transforms, concatenated
ten small moves, concatenated: filtered once
Ten transforms with Grades in between
the same with a Grade between them: filtered ten times

Ten Transforms moving by ±0.37 and ±0.21 pixels, cubic filter. Together they cancel out; when they concatenate the result is the original, when they don't, ten cubic filters stack into a visible blur.



08. Tiny kernels: antialiasing by hand

Sometimes you only want to soften or harden edges a little, without moving anything: CG without enough samples, a hard roto, an upscaled matte. A 3 × 3 convolution is enough. These are the kernels of my AntiAliasingFilter gizmo, each normalised to sum to 1:

kerneleffect
0 1 0 / 1 2 1 / 0 1 0light antialiasing (a small cross)
1 2 1 / 2 4 2 / 1 2 1medium: the binomial, a tiny Gaussian
1 1 1 / 1 1 1 / 1 1 1strong: a box
0 −0.5 0 / −0.5 3 −0.5 / 0 −0.5 0the opposite: a light sharpen

The sharpening ones have negative weights, so the same warning applies: they can produce values below 0, which is why the gizmo has a black clamp.



09. Banding and dither

The last resampling of all happens at the end: the float image is rounded to the integer levels of the output. With 8 bits there are only 256 levels, fewer in the dark part of a gradient, and a smooth sky can show bands. Here the same dark gradient rounded to 64 levels, to make it obvious:

Smooth gradient
the gradient in float
Rounded to 64 levels: bands
rounded to 64 levels: bands
With dither before the rounding: no bands
a little noise added before the rounding: no bands

Rounding makes an error of up to half a level, and in a gradient that error is organised in steps that the eye spots immediately. Dither adds noise of about one level before rounding: the error is the same size, but random, and the eye averages it away. My DitherBlur gizmo refines it for comps: it takes the noise of a Dither node on its own (dither minus original), blurs it a little so it looks like soft grain instead of digital noise, and adds it back to the unpremultiplied image.



Filter Lab

Pick one of Nuke's filters or move B and C yourself. The plot shows the kernel; the image is the eye of chapter 05, scaled 6 times with that kernel, computed here in the page.

Nuke filter

                                                    


Nodes to paste in Nuke

Click a box, copy it (Ctrl+C / Cmd+C) and paste it in Nuke's Node Graph (Ctrl+V / Cmd+V).

Antialiasing kernels. The four 3 × 3 kernels of chapter 08 as Matrix nodes, from the light cross to the sharpen. Disable the ones you don't need.

Soft dither. The DitherBlur idea in three nodes: the noise of a Dither on its own, blurred, added back. Put it last, before the Write.



The math series

The other pages about maths in Nuke:
Merge & Premultiplication The Grade Node ColorCorrect Saturation, Hue & HSV Keying Despill Matching Colour & Light Edge Extend Lin, Log & Gamma Edge Detection Vectors Trigonometry Expressions & Curves
And if you like this, have a look at the Matrices in Nuke series.

Leave a comment