Nodes/AM VFX Tools/AM Grade RGB
ComfyUI Node

AM Grade RGB

The same Nuke grade, one slider per channel

By am-pipeline-prod·Created 4 months ago·Updated 3 months ago· 3
AM Grade RGB
  • image
  • video
  • image
  • video
blackpoint_r0.000
blackpoint_g0.000
blackpoint_b0.000
whitepoint_r1.000
whitepoint_g1.000
whitepoint_b1.000
lift_r0.000
lift_g0.000
lift_b0.000
gain_r1.000
gain_g1.000
gain_b1.000
multiply_r1.000
multiply_g1.000
multiply_b1.000
offset_r0.000
offset_g0.000
offset_b0.000
gamma_r1.000
gamma_g1.000
gamma_b1.000
reversefalse
black_clamptrue
white_clampfalse

AM Grade RGB is AM Grade with the training wheels off. Same Nuke Grade math, same order of operations - but instead of one blackpoint, one gain, one gamma applied to all three channels, you get separate R, G, and B controls for every parameter. 24 float sliders plus the two clamps and the reverse toggle, and yes, it looks like a wall of widgets. That's not a design flaw; it's the point.

It ships in comfyui-am-vfx-tools ("AM VFX Tools/Color" category), Adrian Meyer's 13-node VFX toolkit. Both Grade nodes call the exact same grade_apply function in _core/grade.py - AM Grade broadcasts one value across the channels, AM Grade RGB feeds it a per-channel tensor. Mono vs. RGB is purely a UI decision.

When you actually need per-channel

You don't need it for "make the whole frame brighter" - that's AM Grade. You need it when the problem is in one channel:

  • Skin tones - the classic. Reds are too hot but you don't want to touch the rest of the frame.
  • Bad white balance - a magenta cast is really "too much blue channel / not enough green"; fix it per-channel instead of fighting it with saturation.
  • Matching a plate - if your generated footage sits next to real footage that was shot under different lighting, per-channel blackpoint/gain is how you match it.

The parameters mirror AM Grade exactly: blackpoint_r/g/b, whitepoint_r/g/b, lift_r/g/b, gain_r/g/b, multiply_r/g/b, offset_r/g/b, gamma_r/g/b, then reverse, black_clamp, white_clamp. The tooltip-less fields are self-explanatory once you've seen the mono version.

The mechanism, briefly

The math is identical to AM Grade, computed per channel:

A = multiply * (gain - lift) / (whitepoint - blackpoint)
B = offset + lift - A * blackpoint
out = sign(A*x + B) * pow(|A*x + B|, 1/gamma)

Sign-preserving pow so negative values don't produce NaN, black_clamp on by default (clips negatives to 0), white_clamp off by default (lets scene-linear highlights above 1.0 live). Pure torch, per-pixel, alpha-preserving.

Inputs: image and optional video (lazy per-frame, alpha untouched, image ignored when video is wired). Outputs: image (same shape/channels) and video.

Installing it

Same single install as the rest of the pack:

cd ComfyUI/custom_nodes
git clone https://github.com/am-pipeline-prod/comfyui-am-vfx-tools.git
cd comfyui-am-vfx-tools
pip install -r requirements.txt

Restart ComfyUI, or search comfyui-am-vfx-tools in ComfyUI Manager.

Where people get burned

Same scene-linear assumption as AM Grade - blackpoint/whitepoint of 0/1 expect linear float data, so feed it color-managed input. And a workflow-ergonomics warning: 24 sliders is a lot of state to save in a workflow JSON and a lot to bisect when something looks wrong. My honest advice: start with AM Grade, get the grade close, and only drop into AM Grade RGB when a single channel is actually misbehaving. If you're reaching for the RGB version to fix everything, you're probably solving the wrong problem - that's what white balance and a color match are for.

CategoryAM VFX Tools/Color

Inputs (26)

NameTypeDefaultDescription
blackpoint_rFLOAT0.000
blackpoint_gFLOAT0.000
blackpoint_bFLOAT0.000
whitepoint_rFLOAT1.000
whitepoint_gFLOAT1.000
whitepoint_bFLOAT1.000
lift_rFLOAT0.000
lift_gFLOAT0.000
lift_bFLOAT0.000
gain_rFLOAT1.000
gain_gFLOAT1.000
gain_bFLOAT1.000
multiply_rFLOAT1.000
multiply_gFLOAT1.000
multiply_bFLOAT1.000
offset_rFLOAT0.000
offset_gFLOAT0.000
offset_bFLOAT0.000
gamma_rFLOAT1.000
gamma_gFLOAT1.000
gamma_bFLOAT1.000
reverseBOOLEANfalse
black_clampBOOLEANtrue
white_clampBOOLEANfalse
imageoptIMAGEImage batch to grade.
videooptVIDEOOptional VIDEO input. When wired, returns a lazy `GradedVideo` wrapper applying the grade per-frame on consumption — no IMAGE materialisation here. Alpha (when present) passes through untouched. `image` is ignored when `video` is wired. See invariant 28.

Outputs (2)

NameTypeDescription
imageIMAGEGraded image batch (same shape and channels as the input).
videoVIDEOLazy VIDEO output — emits a `GradedVideo` wrapper when `video` is wired, else a zero-copy `VideoFromComponents` around the IMAGE batch. None when no input is wired.