CS Color Grade
Actual color correction inside ComfyUI, not another img2img guess
- image
- mask
- IMAGE
CS Color Grade is the node to reach for when your AI video comes out technically correct and completely flat. It's a full grade - white balance, exposure, contrast, saturation, per-channel curves, plus external LUT support - applied to image or video frame batches, with an interactive preview window so you can actually see what you're doing. If you've been "fixing colors" by rerunning the sampler with a different prompt, stop. This is the deterministic, millisecond version of that job, and it's why the node exists.
It's a port of After Effects' AFX Grade effect, and it shows. The grade pipeline is the classic chain: white balance, offset/multiply/gamma, brightness, contrast, Rec.709-weighted saturation, per-channel RGB adjustments, PCHIP curves, then an optional external .cube LUT on top with its own strength control. The white point is a #RRGGBB hex string that gets converted to linear Rec.709 and normalized by channel mean - so pointing it at a neutral gray in your footage actually fixes the cast rather than just tinting things warmer or cooler. Color Temperature and Tint are the two sliders you'll adjust most, with Offset/Multiply/Gamma as the exposure core.
The inputs that matter
You don't need every input to get value. The short list:
- image - a standard IMAGE, single frame or a whole video batch (RGBA input just ignores the alpha channel).
- mask - optional. Black keeps the source, white applies the full grade, and gray values blend linearly. That's how you grade only the sky or only a face.
- Load LUT / LUT Strength - pick a
.cubefile fromComfyUI/models/luts(chooseNoneto skip), then blend it in 0–1. Most of the "cinematic look" people buy LUT packs for lives here. - White Point, Color Temperature, Tint - the white balance trio.
The rest - the RGB arrays, the curves JSON - are advanced fields you usually won't touch directly. You'll edit those in the preview window instead.
The Grade Preview window is the real UI
The node opens a front-end window that's honestly nicer than what most desktop NLEs give you. Left/right Result-versus-Original comparison with a draggable divider, a timeline to scrub frames, 50/100/200% zoom, a color picker for the white point, and a curve editor with RGB/R/G/B channels. You tweak, it re-renders just the current frame, and Apply to Node writes the whole parameter set back. That workflow - preview on one frame, apply, run the batch - is the entire point, and it's the reason you'd pick this over hand-typing values.
Install and gotchas
ComfyUI Manager, search "ComfyUI_CineStyle", install - or cd ComfyUI/custom_nodes && git clone https://github.com/chflame163/ComfyUI_CineStyle and restart. The nodes live under 😺dzNodes/CineStyle. One thing to know up front: this pack is written against ComfyUI's newer backend node API (the "V3 schema" - zero NODE_CLASS_MAPPINGS anywhere), so it needs a reasonably recent ComfyUI. Nodes missing from the menu after install? Update ComfyUI first.
Where people get burned:
- Drop a
.cubeintomodels/lutsand it doesn't appear in the dropdown. The list is scanned when the node loads - refresh the node list or restart ComfyUI. - The fancy preview says "no source." If your image comes from a node that generates at runtime (not a loader), run the workflow once first so it builds a preview cache, then open Grade Preview. This is a recurring pattern across the whole CineStyle pack.
- The auto-preview is only guaranteed when the video comes from the pack's own
CS Load Video.
It's new - the whole pack is a few weeks old as of writing, so expect the occasional rough edge. But the core grade is solid torch math, runs fast on a frame batch, and needs no model downloads at all. For the color pass on your video, this is the one I'd reach for.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Standard ComfyUI IMAGE. RGBA inputs ignore the fourth channel. | |
| lut | COMBO | None | Optional .cube LUT from ComfyUI/models/luts; applied after the built-in curves. |
| white_point | STRING | #FFFFFF | sRGB HEX white point converted to linear Rec.709 and normalized by channel mean. |
| color_temperature | FLOAT | 0.000-1–1 | — |
| tint | FLOAT | 0.000-1–1 | — |
| offset | FLOAT | 0.000-1–1 | — |
| multiply | FLOAT | 1.0000–2 | — |
| gamma | FLOAT | 1.0000.000001–10 | — |
| brightness | FLOAT | 0.000-1–1 | — |
| contrast | FLOAT | 0.000-1–1 | — |
| saturation | FLOAT | 1.0000–10 | — |
| rgb_offset | STRING | [0.0,0.0,0.0] | — |
| rgb_multiply | STRING | [1.0,1.0,1.0] | — |
| rgb_gamma | STRING | [1.0,1.0,1.0] | — |
| curves | STRING | {"version":1,"domain":[0.0,1.0],"rgb":[[0.0,0.0],[1.0,1.0]],"r":[[0.0,0.0],[1.0,1.0]],"g":[[0.0,0.0],[1.0,1.0]],"b":[[0.0,0.0],[1.0,1.0]]} | Versioned JSON control points for RGB, R, G, and B PCHIP curves. |
| lut_strength | FLOAT | 1.0000–1 | Blend between the image before the external LUT (0) and the full LUT result (1). |
| maskopt | MASK | Optional effect mask; black keeps the source and white applies the grade. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |