Nodes/ComfyUI ACES EXR Toolkit/Save EXR (Multi-Layer)
ComfyUI Node

Save EXR (Multi-Layer)

Get float EXRs out of ComfyUI, passes and all

By azhagurajpandians·Created 4 months ago·Updated about a month ago· 0
Save EXR (Multi-Layer)
  • image
  • depth
  • normal
  • mask
  • diffuse
  • specular
  • emission
  • path
output_dir/tmp/ComfyUI/output
filenamerender_%04d
bit_depth16f (half-float)
compressionZIP (lossless, recommended)
start_frame1

This is the node people install the pack for. Save EXR (Multi-Layer) takes a float IMAGE and writes a real .exr - 16-bit half-float or 32-bit float, lossless ZIP or wavelet PIZ compression, and optionally a whole stack of extra passes (depth, normal, mask, diffuse, specular, emission) into a single multi-layer file. If you've ever tried to hand an AI-generated element to a Nuke comp or a DaVinci grade, you know the pain this removes: an 8-bit sRGB PNG treats linear light like gamma-encoded values and every blend goes wrong. A float EXR is what a VFX pipeline actually speaks.

The killer use case, and one people keep rediscovering: depth maps. ComfyUI depth estimators usually hand you an 8-bit-ish image, which is useless as a displacement map. This node lets you write a proper float depth pass to depth.Z in a real EXR - the difference between "a grayscale picture" and "data you can displace geometry with."

How it works

The main image becomes the beauty pass (R, G, B, plus A if it has alpha). Each optional input becomes a named layer with convention-correct channel names, which is the detail that makes the file drop into Nuke cleanly:

  • depthdepth.Z (single channel; an RGB input is luma-weighted down)
  • normalnormal.X, normal.Y, normal.Z
  • maskmask.A
  • diffuse, specular, emissionlayer.RGB

Passes are auto-resized to match the beauty pass if their dimensions differ, so a depth map at a different resolution doesn't break the write. If the OpenEXR python package isn't installed, it degrades to a flat single-image EXR via OpenCV, and then tifffile - workable, but you lose the layers and the compression choices. Install openexr.

The settings that matter

  • output_dir - defaults to ComfyUI's output folder (and writes are confined there)
  • filename - a template, render_%04d by default; each frame in a batch gets its number filled in
  • bit_depth - 16f (half-float) or 32f (float). Half-float at half the file size is the right default for almost everything; go 32f only when you genuinely need the headroom
  • compression - ZIP is the recommended default (lossless, universally readable); PIZ is the wavelet option for big files; DWAA if you're writing video sequences and want speed
  • start_frame - offsets the frame counter on the filename

It's an output node (it returns a path string and stops the graph), so it always runs.

Install

Manager: search "ACES EXR Toolkit". Or:

cd ComfyUI/custom_nodes
git clone https://github.com/azhagurajpandians/ComfyUI-ACES-EXR-Toolkit.git
python -m pip install -r ComfyUI-ACES-EXR-Toolkit/requirements.txt

Restart ComfyUI. It sits under image/ACES + EXR with the rest of the pack.

Gotchas

The main trap is skipping the dependency: without the openexr pip package you still get a file, but it's a flat beauty-only EXR and the multi-layer + compression features silently vanish. Check pip list for OpenEXR if your "multi-layer" file opens as one layer. Also remember this is a save, not a preview - to check an HDR result before committing bytes to disk, route it through the pack's Nodex HDR Viewer first.

Categoryimage/ACES + EXR

Inputs (12)

NameTypeDefaultDescription
imageIMAGE
output_dirSTRING/tmp/ComfyUI/output
filenameSTRINGrender_%04d
bit_depthCOMBO16f (half-float)2 options: 16f (half-float), 32f (float)
compressionCOMBOZIP (lossless, recommended)8 options: ZIP (lossless, recommended), ZIPS (lossless, scanline), PIZ (lossless, wavelet), PXR24 (lossy, 24-bit), RLE (lossless, run-length), B44 (lossy, fixed ratio), +2
depthoptIMAGE,MASK
normaloptIMAGE
maskoptMASK
diffuseoptIMAGE
specularoptIMAGE
emissionoptIMAGE
start_frameoptINT10–99999

Outputs (1)

NameTypeDescription
pathSTRING