Luminance Stack Processor (3 Stops)
Three exposures in, one real HDR tensor out — the Luminance Stack Processor, 3-stop version
- ev_plus_2
- ev_0
- ev_minus_2
- hdr_image
The Luminance Stack Processor (3 Stops) is the workhorse of this pack. You feed it three exposure brackets - an overexposed EV+2 shot, a normal EV0, an underexposed EV−2 - and it merges them into a float HDR tensor where highlights legitimately go above 1.0 instead of clipping at white. That's the whole game: one exposure can't capture both the blown-out window and the detail in the dark corner, but three of them can, and this node is what stitches them together.
Where do you get three aligned exposures? Tripod-bracketed photos, or - the workflow this pack is really built around - AI-generated variants. The author trains FLUX.1 Kontext exposure LoRAs precisely so you can take one source image and generate EV+2 / EV0 / EV−2 versions that are perfectly aligned by construction. On r/comfyui the pack gets recommended exactly this way: convert your LDR images into HDR through these nodes.
How it works
Each input image gets an exposure time derived from a 1/60s base scaled by 2^exposure_step, then the chosen algorithm does the merge. The default detail_injection algorithm is the interesting one: it converts the sRGB inputs to linear space, detects the gamma, then injects detail from the underexposed frame into the 1.0–2.0 highlight range and pulls shadow detail out of the overexposed frame. It compensates brightness toward the professional 18% gray standard, keeps hue via luminance-based scaling, and feathers the blend masks with Hermite interpolation so you don't get hard seams. The output is deliberately not normalized - values above 1.0 are the feature, and you should save them with the pack's HDR Export node, never SaveImage.
Inputs that matter
ev_plus_2,ev_0,ev_minus_2- the three IMAGE inputs. Keep the naming straight: EV+2 is the brighter shot (longer exposure), EV−2 the darker one. Get them swapped and your "HDR" will look like a mess.hdr_algorithm- seven options,detail_injectionby default.radiance_fusionis the Nuke-style plus/average alternative;debevecandrobertsongive proper linear radiance for VFX compositing (flat and desaturated - that's correct);hdrutilsonly appears if you've installed the optional HDRutils library.exposure_adjust- Nuke-style exposure compensation in stops, applied to the final result. Default is 0.0 since v1.1.8.exposure_step- the EV spacing. Leave it at 2 unless you shot different brackets.- The
auto_calibrate,debevec_exposure_comp, anddebevec_anti_bandingknobs only matter if you pick Debevec or Robertson. The default −8 stop compensation is tuned for AI-generated brackets; leave it alone until you understand why it's there.
Output is one IMAGE, hdr_image - wire it straight into HDR Export to EXR.
Install
ComfyUI Manager, searching "Luminance Stack Processor", or:
cd ComfyUI/custom_nodes
git clone https://github.com/sumitchatterjee13/Luminance-Stack-Processor.git luminance-stack-processor
pip install -r requirements.txt # or python_embeded\python.exe -m pip on portable
OpenCV is the hard requirement. Restart ComfyUI after installing.
Troubleshooting
This node logs its input and output ranges to the console - if the final range maxes out around 1.0, the merge didn't produce HDR, and the log shows you exactly where. "Module not found" means the requirements never got installed. And if processing throws, the node falls back to returning EV0 so the graph doesn't die - which is kind, but also easy to miss. Check the console; the merge probably failed and you silently got a single exposure.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| ev_plus_2 | IMAGE | — | |
| ev_0 | IMAGE | — | |
| ev_minus_2 | IMAGE | — | |
| exposure_stepopt | FLOAT | 2.00.5–5 | — |
| exposure_adjustopt | FLOAT | 0.0-5–5 | — |
| hdr_algorithmopt | COMBO | detail_injection | 7 options: detail_injection, radiance_fusion, natural_blend, mertens, debevec, robertson, +1 |
| auto_calibrateopt | BOOLEAN | true | Enable adaptive calibration for AI-generated brackets (Debevec/Robertson only) |
| debevec_exposure_compopt | FLOAT | -8.0-15–15 | Exposure compensation for Debevec/Robertson output (in stops). Default -8.0 optimal for AI brackets. |
| debevec_anti_bandingopt | BOOLEAN | true | Apply optional gradient-adaptive dithering to reduce banding (Debevec/Robertson only). Disable for pure lambda=100 smoothness with no color changes. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| hdr_image | IMAGE | — |