Color Grade
Grade a video in PIXELS — lift/gamma/gain, split toning, filmic highlight rolloff, saturation and temperature — via an ffmpeg pass in the youtube-clipper Lambda. This is the UPSTREAM grade: grade the master once and every consumer downstream (matte, slices, the video editor) inherits it, instead of grading one layer inside a composition. Pick a `preset` (the SAME preset ids the sceneGraph color_grade effect uses) and/or set any parameter explicitly; explicit parameters always beat the preset. ⚠️ THIS IS A FULL RE-ENCODE of the video stream (x264, default CRF 18, near-visually-lossless; lower `crf` for less generation loss, higher for a smaller file). Colour metadata is carried across from the source. AUDIO IS STREAM-COPIED, byte-identical to the input. Input is capped by ENCODING COST, not length alone: cost scales with pixels/second, so roughly 180s of 1080p30, ~58s of 4K30 or ~29s of 4K60, with 180 seconds a hard ceiling regardless. The node prices the real file and refuses with the numbers rather than timing out. HDR (PQ/HLG) sources are refused rather than mislabelled as bt709. Calls a Lambda whose cost is operational and absorbed: this node quotes and charges 0 credits.
Color Grade
Node type: utility:color_grade
Category: Editing
Description
Grade a video in PIXELS — lift/gamma/gain, split toning, filmic highlight rolloff, saturation and temperature — via an ffmpeg pass in the youtube-clipper Lambda. This is the UPSTREAM grade: grade the master once and every consumer downstream (matte, slices, the video editor) inherits it, instead of grading one layer inside a composition. Pick a preset (the SAME preset ids the sceneGraph color_grade effect uses) and/or set any parameter explicitly; explicit parameters always beat the preset. ⚠️ THIS IS A FULL RE-ENCODE of the video stream (x264, default CRF 18, near-visually-lossless; lower crf for less generation loss, higher for a smaller file). Colour metadata is carried across from the source. AUDIO IS STREAM-COPIED, byte-identical to the input. Input is capped by ENCODING COST, not length alone: cost scales with pixels/second, so roughly 180s of 1080p30, ~58s of 4K30 or ~29s of 4K60, with 180 seconds a hard ceiling regardless. The node prices the real file and refuses with the numbers rather than timing out. HDR (PQ/HLG) sources are refused rather than mislabelled as bt709. Calls a Lambda whose cost is operational and absorbed: this node quotes and charges 0 credits.
Canvas ports
These appear as port handles on the left side of the node.
| ID | Label | Details |
|---|---|---|
video |
Video | VIDEO (required) |
Sidebar config
These render as form fields in the right-side config panel when the node is selected.
| ID | Label | Details |
|---|---|---|
preset |
Preset | TEXT · options: none, warm_film, teal_orange, clean_commercial, moody, +3 |
crf |
Quality (CRF, 12 best … 30 smallest; blank = 18) | NUMBER |
gain |
Gain | NUMBER |
gamma |
Gamma | NUMBER |
highlightTint |
Highlight Tint | NUMBER |
lift |
Lift | NUMBER |
rolloff |
Rolloff | NUMBER |
saturation |
Saturation | NUMBER |
shadowTint |
Shadow Tint | NUMBER |
temperature |
Temperature | NUMBER |
Outputs
| ID | Label | Type |
|---|---|---|
video |
Graded Video | VIDEO |
What it is for
This is the upstream grade. The other grading surface in Wireflow is the
sceneGraph color_grade effect, which grades one layer inside one
composition on the GPU export path, so a cutout composited over a graded
scene comes out ungraded, and nothing downstream of the composition inherits
the look. Put a Color Grade node on the master instead and every consumer
(matte pass, splitter slices, the video editor) sees the graded pixels.
Preset, parameters, or both
Pick a preset for a named look, then override any dial you want. Explicit parameters always beat the preset's value, and anything you leave blank keeps the preset's. That is the same precedence the sceneGraph effect uses, and the preset ids are literally the same list. One grading vocabulary, two renderers.
Leave the preset on none and set parameters yourself for a fully manual
grade. A node with nothing set at all is refused rather than run: re-encoding
a master to change nothing costs a generation of quality and reads on the
canvas as if the grade did something.
The eight dials
| dial | what it does |
|---|---|
| Lift | shadow offset (negative crushes blacks, positive fades them) |
| Gamma | midtone curve (below 1 brightens mids, above 1 darkens) |
| Gain | highlight multiplier |
| Saturation | 0 is greyscale, 1 unchanged, 2 vivid |
| Temperature | negative cools, positive warms |
| Shadow Tint | split tone in the shadows (negative teal, positive warm) |
| Highlight Tint | split tone in the highlights |
| Rolloff | filmic highlight shoulder (0 hard clip, 1 full soft shoulder) |
How faithful is it to the GPU grade
Lift, gamma, gain and temperature use the shader's exact formulas. Three do not, and the divergence is documented rather than hidden:
- Rolloff shoulders each channel independently here, where the shader shoulders the luma and keeps hue. Identical on neutrals, slightly more desaturation on a saturated highlight.
- Split toning matches the shader's direction and strength but the falloff across the mids follows ffmpeg's shadow/highlight weighting rather than the shader's smoothstep masks.
- Saturation scales chroma in YUV rather than mixing toward Rec.709 luma in RGB. Equivalent in gamut, different where a channel would clip. It also runs last here, after the temperature trim rather than before it, which halves the colour-space conversions per frame; the temperature cast ends up scaled by saturation instead of sitting on top of it.
Plus: this is an 8-bit pass, so an extreme grade can band where the float shader would not.
This is a re-encode, and what that costs
Grading pixels means decoding every frame, changing it, and encoding it again. The output is a new x264 file, not a copy of yours. At the default CRF 18 that is near-visually-lossless and you will not see the difference, but it is one generation of loss, so grading the same master four times in a row is not free. Lower the CRF (12 is the floor) if the master is going on to more processing; raise it (30 is the ceiling) if you want a smaller file and can live with softer detail.
Colour tags travel with it. The node reads the source's primaries, transfer and matrix and stamps the same ones on the output, falling back to bt709 when the source declares nothing, so a graded master does not suddenly play back differently depending on the player.
Size limit, and why it is not just a length
Encoding cost scales with pixels per second, not with running time, so a 4K clip is four times the work of a 1080p clip of the same length. The node prices your actual file (resolution, frame rate, duration) before it starts and refuses anything it cannot finish, telling you the numbers and the limit for that shape. Roughly:
| source | accepted length |
|---|---|
| 1080p30 | ~180s (the hard cap) |
| 1440p30 | ~132s |
| 4K30 | ~58s |
| 4K60 | ~29s |
180 seconds is a hard ceiling on top of that regardless of resolution. For anything longer: cut it with a Media Splitter, grade the segments, then Video Concat them back.
HDR is refused, not guessed at
An HDR master (PQ or HLG) is declined with a message saying so. Running an SDR lift/gamma/gain curve over HDR and tagging the result bt709 would produce a wrong picture carrying a correct-looking label, which is worse than a refusal because nothing downstream could detect it. Tone mapping is not in scope yet. Convert to SDR first, then grade.
Audio
Stream-copied. The soundtrack of a graded master is byte-identical to the input. A grade touches pixels only.
Auto-generated from the Wireflow node registry.