Read
EXR, DPX, ProRes and sequences — the loader ComfyUI should have had
- image
- mask
- info
Stock ComfyUI's LoadImage reads PNGs and JPEGs and hands you an sRGB-ish batch. That's fine right up until you have a numbered EXR sequence from a renderer, a ProRes 4444 with alpha, a camera-log clip, or anything with a colour tag you'd like to respect. Then you're writing scripts.
Read is Radiance's answer to all of that in one node, and it's the most immediately useful thing in the pack for anyone with a pipeline. Images (PNG, JPG, TIFF, EXR, DPX, HDR, WebP), video (MP4, MOV, MXF, AVI, WebM, MKV), and numbered sequences. Video decodes at the source bit depth through ffmpeg, ProRes 4444 alpha lands on the mask output, and colour tags are honoured rather than ignored. The KB's post-processing.md §(b) is right that this layer is nearly invisible in the community - it's VFX muscle, and it's rare enough in ComfyUI that the node is worth the install on its own.
Getting files in
There are two routes and they don't mix. browse is the picker: click the upload icon to open a native file dialog, and uploaded files get copied into ComfyUI's input/ folder. Leave browse blank and use path instead, which takes an absolute path, a UNC path like \\server\share\shot, a directory, or a sequence pattern - /frames/f.%04d.exr, /frames/f.####.png. media_type (Auto, Image, Video, Sequence) exists to override auto-detection if a pattern confuses it.
The sequence controls matter more than they look. start_frame defaults to 1001 because that's the VFX convention, and for sequences it's the frame number in the filename; for video it's a 0-based offset, and - nice detail - because 1001 is a sequence convention, it's ignored for any clip shorter than that rather than reading nothing. end_frame (0 = to the end), frame_step (read every Nth frame), and missing_frames (Error, Black, Skip) handle the rest. Skip is the default; Black inserts zeros, which is exactly the kind of silent substitution that gets a broken master delivered.
One field earns its own paragraph: max_video_frames. Frames are float32 RGB in RAM, and the docs give the number - 240 frames of 4K RGBA is about 31 GB. That's the node's real gotcha, and capping it while you build a graph is not optional on a 24 GB card. proxy_scale (0 = full res, 0.5 = half) is the other iteration-speed lever.
Colour, and why this node is different
color_space is where the pipeline starts. The default, Auto / Linear (pass-through), hunts for the file's own tag and otherwise passes through; the rest of the list is a real menu of encodings (sRGB, Rec.709 BT.1886, Rec.709 camera OETF, Rec.2020, P3-D65 gamma 2.6, PQ, HLG, linear variants, ACEScg and more). working_space is what the IMAGE is delivered in - default Linear Rec.709 (sRGB) because that matches ComfyUI, ACEScg if you're in an ACES pipeline. Decoding goes transfer and primaries.
ocio_colorspace overrides color_space entirely and hands the conversion to OpenColorIO; ocio_config points at a config, or an ocio:// built-in URI, or falls back to $OCIO, or - with neither - OpenColorIO's built-in ACES 2.0 studio config, which covers every major camera log. That's a remarkably good default: most people reading a Sony or ARRI clip never need to touch a config. hdr_reference_nits (default 203) sets where scene-linear 1.0 sits for PQ/HLG, which is BT.2408 and matches the rest of Radiance's HDR nodes; set 100 if you need to match OCIO/ACES conventions.
raw hands back exactly what's stored: no decode, no conform to the EXR display window, so overscan survives. That's Nuke's "raw data" and there are real cases for it. premultiplied divides alpha back out of RGB on read - off by default, matching Nuke, because turning it on changes pixels. reload (an INT you bump) forces a re-read when the file changed but its timestamp didn't, which saves a restart at 2am.
The defaults that keep you out of trouble
on_error defaults to Error: the node goes red and the queue stops. The tooltip is unusually frank about why - Black frame, the alternative, is what older versions always did, silently, "which is how a black master got delivered." That's the single best argument for the default, and if you turn it off you should know you're choosing convenience over the failure mode you're paid to avoid.
layer selects which EXR layer to read: auto takes the beauty, or the first colour layer, or - for a data-only file like a Z-depth pass - the first layer of any kind. With the frontend loaded it's a dropdown of the layers actually in the file, which is a much nicer experience than typing.
Outputs
image is your frame batch, scene-linear once color_space has decoded it. mask is alpha: the file's own matte for a ProRes 4444, RGBA EXR or RGBA sequence, zeros otherwise - that's how you get a real key in without a matte-extraction hack. info is JSON describing what was actually read: resolution, frame count and range, bit depth, codec, EXR layers and windows, colour tags, timecode. Wire it into a note or a text node; it's a metadata tab you can plug in, and it's the fastest way to find out why a read behaved unexpectedly.
Install
ComfyUI Manager → search Radiance → install → restart → refresh. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/fxtd-studios/radiance.git
cd radiance
python -m pip install -r requirements.txt
This is the node that makes the dependency list worth reading. OpenImageIO is the VFX-standard library behind EXR/DPX/TIFF handling. OpenEXR is used when a wheel exists - there is none for Python 3.14 yet, and the pack deliberately degrades to OpenImageIO then OpenCV instead of failing the whole install. imageio-ffmpeg provides the ffmpeg binary video decoding uses, and tifffile is the only writer/depth-probe for 16- and 32-bit float TIFF. If any of it is missing, pip probably installed into a different Python than the one running ComfyUI - that's the failure, nine times out of ten.
And note the RUDRA licence term if you go on to the HDR nodes: model weights are non-commercial, separate from the code's GPL-3.0. Reading files doesn't involve them.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| browse | COMBO | Browse or upload a file from disk. • Click the upload icon (📎) to open a native file picker. • Supports images (PNG, JPG, TIFF, EXR, DPX, HDR, WebP) and video (MP4, MOV, MXF, AVI, WebM, MKV). • Uploaded files are copied to ComfyUI's input• Leave blank and fill in 'path' below for absolute / network / sequence paths. | |
| media_typeopt | COMBO | Auto | Override auto-detection. Auto infers from path extension and pattern. |
| pathopt | STRING | Optional — used only when 'browse' is left blank. Accepts any absolute path, UNC network path, or sequence pattern: Sequence patterns: /frames/f.%04d.exr · /frames/f.####.png · /dir/ Network paths: /mnt/nas/renders/shot or \\server\share\shot Format is auto-detected from extension. | |
| color_spaceopt | COMBO | Auto / Linear (pass-through) | Decode the input from this color space to scene-linear before processing. |
| start_frameopt | INT | 10010–99999 | First frame to read. • Sequence: the frame number in the filename (1001 is the usual VFX start). • Video: a 0-based offset into the clip. The 1001 default is a sequence convention, so it is ignored for any clip shorter than that rather than reading nothing. |
| end_frameopt | INT | 00–99999 | Last frame to read, inclusive. 0 = to the end. Applies to sequences and video. |
| frame_stepopt | INT | 11–100 | Step size — e.g. 2 reads every other frame. Applies to sequences and video. |
| max_video_framesopt | INT | 00–99999 | Hard cap on decoded video frames (0 = all). Frames are float32 RGB in RAM: 240 frames of 4K RGBA is about 31 GB, so cap this while building a graph. |
| proxy_scaleopt | FLOAT | 0.000–1 | Downscale factor for proxy preview (0 = full resolution). 0.5 = half res for faster iteration. |
| missing_framesopt | COMBO | Skip | A frame inside a sequence that is not on disk. Black inserts a zero frame, Skip omits it, Error raises. For a read that fails outright, see on_error. |
| layeropt | STRING | auto | Which EXR layer to read. 'auto' takes the beauty, or the first colour layer, or — for a data-only file such as a Z-depth pass — the first layer of any kind. With the frontend loaded this is a dropdown listing the layers actually in the selected file. |
| on_erroropt | COMBO | Error | What to do when the read fails — file missing, corrupt, unreadable. • Error: the node goes red and the queue stops. What Nuke and every other application does, and the default. • Black frame: return black and carry on. This is what 3.1.x always did, silently, which is how a black master got delivered. |
| rawopt | BOOLEAN | false | Hand back exactly what is stored in the file: no colour space decode, and no conform to the EXR display window (so overscan is preserved). Nuke's 'raw data'. |
| premultipliedopt | BOOLEAN | false | Tick when the file's RGB is already multiplied by its alpha — the EXR convention — and you want it divided back out on read. Off by default, matching Nuke, because turning it on changes pixels. |
| reloadopt | INT | 00–2147483647 | Bump to force a re-read of the file, for when the contents changed but the timestamp did not. |
| working_spaceopt | COMBO | Linear Rec.709 (sRGB) | Scene-linear space the IMAGE is delivered in. color_space is decoded all the way here: transfer AND primaries. Linear Rec.709 matches ComfyUI; ACEScg for an ACES pipeline. |
| ocio_colorspaceopt | STRING | Any colorspace name or alias from the OCIO config. When set it overrides color_space and OpenColorIO converts it to the working space. Empty = use color_space. | |
| ocio_configopt | STRING | Path to a config.ocio, or an ocio:// built-in URI. Empty uses $OCIO, and without it OpenColorIO's built-in ACES 2.0 studio config (every major camera log). Used by ocio_colorspace and, when OCIO is installed, by the named color_space entries. | |
| hdr_reference_nitsopt | FLOAT | 20348–1000 | PQ and HLG only: the luminance that scene-linear 1.0 (diffuse white) sits at. 203 is BT.2408 and what Radiance's HDR nodes use; 100 matches OCIO/ACES conventions. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | Frames as a batch. Scene-linear once color_space has decoded them. |
| mask | MASK | Alpha. For a ProRes 4444, an RGBA EXR or an RGBA sequence this is the file's own matte; otherwise zeros. |
| info | STRING | JSON describing what was actually read: resolution, frame count and range, bit depth, codec, EXR layers and windows, colour tags, timecode. Nuke's metadata tab, as a wire you can plug in. |