ComfyUI Node

SaveHDR

The last node in the pipeline — actually getting a .hdr out of ComfyUI

By DiffusionLight·Created about a year ago·Updated about a year ago· 23
SaveHDR
  • hdr_image
  • IMAGE
filename_prefixDiffusionLight
file_extensionhdr

Every node in the DiffusionLight pack produces a tensor. SaveHDR is the one that turns it into a file you can actually drag into Blender, Maya, or Arnold. Without it, the whole pipeline ends in a tensor sitting in RAM - a great demo, a useless deliverable.

Here's the thing to know up front: this isn't a fancy node, it's a save node, in the same spirit as core SaveImage - a filename prefix, a counter, a folder, done. The interesting part is what it saves and the three formats it can write.

What it does

It grabs the first frame of the batch, converts it to float32, and writes it to ComfyUI/output with a numbered name like DiffusionLight_0001.hdr (the README shows a hyphen in its example, but the code produces an underscore - the code wins). Then it passes the original image through as an output so you can keep wiring a preview or a tonemap after it.

Why float32 matters: the HDR from Exposure2HDR carries values above 1.0, and float32 keeps them. Save this as an 8-bit PNG and you've thrown away the entire point - the whole reason you went through this pipeline is to capture brightness range, not just color. The .hdr file you get back is a proper Radiance RGBE image that your renderer will read as lighting.

The inputs

Only three, all of them obvious:

  • hdr_image - the IMAGE from Exposure2HDR (or anything else in HDR range). Feed it SDR data and you'll save an SDR file with extra steps.
  • filename_prefix - default DiffusionLight. Change it per shot or per scene; it becomes prefix_0001.ext in ComfyUI/output.
  • file_extension - the one that matters, with three choices:
    • hdr - Radiance RGBE via imageio. The default and the most dependable; every 3D app reads it. This is what you want 95% of the time.
    • exr - OpenEXR via OpenCV's cv2.imwrite. The 3D-industry standard, but it depends on your OpenCV build shipping OpenEXR support, which not every wheel does. If you get a "can't write" error on .exr, drop to .hdr - the data is the same.
    • npy - a raw NumPy dump. Nothing 3D reads this; it's for post-processing the array in Python yourself. You'll know if you need it.

The gotchas

First, only the first image in the batch is saved - the code literally indexes hdr_image[0]. If you batch several HDRs, you'll get one file and wonder where the rest went. The stock workflow feeds it one image, so this rarely bites, but it's worth knowing before you automate.

Second, the pass-through output is the raw HDR, so PreviewImage after this node will look blown out. That's correct behavior - the image is brighter than 1.0 and previews clamp it. Add a PercentileToPixelValueTonemap if you want to see what you're saving; the file itself is fine.

Third, it prints the save path to the console but shows nothing in the UI. Missing file? Look at the ComfyUI terminal, not the graph.

Installing it

Same as the rest of the pack. ComfyUI Manager → search "DiffusionLight-ComfyUI", or:

cd ComfyUI/custom_nodes
git clone https://github.com/pureexe/DiffusionLight-ComfyUI

Restart, and you're done - the pack itself declares no Python requirements beyond what ComfyUI ships (torch, numpy, OpenCV, imageio). The heavy lifting is the workflow's models, not this node.

SaveHDR is the payoff node of the whole pack: everything before it is about estimating light, this is about handing it to your renderer. For anyone doing CG compositing, relighting, or product shots, that's the whole ballgame - and it's why the community that adopted DiffusionLight was 3D artists, not image hobbyists. This node is the handshake between them.

Categorysd

Inputs (3)

NameTypeDefaultDescription
hdr_imageIMAGE
filename_prefixSTRINGDiffusionLight
file_extensionCOMBOhdr3 options: hdr, npy, exr

Outputs (1)

NameTypeDescription
IMAGEIMAGE