KSampler Affine
Detail enhancement baked into the sampler, no bolt-on
- model
- positive
- negative
- latent_image
- affine_schedule
- external_mask
- options
- noise_options
- LATENT
- MASK
KSampler Affine is a drop-in replacement for the plain KSampler that applies the WAS Affine transform inside the sampling loop instead of as a separate node between passes. Same idea as the two-sampler manual workflow - nudge the latent where a mask says so - but the sampler handles the scheduling, so you get the effect without wiring up a second KSampler and a Latent Affine in the middle.
How it works
All the standard KSampler inputs are there - model, positive, negative, latent_image, seed, steps, cfg, sampler_name, scheduler, denoise. On top of them sit the affine controls:
- affine_interval (default 1) - apply affine every N steps. 1 = every step, 2 = every other step. Doesn't change total steps.
- max_scale / max_bias - the peak values at the schedule's strongest point. Scale is interpolated as
1 + (max_scale - 1) * twhere t comes from your schedule; bias asmax_bias * t. - pattern - the mask pattern (default white_noise).
- affine_seed / affine_seed_increment - a seed separate from the sampler seed, so the mask changes independently of the image content. Increment rolls it per application, which is what you want for temporal masks.
- affine_schedule - a DICT from WASAffineScheduleOptions, interpreted over total steps. Leave it unplugged and the defaults apply.
- Optional:
external_mask(gates where affine applies),optionsandnoise_options(mask tuning DICTs), andmerge_inactive_steps(greedily merges steps outside the active schedule window into bigger batches to save time; default on).
The schedule is the real control. From the author's own comparison workflow, the sensible starting shape is start 0.1 → end 0.3 with easeInOutSine: affine bites in the early-to-mid steps, then gets out of the way while the sampler settles detail. Pair it with a high-pass pattern (highpass_white, perlin) for texture, or green/pink for natural-ish detail.
Outputs: LATENT (your sampled latent, straight to VAE Decode) and MASK (the mask from the last affine application - preview it to see what got affected).
Why reach for it
It's the integrated path the README sells as "Option 2": automatic scheduling, no manual node choreography, and everything stays in latent space so it's cheap. If you're already tweaking a KSampler workflow and the image is close but the detail reads flat or the contrast looks burned (classic speed-LoRA symptom), this is a low-friction experiment: swap the KSampler, set max_scale ~1.05–1.1, and A/B it.
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, no model downloads.
Common issues
The usual mistake is max_scale way too high. 1.2 is the default ceiling, not a suggestion - at that strength with a hard pattern you'll reshape the image, not enhance it. Also remember the affine seed is independent: same sampler seed, different affine_seed, different result, so when you're chasing a seed, don't forget there are two of them. And if you see banding, that's the mask edges - blur them via options (blur_sigma ~1.5).
Inputs (21)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | Diffusion model to sample with. | |
| positive | CONDITIONING | Positive prompt conditioning. | |
| negative | CONDITIONING | Negative prompt conditioning. | |
| latent_image | LATENT | Input latent to continue sampling from. | |
| seed | INT | 00–2147483647 | Random seed for the sampler. |
| steps | INT | 201–200 | Number of denoising steps. |
| cfg | FLOAT | 4.50–100 | Classifier-free guidance scale. Can be a single float value or a list of float values for per-step CFG. If list is shorter than total steps, the last value will be repeated for remaining steps. |
| sampler_name | COMBO | The algorithm used when sampling, this can affect the quality, speed, and style of the generated output. | |
| scheduler | COMBO | The scheduler controls how noise is gradually removed to form the image. | |
| denoise | FLOAT | 1.000–1 | Fraction of noise to remove (lower = stronger preserve). |
| affine_interval | INT | 11–100 | Interval in steps to apply affine (1 = every step). Does not change total steps. |
| max_scale | FLOAT | 1.2000–2 | Upper bound on multiplicative affine strength applied at schedule peak. |
| max_bias | FLOAT | 0.000-2–2 | Upper bound on additive bias applied at schedule peak. |
| pattern | COMBO | white_noise | Mask/noise pattern used when applying affine between sampling steps. |
| affine_seed | INT | 00–2147483647 | Seed for affine mask generation (separate from sampler seed). |
| affine_seed_increment | BOOLEAN | false | If enabled, increment affine seed for each group application (temporal masks). |
| affine_schedule | DICT | Use WASAffineScheduleOptions (interpreted over total steps). | |
| external_maskopt | IMAGE | Optional external mask image; when provided and pattern != external_mask, it gates where affine applies. | |
| optionsopt | DICT | Base options DICT for affine (e.g., common or full options). | |
| noise_optionsopt | DICT | Pattern-specific overrides that layer onto 'options'. | |
| merge_inactive_stepsopt | BOOLEAN | true | Greedily merge steps outside the active schedule window into larger batches. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |
| MASK | MASK | — |