Image Upscale Sampler (CRT)
Image Upscale Sampler (CRT)
- model
- positive
- negative
- image
- latent
- vae
- image
- latent
Image Upscale Sampler (CRT) is a tiled upscale-and-redetail node: it splits your image into a grid of tiles, optionally runs an AI upscale model, runs a fresh sampling pass on each tile, then stitches them back with feathered blending and color matching. Display name says "Upscale Sampler," class name says PonyUpscaleSamplerWithInjection - the Pony part is history, a leftover from the node's SD1.5-era origin; what it actually is today is a general generative-upscale pass that works with whatever checkpoint you feed it, FLUX included.
It sits on the "more detail" rung of the upscaling ladder, the one the KB separates from plain pixel interpolation. Pixel upscalers add resolution and nothing else; this node adds content - texture, grain, face detail - by re-rendering the image through your model at a larger working size. The tiling is what makes that feasible on consumer VRAM: instead of one giant latent, it processes a grid of manageable tiles and blends the edges so no seam shows. That's the same tiled-diffusion idea as Ultimate SD Upscale or the multidiffusion extension, pulled into one node with the CRT two-stage sampler underneath.
Here's the flow, readable off the inputs. tile_grid (2x2 up to 8x8, default 4x4) sets how the image is divided; tile_size_megapixels (default 1.0) is the per-tile budget that drives the upscale factor. Each tile gets padding (tile_padding, default 5%) so the model sees context across the edge, and results are blended with a blurred mask (mask_blur, default 10) so tile boundaries disappear. Optionally you can run a real ESRGAN-style AI upscaler first by enabling enable_upscale_model and picking from upscale_model_name (your models/upscale_models folder) - that's the "more pixels" stage. Then the per-tile sampling pass does the "more detail" stage: defaults euler, simple, cfg 1.0, steps 4, denoise 0.33 - a light img2img re-render, not a from-scratch generation. The two-stage schedule (stage1_sigma_*, stage2_sigma_*, details_amount_stage1/2) and the noise-injection block (enable_noise_injection, injection_point, injection_strength, injection_seed_offset) give you fine control over how much invented texture lands in the final image. vae_decode_tiled (default on) keeps the decode from blowing VRAM on huge outputs, and color_match_strength re-aligns the result with the source colors so a redetail pass doesn't drift the palette.
Inputs a beginner actually sets: model, positive, image (optional - if you leave it out, plug latent instead and it works entirely in latent space), denoise, steps, tile_grid, enable_upscale_model + upscale_model_name if you have an upscaler, and color_match_strength. Optional negative and vae round it out. Outputs: image (the composited result) and latent (the latent version, handy if you want to keep working in latent space or chain another pass).
Grounded gotchas. Start with denoise near the default 0.33 - this is a detail pass, and cranking denoise toward 1.0 turns it into a full re-render that changes composition, which is the classic "why did my face change" complaint from the KB's upscaling doc. seed_shift adds variation across runs. If tiles look mismatched, raise tile_padding and mask_blur. And expect it to be slower than a plain ESRGAN upscale - that's the price of generating detail rather than interpolating it.
Install with the pack (ComfyUI Manager → search "CRT-Nodes", or clone https://github.com/plugcrypt/CRT-Nodes.git into custom_nodes, pip install -r requirements.txt, restart). The color-matcher dependency is required for the color-matching path - it's in the requirements file, but if you see a "ColorMatch requires color-matcher" error, that's the missing piece, installable with pip install color-matcher.
Inputs (35)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| positive | CONDITIONING | — | |
| sampler_name | COMBO | euler | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 |
| scheduler | COMBO | simple | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 |
| cfg | FLOAT | 1.00–100 | Classifier Free Guidance scale. Higher values follow the prompt more closely. |
| steps | INT | 41–10000 | — |
| denoise | FLOAT | 0.330–1 | Amount of denoising to apply. 1.0 = full denoising (txt2img), 0.5-0.8 typical for img2img. |
| seed | INT | 00–18446744073709550000 | — |
| seed_shift | INT | 0-100000–100000 | Offset added to the main seed for variation |
| edit_model_flux2klein | BOOLEAN | false | Enable per-tile ReferenceLatent-style conditioning for edit models |
| enable_upscale_model | BOOLEAN | false | Enable AI model upscaling before sampling |
| upscale_model_name | COMBO | Select upscale model from models/upscale_models folder | |
| tile_size_megapixels | FLOAT | 1.00.1–16 | Target megapixels per tile used to derive upscale factor |
| tile_grid | COMBO | 4x4 | Grid size for tiling (e.g., 4x4 = 16 tiles) |
| tile_padding | FLOAT | 5.00–25 | Padding around each tile as percentage of tile size |
| mask_blur | FLOAT | 10.00–50 | Blur radius for tile blending as percentage of tile size |
| stage1_sigma_factor | FLOAT | 1.0050–100 | — |
| stage2_sigma_factor | FLOAT | 0.9950–100 | — |
| stage1_sigma_start | FLOAT | 0.3000–1 | — |
| stage1_sigma_end | FLOAT | 0.5000–1 | — |
| stage2_sigma_start | FLOAT | 0.0000–1 | — |
| stage2_sigma_end | FLOAT | 0.7000–1 | — |
| details_amount_stage1 | FLOAT | 0.50-5–5 | — |
| details_amount_stage2 | FLOAT | 0.15-5–5 | — |
| enable_noise_injection | COMBO | disable | Enable noise injection during sampling |
| injection_point | FLOAT | 0.750–1 | Percentage of steps after which to inject noise |
| injection_seed_offset | INT | 1-100–100 | Offset added to main seed for injection noise |
| injection_strength | FLOAT | 0.25-20–20 | Strength of injected noise |
| normalize_injected_noise | COMBO | enable | Normalize injected noise to match latent statistics |
| vae_decode_tiled | BOOLEAN | true | Use tiled VAE decode. Tile size and overlap are derived from tile size megapixels and tile padding. |
| color_match_strength | FLOAT | 1.000–2 | Strength of color matching between original and enhanced result. 0.0 = disabled, 1.0 = full matching |
| negativeopt | CONDITIONING | — | |
| imageopt | IMAGE | — | |
| latentopt | LATENT | — | |
| vaeopt | VAE | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| latent | LATENT | — |