Nodes/radiance/VAE Encode (HDR)
ComfyUI Node

VAE Encode (HDR)

The encode that survives above 1.0

By FXTD-Studios·Created 8 months ago·Updated about 18 hours ago· 246
VAE Encode (HDR)
  • pixels
  • vae
  • samples
  • alpha
  • metadata
  • latent_format
  • quality_report
◄source_spaceLinear►
◄tile_sizeAuto►
◄overlap128►
◄exposure0.0►
◄alpha_handlingPreserve►
◄hdr_modeCompress (Log)►
◄latent_samplingsample►
◄processing_modesequential►

Feed a scene-linear image with values peaking at 8.0 into a stock VAE Encode and you get a latent built from an image where everything above 1.0 has been flattened to white. The encoder never saw your highlights. Decode it and they're gone - not compressed, not recovered, gone.

VAE Encode (HDR) exists to stop that. It codes the HDR range before the VAE sees it, and stamps the latent with a record of exactly what it did, so the matching decode can undo it.

How it works

Three stages, in this order: your image is linearised according to source_space, exposure is applied in stops, then the HDR coding named by hdr_mode is applied. Only then does the VAE look at it.

The modes are the decision that matters:

  • Compress (Log) - the default, and the one to use. Values above 1.0 survive, and because the encode writes metadata (the coding, the source space, a latent fingerprint) onto the latent, VAE Decode (HDR) in Auto inverts it exactly. The author's own measured figure: through an SD VAE on an HDR plate peaking at 7.75, highlights return within about 0.03 stops median error and 97% of the values above 1.0 come back above 1.0.
  • Soft Clip - a gentler roll-off. Survives, but the inverse is approximate rather than exact.
  • Clip (SDR) - an ordinary SDR encode. Use it when you want the old behaviour.
  • Passthrough - no coding at all.

This node is the successor to the retired HDR Latent Encoder and HDR Turbo Encoder, whose partner decoders were removed in 3.5.0. Those two produced latents that came back clipped. If you're migrating, this is the swap.

What you set, and the five outputs

Required: pixels, vae, source_space (12 options, default Linear - pick your actual encoding, since the node linearises from it). Then the useful optional ones: exposure in stops, hdr_mode, tile_size and overlap (Auto from VRAM; 128 px overlap is the documented sweet spot for cosine blending), latent_sampling (sample for the classic diffusion behaviour, mean for deterministic img2img), processing_mode (sequential for minimal VRAM, batched for 2–4× faster encode on big cards), and alpha_handling.

Outputs, and there are five, which is more than people expect:

  • samples - the latent, to your sampler.
  • alpha - an IMAGE tensor for the alpha channel, to hand to VAE Decode (HDR)'s alpha input.
  • metadata - the encode metadata JSON that lets the decode auto-crop correctly.
  • latent_format - a string like flux_16ch for Radiance's Sampler.
  • quality_report - clipping percentage, NaN count, latent range, tile info. Actually read this one. A NaN count above zero means your source had bad values and everything downstream is compromised.

Round trip: VAE Encode (HDR) with Compress (Log) → sampler (or straight to decode) → VAE Decode (HDR) with hdr_mode = Compress (Log) and decode_mode = Auto. Same VAE in both, or the coding can't be inverted.

Installing Radiance

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

With the Windows portable build, use python_embeded\python.exe for pip. Radiance is GPL-3.0, roughly 147 visible nodes from FXTD Studios, and it installs OpenEXR, OpenImageIO, OpenColorIO, diffusers and accelerate into ComfyUI's environment - which is the real reason to think before adding it to a working setup. No model downloads for this node. Note separately that the pack's learned SDR → HDR weights are non-commercial-licensed, unlike the code.

Troubleshooting

Values still clamp to white on decode. Your hdr_mode on the decode doesn't match the encode. This node and VAE Decode (HDR) have to agree.

"My latent came back weird after sampling." Normal. The fingerprint only survives an untouched encode; once a sampler has processed the latent, Decode treats it as an ordinary diffusion latent and takes the sampler-safe path. If you need true HDR after sampling, that's a different problem than this node solves.

Encoding is slow at 4K. Try processing_mode = batched if you have VRAM to spare, and check tile_size isn't fighting you - a large tile leaves less VRAM room per frame in the joint spatial/temporal budget.

Quality report shows clipping. Your source_space is probably wrong, so the linearisation is off and the HDR coding is squeezing the wrong part of the range. A camera log clip read as Linear will do this.

On the pack generally: when Radiance was posted to r/StableDiffusion, the highest-voted comment fairly criticised some nodes for dropping precision to 8 bits inside a "32-bit pipeline". 3.5.0 is much more careful and much more honest about which nodes are heuristic, but verify your round trip instead of trusting the badge - the quality_report output exists precisely so you can.

CategoryFXTD STUDIOS/Radiance/Generate

Inputs (10)

NameTypeDefaultDescription
pixelsIMAGEImage to encode, in the encoding named by source_space (scene-linear by default, values above 1.0 allowed). It is linearised, exposed and HDR-coded per hdr_mode before the VAE sees it.
vaeVAEVAE of the model the latent is meant for. Pair it with the same VAE in VAE Decode (HDR) so the HDR coding can be inverted.
source_spaceCOMBOLinearInput color space. Auto-linearized before VAE encode.
tile_sizeoptCOMBOAutoTile size in pixels. Auto queries VRAM.
overlapoptINT12832–256Overlap between tiles in pixels. 128px optimal for cosine blending.
exposureoptFLOAT0.0-10–10Exposure adjustment in stops (linear space).
alpha_handlingoptCOMBOPreservePreserve alpha channel for roundtrip.
hdr_modeoptCOMBOCompress (Log)How HDR is carried through the VAE. Compress (Log): values above 1.0 survive and VAE Decode (HDR) inverts them exactly (recommended). Soft Clip: gentler roll-off, less exact. Clip (SDR): ordinary SDR encode. Passthrough: no coding.
latent_samplingoptCOMBOsampleHow to sample from the VAE posterior distribution. 'mean' gives deterministic, lowest-noise results for img2img. 'sample' gives diverse outputs (default ComfyUI behaviour).
processing_modeoptCOMBOsequential'sequential' uses minimal VRAM (one tile at a time). 'batched' groups tiles for 2-4x faster encode on high-VRAM GPUs.

Outputs (5)

NameTypeDescription
samplesLATENTEncoded latent — wire to Radiance Sampler or save node.
alphaIMAGEAlpha channel tensor — wire to Radiance VAE 4K Decode alpha input.
metadataSTRINGEncode metadata JSON — wire to Decode crop_padding for auto-crop.
latent_formatSTRINGLatent format string (e.g. 'flux_16ch') — wire to Radiance Sampler latent_format input.
quality_reportSTRINGQuality metrics JSON: clipping %, NaN count, latent range, tile info.