UltraHDR Parameters
The six knobs behind your Ultra HDR JPEG
- hdr_params
Save UltraHDR Image works fine with nothing plugged into it. This is the node you add when you want to argue with it.
What it is
A pure value node - no pixels, no model, no output image. It holds six numbers and hands them to the save node as a single hdr_params bundle. Its only output is hdr_params (type HDR_PARAMS), and that type is accepted in exactly one place in the whole pack: the hdr_params input of Save UltraHDR Image. Nothing else reads it.
The detail worth knowing before you spend a run on it: these defaults are identical to the fallback dictionary baked into the save node, so wiring it up and changing nothing produces a bit-for-bit identical file. It earns its place when you want different numbers - or when you have two save nodes and want one place to change them, the "one authoritative source, many consumers" idea every primitive node in ComfyUI exists for (comfyui-node-plumbing.md).
The six settings, in the order they matter
peak_nits (default 1000, range 300–10000) is the headline claim about your file. The ratio peak_nits ÷ sdr_white becomes the JPEG's HDRCapacityMax field - literally the headroom a viewer is allowed to apply. 1000 over 203 white is about 2.3 stops. Going higher doesn't invent detail, it just shoves already-near-white regions harder. 1000–2000 is the sane band; 10000 is a number you can type, not a look you want.
sdr_white (default 203, range 80–500) is the assumed brightness of SDR white, and it's the anchor of the entire mapping - every gain is expressed relative to it. 203 nits is the conventional reference level for SDR graphics white in HDR mastering, so the default is right. Touch it only to match a specific deliverable.
shadow_boost (default 1.3, range 1–3) is a flat multiplier on the dark end. At 1.0 the expansion is purely peak-driven and your shadows stay put; higher values lift the bottom of the image too, which is where the "everything is glowing" look comes from. It's a mood knob, not a technical one.
hi_gamma (default 1.0, range 0.1–3) shapes where the boost crosses over. Raise it and the lift stays small through the midtones, only really kicking in on bright pixels - the safe setting for faces and mid-tone interiors, and what you want when your first test looks crunchy. Lower it and the expansion spreads into the midtones: dramatic on a sunset, washed-out on a portrait.
quality (default 92) is the base JPEG's quality. Chroma subsampling is already disabled (4:4:4) in the code, so color survives well; pushing this to 100 mostly buys file size.
gainmap_quality (default 85) is the quality of the grayscale JPEG that is the HDR delta - the one with a hidden cost. It's low-bit-depth luminance, so its compression artifacts land as banding across skies and blotches around lights. If highlights look blocky or gradients step, raise this to 95 before touching anything else.
Wiring it up
One wire: hdr_params out of this node into hdr_params on Save UltraHDR Image. That's the whole graph. If you'd rather drive a value from elsewhere - a Primitive shared with the rest of the workflow - right-click the widget and use "Convert widget to input".
Iterating is cheap. The save node is an output node, so it always runs, and ComfyUI's cache works backwards from it: tweak peak_nits, re-queue, and the JPEG re-encodes without re-running the sampler. Judging the result needs a real HDR display, though - the canvas preview is the SDR base layer and won't move no matter what you type here.
Installing it
Same pack, same steps. Search lhyNodes in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/lihaoyun6/ComfyUI-lhyNodes.git
python -m pip install -r ComfyUI-lhyNodes/requirements.txt
Restart, then search UltraHDR in the node menu - the README doesn't document either of these nodes yet. And don't skip the requirements step: the pack imports every module in its nodes/ folder on load, and one of them pulls in cv2 and ultralytics at the top, so missing dependencies take the whole pack down, these two included.
Where people get burned
Adding this node at defaults and expecting something to change. Nothing will, by design.
Reading peak_nits as a quality slider. It sets the gain ceiling and the number your file advertises; a bigger one isn't more HDR, it just gives the display a bigger knife - and it's how you get the "everything is a light source" real-estate look.
And one honest caveat: there's no crowd wisdom on these values to lean on. In the reddit corpus behind most of this site's opinions, "gain map" appears in exactly zero threads - this node landed in the repo the same day this article was written. The guidance above comes from what the code does with each number, not consensus. If your taste disagrees, your taste wins.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| peak_nits | FLOAT | 1000300–10000 | — |
| sdr_white | FLOAT | 20380–500 | — |
| shadow_boost | FLOAT | 1.301–3 | — |
| hi_gamma | FLOAT | 1.000.1–3 | — |
| quality | INT | 921–100 | — |
| gainmap_quality | INT | 851–100 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| hdr_params | HDR_PARAMS | — |