Nodes/Orion4D Pixel-Shift Nodes for ComfyUI/Ensemble Super-Resolution (HDR)
ComfyUI Node

Ensemble Super-Resolution (HDR)

Run your upscaler N times and fuse the good parts

By orion4d·Created 12 months ago·Updated 12 months ago· 7
Ensemble Super-Resolution (HDR)
  • image
  • upscale_model
  • image_float
  • image_clamped
  • image16
use_fliptrue
use_translatetrue
randomize_each_runfalse
use_unsharptrue
passes8
translate_pixels1.50
interpolation
fusion_mode
mix_weight0.50
seed0
unsharp_amount0.30

The name sounds like marketing, but it's literal. Camera makers do "pixel shift" by nudging the sensor by sub-pixel amounts, stacking the shots, and recovering detail that sat between pixels. This node does the same thing to an AI upscaler: instead of trusting one upscale pass, it runs the model you give it several times on shifted and flipped copies, realigns them, and fuses the results. The output is a 32-bit float "digital RAW" master, values above 1.0 intact, ready for real color grading.

Know what it isn't, though, because the upscaling world is full of category confusion. This is the more pixels rung, not the more detail rung. It doesn't invent content the way SeedVR2 or SUPIR do - it makes whatever ESRGAN/SwinIR model you already own behave better. The README says it plainly: "this node will not correct AI image hallucinations." Feed it a good, finished image (it suggests 2000/3000px and an X2 or X4 model) as the last pass, not a broken render you're hoping to rescue.

How it works

The mechanism, from the source: every pass randomly shifts the image by up to translate_pixels in X and Y, optionally flips it, upscales through ComfyUI's standard upscale path (the same ImageUpscaleWithModel that powers plain upscaling - that's why it accepts a normal UPSCALE_MODEL), then un-flips and translates back scaled by the upscale factor so every pass lines up pixel-for-pixel. The aligned stack gets fused, sharpened with an unsharp mask that's deliberately not clamped, and split into three outputs.

That "not clamped" bit is the whole point. Mean/average fusion plus unsharp can push highlights past 1.0, which is exactly what you want before grading and exactly what a normal node will throw away.

The inputs that matter

image and upscale_model are obvious. The rest you actually set:

  • passes (default 8, 2–32) - the quality/CPU knob. More passes = better noise and artifact removal, but each one is a full upscale run. 6–12 is the sweet spot; below 4 the benefits vanish, above 16 the gains shrink while the render time climbs.
  • use_translate (default true) - this is the pixel-shift. Leave it on; without it you're just averaging N identical upscales.
  • translate_pixels (default 1.5) - max shift distance. 0.75–1.5 is the sensible band; above 3.0 you start getting realignment problems at the borders.
  • fusion_mode / mix_weight - MEAN kills random noise, MEDIAN kills outlier artifacts, MIX blends both. Leave it on MIX at 0.5.
  • use_flip (true), unsharp_amount (0.3), seed + randomize_each_run (leave randomize false unless you want a different result every queue even with a fixed seed).

One quiet trap: interpolation defaults to BICUBIC, but the source falls back to BILINEAR automatically when BICUBIC isn't supported on the Tensor backend - and the README recommends BILINEAR anyway. So if you set BICUBIC and notice soft output, that fallback is probably why.

Outputs

Three IMAGE sockets: image_float (the unclamped float32 master - values can exceed 1.0), image_clamped (same thing forced to 0–1, for previews and standard nodes), and image16 (16-bit quantized from the clamped version, ready for a plain PNG). Wire image_float into the pack's Save Image Advanced node and you have a real grading pipeline.

Model choice actually matters

The node orchestrates; the model sets the character. ESRGAN derivatives (4x-UltraSharp, Remacri) are sharp and can hallucinate texture - the ensemble averaging is genuinely good at taming that. SwinIR is cleaner and more faithful but softer; the unsharp pass is welcome there. Anime models work too - the multi-pass fusion tends to clean up flat-color banding and compression artifacts.

Install and gotchas

ComfyUI Manager, search "Orion4D Pixel-Shift", or:

cd ComfyUI/custom_nodes
git clone https://github.com/orion4d/Orion4D_pixelshift

Then the part that bites: the pack ships no requirements.txt, so Manager won't install its deps for you. You need them for the save node, but they're harmless here:

pip install imageio tifffile opencv-python-headless

Restart after. No models to download - you load your upscaler with the normal UpscaleModelLoader. The real cost is time: 8 passes is roughly 8x a single upscale. Budget accordingly, and don't judge the node by the clamped preview alone - the float master is the point.

CategoryPixel-Shift

Inputs (13)

NameTypeDefaultDescription
imageIMAGE
upscale_modelUPSCALE_MODEL
use_flipBOOLEANtrue
use_translateBOOLEANtrue
randomize_each_runBOOLEANfalse
use_unsharpBOOLEANtrue
passesINT82–32
translate_pixelsFLOAT1.500–8
interpolationCOMBO3 options: BICUBIC, BILINEAR, NEAREST
fusion_modeCOMBO3 options: MIX, MEAN, MEDIAN
mix_weightFLOAT0.500–1
seedINT00–2147483647
unsharp_amountFLOAT0.300–2

Outputs (3)

NameTypeDescription
image_floatIMAGE
image_clampedIMAGE
image16IMAGE