Color Balance
Slope/offset/power grading without the color cast
- image
- mask
- image
- mask
- color_balance_info
Most "color balance" sliders are a blunt additive tint. x1ColorBalance is built on the slope/offset/power model - the same math behind ASC CDL grades - which is how colorists move a look without wrecking the whites. It sits in MKRShift Nodes' Color/Grade branch alongside the pack's color wheels and mesh warp nodes, and it's the deterministic, maskable workhorse of that section.
The pack is young (zero impressions, no community chatter I could find), so the honest framing is: fresh, clean, unproven-by-crowd code. But the grading nodes share one genuinely nice design decision - every settings_json widget gets a frontend panel, so you're dragging sliders, not typing JSON.
How it works
The pipeline, straight from the source: multiply by per-channel slope (scales the signal), add per-channel offset (shifts blacks), raise to per-channel power (the gamma-like curve), then apply saturation and blend by mix. The power step is the reason this feels like a grade instead of a tint - it reshapes the tone response per channel without moving the black point the way an additive tint does. That's the additive-vs-power distinction worth internalizing if you've been reaching for brightness offsets.
Two switches matter beyond the triplets:
preserve_luma- rescales the result so the output luminance matches the input. This is the "don't wreck my exposure while I fix the cast" button, and it's on by default for good reason.- The optional
mask+mask_feather- grade only part of the frame, like an HSL qualifier without the selection UI.
Outputs: image, mask (the grade matte, not your input mask), color_balance_info (resolved settings).
Inputs that matter
slope_r/g/b- the first knob to reach for; slight channel imbalance here is a warm/cool cast fixpower_r/g/b- the curve control; this is where contrast-y per-channel shaping happensoffset_r/g/b- shifts shadows; go easy, it lifts blacks fastsaturationandmix- global seasoning and the safety valve
Installing
ComfyUI Manager → search MKRShift Nodes, or:
cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes
Restart ComfyUI. No models, no new dependencies.
Where people get burned
- Offsets on clipped highlights. Offset is additive, so it pushes brights toward the clip hard. Fix a cast with slope first; use offset for shadow work.
preserve_lumaoff when you don't want it. If your grade keeps changing overall exposure in ways you didn't ask for, it's usually this toggle.- The
maskoutput is the grade matte, not the input mask. Same pack-wide trap. - A corrupted
settings_jsonfalls back to defaults silently - if the whole look resets, that's the smell.
It's the "fix the cast without the wash" node - a one-node CDL-style grade that stays reproducible and plays nice with the rest of the pack's Color branch.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| settings_json | STRING | {"slope_r":1.0,"slope_g":1.0,"slope_b":1.0,"offset_r":0.0,"offset_g":0.0,"offset_b":0.0,"power_r":1.0,"power_g":1.0,"power_b":1.0,"saturation":1.0,"mix":1.0,"preserve_luma":true,"mask_feather":12.0,"invert_mask":false} | — |
| maskopt | MASK | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| color_balance_info | STRING | — |