KSampler Hires Fix (Umbra UI)
A Forge-style hires fix in one node — with an honest upscale list
- model
- vae
- positive
- negative
- latent_image
- samples
- model_name
- seed
- steps
- cfg
- sampler_name
- scheduler
- hires_seed
Hires fix is the oldest trick in the book and still the most reliable one: generate at native resolution, upscale, then run a low-denoise second pass so the model spends its detail budget on pixels that exist instead of hallucinating them. KSampler Hires Fix (Umbra UI) packages that two-pass loop into a single node the way Forge and A1111 users remember it - one checkbox, one upscaler selector, one set of hires-specific settings. If you've been hand-assembling UpscaleLatent → VAEDecode → ImageScale → VAEEncode → second sampler chains, this is the one node that replaces the whole pile.
How it works
The first pass is a normal common_ksampler run with your base steps/cfg/denoise. Then, if enabled is on, it takes the output latent and upscales it by one of three routes:
- Latent - upscales the latent directly (default method
bislerp). Cheapest, slightly soft, and perfectly fine for SDXL-class models. - Pixel methods -
Nearest,Bilinear,Area,Bicubic,Lanczos: it decodes to pixels, resizes, re-encodes. Cleaner edges, costs a VAE round-trip. - A real upscale model - it scans your
upscale_modelsfolder and offers them in the dropdown, defaulting to4x-AnimeSharp.pth. It decodes, runs the model, then downscales to the exact target size with Lanczos so the output matches what you asked for.
The target size is where this node is genuinely well-behaved. resize_mode gives you upscale by (scale scale_by, default 2.0) or resize to (exact resize_width/resize_height, missing dimension auto-derived from aspect). Everything is rounded to multiples of 8, and if only one resize to dimension is set, the other is computed from the source aspect ratio - no stretching. The second pass then runs with its own settings: hires_steps (0 = inherit base), hires_cfg (0 = inherit), hires_sampler_name/hires_scheduler (both default to "Use same"), and hires_denoise (default 0.35 - the sweet spot for a detail pass; too high and you get a different image, too low and the upscale just looks like a blurry zoom).
The settings a beginner actually sets
Three knobs do 90% of the work: enabled (it's off by default - flip it on), upscaler (start with Latent on low VRAM, 4x-AnimeSharp.pth when you want sharpness), and hires_denoise (0.3–0.4). scale_by of 2.0 is the safe default. Everything else has sane inheritance behavior, which is the point - you shouldn't have to re-pick your sampler for the second pass.
Installing it
Ships in Umbra-Nodes, the ComfyUI companion pack for Umbra Studio (NocturneLabs' open-source local AI suite). ComfyUI Manager → search "Umbra Nodes", or clone:
cd ComfyUI/custom_nodes
git clone https://github.com/Nocturne-Ai-Labs/Umbra-Nodes
Restart ComfyUI. No pip deps, but if you want the model-based upscaler you need 4x-AnimeSharp.pth (or any ESRGAN-family .pth) in ComfyUI/models/upscale_models/. The pixel and latent routes need nothing extra.
Gotchas
Two classic traps. VRAM. The pixel and model routes decode to full-resolution pixels before the second pass - on a 6GB card a 2x latent upscale at high base resolution can OOM. If it dies mid-hires, fall back to Latent, or drop scale_by to 1.5. And don't over-denoise: the whole point is a gentle refinement pass, and cranking hires_denoise toward 1.0 turns it into a full re-generation that can drift colors and identity. Also note the output's hires_seed matches the base seed - the second pass reuses it, which is what keeps the refinement deterministic.
Inputs (22)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| vae | VAE | — | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| latent_image | LATENT | — | |
| seed | INT | 00–18446744073709550000 | — |
| steps | INT | 241–10000 | — |
| cfg | FLOAT | 7.00–100 | — |
| sampler_name | COMBO | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 | |
| scheduler | COMBO | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 | |
| denoise | FLOAT | 1.000–1 | — |
| enabled | BOOLEAN | false | — |
| upscaler | COMBO | Latent | 12 options: Latent, Latent (nearest-exact), Latent (bilinear), Latent (area), Latent (bicubic), Latent (bislerp), +6 |
| resize_mode | COMBO | upscale by | 2 options: upscale by, resize to |
| scale_by | FLOAT | 2.001–8 | — |
| resize_width | INT | 00–16384 | — |
| resize_height | INT | 00–16384 | — |
| hires_steps | INT | 00–10000 | — |
| hires_cfg | FLOAT | 0.00–100 | — |
| hires_sampler_name | COMBO | Use same | 45 options: Use same, euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, +39 |
| hires_scheduler | COMBO | Use same | 10 options: Use same, simple, sgm_uniform, karras, exponential, ddim_uniform, +4 |
| hires_denoise | FLOAT | 0.350–1 | — |
Outputs (8)
| Name | Type | Description |
|---|---|---|
| samples | LATENT | — |
| model_name | STRING | — |
| seed | INT | — |
| steps | INT | — |
| cfg | FLOAT | — |
| sampler_name | STRING | — |
| scheduler | STRING | — |
| hires_seed | INT | — |