Load SDR to HDR Model [Beta]
The .pth that invents the highlights your SDR never had
- model
Your SDR image is capped at 1.0 and it means it. Everything ComfyUI hands you is an 8-bit-ish, sRGB-encoded tensor in a 0–1 range, and HDR needs to know what lives above white - sun glints, lamp filaments, the highlights a phone camera clipped or a diffusion model never had a reason to invent. Bridging that gap is inverse tone mapping, and there are exactly two ways to do it: a curve you tune by hand, or a network that learned what real HDR footage looks like. This is the loader for the second kind. It loads a model and hands you a handle. That's the whole job.
One honest note before you invest: HDR output is a small niche here, and the reason is mundane - most people don't own a display that can show it, so the payoff is invisible. The argument that survives that is the grading one: a wider-gamut, higher-range intermediate gives you more to push around in post even if you deliver SDR in the end.
How it works
The node registers ComfyUI/models/sdr_to_hdr as a model folder, resolves the filename you picked against it, and if the file isn't there, downloads it. Yes, really - the pack ships download URLs for the four models the author cares about and pulls them from the upstream research repos (HDRTVNet-plus, HDRTVDM, ITMLUT) the first time you run the node. No Hugging Face token, no manual step.
From there it's the standard ComfyUI loader dance: comfy.utils.load_torch_file with safe_load=True, then the pack inspects the state dict and works out which architecture it's holding - AGCM (global color mapping), the AGCM+LE ensemble, HDRTVDM (a Restormer-style transformer), or ITMLUT (a neural 3D LUT). Finally the bundle gets parked on the offload device, so the weights aren't sitting in VRAM while the rest of your graph runs.
The input, and the one output that matters
There is exactly one input: model_name, a dropdown. One output: model, of type XE_SDR2HDR_MODEL, which goes into SDR to HDR (using Model) [Beta] and nowhere else. Nothing else in the ecosystem accepts that type, which is a feature - you can't accidentally wire a model handle into a sampler.
Subtle but useful: the dropdown isn't a hardcoded list. It's the four defaults plus anything else you drop into models/sdr_to_hdr, with a few partial checkpoints filtered out because they're sub-models rather than standalone tone mappers. So a load failure complaining about an unexpected architecture means the file you added isn't one the pack can build.
Which of the four you actually want
- Ensemble_AGCM_LE.pth - the default, and the one the author recommends for anime and video. Global mapping sets the overall look, then a local-enhancement net cleans up detail. It's also the only file where the downstream
use_refinetoggle does anything, because it's the only one that ships an LE module. - HDRTVDM_params.pth - the CVPR 2023 Restormer baseline. If you have no opinion, this is the neutral pick.
- HDRTVDM_params_3DM.pth - same family, tuned for heavily compressed real-world SDR. Macroblocked streaming rips and re-encoded home videos are what it was built for; on clean synthetic input it's not obviously better.
- ITMLUT_params.pth - a neural 3D LUT. Not the prettiest output, far and away the fastest. This is the one you pick when you're expanding 240 video frames and don't want to wait.
Install
ComfyUI Manager, search the pack title (XENodes), or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/xeinherjer-dev/ComfyUI-XENodes.git xenodes
Restart ComfyUI and you're done - the dependency story is unusually clean. requirements.txt is empty and the only declared dependency is imageio-ffmpeg, so there are no exotic wheels to fight. Models land in ComfyUI/models/sdr_to_hdr on first execution; if you'd rather pre-fetch, that's the folder.
Common issues
The download happens when the node runs, not when ComfyUI starts. If raw.githubusercontent.com or the github.com/.../raw/ paths are blocked on your network, you won't find out at launch - you'll find out mid-queue with a FileNotFoundError naming models/sdr_to_hdr. Fix: grab the .pth from the URL in the error message and drop it in that folder by hand. Same result.
An interrupted download leaves a .downloading file next to where the real one should be. Delete it and re-run; the node checks for the finished file and won't touch the partial one.
The node doesn't appear in the menu at all. The pack builds on comfy_api.latest, so a ComfyUI old enough to predate that won't import it - you'll see an import error in the console and no XENodes category. Update ComfyUI.
Don't judge HDR output through a PNG. Save through the pack's own Save Image (AVIF) or Save Video, which carry the 10-bit/HDR tag properly; a plain 8-bit PNG drops it and you'll conclude the whole thing does nothing.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| model_name | COMBO | HR.pth | Model file: 'HR.pth' (highest quality / anime / CG), 'HDRTVDM_params_3DM.pth' (live-action / video / artifact restoration), 'ITMLUT_params.pth' (ultra-fast real-time 3D-LUT). Automatically downloaded if missing. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| model | XE_SDR2HDR_MODEL | — |