DiffHDR Postprocess
The one node that undoes DiffHDR's log curve
- images
- hdr
DiffHDR Postprocess takes the frames that came out of your VAE decode, which are still in DiffHDR's log-gamma encoding, and converts them back to linear scene-referred HDR. One input, one output, no widgets. It is the smallest node in this pack and, in a modular graph, the one you'll most often forget - and the symptom of forgetting it is not an error message, it's grey, low-contrast output that you'll spend twenty minutes blaming the sampler for.
Why a node is needed at all
DiffHDR doesn't sample ordinary image values. The whole pipeline works in a log-gamma space: your frames were encoded with pow(log(2.2·x + 1) / log(2.2·65536 + 1), 1/2.2) on the way in, and the model reconstructs that. It's the standard trick for high dynamic range - compressing a huge radiance range into a well-behaved 0–1 window - and it's why the model can hand you four stops of recovered highlight at all.
The VAE decodes the latent back into that same log-encoded space. So what leaves VAEDecode looks like a washed-out, milky image, because it literally isn't an image yet: it's an encoding.
Postprocess inverts it exactly: it clamps negative values to zero (VAE output drifts slightly below zero and log_to_lin needs a non-negative input), then applies (exp(x^2.2 · log(2.2·65536 + 1)) − 1) / 2.2. The 65536 ceiling is DiffHDR's headroom - the brightest thing the curve can represent is about 16 stops above 1.0, which is why the hdr output can carry a sun.
Inputs and output
images- VAE-decoded, log-encoded frames. That is, the direct output ofVAEDecodein a DiffHDR modular graph, after the latent trim.hdr- float linear Rec.709, values legitimately above 1.0.
That's the whole node. No exposure, no operator, no colour space picker, because there's nothing to decide: the curve is fixed by what the model was trained with, and any deviation would be a different, wrong answer.
From here, hdr goes to DiffHDR Save EXR for delivery, to DiffHDR Tonemap Preview for looking at, or into a relight / colour-match node. What it must not go into is anything 8-bit: SaveImage, PreviewImage, most upscalers. Those assume a gamma-coded 0–1 image, and a linear HDR frame will arrive looking dark and flat, then clip the moment you try to brighten it. This is the same scene-linear-vs-sRGB mismatch that the VFX handoff has had forever - gamma-encoded values treated as linear light blow out every blend.
Where it goes in the graph
DiffHDR Apply LoRA → ModelSamplingSD3 (shift 8)
DiffHDR Preprocess → WanVaceToVideo (control_video, control_masks)
KSampler (cfg 1) → TrimVideoLatent → VAEDecode → DiffHDR Postprocess → Save EXR / Tonemap
Copy workflows/diffhdr_modular.json from the repo rather than rebuilding it; the same file also carries the ModelSamplingSD3 shift and the cfg-1 sampler settings that the node needs to produce anything sane.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/claussteinmassl/ComfyUI-DiffHDR.git
pip install -r ComfyUI-DiffHDR/requirements.txt # OpenEXR + huggingface_hub
Restart ComfyUI; the node registers under DiffHDR. Manager users can install the pack by searching its title.
Getting it wrong
- Using it with the all-in-one node.
DiffHDR (Image / Video)andDiffHDR HDRI (Panorama)already invert the curve before handing youhdr. Run that output back through Postprocess and you've applied the inverse curve twice - highlights will detonate into four- and five-digit numbers. Postprocess is for modular graphs only. - Placing it before the VAE decode. It takes decoded frames. On a latent it will happily produce nonsense.
- Judging it on an 8-bit preview. The first thing most people do is look at the
hdrtensor in a preview node and conclude it's broken. It isn't; it's linear. UseDiffHDR Tonemap Previewwith an exposure of −2 to −4 stops - the author's own demo images are shown at −4 EV, which is where the recovered sky and trees actually become visible. - Anything that isn't Wan 2.1 VAE. The curve is DiffHDR's, not the VAE's, but the pipeline around it expects
wan_2.1_vae.safetensors; the check is in the all-in-one nodes, and a mismatched VAE in a hand-built graph will show up as colour weirdness or banding rather than a clean error. - Nodes missing from the menu after install usually means your ComfyUI predates the
comfy_apiV3 interface this pack registers through - it imports and registers nothing. Update ComfyUI.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | VAE-decoded, log-encoded frames. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| hdr | IMAGE | Linear HDR (Rec.709 primaries). |