▭ Auto Outpaint (Illustrious)
Canvas extension without hand-building a mask chain
- image
- model
- clip
- vae
- refiner_model
- image
- latent
Outpainting the manual way is a fair number of nodes: pad the canvas, paint or generate a border mask, VAE-encode with that mask, sample, decode, deal with the seam. This node collapses all of that into one block - feed it your image plus model/clip/vae directly, tell it how far to expand each side, and it builds its own border mask and handles sampling internally. The pack's own docs say this outright: VAE "regional" mode isn't required for it, because the node isn't routing through the regional-conditioning path at all - it's self-contained.
Why a dedicated node still earns its keep in 2026
A lot of casual outpainting has moved to instruction-editing models - pad the canvas with a solid color and ask the model to fill it in. That's genuinely faster for a lot of cases. But it comes with a real cost: those models re-render the whole frame, so your original pixels drift slightly even where you didn't want anything to change, and the drift compounds if you extend more than once. Mask-based outpainting like this node doesn't have that problem, and since it wires model/clip/vae straight from your existing Illustrious graph, it's the right tool when you want to stay on your checkpoint rather than round-trip through a different architecture.
How it handles the actual growing
expand_left/right/top/bottom (default 256px each, independently adjustable) set how far each side extends. Internally the node runs something close to a two-phase process: two_stage_growth and grow_steps_frac/grow_denoise rough in the new content at high denoise first, then refine_denoise (default 0.55) tightens it up - you can even hand that refine phase to a completely different model via refiner_model if you want a slower, detail-focused checkpoint doing the polish pass while a faster one does the rough growth.
seam_toning, seam_tone_strength, and seam_feather_px target the outpainting failure mode everyone hits eventually: a visible pasted-on border where old and new content meet. This is the same fix good manual outpainting always needed - generous overlap, real feathering, decreasing denoise near the seam - just exposed as parameters instead of something you build by hand.
Two fields worth flagging honestly: weight_interpretation and token_normalization both say in their own tooltips that they require a separate BNK advanced encoder to actually do anything. If you don't have that wired in, treat these two as inert regardless of what you set them to.
The inputs and outputs that matter
image,model,clip,vae- required, this node needs your full pipeline, not just a checkpoint.expand_left/right/top/bottom- the core control, all default 256px.denoise(0.65 default) controls how much of the new region is free invention versus staying close to a rough fill.feather_px(64) softens the boundary before sampling even starts, on top of the later seam-toning pass.
Outputs: image and latent - you get both, so you can decode immediately or keep working in latent space.
Installing it
ComfyUI Manager: search "EasyIllustrious," install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/regiellis/ComfyUI-EasyIllustrious
pip install -r ComfyUI-EasyIllustrious/requirements.txt
No extra downloads for this node specifically.
Common issues
Visible seam despite seam_toning being on. Raise seam_feather_px before seam_tone_strength - a narrow feather zone gives the tone-matching less room to work with, no matter how strong you set it. The default 256px expansion per side is deliberately generous for the same reason: too small an expansion gives the blend nothing to work into.
weight_interpretation or token_normalization seem to do nothing. That's expected unless you've got a BNK advanced encoder wired into your graph - both fields say so in their own tooltips.
Inputs (33)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| model | MODEL | — | |
| clip | CLIP | — | |
| vae | VAE | — | |
| prompt | STRING | — | |
| negative | STRING | — | |
| expand_left | INT | 2560–4096 | — |
| expand_right | INT | 2560–4096 | — |
| expand_top | INT | 2560–4096 | — |
| expand_bottom | INT | 2560–4096 | — |
| steps | INT | 301–200 | — |
| cfg | FLOAT | 5.500–20 | — |
| sampler_name | COMBO | euler_ancestral | 8 options: euler, euler_ancestral, ddim, dpmpp_2m, dpmpp_2m_sde, dpmpp_sde, +2 |
| scheduler | COMBO | normal | 4 options: normal, karras, exponential, sgm_uniform |
| seed | INT | 00–2147483647 | — |
| denoise | FLOAT | 0.650–1 | — |
| noise_outside | FLOAT | 1.000–1 | — |
| feather_px | INT | 640–1024 | — |
| scene_hint | COMBO | none | 5 options: none, landscape, interior, street, portrait |
| two_stage_growth | BOOLEAN | true | — |
| use_refiner | BOOLEAN | false | — |
| two_phase_schedule | BOOLEAN | false | — |
| grow_steps_frac | FLOAT | 0.450.05–0.9 | — |
| grow_denoise | FLOAT | 0.900–1 | — |
| refine_denoise | FLOAT | 0.550–1 | — |
| seam_toning | BOOLEAN | true | — |
| seam_tone_strength | FLOAT | 0.250–1 | — |
| seam_feather_px | INT | 488–256 | — |
| refiner_modelopt | MODEL | — | |
| refiner_stepsopt | INT | 121–60 | — |
| refiner_denoiseopt | FLOAT | 0.220–1 | — |
| weight_interpretationopt | COMBO | comfy | How to apply token weights; requires BNK advanced encoder for non-comfy modes. |
| token_normalizationopt | COMBO | none | Normalize token weights; requires BNK advanced encoder to take effect. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| latent | LATENT | — |