Nodes/WAS_Extras/Latent Hybrid Upscale
ComfyUI Node

Latent Hybrid Upscale

Latent upscaling that protects edges instead of smearing them

By WASasquatch·Created 3 years ago·Updated 17 days ago· 43
Latent Hybrid Upscale
  • latent
  • vae
  • donor_latent
  • latent
  • edge_mask
scale2.00
pre_blur_sigma_px1.00
canny_threshold125
canny_threshold2155
canny_l2gradienttrue
dilate_radius_px8
feather_sigma_px6.00
mask_min0.00
mask_max1.00
use_nearest_exacttrue
output_mask_resolutionimage
video_decode_horizontal_tiles2
video_decode_vertical_tiles2
video_decode_overlap_latent4
video_decode_last_frame_fixfalse
video_decode_enable_cudnntrue

Plain latent upscaling - the nearest/bilinear resize you get from ComfyUI's stock latent upscale node - is fast, but it doesn't know where your edges are. It'll happily smear a hard line between a subject and its background right along with the smooth gradients. Latent Hybrid Upscale (class WASLatentUpscaleHybrid) is WAS_Extras' answer: it decodes the latent, figures out where the real edges are, and uses that map to protect them while it upscales.

This is one of several nodes the pack's author, WASasquatch, has shipped since retiring the old WAS Node Suite (the sprawling original pack, archived June 2025 and now community-forked). WAS_Extras is the newer, smaller, still-actively-updated home for stuff like this - don't confuse the two if you're hunting for it in ComfyUI Manager.

How it works

The node decodes your latent to pixel space with the vae you feed it, then runs a Canny edge detector (via OpenCV, "if available" per the pack's own README) to build an edge mask - dilated and feathered so it's a soft band around edges rather than a hard line. That mask governs how the upscale blends: near edges it leans on the decoded image-space detail to avoid ringing and haloing; elsewhere it upscales the latent more freely. You can also hand it a donor_latent to blend in instead of relying purely on the computed scale. It has explicit handling for video latents too, with its own tiled-decode controls so a long clip doesn't blow your VRAM at the decode step.

The inputs and outputs that matter

  • latent, vae - required, the obvious two.
  • scale (default 2, range 1–8) - the one knob you'll actually touch day to day.
  • canny_threshold1 / canny_threshold2 / canny_l2gradient / pre_blur_sigma_px - tune how aggressively the edge detector fires. Leave at defaults until you see ringing or a mask that's obviously wrong.
  • dilate_radius_px / feather_sigma_px / mask_min / mask_max - grow and soften the edge band, and clamp how strong its influence gets.
  • use_nearest_exact - the resize kernel used away from edges.
  • output_mask_resolution (image or latent) - whether the mask output matches your image size or your latent size.
  • video_decode_* group (horizontal_tiles, vertical_tiles, overlap_latent, last_frame_fix, enable_cudnn) - only relevant when your latent is a video batch; these tile the decode step to keep it VRAM-safe.
  • Optional donor_latent.

Outputs: latent (the upscaled result, wire straight into your next sampler or VAE decode) and edge_mask (a MASK you can preview to sanity-check what the node thought counted as an edge, or feed into a compositing step).

How to install it

Via ComfyUI Manager: search WAS_Extras, install, restart. Manually:

cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/WAS_Extras

Then restart ComfyUI. None of the requirements-file dependencies the README mentions apply to this node - those are for a different file in the pack (the sampler sequencer). This one just needs OpenCV.

Common issues & troubleshooting

Edge mask looks blank or solid. The README is explicit that Canny detection depends on OpenCV being importable - if opencv-python isn't installed in ComfyUI's Python environment, run pip install opencv-python there. Otherwise, your canny_threshold1/canny_threshold2 pair is probably mismatched for your image's contrast; nudge them before assuming the node is broken.

You grabbed the wrong node from a shared workflow. WAS_Extras ships a second, related node - WAS Adaptive Difference Latent Upscale (Damped) - that does a similar-sounding but different job (damping the upscale delta near edges rather than Canny-masking in image space). If a downloaded workflow's behavior doesn't match what's described here, check you actually have WASLatentUpscaleHybrid and not its sibling.

VRAM spikes on video latents. The decode step for a batch of frames is where this bites. Reduce video_decode_horizontal_tiles/vertical_tiles, or increase overlap_latent only if you're seeing seams - it costs more VRAM, not less.

Ringing near hard edges at high scale. Back off dilate_radius_px or raise feather_sigma_px so the protected band is softer and wider rather than a hard cutout.

Categorylatent/upscale

Inputs (19)

NameTypeDefaultDescription
latentLATENT
vaeVAE
scaleFLOAT2.001–8
pre_blur_sigma_pxFLOAT1.000–20
canny_threshold1INT250–1000
canny_threshold2INT1550–1000
canny_l2gradientBOOLEANtrue
dilate_radius_pxINT80–64
feather_sigma_pxFLOAT6.000–50
mask_minFLOAT0.000–1
mask_maxFLOAT1.000–1
use_nearest_exactBOOLEANtrue
output_mask_resolutionCOMBOimage2 options: image, latent
video_decode_horizontal_tilesINT21–8
video_decode_vertical_tilesINT21–8
video_decode_overlap_latentINT40–32
video_decode_last_frame_fixBOOLEANfalse
video_decode_enable_cudnnBOOLEANtrue
donor_latentoptLATENT

Outputs (2)

NameTypeDescription
latentLATENT
edge_maskMASK