Wan I2V Conditioning Mask Pro
Wan I2V won't stop moving your whole frame. Tell it where it's allowed.
- positive
- negative
- vae
- image
- mask
- depth_map
- positive
- negative
- mask_out
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 aconcat_maskthat 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 hextint_color), VAE-encodes it across the whole clip, and blends it into the latent. It also updatesconcat_maskso 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 likemask_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 ofWanImageToVideo, not a bare text/CLIP conditioning. - Ghost edges on dynamic masks - the author's own fix:
featheraround 0.015. - Face landmarks ignoring a face - low resolution or a small face in frame. Go 720p+, use close-ups, keep
refine_mask_detectionon. - Multiple people, and it grabs the wrong one -
ignore_area+ignore_percent(0.5 is a sane start). - Weird fill results - keep
fill_brightnessbetween 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.
Inputs (36)
| Name | Type | Default | Description |
|---|---|---|---|
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| vae | VAE | — | |
| image | IMAGE | — | |
| maskopt | MASK | Custom mask. White=fill, Black=keep. Overrides depth_map and mask_mode. Tip: LoadImage MASK output can be connected here for alpha masks. | |
| depth_mapopt | IMAGE | Depth map image. White (close)=fill, Black (far)=keep. Overrides mask_mode only. | |
| mask_modeopt | COMBO | full | Preset mask shape. Ignored if mask or depth_map connected. |
| depth_thresholdopt | FLOAT | 0.500–1 | Depth cutoff. 0=use depth as gradient. Higher values=fill more of the foreground. 0.5=fill close objects, keep distant. |
| fill_brightnessopt | FLOAT | 0.500.25–0.75 | Fill 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_fillopt | BOOLEAN | false | Enable color tint on fill to influence the vibe of generated areas |
| tint_coloropt | STRING | Hex color for tint (e.g. FF8800 for warm orange, 4488FF for cool blue). Leave empty for no tint. | |
| mask_strengthopt | FLOAT | 1.000–1 | Mask intensity. Values below 1 let some original detail bleed through in filled areas, useful for subtle changes. |
| grow_maskopt | FLOAT | 0.00-0.5–0.5 | Expand or shrink the fill region. Positive=grow fill area, negative=shrink. Value is % of mask size (0.05=5% growth relative to masked area). |
| featheropt | FLOAT | 0.000–1 | Blur mask edges for smooth transitions. Value scales from 0 (sharp) to 1 (blur radius ~25% of image). Applied after grow_mask. |
| invert_maskopt | BOOLEAN | false | Flip fill and keep regions. Applied last, after grow_mask, feather, and mask_strength. |
| text_strengthopt | FLOAT | 1.000.5–3 | Scale text conditioning strength. >1.0 boosts text influence for sharper results. |
| generate_person_maskopt | BOOLEAN | false | Enable built-in person/face mask generation using MediaPipe. Highest priority - overrides all other mask sources. |
| mask_faceopt | BOOLEAN | true | Include face skin area in mask (requires generate_person_mask) |
| mask_hairopt | BOOLEAN | false | Include hair in mask (requires generate_person_mask) |
| mask_bodyopt | BOOLEAN | false | Include body/skin in mask (requires generate_person_mask) |
| mask_clothesopt | BOOLEAN | false | Include clothing in mask (requires generate_person_mask) |
| mask_backgroundopt | BOOLEAN | false | Include background in mask (requires generate_person_mask) |
| mask_face_ovalopt | BOOLEAN | false | Full face oval outline. Works best on close-ups or 720p+ resolution. |
| mask_eyesopt | BOOLEAN | false | Both eyes. Works best on close-ups or 720p+ resolution. |
| mask_eyebrowsopt | BOOLEAN | false | Both eyebrows. Works best on close-ups or 720p+ resolution. |
| mask_lipsopt | BOOLEAN | false | Lips/mouth area. Works best on close-ups or 720p+ resolution. |
| mask_pupilsopt | BOOLEAN | false | Pupils only. Works best on close-ups or 720p+ resolution. |
| mask_noseopt | BOOLEAN | false | Nose area. Works best on close-ups or 720p+ resolution. |
| mask_cheeksopt | BOOLEAN | false | Cheek areas. Works best on close-ups or 720p+ resolution. |
| mask_foreheadopt | BOOLEAN | false | Forehead area. Works best on close-ups or 720p+ resolution. |
| mask_jaw_chinopt | BOOLEAN | false | Jaw and chin area. Works best on close-ups or 720p+ resolution. |
| mask_earsopt | BOOLEAN | false | Both ears. Works best on close-ups or 720p+ resolution. |
| mask_confidenceopt | FLOAT | 0.400.01–1 | Detection confidence threshold for person mask generation |
| refine_mask_detectionopt | BOOLEAN | true | Crop and re-run detection for better accuracy on smaller faces |
| ignore_areaopt | COMBO | none | Exclude a region from person/face detection. Use to isolate one person when multiple are in frame. |
| ignore_percentopt | FLOAT | 0.500.1–0.9 | % of image to ignore from selected edge (0.5 = half the image). |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| positive | CONDITIONING | — |
| negative | CONDITIONING | — |
| mask_out | MASK | — |