Nodes/WAS Affine/KSampler Affine Advanced
ComfyUI Node

KSampler Affine Advanced

The affine sampler for two-pass people

By WASasquatch·Created about a year ago·Updated 4 months ago· 5
KSampler Affine Advanced
  • model
  • positive
  • negative
  • latent_image
  • affine_schedule
  • external_mask
  • options
  • noise_options
  • LATENT
  • MASK
add_noisetrue
seed0
steps20
cfg4.5
sampler_name
scheduler
denoise1.00
affine_interval1
max_scale1.200
max_bias0.000
patternwhite_noise
affine_seed0
affine_seed_incrementfalse
temporal_modestatic
start_at_step0
end_at_step10000
return_with_leftover_noisefalse
merge_inactive_stepstrue

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.

Categorysampling/ksampler

Inputs (26)

NameTypeDefaultDescription
modelMODELDiffusion model to sample with.
positiveCONDITIONINGPositive prompt conditioning.
negativeCONDITIONINGNegative prompt conditioning.
latent_imageLATENTInput latent to continue sampling from.
add_noiseBOOLEANtrueAdd initial noise at the first step (common for text-to-image).
seedINT00–2147483647Random seed for the sampler.
stepsINT201–200Number of denoising steps.
cfgFLOAT4.50–100Classifier-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_nameCOMBOThe algorithm used when sampling, this can affect the quality, speed, and style of the generated output.
schedulerCOMBOThe scheduler controls how noise is gradually removed to form the image.
denoiseFLOAT1.000–1Fraction of noise to remove (lower = stronger preserve).
affine_intervalINT11–100Interval in steps to apply affine (1 = every step; 2 = every 2 steps, etc.). Does not change total steps.
max_scaleFLOAT1.2000–2Upper bound on multiplicative affine strength applied at schedule peak.
max_biasFLOAT0.000-2–2Upper bound on additive bias applied at schedule peak.
patternCOMBOwhite_noiseMask/noise pattern used when applying affine between sampling steps.
affine_seedINT00–2147483647Seed for affine mask generation (separate from sampler seed).
affine_seed_incrementBOOLEANfalseIf enabled, increment affine seed for each group application (temporal masks).
affine_scheduleDICTUse WASAffineScheduleOptions (interpreted over total steps).
temporal_modeCOMBOstaticTemporal 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_maskoptIMAGEOptional external mask image; when provided and pattern != external_mask, it gates where affine applies.
optionsoptDICTBase options DICT for affine (e.g., common or full options).
noise_optionsoptDICTPattern-specific overrides that layer onto 'options'.
start_at_stepoptINT00–10000First step index (inclusive) to run within the sampler.
end_at_stepoptINT100000–10000End step index (exclusive) within the sampler.
return_with_leftover_noiseoptBOOLEANfalseIf true, force last step to full denoise behavior.
merge_inactive_stepsoptBOOLEANtrueGreedily merge steps outside the active schedule window into larger batches.

Outputs (2)

NameTypeDescription
LATENTLATENT
MASKMASK