LUT Export (.cube)
Turn any Darkroom grade into a .cube and use it in Resolve, Premiere, or Photoshop
- processed_lattice
- file_path
LUT Export (.cube) is the payoff node for the whole Darkroom bake pipeline. You grade a photo, bake the grade into a .cube file, and that file becomes a reusable look you can load in DaVinci Resolve, Premiere Pro, Photoshop, Capture One, or Final Cut. One grade, applied to an entire video edit or a whole batch of photos, without ComfyUI in the loop. That's the entire point: you get your film emulation out of the node graph and into your actual working tools.
The thing most people miss is that this node doesn't do the grading. It just reads back a processed identity lattice - the grid image that came out the other side of your color chain - and writes it out as a standard .cube. The grading itself happens upstream, between LUT Bake Inject and LUT Bake Extract. If you're doing the manual version, you run LUT Identity Generator → Inject → your color nodes → Extract → this node, and both your graded photo and the LUT come out of the same run with the same settings.
How it works
A 3D LUT is just a lookup table: for every (R, G, B) input combination it stores the output color. The identity lattice encodes every one of those combinations as a grid image (size pixels wide, size × size tall, arranged R-fastest like .cube ordering). Darkroom's color nodes process images pixel-by-pixel, so they transform the lattice exactly like they transform your photo. Export reads the lattice back, reshapes it into a (size, size, size, 3) table, and writes the .cube header with your title embedded.
Because a LUT has no idea about neighboring pixels, only color-only nodes can live in the bake chain - Tone Curve, Film Stock, Print Stock, OkLab Color, Vibrance, the Hue vs X nodes, and friends. Anything spatial (grain, Sharpening Pro, Vignette, Sabattier) will corrupt the lattice. Apply those after Extract, on the photo only.
The inputs that matter
- processed_lattice (IMAGE) - wire this from LUT Bake Extract's
graded_latticeoutput. The node validates the dimensions and throws if they don't matchlut_size. - lut_size (INT, 2–129, default 33) - the tooltip says it plainly: must match the LUT Identity Generator size. Mismatch here is the single most common error, and it's a hard
ValueError, not a subtle one. 33 is the standard for DaVinci and friends; 65 is finer but slower to apply. - filename (STRING, default
darkroom_grade) - no extension needed; the node appends.cubeand replaces spaces with underscores. - title (optional) - embedded in the file metadata so you can tell LUTs apart in Resolve's dropdown.
- output_directory (optional) - leave empty and the file lands in
ComfyUI/output/luts/.
The single output is file_path (STRING), so you can wire it into a text display or downstream tooling if you're automating.
Install & gotchas
It ships with the ComfyUI-Darkroom pack: Manager → search "Darkroom", or cd ComfyUI/custom_nodes && git clone https://github.com/jeremieLouvaert/ComfyUI-Darkroom && pip install -r ComfyUI-Darkroom/requirements.txt, then restart. No model downloads - everything is numpy/scipy plus the data bundled in the repo, so it runs on CPU just fine.
Grab the ready-made workflows/lut_bake_and_apply.json from the repo and drag it into ComfyUI - that's the fastest way to see the whole chain wired correctly. The common failure is putting a spatial node inside the bake chain; the output will look fine on the photo and produce garbage in the .cube, so check the LUT, not just the preview.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| processed_lattice | IMAGE | — | |
| lut_size | INT | 332–129 | Must match the LUT Identity Generator size |
| filename | STRING | darkroom_grade | Output filename (without .cube extension) |
| titleopt | STRING | Darkroom Grade | Title embedded in the .cube file metadata |
| output_directoryopt | STRING | Output directory. Leave empty for ComfyUI output/luts/ |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| file_path | STRING | — |