ComfyUI Node

Apex HDRI Viewer

Point a lens at your 360 panorama and get a real frame back

By ApexArtist·Created about a year ago·Updated 21 days ago· 5
Apex HDRI Viewer
  • image_input
  • front_view
  • back_view
◄yaw0.0►
◄pitch0.0►
◄roll0.0►
◄fov90►
◄back_fov150►
◄lens_typerectilinear►
◄output_width1024►
◄output_height1024►
◄exposure0.0►

A 2:1 equirectangular panorama is a great way to store an environment and a terrible thing to look at - all fishbowl warp in the middle and smear at the poles.

Apex HDRI Viewer fixes the framing: it reprojects the equirect as if a camera with a real lens were standing in the middle of it, at whatever yaw, pitch, roll, field of view and aspect you dial in. Two outputs - the view you aimed at, and the view 180° behind you.

Why you'd want this

The obvious pipeline is sky and background plates. Generate or download an environment, then pull a properly-framed crop out of it at 16:9 or 3:2 instead of fighting the projection in Photoshop. Point it down for a ground plane, up for a sky plate, or 180° off for the back wall - the one piece of an environment you can't generate from the camera angle itself.

It's also the missing half of panorama generation: Flux 2 Klein picked up 360° ERP outpaint LoRAs and a community panorama editor in early 2026, and a generated equirect is only useful once you can sample a sane frame out of it. Same story if the downstream job is lighting rather than background - matching a subject into an environment needs a plate first.

Honest expectation-setting: literal "HDRI" mentions across the SD/Comfy community sit at roughly 67 threads from 2024 through mid-2026 with no spike, and "environment map" is 7. This is a niche node for a niche job.

How it works

For each output pixel it builds a ray: a pinhole projection (rectilinear) where fov is the horizontal field of view and the vertical is scaled to your output aspect, or an equidistant fisheye mapping where fov is the angular diameter of the circle. The ray is rotated by yaw around Y, pitch around X and roll around Z, converted to longitude/latitude, then used to bilinearly sample the panorama. The horizontal wrap pads a repeated column at the 360° seam, so there's no visible line where the image joins itself.

Two consequences from the shipped code: rendering happens at output_width × output_height, independent of the panorama's resolution, and the back view flips only yaw - it keeps your pitch and roll and uses back_fov (default 150°) instead of fov.

It's an output node, and the frontend draws a live reprojection while you drag the sliders - you aim by eye, the full-resolution render happens on queue.

Inputs and outputs that matter

  • image_input (IMAGE) - the equirect panorama. It's a socket, not a file picker. The README says "load"; the schema says connect. Believe the schema.
  • yaw / pitch / roll - where the camera points and how it's tilted. Pitch is clamped to ±89° so you can't quite look at the zenith or the floor directly. Yaw wraps.
  • fov - front lens. 90° is a good default; 10–30° gives you a long-lens plate; push toward 179° and rectilinear edges stretch into soup, which is what fisheye is for.
  • lens_type - rectilinear or fisheye.
  • back_fov - the rear view's field of view, rendered whether you want it or not.
  • output_width / output_height - the render resolution, independent of the panorama's.
  • exposure - in stops: the source is multiplied by 2^exposure before reprojection.

Two outputs: front_view and back_view, both IMAGE. Wire them to SaveImage/PreviewImage, or keep going - a composite plate, an upscale, a depth ControlNet pass.

Install

Manager: search Apex Artist (listed in some places as Apex Artist - Image Resize). Manual is the usual:

cd ComfyUI/custom_nodes
git clone https://github.com/ApexArtist/comfyui-apex-artist.git
pip install -r comfyui-apex-artist/requirements.txt

Restart ComfyUI, then hard-refresh the browser - the aiming widget is a frontend extension, so a stale tab means missing sliders. No model files, and the pack's only dependency (opencv-python) is needed just for true .hdr/.exr/.pic panoramas; PNG, JPEG, WEBP and TIFF go through Pillow.

Traps

The output is float and keeps values above 1.0, but the preview does not. Bright sky in an HDR pano will show as flat white in the node's preview and on save, because the display path clips to 0–255. Take exposure negative (it's f-stops) to pull highlights back into range, or tone-map upstream.

True .hdr files get tone-mapped on the way in. The OpenCV path divides by 1 + pixel, so what reaches the renderer is already compressed - fine for looking at, useless if you wanted raw radiance for relighting. Core Load Image won't read .hdr/.exr either, so you need an EXR-aware loader upstream. First run: use a 2:1 PNG or JPEG and skip the question.

These are per-pixel ray samples in PyTorch. Cost scales with output resolution and batch size, so start at the default 1024×1024 and raise it once the framing is right.

CategoryApex Artist/Image

Inputs (10)

NameTypeDefaultDescription
image_inputIMAGE—
yawFLOAT0.0-360–360—
pitchFLOAT0.0-89–89—
rollFLOAT0.0-180–180—
fovFLOAT9010–179—
back_fovFLOAT15010–179—
lens_typeCOMBOrectilinear2 options: rectilinear, fisheye
output_widthINT102464–8192—
output_heightINT102464–8192—
exposureFLOAT0.0-5–5—

Outputs (2)

NameTypeDescription
front_viewIMAGE—
back_viewIMAGE—