ComfyUI Node

Tone Curve

Tone Curve — the 5-point spline that does the heavy lifting in every grade

By jeremieLouvaert·Created 5 months ago·Updated 2 days ago· 101
Tone Curve
  • image
  • image
presetCustom (manual)
shadows0
darks0
midtones0
lights0
highlights0
red_shadows0
red_highlights0
green_shadows0
green_highlights0
blue_shadows0
blue_highlights0
strength1.00

Tone Curve is the workhorse of the whole Darkroom grading set - the node you'll put in nearly every workflow, even the ones built around Film Stock and Print Stock, because it's the fastest way to shape contrast and shadow character after the film math has done its thing. It gives you a 5-point curve (black point, 25%, midtones, 75%, white point) per channel, plus 11 presets from the essential S-curve through Faded Blacks, Crushed Blacks, High Key, Matte Film, and the cross-over color pushes.

Two implementation details make it worth trusting. First, the curve is built with scipy's PchipInterpolator - a monotonic cubic spline, which means no overshoot or wiggles between your points, so dragging a shadow point won't produce weird midtone artifacts. Second, it runs in linear light with the standard Darkroom strength blend, so it plays nicely with every other node in the pack and bakes into a LUT cleanly.

How it works

You place up to five control points at fixed positions - shadows at 0% luminance, darks at 25%, midtones at 50%, lights at 75%, highlights at 100% - and the spline interpolates the whole curve between them. The master channel shapes overall tone; the per-channel shadow/highlight offsets let you push color into the extremes (raising red_shadows warms blacks; pushing blue_highlights cools whites - that's the cross-over look in miniature).

The inputs that matter

  • preset (12 choices, default Custom) - S-Curve Light/Medium/Strong for the classic contrast bump, Faded Blacks for the filmic lifted-black look, Crushed Blacks, High Key / Low Key, Cross-over Red/Blue Push, Linear Contrast, Matte Film. Start here, always.
  • shadows / darks / midtones / lights / highlights (±50, default 0) - the five master curve points. Negative pushes a point down (darker), positive raises it. Raising shadows is how you get faded blacks; lowering highlights tames clipped whites.
  • red/green/blue_shadows and red/green/blue_highlights (±50) - per-channel offsets at the dark and bright ends. One or two of these is usually all a grade needs for a believable cast.
  • strength (0–1) - blend between original and curved.

Output is image.

Install & notes

Pack install as usual: Manager → search "Darkroom", or git clone https://github.com/jeremieLouvaert/ComfyUI-Darkroom + pip install -r requirements.txt + restart. Scipy does the spline; CPU-only and instant.

The common misstep is treating the five points as independent - they aren't, they're a single spline, so moving midtones a lot will subtly move the 25% and 75% regions too. That's expected spline behavior, and it's why the monotonic Pchip choice matters: you'll never get a curve that loops back on itself. And remember the tooltip order - the points map to 0/25/50/75/100%, so darks is not "deep shadows," it's the quarter-tone region. Read them in order and the presets will teach you the mapping in one session.

CategoryAKURATE/Darkroom/Grading

Inputs (14)

NameTypeDefaultDescription
imageIMAGE
presetCOMBOCustom (manual)Select a tone curve preset or use Custom for manual control
shadowsoptFLOAT0-50–50Curve point at 0% luminance (black point)
darksoptFLOAT0-50–50Curve point at 25% luminance
midtonesoptFLOAT0-50–50Curve point at 50% luminance
lightsoptFLOAT0-50–50Curve point at 75% luminance
highlightsoptFLOAT0-50–50Curve point at 100% luminance (white point)
red_shadowsoptFLOAT0-50–50Red channel shadow offset
red_highlightsoptFLOAT0-50–50Red channel highlight offset
green_shadowsoptFLOAT0-50–50Green channel shadow offset
green_highlightsoptFLOAT0-50–50Green channel highlight offset
blue_shadowsoptFLOAT0-50–50Blue channel shadow offset
blue_highlightsoptFLOAT0-50–50Blue channel highlight offset
strengthoptFLOAT1.000–1Blend between original (0) and curved (1)

Outputs (1)

NameTypeDescription
imageIMAGE