Nodes/DJZ-Nodes/Video Chromatic Aberration
ComfyUI Node

Video Chromatic Aberration

Animated chromatic aberration

By MushroomFleet·Created 2 years ago·Updated 5 months ago· 78
Video Chromatic Aberration
  • images
  • IMAGE
red_offset_x5.0
red_offset_y0.0
blue_offset_x-5.0
blue_offset_y0.0
animation_preset
custom_expressionsin(t * 2 * pi) * intensity
animation_speed1.0
effect_intensity1.0
chromatic_blur0.0

Chromatic aberration - the red/blue fringe where a lens fails to focus all colors to the same point - is a cheap, beloved way to make an image look imperfect. Video Chromatic Aberration takes that trick and adds what most RGB-split nodes lack: motion. A menu of animation presets (pulse, wave, strobe, broken_lighting, random_jitter) modulates the split over time, so the aberration doesn't just sit there - it breathes, shivers, and strobes across your video.

How it works

The static part is standard: the red channel is shifted by red_offset_x/red_offset_y, the blue channel by blue_offset_x/blue_offset_y (each ±50, defaults +5 / −5 on X). chromatic_blur (0–10) can blur the shifted channels for a softer, more lens-like fringe instead of a hard offset.

The animated part is the differentiator. Each frame computes a multiplier from your chosen animation_preset, driven by t = (frame / total_frames) * speed * 2π:

  • pulse - |sin(t)|-style breathing
  • wave - a gentler 1 + sin(t)*0.5 sway
  • strobe - hard on/off at a low value (the "broken neon" look)
  • broken_lighting - random flicker layered over a sine
  • random_jitter - per-frame random wobble
  • custom - evaluates your own expression via a safe eval with sin, cos, tan, pi, abs, pow, t, and intensity available. The default, sin(t * 2 * pi) * intensity, is a good template.

animation_speed (0.1–10) scales how fast the pattern moves, and effect_intensity (0–5) scales the whole multiplier. The offset values set the amount of split; the preset decides how that amount varies frame to frame.

Inputs and outputs

Required: images, red_offset_x/y, blue_offset_x/y, animation_preset (the seven-way menu), custom_expression, animation_speed, effect_intensity, chromatic_blur. Output: IMAGE, batch-safe.

The custom_expression input is always there, but it only matters in custom mode - the other presets ignore it.

Where it sits in a workflow

This is a video-first node; on a still it's just a static RGB split, and you can get that anywhere. The magic is dropping it on a clip and letting wave or pulse sell the "cheap lens / glitching playback" illusion. It pairs naturally with the rest of DJZ's retro stack - VGA Effect, film damage, the datamosh suite - and it's a solid go-to when a clip needs some texture and you don't want to overthink it.

Install

Part of DJZ-Nodes by Drift Johnson. ComfyUI Manager → "DJZ-Nodes", or:

cd ComfyUI/custom_nodes
git clone https://github.com/MushroomFleet/DJZ-Nodes
cd DJZ-Nodes
pip install -r requirements.txt

Restart ComfyUI. numpy/torch/cv2 - already in ComfyUI.

Gotchas

Random presets (random_jitter, broken_lighting) are genuinely random per frame - no seed control - so runs aren't reproducible and adjacent runs differ. For a precise animation, use pulse/wave/strobe or write your own expression in custom mode. And remember: if an expression errors, the node silently falls back to a multiplier of 1.0 rather than telling you - so test custom expressions before you rely on them.

Categoryimage/effects

Inputs (10)

NameTypeDefaultDescription
imagesIMAGE
red_offset_xFLOAT5.0-50–50
red_offset_yFLOAT0.0-50–50
blue_offset_xFLOAT-5.0-50–50
blue_offset_yFLOAT0.0-50–50
animation_presetCOMBO7 options: none, custom, pulse, broken_lighting, wave, random_jitter, +1
custom_expressionSTRINGsin(t * 2 * pi) * intensity
animation_speedFLOAT1.00.1–10
effect_intensityFLOAT1.00–5
chromatic_blurFLOAT0.00–10

Outputs (1)

NameTypeDescription
IMAGEIMAGE