Video Chromatic Aberration
Animated chromatic aberration
- images
- IMAGE
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.5sway - 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
evalwithsin,cos,tan,pi,abs,pow,t, andintensityavailable. 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.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| red_offset_x | FLOAT | 5.0-50–50 | — |
| red_offset_y | FLOAT | 0.0-50–50 | — |
| blue_offset_x | FLOAT | -5.0-50–50 | — |
| blue_offset_y | FLOAT | 0.0-50–50 | — |
| animation_preset | COMBO | 7 options: none, custom, pulse, broken_lighting, wave, random_jitter, +1 | |
| custom_expression | STRING | sin(t * 2 * pi) * intensity | — |
| animation_speed | FLOAT | 1.00.1–10 | — |
| effect_intensity | FLOAT | 1.00–5 | — |
| chromatic_blur | FLOAT | 0.00–10 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |