TS LTX Load HDR EXR
Read an EXR the way the HDR pipeline needs — without flattening everything above 1.0
- config
- hdr_linear
- info
ComfyUI's ordinary Load Image quietly flattens anything above 1.0 to exactly 1.0. No warning, no error - your EXR's blown highlights just stop existing. If your guide frames are renders rather than screenshots, that's a silent disaster, and TS LTX HDR Load EXR is the node that reads them properly: as linear float32, no normalization, no upper clamp.
This is the front door of the pack's native HDR path. The range has to survive the reading before it can survive anything else, and this node is where the range comes in.
How it works
It reads an EXR and reports what it found - size, backend, range, and crucially, what share of the frame is above 1.0. If that share is zero, the highlights were already lost upstream and the rest of the path has nothing to preserve; the node tells you that instead of pretending otherwise.
Three backends, selected by backend (default auto):
- OpenImageIO - what the official LTX pipeline uses. Rarely installed, so not usually the one that runs.
- PyAV - ships with ComfyUI, needs no setup. This is the default in practice.
- OpenCV - only reads EXR if
OPENCV_IO_ENABLE_OPENEXR=1was set before ComfyUI started. Setting it later does nothing, because the reader registers at import.
Half-float files - what almost everyone actually renders - work too, and that was real work: PyAV can't convert gbrpf16le to an array at all, and any format conversion goes through swscale, which clamps float data to [0, 1]. Measured: a 4-channel EXR holding 4.0, read the convenient way, comes back as 1.0. This node reads the raw planes by hand to keep the values intact.
Inputs and outputs
- exr_file - an
.exrfrom ComfyUI's input folder, subfolders included. - path_override - a full path to an
.exranywhere on disk. Wins over the list above, and renders usually don't live in the input folder. - backend -
auto, or forced OIIO/PyAV/OpenCV. - config (optional) - the settings node; its
input_color_spacebecomes the label this frame carries downstream.
Outputs: hdr_linear - the frame tagged with its color space - and info - size, backend, range and how much is above 1.0.
Installation
Part of the comfyui-timesaver pack. Install via ComfyUI Manager (search "Timesaver") or:
cd ComfyUI/custom_nodes
git clone https://github.com/AlexYez/comfyui-timesaver
cd comfyui-timesaver
python -m pip install -r requirements.txt
Restart ComfyUI. It's under TS/Video/HDR.
The three things that bite
- OpenCV backend silently doing nothing. If you picked OpenCV and the EXR reads as flat, it's almost certainly the env var - and it has to be set before the server starts. Just use
autoand let PyAV do it. - Trusting the
infooutput. It's there for exactly this: the first line of debugging any "my HDR looks flat" complaint is that share-above-1.0 number. Zero means the source was already clipped. - The ordinary loader in the same graph. If the EXR node is wired but some other path still uses
Load Imageon the same frame, the flattened version can still leak in. The HDR branch bypasses the stock loader entirely - keep it that way.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| exr_file | COMBO | An .exr from ComfyUI's input folder, subfolders included. | |
| path_override | STRING | Full path to an .exr anywhere on disk. Wins over the list above — renders usually do not live in ComfyUI's input folder. | |
| backend | COMBO | auto | auto prefers OpenImageIO (what the official LTX pipeline uses), then PyAV, which ships with ComfyUI and needs no setup. OpenCV only reads EXR when OPENCV_IO_ENABLE_OPENEXR=1 was set before ComfyUI started. |
| configopt | TS_LTX_HDR_CONFIG | Settings node. Its input_color_space becomes the label this frame carries downstream. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| hdr_linear | TS_LTX_HDR_IMAGE | The frame, tagged with the colour space it is in. |
| info | STRING | Size, backend, range and how much of the frame is above 1.0. |