Nodes/radiance/Multipass AOV Reader
ComfyUI Node

Multipass AOV Reader

Real renderer passes from a multilayer EXR, not guesses

By FXTD-Studios·Created 8 months ago·Updated about 18 hours ago· 246
Multipass AOV Reader
    • passes
    • beauty
    • albedo
    • normal_map
    • depth
    • roughness
    • specular
    • metallic
    • ao
    • emission
    • transmission
    • highpass
    • world_position
    • curvature
    • shadow_mask
    • midtone_mask
    • highlight_mask
    • reflection_mask
    • motion_vector
    • segmentation_id
    • motion_visualization
    • alpha
    ◄exr_path►
    ◄beauty_layerauto►
    ◄albedo_layerauto►
    ◄normal_layerauto►
    ◄depth_layerauto►

    This is the "you already have the data" node. Radiance's other multipass nodes estimate passes from a flat plate - clever, occasionally wrong, and it flickers in video. This one reads an actual multilayer EXR exported from Arnold, Redshift, Karma, Cycles or V-Ray, splits the named layers, and hands you ground truth: the same depth, normals, albedo and roughness buffers the renderer computed, not a model's opinion of them.

    If your pipeline starts from real renders, this is the node you want at the front of it.

    How it works

    You give it a path. It opens the EXR, finds the layers, and exposes the ones it recognises on 22 outputs. Layer naming is detected automatically - beauty, RGBA and the usual suspects - and four optional overrides let you name the beauty, albedo, normal and depth layers explicitly when your renderer used something idiosyncratic. Those four overrides cover the passes worth fighting over; everything else is matched by convention.

    The important behaviour, straight from the author's description: missing layers come through black. Nothing errors, nothing warns loudly, you just get a black image on that output. So if your normals look suspiciously flat and dark, check whether they're actually in the file before you start debugging the node. Open the EXR in a viewer with layer browsing, or just look at the output from a pass you know exists.

    The outputs

    22 of them, and they mirror Radiance's Multipass Extract (Legacy) node exactly - same order, same names - so the two are drop-in interchangeable. That's deliberate and it's the right call: you can start with estimated passes, upgrade to real ones later, and change one node rather than relinking a dozen wires.

    The ones you'll actually use: passes (a RADIANCE_PASSES bundle for Write EXR Passes and Relight), beauty, albedo, normal_map, depth, roughness, specular, metallic, ao, emission, transmission, plus utility passes like highpass, world_position, curvature, shadow_mask, midtone_mask, highlight_mask, reflection_mask, motion_vector, segmentation_id, motion_visualization and alpha.

    For compositing, depth is the one that earns its keep: feed foreground and background depth into Multipass Composite and you get a proper depth holdout when the CG element passes behind something in the plate - the thing you cannot do with an alpha alone. albedo and normal_map are what Multipass Relight needs to actually relight rather than colour-shift.

    Installing Radiance

    Manager → search Radiance → install → restart → refresh. Manual:

    cd ComfyUI/custom_nodes
    git clone https://github.com/fxtd-studios/radiance.git
    cd radiance
    python -m pip install -r requirements.txt
    

    Windows portable: use python_embeded\python.exe. No model downloads - this node reads files. What it does need is real EXR support: OpenEXR is the primary path, with OpenImageIO and then OpenCV as fallbacks, and OpenImageIO is also what handles DPX elsewhere in the pack. On Python 3.14 there's no OpenEXR wheel yet and the fallback chain is what keeps you running.

    Troubleshooting

    Everything is black. Either the path is wrong or the layers aren't named the way the detector expects. Rename-check first, then use the four override fields. Remember black is the documented missing-layer behaviour, not a crash.

    Path handling. It's a plain STRING, so it wants a real path - absolute is safest, and forward slashes work on Windows. Relative paths resolve against wherever the ComfyUI process was started, which is rarely where you think.

    Depth holdout looks inverted. Common, and it's not this node. Renderers disagree about depth polarity. Multipass Composite has a depth_near_is_white toggle for exactly this; flip it.

    Normals look wrong in the comp. Check the convention. DirectX flips green relative to OpenGL, and the choice needs to match whichever tool reads the pass downstream.

    A real limitation from the wider conversation. One user in the community discussion of this pack mentioned using Radiance mainly for depth maps and hitting a wall on genuinely deep bit depths: "it definitely won't create real 16/32 bit exr. For that you need your input to have the data" - and that VRAM caps how large a model they could run on a 4090 above about 1–2K. That's the exact distinction this node sidesteps. It doesn't create depth from a plate; it reads the depth your renderer already wrote, at the renderer's own precision. If you have the EXRs, you're outside that whole argument.

    CategoryFXTD STUDIOS/Radiance/VFX

    Inputs (5)

    NameTypeDefaultDescription
    exr_pathSTRINGPath to a multilayer/AOV EXR (Arnold/Redshift/Karma/Cycles/V-Ray).
    beauty_layeroptSTRINGautoOverride the beauty layer name, or 'auto' to detect (RGBA / 'beauty').
    albedo_layeroptSTRINGautoOverride the albedo/diffuse layer name, or 'auto'.
    normal_layeroptSTRINGautoOverride the normal layer name, or 'auto'.
    depth_layeroptSTRINGautoOverride the depth (Z) layer name, or 'auto'.

    Outputs (22)

    NameTypeDescription
    passesRADIANCE_PASSES—
    beautyIMAGE—
    albedoIMAGE—
    normal_mapIMAGE—
    depthIMAGE—
    roughnessIMAGE—
    specularIMAGE—
    metallicIMAGE—
    aoIMAGE—
    emissionIMAGE—
    transmissionIMAGE—
    highpassIMAGE—
    world_positionIMAGE—
    curvatureIMAGE—
    shadow_maskIMAGE—
    midtone_maskIMAGE—
    highlight_maskIMAGE—
    reflection_maskIMAGE—
    motion_vectorIMAGE—
    segmentation_idIMAGE—
    motion_visualizationIMAGE—
    alphaIMAGE—