Nodes/comfyui-wan-i2v-control/Wan I2V Conditioning Mask Pro
ComfyUI Node

Wan I2V Conditioning Mask Pro

Wan I2V won't stop moving your whole frame. Tell it where it's allowed.

By shootthesound·Created 7 months ago·Updated 3 months ago· 26
Wan I2V Conditioning Mask Pro
  • positive
  • negative
  • vae
  • image
  • mask
  • depth_map
  • positive
  • negative
  • mask_out
mask_modefull
depth_threshold0.50
fill_brightness0.50
tint_fillfalse
tint_color
mask_strength1.00
grow_mask0.00
feather0.00
invert_maskfalse
text_strength1.00
generate_person_maskfalse
mask_facetrue
mask_hairfalse
mask_bodyfalse
mask_clothesfalse
mask_backgroundfalse
mask_face_ovalfalse
mask_eyesfalse
mask_eyebrowsfalse
mask_lipsfalse
mask_pupilsfalse
mask_nosefalse
mask_cheeksfalse
mask_foreheadfalse
mask_jaw_chinfalse
mask_earsfalse
mask_confidence0.40
refine_mask_detectiontrue
ignore_areanone
ignore_percent0.50

Wan's image-to-video mode treats your starting image as scripture. Every pixel gets animated forward - whether you wanted it moved or not. So when you just want to change a character's face while the background stays put, you're stuck regenerating everything and hoping. Wan I2V Conditioning Mask Pro is the edit-before-the-video: you mask the regions you want rebuilt, and Wan leaves everything else alone.

It's the flagship node of comfyui-wan-i2v-control, one author's (Peter Neill, aka ShootTheSound) passion project with a demo video and a buy-me-a-coffee button rather than a corporate support team. It's new-ish - announced on r/comfyui in February 2026 with a small but real reception - so treat it as sharp but young.

How it works

This is the part that makes it worth using. It doesn't do a sloppy full-frame inpaint-and-blend. It sits between WanImageToVideo and your sampler, reaching into the conditioning itself:

  • Wan's I2V conditioning carries a concat_latent_image - the VAE-encoded starting frame - plus a concat_mask that tells the model where it's free to generate.
  • For protected regions, the node keeps the original latent untouched. No decode-encode round trip, so no quality loss.
  • For fill regions, it builds a flat grey image (your fill_brightness, optionally tinted with a hex tint_color), VAE-encodes it across the whole clip, and blends it into the latent. It also updates concat_mask so the model knows those areas are open for business.

That's why masked regions don't flicker and protected regions don't degrade. It's genuinely the right mechanism, not a hack.

The inputs that matter

Four required: positive, negative, vae (use the Wan VAE), and image (your start frame). Everything else is optional, and the mask sources have a fixed priority: generate_person_mask > custom mask input > depth_map > mask_mode preset.

For a first run, you mostly touch these:

  • generate_person_mask - flips on built-in MediaPipe person/face detection, then pick what to include: mask_face, mask_hair, mask_body, mask_clothes, mask_background, plus fine landmark options like mask_eyes, mask_lips, mask_forehead. It works best at 720p+ and on close-ups; refine_mask_detection (on by default) crops and re-runs detection for small faces.
  • mask - connect your own mask. White = fill, black = keep. The author's tip: LoadImage's MASK output works here, so transparent PNGs become alpha masks.
  • mask_mode - presets for when you don't have a mask: full, halves, center, edges, the gradient modes, vignette.
  • ignore_area + ignore_percent - exclude one side of the frame so you can isolate a single person in a multi-person shot.

Then the polish dials: feather (soften edges), grow_mask (expand or shrink the fill region, as a % of mask size), mask_strength (below 1 lets original detail bleed through), invert_mask, and text_strength (boost prompt influence).

Outputs are positive and negative - which rewire straight into your sampler - plus mask_out. Connect that to a preview/ConvertMaskToImage node: it's your debug tool for seeing what you're actually editing before you burn a generation on it.

Quick start

Load example_workflows/Wan Demo.json from the repo - that's the workflow from the demo video, and it'll save you an hour of guesswork. Or: add the node between WanImageToVideo and the sampler, turn on generate_person_mask, pick your regions, and run.

Installing and troubleshooting

Install is the shared pack story:

cd ComfyUI/custom_nodes
git clone https://github.com/shootthesound/comfyui-wan-i2v-control
pip install mediapipe

Restart ComfyUI. Or search "WAN I2V Control" in ComfyUI Manager. mediapipe is the pack's only declared dependency, and it's what powers person/face detection - if it's missing, the node logs a warning to the console and silently falls back to other mask sources. That's the first thing to check when person masks do nothing.

