Aberration
The two-pixel lie that makes an image look shot, not rendered
- image
- image
What it is
Lateral chromatic aberration - colour fringing. Real lenses refract red, green and blue by slightly different amounts, so the three channels land on the sensor at slightly different scales. The tell is a red or cyan fringe on high-contrast edges, strongest toward the corners, because the error grows with distance from the optical centre.
It's a defect. It's also one of the reliable tells of real capture, which is why every de-AI recipe in the KB's photo-realism material includes it - one thread's stack literally listed "red channel aberration" as step four of five. Generated images are geometrically perfect, and perfect optics don't exist.
How the node does it
Per channel, it resamples the image with a radial scale factor around a configurable centre, using bicubic sampling with reflection padding at the borders. Alpha is deliberately not shifted, which is the correct choice for compositing - you don't want your mask drifting along with the fringing.
The defaults are a physically sensible pair: shift_r +0.005, shift_g 0, shift_b −0.005. Red pushed outward, blue pulled inward, green as the reference channel. That's the classic dispersion pattern and it produces a red/cyan fringe, which is what you actually see on real glass.
One nice detail in the implementation: a shift of exactly 0 skips the resample entirely and copies the channel, so the reference channel is bit-exact. And invert is an exact inverse - the source notes it's verified as forward(inverse(x)) == x, which is stronger than "approximately the opposite" and means you can genuinely use it to remove aberration you added, or to correct real footage.
Inputs
image - anything, scene-linear or display-referred. Unlike the ACES nodes, this one's operation is geometric and doesn't care about encoding.
shift_r, shift_g, shift_b - the radial scales. Positive pushes outward, negative pulls inward. Range is ±0.1, which is a huge amount of aberration; the defaults are at 0.005 because on a 2K frame that's already a visible fringe. If you're reaching for 0.05 you're building a stylised effect, not simulating a lens.
center_x, center_y - where the distortion originates, in normalised 0–1 coordinates. The default 0.5/0.5 is the frame centre. Move it to match the actual optical centre if you're correcting footage that was cropped - and if you're adding aberration to match a plate shot on a lens with an offset centre, this is how.
invert - flips the shifts for a removal pass.
Output
image. One in, one out, no mask, no diagnostics. Dead simple node.
Use it like this
For the "shot, not rendered" pass: default shifts, done. Maybe nudge to 0.006/0.004 if you want it visible at 100% zoom on a 4K frame. The whole point is that you shouldn't notice it as an effect.
For correcting real footage: the correct sign, then find invert. It won't fix longitudinal CA (which changes with focus distance and can't be modelled as a radial scale), only lateral. Nobody has a one-node fix for longitudinal aberration and this isn't pretending to be one.
For a stylised look - a cheap vintage-lens sim - push the shifts up an order of magnitude, add the Anamorphic Streaks node, and you've got the two-thirds of a lens package. Add grain and you're at the point most people stop.
Install
ComfyUI Manager → search Radiance → install → restart → refresh the browser. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/fxtd-studios/radiance.git
cd radiance
python -m pip install -r requirements.txt
Windows portable users need ComfyUI's bundled python_embeded\python.exe for the pip step. Pure torch, no models, no colour config needed.
If you're on an older Radiance: the 3.5.0 changelog notes this node used to rebuild its sample grid per frame and process whole clips on the CPU, and now builds the grid once and processes frames in GPU chunks. Long clips got substantially faster. Worth knowing if you tried it before and it crawled.
Gotchas
- Cranking the shifts until you can see it. Then it looks like a broken lens rather than a camera. Subtle is the whole trick.
- Expecting it to fix longitudinal CA. It can't; radial scaling only models the lateral kind.
- Applying it twice when you meant to remove it. Use
invertrather than negative values you guessed at - the exact inverse is the correct one. - Cropped footage. If the optical centre isn't the frame centre, move
center_x/center_yor the correction will be asymmetric and look worse than the original. - It's order-dependent with the streak node. Aberration after a flare pass fringes the flare too. Usually what you want; sometimes not.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Image whose red, green and blue channels are scaled radially by separate amounts. Alpha is not shifted. | |
| shift_r | FLOAT | 0.005-0.1–0.1 | Radial scale for Red channel. Positive = pushed outward. |
| shift_g | FLOAT | 0.000-0.1–0.1 | Radial scale for Green channel. Typically 0 (reference channel). |
| shift_b | FLOAT | -0.005-0.1–0.1 | Radial scale for Blue channel. Negative = pulled inward. |
| center_x | FLOAT | 0.500–1 | Horizontal center of the distortion/effect (0.0 = left, 1.0 = right). |
| center_y | FLOAT | 0.500–1 | Vertical center of the effect (0.0 = top, 1.0 = bottom). |
| invert | BOOLEAN | false | Invert shift for CA removal / undistortion pass. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |