Nodes/ComfyUI-VideoColorGrading/Apply 3D LUT (VCG)
ComfyUI Node

Apply 3D LUT (VCG)

Apply a baked color grade to any footage, instantly

By kijai·Created 5 months ago·Updated 5 months ago· 63
Apply 3D LUT (VCG)
  • images
  • lut
  • original_images
  • IMAGE
strength1.00

This is the node where all the work you did earlier finally pays off. Apply 3D LUT (VCG) takes the 16³ color LUT that VCGGenerateLUT baked for you and slaps it onto your frames - and because it's just an interpolation of a lookup table, it's effectively free. No diffusion, no model in VRAM, no waiting. You generate the LUT once, then apply it to every frame of your video in the time it takes to blink.

What it's for

In the VideoColorGrading pipeline the expensive part is making the LUT. Applying it is the cheap part, and that's the whole point of the approach: you get one reference image with the look you want, run the two-stage diffusion once, and then every frame gets graded consistently with the same LUT. If you've ever fought a per-frame color match drifting across a clip, you already know why that's valuable.

The node lives at the end of the workflow, right before your video encoder. It pairs with the VCGGenerateLUT node (which produces the lut), and it does exactly what the name says - no more, no less. The main thing to know up front: a 3D LUT is resolution-independent, so the LUT you baked at the generator's internal 512×512 works on footage of any size.

How it works

A 16³ LUT is a lookup table with 4096 entries - a coarse 3D grid of RGB values. To grade a pixel you find the cell it falls in and interpolate. Under the hood VCGApplyLUT does this with a grid_sample pass over the LUT volume, so applying it is just arithmetic over tensors. That's why it's near-instant even on long clips, and why you don't need the model checkpoint loaded at this stage.

The inputs that matter

  • images - your frames. Wire up preprocessed_frames from VCGGenerateLUT here, not your raw source; that's the intended chain (the generator's tooltip literally says "apply LUT to these").
  • lut - the VCG_LUT output of VCGGenerateLUT. Nothing else produces this type, so if you can't connect it, you're missing the generator.
  • strength (float, default 1, range 0–2) - the one dial worth touching. 0 is the original image, 1 is full effect, above 1 is exaggerated. At values below 1 the node blends back toward the original pixels, which is a nice way to tame a grade that's too aggressive without regenerating anything.
  • original_images (optional) - original source frames to blend toward at lower strength. If you leave it empty, low-strength blends toward whatever you passed into images instead.

The output

One IMAGE output, same resolution and batch size as the input. Feed it straight into a VHS_VideoCombine (or any video encoder) and you're done. The pack's example workflow wires exactly that: LoadImage → VCGGenerateLUTVCGApplyLUT → Video Combine.

Install

Install the pack once - it's the same for all three nodes in it:

  • Via ComfyUI Manager: search for "VideoColorGrading" and install.
  • Or manually: cd ComfyUI/custom_nodes && git clone https://github.com/kijai/ComfyUI-VideoColorGrading, then restart ComfyUI.

There's no requirements.txt - the pack only uses what ComfyUI already ships (torch, numpy, Pillow), so no dependency hell here. It does use ComfyUI's newer node API, so keep ComfyUI reasonably up to date. The checkpoint (a ~4.1GB vcg_combined_fp16.safetensors from HuggingFace) goes in ComfyUI/models/checkpoints - you need it for the loader and generator, though notably not for this node.

Gotchas

Because the lut input is a custom VCG_LUT type, you can't feed it an arbitrary LUT from somewhere else - it has to come out of VCGGenerateLUT. And remember the strength math: it blends against the pixels you gave it, so if you want to dial down toward your original footage, pass original_images, not a graded intermediate.

Categoryvideo/color-grading

Inputs (4)

NameTypeDefaultDescription
imagesIMAGE
lutVCG_LUT
strengthoptFLOAT1.000–2LUT strength: 0=original images, 1=full effect, >1=exaggerated
original_imagesoptIMAGEOriginal source frames to blend towards at lower strength

Outputs (1)

NameTypeDescription
IMAGEIMAGE