Other things people actually hit:

  • A ValueError about concat_latent_image - you've wired it somewhere wrong. It must be fed conditioning straight out of WanImageToVideo, not a bare text/CLIP conditioning.
  • Ghost edges on dynamic masks - the author's own fix: feather around 0.015.
  • Face landmarks ignoring a face - low resolution or a small face in frame. Go 720p+, use close-ups, keep refine_mask_detection on.
  • Multiple people, and it grabs the wrong one - ignore_area + ignore_percent (0.5 is a sane start).
  • Weird fill results - keep fill_brightness between 0.25 and 0.75; the tooltip warns the model doesn't process well outside that band.

One more: use the matching Wan VAE. Wan's VAE compresses time as well as space, and the wrong autoencoder gives you noise instead of a video. If you've loaded your model correctly, the workflow's VAE is the right one.

Categoryconditioning/Wan

Inputs (36)

NameTypeDefaultDescription
positiveCONDITIONING
negativeCONDITIONING
vaeVAE
imageIMAGE
maskoptMASKCustom mask. White=fill, Black=keep. Overrides depth_map and mask_mode. Tip: LoadImage MASK output can be connected here for alpha masks.
depth_mapoptIMAGEDepth map image. White (close)=fill, Black (far)=keep. Overrides mask_mode only.
mask_modeoptCOMBOfullPreset mask shape. Ignored if mask or depth_map connected.
depth_thresholdoptFLOAT0.500–1Depth cutoff. 0=use depth as gradient. Higher values=fill more of the foreground. 0.5=fill close objects, keep distant.
fill_brightnessoptFLOAT0.500.25–0.75Fill brightness for masked regions. Below 0.5=darker generation, above 0.5=brighter. Model doesn't process well outside 0.25-0.75 range.
tint_filloptBOOLEANfalseEnable color tint on fill to influence the vibe of generated areas
tint_coloroptSTRINGHex color for tint (e.g. FF8800 for warm orange, 4488FF for cool blue). Leave empty for no tint.
mask_strengthoptFLOAT1.000–1Mask intensity. Values below 1 let some original detail bleed through in filled areas, useful for subtle changes.
grow_maskoptFLOAT0.00-0.5–0.5Expand or shrink the fill region. Positive=grow fill area, negative=shrink. Value is % of mask size (0.05=5% growth relative to masked area).
featheroptFLOAT0.000–1Blur mask edges for smooth transitions. Value scales from 0 (sharp) to 1 (blur radius ~25% of image). Applied after grow_mask.
invert_maskoptBOOLEANfalseFlip fill and keep regions. Applied last, after grow_mask, feather, and mask_strength.
text_strengthoptFLOAT1.000.5–3Scale text conditioning strength. >1.0 boosts text influence for sharper results.
generate_person_maskoptBOOLEANfalseEnable built-in person/face mask generation using MediaPipe. Highest priority - overrides all other mask sources.
mask_faceoptBOOLEANtrueInclude face skin area in mask (requires generate_person_mask)
mask_hairoptBOOLEANfalseInclude hair in mask (requires generate_person_mask)
mask_bodyoptBOOLEANfalseInclude body/skin in mask (requires generate_person_mask)
mask_clothesoptBOOLEANfalseInclude clothing in mask (requires generate_person_mask)
mask_backgroundoptBOOLEANfalseInclude background in mask (requires generate_person_mask)
mask_face_ovaloptBOOLEANfalseFull face oval outline. Works best on close-ups or 720p+ resolution.
mask_eyesoptBOOLEANfalseBoth eyes. Works best on close-ups or 720p+ resolution.
mask_eyebrowsoptBOOLEANfalseBoth eyebrows. Works best on close-ups or 720p+ resolution.
mask_lipsoptBOOLEANfalseLips/mouth area. Works best on close-ups or 720p+ resolution.
mask_pupilsoptBOOLEANfalsePupils only. Works best on close-ups or 720p+ resolution.
mask_noseoptBOOLEANfalseNose area. Works best on close-ups or 720p+ resolution.
mask_cheeksoptBOOLEANfalseCheek areas. Works best on close-ups or 720p+ resolution.
mask_foreheadoptBOOLEANfalseForehead area. Works best on close-ups or 720p+ resolution.
mask_jaw_chinoptBOOLEANfalseJaw and chin area. Works best on close-ups or 720p+ resolution.
mask_earsoptBOOLEANfalseBoth ears. Works best on close-ups or 720p+ resolution.
mask_confidenceoptFLOAT0.400.01–1Detection confidence threshold for person mask generation
refine_mask_detectionoptBOOLEANtrueCrop and re-run detection for better accuracy on smaller faces
ignore_areaoptCOMBOnoneExclude a region from person/face detection. Use to isolate one person when multiple are in frame.
ignore_percentoptFLOAT0.500.1–0.9% of image to ignore from selected edge (0.5 = half the image).

Outputs (3)

NameTypeDescription
positiveCONDITIONING
negativeCONDITIONING
mask_outMASK