Latent Upscale (WIP Exp.)
An experimental latent resizer that cares about edges
- latents
- LATENT
The display name is honest about this one: Latent Upscale (WIP Exp.). It resizes a latent in latent space - the "stay out of pixel space" trick that keeps big upscales fast - but unlike ComfyUI's plain latent resize, it actually tries not to smear your edges. It's experimental, so treat it as a toy with promise, not a production workhorse.
How it works
The trick is splitting the latent into a low-pass and high-pass component before resizing, then treating them differently:
- Split: blur the latent with a Gaussian of sigma
hp_sigma(default 0.5) to get the low-pass; the high-pass is original minus blurred.hp_sigma0 disables the split entirely. - Resize: in
hybridmode (default), the low-pass goes up with bicubic + antialiasing (smooth, no shimmer) while the high-pass goes up with nearest-neighbor (crisp, no smearing), then the high-pass std is rescaled to match the original via variance matching. - Optional renoise:
renoise(0–1) adds high-frequency noise back, and ifcurrent_sigma> 0 it's scaled by that sigma - meaning you can feed this node mid-sampling and add noise proportional to how much denoising remains.
The other modes are plain bicubic, bilinear, or nearest for the whole thing, with antialias where supported.
Inputs and outputs
- latents - a LATENT dict. Handles the standard [B,C,H,W], and also squeezes a singleton frame dimension from [B,C,1,H,W] latents (e.g. Qwen-style), which is a nice compatibility touch.
- scale_by (default 2) - upscale factor in latent space, 1–8.
- Optional: mode, antialias, hp_sigma, renoise, current_sigma, seed.
Output: LATENT, same shape as input scaled by scale_by.
When to use it
If you're building a latent-space hi-res-fix pipeline - upscale the latent, run a second denoise pass at low denoise - this is the resize step. It fits the two-pass philosophy from the upscaling playbook: get the pixels bigger in latent space, then let a second sampler add detail back. The variance-matched hybrid mode is the reason to pick this over core's plain latent resize.
Installing
Part of WAS Affine by WASasquatch. ComfyUI Manager → Install Custom Nodes → search "WAS Affine" → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/was_affine
Restart ComfyUI. ComfyUI 1.0.0+, torch and numpy.
Common issues
It's marked WIP for a reason: latent-space resizing is inherently lossy vs. pixel-space upscalers, and you can get mushy structure or artifacts that a real ESRGAN pass wouldn't have. If the result looks soft, try renoise above 0 with a current_sigma set - the renoise path is exactly for re-seeding texture. And don't reach for this when you want a final high-quality upscale; that's the job of pixel-space upscalers, not a latent resize.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| latents | LATENT | Latent dict with key 'samples' shaped [B,C,H,W]. Also accepts [B,C,1,H,W] (e.g., Qwen) and will squeeze the singleton frame dimension automatically. | |
| scale_by | FLOAT | 2.001–8 | Upscale factor in LATENT space. |
| modeopt | COMBO | Hybrid = LP bicubic(+AA) + HP nearest with variance match. | |
| antialiasopt | BOOLEAN | true | Antialias for bilinear/bicubic where supported. |
| hp_sigmaopt | FLOAT | 0.500–3 | Gaussian σ for LP/HP split. 0 disables split. |
| renoiseopt | FLOAT | 0.000–1 | Optional additional HP noise (0–1). |
| current_sigmaopt | FLOAT | 0.00000–2000 | If >0, scales renoise by this sigma. |
| seedopt | INT | 00–18446744073709550000 | RNG seed for renoise. 0 = nondeterministic. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |