KSampler Affine Advanced
The affine sampler for two-pass people
- model
- positive
- negative
- latent_image
- affine_schedule
- external_mask
- options
- noise_options
- LATENT
- MASK
If KSampler Affine is the easy drop-in, this is the one for people who already live in KSamplerAdvanced territory. It's the same integrated affine sampling - apply scale/bias transforms between steps, where a pattern mask says so, on a schedule - plus the KSamplerAdvanced controls that let you decide exactly which slice of the denoising range it operates on.
What you get over the plain version
All the standard inputs (model, positive, negative, latent_image, add_noise, seed, steps, cfg, sampler_name, scheduler, denoise) and all the affine controls (affine_interval, max_scale, max_bias, pattern, affine_seed, affine_seed_increment, affine_schedule, temporal_mode). Then the advanced extras:
- start_at_step / end_at_step - run only the given slice of the step range, KSamplerAdvanced style. This is the whole point for two-pass workflows: run a first sampler, then let this node handle just the low-noise tail with affine applied, instead of manually placing a Latent Affine between passes.
- return_with_leftover_noise - force the last step to full-denoise behavior, for when you want to chain into another pass.
- merge_inactive_steps - greedily merge steps outside the active schedule window into bigger batches (default on) so you're not wasting passes.
One difference from the plain KSampler Affine: temporal_mode (static/per_frame) is required here rather than optional, which is the node being honest about its target - video and multi-pass work.
Also note cfg accepts a single float or a list for per-step CFG, with the last value repeated if the list is shorter than the step count. Nice if you already run scheduled-CFG workflows.
Outputs: LATENT and MASK, same as the plain sampler.
When this beats the manual workflow
The classic pattern is: KSampler for high-noise steps → Latent Affine → KSampler for the tail. This node collapses that into one sampler that only acts on the slice you give it, with the affine built in and scheduled. For a hi-res-fix-style second pass where you want a specific denoise window (the 0.3–0.5 range that the two-pass guides keep landing on), start_at_step/end_at_step plus a gentle max_scale around 1.05–1.1 is a clean setup.
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 only.
Common issues
The step-range inputs are inclusive/exclusive (start inclusive, end exclusive) - off-by-one there is the standard gotcha, and it's why people see the node "doing nothing" when they set the window wrong. If you're not using start/end at all, this behaves like a normal sampler, so remember the affine only fires inside the active window. And since add_noise defaults to True here, for a second-pass use you'll usually want it off so you don't re-noise your existing latent.
Inputs (26)
| 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. | |
| add_noise | BOOLEAN | true | Add initial noise at the first step (common for text-to-image). |
| 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; 2 = every 2 steps, etc.). 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). | |
| temporal_mode | COMBO | static | Temporal behavior of the affine mask for video latents. 'static': one mask reused across all frames at each application. 'per_frame': re-generate mask per frame (livelier/noisier motion). |
| 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'. | |
| start_at_stepopt | INT | 00–10000 | First step index (inclusive) to run within the sampler. |
| end_at_stepopt | INT | 100000–10000 | End step index (exclusive) within the sampler. |
| return_with_leftover_noiseopt | BOOLEAN | false | If true, force last step to full denoise behavior. |
| 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 | — |