AfterDark Live Grade
Stop re-running the queue to see your grade — this node previews it at 60 FPS
- image
- image
Color grading in ComfyUI is usually a loop: nudge a slider, hit queue, stare at the temp directory, repeat. AfterDark Live Grade (class HackAfterDarkLiveGrade) breaks that loop. It grades the image in your browser in real time - drag exposure, saturation, split-toning, whatever, and the preview updates instantly - then reproduces the exact same math on the GPU when you actually run the workflow. It's one of the few ComfyUI nodes where "interactive" isn't marketing.
That matters because grading is the cheapest realism upgrade you can make. The KB's post-processing essay says it plainly: almost none of this is AI, and the whole layer exists so you reach for a deterministic, millisecond GPU pass instead of re-rolling a generation or exporting to Photoshop to fix flat colors. Live Grade bundles that pass into one node with a full film-grade control suite - exposure in EV stops, contrast, film-toe black lift, hue and saturation, split toning, and two kinds of local contrast - plus optional .cube LUT support. It's the star of the HackAfterDark "AfterDark" pack, which ships its film-grain, halation, optics, and LUT siblings for building a full analog-film look around it.
How the live preview works
The clever bit: on your first queue run (with output_original on, which is the default), the node saves a full-resolution copy of the incoming image to ComfyUI's temp folder and hands the filename to the frontend. The live_grade.js client then does all the slider work in the browser - offscreen canvas rendering, a side-by-side Dual View, a draggable split-wipe, and a full-screen lightbox with zoom. Drag a slider and the preview updates without touching the queue. The backend runs the same pipeline in order: LUT (3D trilinear interpolation via grid_sample, blended by lut_strength), exposure (multiply by 2^EV), contrast, black_lift toe, HSV hue/saturation, green/magenta + amber/blue tints, luminance-weighted split toning, then micro-contrast and clarity.
The inputs that actually matter
There are a lot of them, but a beginner lives on three, then graduates:
exposure(−3 to +3 EV) - your first move. Real exposure, not a washed-out brightness add.contrast(0.5–1.5) andsaturation(0–2) - the obvious next stops.black_lift- lifts blacks like film toe, faking shadow density that flattens the "AI default" look.
From there: shadow_tint / highlight_tint dropdowns (Teal/Cyan shadows, Golden Amber highlights - the teal-and-orange move) with matching intensity sliders, balance to shift where the split sits, and micro_contrast vs clarity. That last pair trips people up: micro-contrast is a 3×3 high-pass for pin-sharp texture, clarity is a 9×9 midtone-only pass for face/contour pop - the README explains it better than most paid apps.
lut_file scans ComfyUI/models/luts/ for .cube and .3dl files (default "None"), with lut_strength to blend. Output is a single image - wire it onward or let it act as your output node.
Installing it
ComfyUI Manager, search "HackAfterDark", install, restart. Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/hackafterdark/ComfyUI-HackAfterDark-Nodes
# restart ComfyUI
The pack's requirements.txt pulls google-generativeai too (for the Gemini Prompter sibling), so portable installs that skip Manager's dependency step may need a manual pip install -r requirements.txt before the node loads.
Gotchas
- LUTs only show what's on disk. Drop a
.cubeintoComfyUI/models/luts/, restart or refresh. The source also scans the node's ownluts/folder and even a hardcoded Windows path - harmless elsewhere. output_originalwrites a temp PNG every run so the frontend has its preview. If you're running unattended batches and never open the interactive view, switch it off to skip the disk writes.- It wants 3-channel RGB. Feed it an RGBA image and it raises "Live Grade requires a 3-channel RGB image." Strip the alpha first.
Honest caveat: it's a young node with zero community track record yet (its reddit footprint is a few noise mentions), so treat the client preview's first run as the sanity check. But as a way to actually see your grade before committing a queue run, nothing in the pack comes close.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| lut_file | COMBO | 1 options: None | |
| lut_strength | FLOAT | 1.000–1 | — |
| exposure | FLOAT | 0.00-3–3 | — |
| contrast | FLOAT | 1.000.5–1.5 | — |
| black_lift | FLOAT | 0.000-0.5–0.5 | — |
| hue | FLOAT | 0-180–180 | — |
| saturation | FLOAT | 1.000–2 | — |
| tint_green_magenta | FLOAT | 0.00-1–1 | — |
| tint_amber_blue | FLOAT | 0.00-1–1 | — |
| shadow_tint | COMBO | Neutral | 5 options: Neutral, Teal / Cyan, Deep Blue, Emerald Green, Warm Sepia |
| shadow_intensity | FLOAT | 0.000–1 | — |
| highlight_tint | COMBO | Neutral | 5 options: Neutral, Golden Amber, Warm Yellow, Peach Rose, Cool Cyan |
| highlight_intensity | FLOAT | 0.000–1 | — |
| balance | FLOAT | 0.00-1–1 | — |
| micro_contrast | FLOAT | 0.000–1 | — |
| clarity | FLOAT | 0.000–1 | — |
| clip_output | BOOLEAN | true | — |
| output_original | BOOLEAN | true | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |