HDR Export to EXR
Your 'HDR' PNG is a lie — this node writes the real 32-bit EXR
- hdr_image
- filepath
If you've ever fed an HDR tensor through ComfyUI's built-in SaveImage, you already know the problem: it normalizes everything back to 0–1 and writes an 8-bit PNG. All that highlight data above 1.0 - the entire point of doing HDR work - is silently flattened into clipping. HDR Export to EXR is the escape hatch. It takes the float tensor your Luminance Stack Processor produced and writes an actual .exr (or Radiance .hdr) file with the values left intact, so Nuke, Resolve, Blender, or whatever you're compositing in can actually see them.
This is the output node that makes the rest of the pack useful, and it's the one you should always wire up when you're serious about the result. The pack's README is blunt about it: never use the built-in save nodes for HDR. This is why.
How it works
The node grabs your hdr_image tensor, squeezes off the batch dimension, converts to a float numpy array, and hands it to a writer. For 32-bit EXR it uses imageio to write true float32 precision per channel; for 16-bit it writes half-float, which is still genuine HDR but smaller files. OpenCV is only the fallback if imageio is missing - and it logs a warning when that happens, because OpenCV's EXR bit-depth control is genuinely unreliable.
The nice part is the built-in verification: after writing, it reads the file back and logs whether values above 1.0 actually survived, plus the min/max range and file size. So if your export silently flattened itself, the console tells you instead of you discovering it in Nuke an hour later.
The inputs that matter
hdr_image- the IMAGE tensor straight out of a Luminance Stack Processor. Values above 1.0 are expected and preserved.filename_prefix- base name without extension. Works like any ComfyUI save node.output_path- leave empty forComfyUI/output, use/subfolderto go under output, or type an absolute path to write anywhere you like.counter- frame/sequence number, zero-padded to five digits. Set it to 0 for a plain filename.bit_depth- 32bit (default, max quality) or 16bit (half the file size). For final deliverables pick 32; for quick passes 16 is fine.compression- zip by default;pizgives better compression on noisy HDR data if size matters.noneif you want to play it safe with compatibility.
The single output, filepath, is a string with where the file landed - handy if you're scripting or want to display it.
Install
Install the pack through ComfyUI Manager (search "Luminance Stack Processor") or clone it:
cd ComfyUI/custom_nodes
git clone https://github.com/sumitchatterjee13/Luminance-Stack-Processor.git luminance-stack-processor
Then install requirements - for a portable install that means the embedded Python:
python_embeded\python.exe -m pip install -r requirements.txt
The requirements.txt pulls in imageio and imageio-ffmpeg alongside OpenCV, so a Manager install usually just works. If you only clone without running pip, you'll still get a working node - just one that silently falls back to OpenCV writing. Watch the console for the warning.
Gotchas
The most common "why is it broken" moment isn't the node - it's expecting the output to look pretty. Debevec/Robertson output is flat and desaturated because it's linear scene-referred radiance; that's correct, and this is where you save it, then apply a viewing LUT in your compositor. People also ask why a saved EXR "looks too bright/dark" - it's not an 8-bit preview. Open it in Nuke or Resolve and grade it.
One more trap worth naming: this node saves what you give it. If you route a plain 8-bit image through it and the log reports "no HDR values above 1.0 detected," your input never was HDR - the verification is telling you the truth. Feed it from the processor nodes and you're set.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| hdr_image | IMAGE | HDR image tensor with values potentially above 1.0 | |
| filename_prefix | STRING | ComfyUI | Base filename (without extension) |
| output_pathopt | STRING | Output path: Empty=default ComfyUI/output, /subfolder=output/subfolder, or full custom path | |
| counteropt | INT | 10–99999 | Frame/sequence counter |
| formatopt | COMBO | exr | HDR file format |
| bit_depthopt | COMBO | 32bit | EXR precision: 32bit = maximum quality, 16bit = smaller files |
| compressionopt | COMBO | zip | EXR compression type |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| filepath | STRING | — |