Atlas HDR Vertex Transfer π
HDR for the side of the object no camera ever saw
- solve
- source_image
- hdr_image
- solve
- report
Here's a problem you only hit once you've got a generated object sitting inside an HDR plate. You converted the photograph to ACEScg float with the LTX-2.5 SDRβHDR chain. Beautiful. But the object's hidden side - the back you got from Pixal3D - isn't painted by any image at all. It's vertex colour. The SDRβHDR model never sees it, so your sunlit back plate has a generated object whose far side is stuck in display-referred 0β1.
Atlas HDR Vertex Transfer π closes that gap, and it does it by fitting the conversion's own tone curve rather than guessing.
How it works
It takes the pixel-aligned SDR plate and HDR plate pair and fits the model's per-channel tone curve - log-binned, monotone, with the SDR linearised and moved from Rec.709 into ACEScg first (core/hdr_transfer.py). Then it applies that curve to every pixal3d primitive's vertex colours, giving them ACEScg linear values that may legitimately exceed 1.0.
The clever bit is the honesty clause: report tells you how well ONE global curve explains the plate, in residual stops. If your pair is badly mismatched or the model's conversion is non-monotone in some region, you find out from a number instead of from a weird-looking object three tools downstream.
It also tells you where the result can and cannot travel. AtlasSceneTo3D writes the HDR vertex colours as a float-colour binary PLY sidecar, because glTF's COLOR_0 is clamped to 0..1. So the GLB carries the display version and the PLY carries the real one.
Inputs and outputs
Required: solve (the scene, carrying the generated primitives), source_image - the SDR plate the HDR was converted from.
Optional, and only one of these two gets used:
hdr_exr_path- the HDR plate EXR from the matrixZone still workflow. Relative to ComfyUI's output or input folder (e.g.atlas/hdr_plate_00001.exr), or absolute inside those folders or$ATLAS_PROJECT_ROOT; other absolute paths are refused unless you setATLAS_ALLOW_ABSOLUTE_READS=1. Empty means pass-through.hdr_image- a float HDR IMAGE (ACEScg linear) instead, if you already have it on the wire.
There's a caching subtlety in the tooltip worth repeating because it's the kind of thing that costs an hour: a typed path re-runs the node when the file changes on disk, but a linked path re-runs only when the upstream node does. ComfyUI doesn't pass linked values to IS_CHANGED, so a consumed EXR path won't invalidate on its own.
Outputs are just solve and report - the HDR vertex colours ride on the primitives inside the solve, they're not a separate socket.
Install
cd <ComfyUI>/custom_nodes
git clone https://github.com/mikejamesvfx/atlas-camera.git
Or Manager β search atlas-camera (ComfyUI Registry). Restart ComfyUI. No pip step for this node itself - it's pure Python. MIT.
You will need the surrounding lane set up:
- ComfyUI V135 or later for the Pixal3D core nodes and the
LOAD3D_*socket types this chain ends up in. - The LTX-2.5 files if you haven't made the HDR plate yet:
ltx-2.5-22b-distilled-transformer-bf16.safetensors,ltx-2.5-22b-ic-lora-sdr-to-hdr-1.0.safetensors, the scene-emb variant, and the two VAEs. If theLTXV*nodes load red, install ComfyUI-LTXVideo. - Pixal3D model files for the generated object, via the four-file Comfy-Org repack listed in
INSTALL.md.
None of this is pip install; it's model files in ComfyUI's model folders, which is why the pack calls these the V135 lane.
Where this bites
Two things bite. Mixed colour encodings - the SDR plate has to be linearised and gamut-shifted before the fit, which the node does for you, but if you feed it a plate that's already been through a look, the fitted curve is that look's curve and your hidden side inherits it. And expectation-setting: highlights above 1.0 here are inferred, not photographed. Same caveat as the HDR plate itself; the far side of the object was never in front of a camera either.
Licence note if you're shipping: Pixal3D's code is MIT but the weights' commercial status hasn't been confirmed upstream. LTX-2.x is free for commercial use by organisations under US$10M annual revenue.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| solve | ATLAS_SOLVE | β | |
| source_image | IMAGE | The SDR plate the HDR was converted from. | |
| hdr_exr_pathopt | STRING | The HDR plate EXR from the matrixZone still workflow, relative to ComfyUI's output or input folder (e.g. atlas/hdr_plate_00001.exr), or absolute INSIDE the output/input folder or $ATLAS_PROJECT_ROOT; other absolute paths are refused unless ATLAS_ALLOW_ABSOLUTE_READS=1. Empty = pass through. A TYPED path re-runs the node when the file changes on disk; a LINKED path (e.g. from the stitch's exr_path) re-runs only when the upstream node does -- ComfyUI does not pass linked values to IS_CHANGED. | |
| hdr_imageopt | IMAGE | Alternative to the path: a float HDR IMAGE (ACEScg linear). |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| solve | ATLAS_SOLVE | β |
| report | STRING | β |