Exposure Bracket Merge 📸
Debevec HDR merging inside ComfyUI
- image1
- image2
- image3
- image4
- image5
- hdr_image
Exposure Bracket Merge is the real-deal half of the pack's synthetic-HDR pipeline: it takes a stack of differently-exposed images and merges them into a single 32-bit HDR tensor using OpenCV's Debevec algorithm - the classic Paul Debevec method that photography HDR tools have used for decades. Feed it your bracketed exposures and out comes a scene-linear-ish HDR image with values above 1.0 where the highlights used to be.
The two ways to feed it, both valid:
- Real brackets - if you have actual exposure stacks, it merges them properly.
- Synthetic brackets - run your SDR AI output through
Auto Bracket Generatorfirst, and this merges the fake stack. That's the pack's whole "SDR AI image → HDR for 3D/env-map post" play, and it's the one you'll probably use, because AI generators don't give you real exposure brackets for free.
How it works
You connect up to five images: image1 is required, image2 through image5 optional. The ev_values string (default -2.0, 0.0, 2.0) must contain exactly one EV per image - three images, three values - or the node throws a "number of EV values must match number of images" error. It then calls OpenCV's createMergeDebevec, which weights each pixel by how well-exposed it is in its frame and fuses them into a radiance image: the dark pixels from the +EV bracket, the bright pixels from the -EV bracket, all the midtones blended.
The adaptive_calibration toggle (default on) is the interesting part and the reason this node is a good match for synthetic brackets. Real cameras obey exposure physics; AI-generated brackets are just clamped multiplications, so the actual brightness ratio between frames is a fiction. When enabled, the node measures real midtone brightness relationships across the images and re-derives the exposure ratios from what's actually there instead of trusting your EV numbers. It's the difference between a merge that produces a credible HDR from fake brackets and one that produces garbage. Leave it on; turn it off only if you have true camera brackets with exact, trustworthy EV steps.
The output hdr_image is float and unbounded - don't preview it raw. Route it through ACES Tone Map or the Nodex HDR Viewer to actually look at it, then Save EXR to keep it as a file.
The settings that matter
image1+image2–image5- your stackev_values- one value per image, in orderadaptive_calibration- leave it on for synthetic brackets
Install
Same pack, so:
cd ComfyUI/custom_nodes
git clone https://github.com/azhagurajpandians/ComfyUI-ACES-EXR-Toolkit.git
python -m pip install -r ComfyUI-ACES-EXR-Toolkit/requirements.txt
Restart ComfyUI; it's under image/ACES + EXR. (OpenCV ships with ComfyUI, so the Debevec dependency is already there.)
Gotchas
The EV-count-must-equal-image-count check is the one that bites beginners - if you connect four images and leave ev_values at the default three entries, it errors immediately and the message tells you exactly why. Also keep all inputs the same resolution; the node batch-concatenates them and will complain about mismatched dimensions. And remember the limit: like everything in this pack's synthetic HDR corner, the merge is only as good as the data it's given. Clipped synthetic brackets merge into clipped HDR, which is where Synthetic HDR Expansion's highlight reconstruction comes in.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image1 | IMAGE | — | |
| ev_values | STRING | -2.0, 0.0, 2.0 | Comma-separated EV values, e.g. -2.0, 0.0, 2.0 |
| adaptive_calibration | BOOLEAN | true | Analyze actual brightness relationships instead of assuming perfect camera physics |
| image2opt | IMAGE | — | |
| image3opt | IMAGE | — | |
| image4opt | IMAGE | — | |
| image5opt | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| hdr_image | IMAGE | — |