RGB Curve
RGB Curve for washed-out renders
- image
- image
Every AI render has that one failure mode: technically correct, totally flat. Even lighting, muddy shadows, no depth - the "generated image" look that photorealism threads keep blaming on models when half the time it's just missing a grade. This node is the fastest fix: it applies an S-curve to all three RGB channels at once, and with two sliders you've got contrast that pops. It's the lean sibling of the same pack's Bleach Bypass - no desaturation, no overlay, no film drama. Just punch.
That's why you'd grab it. Where Bleach Bypass is the cinematic statement piece, RGB Curve is the utility you reach for when the image is almost there but needs life. Drop it between the VAE decode and Save Image, push slope up until highlights and shadows separate, and your flat render suddenly has dimension. If you're about to upscale, running this first gives the upscaler a cleaner tonal range to work with.
How it works
Under the hood it's one function: a normalized tanh S-curve applied to every channel simultaneously. That's tanh(slope * (x - offset)), normalized so black stays black and white stays white. Steeper slope = more contrast; the offset moves where the curve pivots. There's no clever channel-splitting or luminance magic - the same curve hits R, G, and B together, which is exactly what you want when you're after contrast and not a color cast.
The node draws a live SVG preview of that curve on the node itself, redrawing as you drag the sliders. It's the pack's quiet killer feature: you watch the S bend in real time instead of guessing at numbers.
The inputs that matter
Just three, and you'll mostly touch one:
- image - any IMAGE tensor from a VAE decode or another node.
- slope (default 4, range 1–50) - the steepness. Tooltip says 2–10 for good results, and that's accurate; past ~10 you're turning your photo into a poster.
- shadow_offset (default 0.5, range 0–1) - the pivot point. Above 0.5 pushes shadows darker (more presence), below 0.5 lifts them toward the lights. Start at 0.5 and only move it if highlights or shadows are clipping.
Output is a single image, so it feeds a Save Image, a preview, or another processing node. Batch isn't a thing here - it processes one image at a time.
Installing it
Same as its big sibling, it's in the same pack. ComfyUI Manager → search "M3D" → install M3D photo effects. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/metal3d/ComfyUI_M3D_photo_effects
Restart and it's there. No pip install needed - the pack only uses numpy and Pillow, both of which ComfyUI already has. No models, no checkpoints, no downloads. In a custom node ecosystem where dependency hell is the #1 complaint, a pack with zero extra requirements is genuinely refreshing.
Gotchas
The usual caveats from this pack apply: the author develops on Linux and says Windows/macOS are untested-but-should-work, and the node only handles a single image (feeding it a batched tensor crashes, since the code squeezes the batch dimension). The curve preview is labeled experimental in the README and can draw imperfectly - it's a hint, not gospel.
One honest take: for pure contrast control, ComfyUI's core has no direct built-in, so this fills a real gap - but it's a one-trick node from a two-node hobby pack, not a full color-grading suite. If you want curves per channel or a proper color wheel, you'll outgrow it fast. If you want your flat renders to stop looking like renders, this is 30 seconds of work.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| slope | FLOAT | 4.01–50 | The slope of the S-curve. keep value from 2 to 10 to expect good results. |
| shadow_offset | FLOAT | 0.500–1 | The shadow offset of the image. keep value near 0.5. If >0.5 the shadows are more present, <0.5 the lights are more present. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |