xLUT Output
Turn an In-Memory LUT Into a Real .cube File
- lut
- lut_image
- lut
- saved_path
- save_info
Here's the workflow gap xLUTOutput exists to close: xLUT can cook up a gorgeous grade in memory, and then... what? ComfyUI forgets it when the queue empties. xLUTOutput is the save button for that look - it takes a LUT payload and writes it to disk as a standard .cube file you can reuse tomorrow, hand to a teammate, or pull into Resolve and Premiere. It's the partner node to xLUT in the MKRShift Nodes pack, and honestly, it's the one you want on the end of any LUT workflow you plan to keep.
How it works
xLUTOutput accepts the lut output from xLUT (the MKR_LUT payload) and serializes it to a .cube file with proper TITLE, LUT_3D_SIZE, and DOMAIN_MIN/DOMAIN_MAX headers - the same format Resolve and DaVinci read. If no LUT payload is connected, it can generate one on the fly from a lut_image, using the same image-to-LUT machinery as xLUT itself.
It's declared an output node, and its IS_CHANGED always returns "changed," so it runs on every queue even when its inputs haven't changed. That's deliberate: save nodes that get skipped by ComfyUI's caching are how you lose renders to thin air. xLUTOutput refuses to be silently skipped.
The inputs that matter
Most of these are set-and-forget, but a few matter:
save_name- the filename stem. Defaults tomkrshift_lut.subfolder- defaults togenerated. The file lands inside the pack'sluts/folder, which is exactly the folderxLUT's dropdown scans. Save it here and your new LUT shows up in the picker immediately. Nice round-trip.overwrite- off by default, and here's the trap: with it off, a name collision quietly becomesname_2.cube, thenname_3.cube. If you're iterating on a look and the files keep piling up, flip this on.save_preview/preview_size- writes a PNG next to the.cubeshowing the LUT's color table on the left and the reference image (or a test chart) on the right. Cheap and worth keeping on, because a LUT on disk with no preview is impossible to tell apart from the other forty you generated.generated_lut_size/generated_style_strength- only used when you feed alut_imageinstead of a LUT payload.
Wire it the fast way: xLUT's lut output straight into xLUTOutput's lut input.
What comes out
lut- the sameMKR_LUTpayload, passed through so you can keep chaining.saved_path- the absolute path to the file that got written. Grab this if you want to show it somewhere.save_info- a status string with the full story, including where the preview went.
Installing it
Same pack as xLUT: ComfyUI Manager → search "MKRShift Nodes", or:
cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes
Restart, and you'll find it under MKRShift Nodes → Color → LUT. No extra dependencies, no models to fetch.
Common issues
If save_info complains about "No LUT input connected," you've wired neither lut nor lut_image - connect one and re-run. The overwrite name-collision behavior above catches people constantly, so if your saved_path ends in _2 and you didn't expect it, that's why. And if the LUT won't load in an external tool, double-check you actually saved from a real payload rather than generating from a lut_image at a tiny generated_lut_size - a 4³ cube is technically valid and practically useless in Resolve. Keep 33 as your default and you'll be fine.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| save_name | STRING | mkrshift_lut | — |
| subfolder | STRING | generated | — |
| overwrite | BOOLEAN | false | — |
| save_preview | BOOLEAN | true | — |
| preview_size | INT | 448128–2048 | — |
| generated_lut_size | INT | 334–64 | — |
| generated_style_strength | FLOAT | 1.000–2 | — |
| lutopt | MKR_LUT | — | |
| lut_imageopt | IMAGE | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| lut | MKR_LUT | — |
| saved_path | STRING | — |
| save_info | STRING | — |