Wan I2V Masked-Video Conditioning
Let WAN fill only the holes in your camera path — masked-video conditioning for Wan 2.1
- positive
- negative
- vae
- control_video
- control_mask
- clip_vision_output
- positive
- negative
- latent
ComfyUI's native WanImageToVideo node conditions Wan 2.1 on a single start frame. That's fine for a talking head, useless for what SplatKit needs: a camera path rendered through a MoGe mesh, where most of each frame is known (the panorama saw it) and only the disocclusion holes need inventing. Wan I2V Masked-Video Conditioning is the node that makes the latter work. It reproduces Matrix-3D's masked-video latent-concat conditioning: instead of one start frame, it conditions Wan on the full masked control video plus a per-pixel validity mask, so the model fills exactly the holes - with temporally coherent content - and leaves the known geometry alone.
This is quietly the most important node in the pack after the SfM ones. Without it, WAN would repaint whole frames, drift the scene, and your SfM stage would be solving garbage. With it, the pano's real detail survives into the generated fly-through.
How it works
Mechanically it's the same path as WanImageToVideo - VAE-encode a reference video, attach it to the conditioning as concat_latent_image plus a concat_mask - only what fills it changes. The control_video is your mesh-rendered trajectory (from the Camera Plot node), resized to your target width/height; control_mask is the validity mask, where white = valid/known, black = hole. Holes are painted with the hole_fill color (black or gray) before the VAE encode so the encoder never sees stale content, then the mask is pooled to latent resolution and packed into Wan's 4-frames-per-latent temporal structure.
One practical detail: the mask convention is the reverse of what you might expect from ComfyUI inpainting. The concat_mask the sampler uses follows ComfyUI's convention (0 = known, 1 = generate), but the node handles that flip for you - you just feed white=valid. If the first run fills the wrong regions, flip invert_mask.
Inputs and outputs
Required: positive and negative (your Wan text conditionings, wired as usual), vae, control_video, control_mask, and the geometry trio - width (default 1440), height (720), length (81, the Wan clip length in frames). Optional: clip_vision_output (passed through to the conditioning, which you want if your Wan graph uses CLIP vision), hole_fill, and invert_mask.
Outputs are positive, negative, and latent - the last is a zeroed latent of the right shape, and the whole triple wires straight into a Wan KSampler in place of the output of a native conditioning node. If you've built a Wan image-to-video graph before, it slots in exactly where you'd expect.
Install
Pack-wide install, nothing Wan-specific beyond the checkpoint:
cd ComfyUI/custom_nodes
git clone https://github.com/mickmumpitz/ComfyUI-SplatKit
python_embeded\python.exe -m pip install -r ComfyUI-SplatKit/requirements.txt
Restart ComfyUI. You supply a Wan 2.1 i2v checkpoint and the Matrix-3D pano LoRA (converted with tools/convert_pano_lora.py into pano_video_gen_720p_comfy.safetensors in your loras folder). The MoGe checkpoint downloads itself on first use.
Common issues
- Wrong regions filled - flip
invert_mask. The default convention is white=valid, and if your mask pipeline handed you the inverse, Wan will happily hallucinate over your known geometry. - Drifty, soft output - this is usually the prompt, not the node. The README is blunt: the prompt must describe the actual scene in the panorama, because WAN's job here is to fill holes in that scene. A vague or wrong prompt visibly degrades what gets painted, and bad fills cascade straight into the SfM stage.
- Latent shape errors at the sampler -
lengthneeds to be sane for Wan's temporal packing (81 is the pack's default and works); wildly off values can produce a mismatch at the KSampler.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| vae | VAE | — | |
| control_video | IMAGE | — | |
| control_mask | IMAGE | — | |
| width | INT | 144016–8192 | — |
| height | INT | 72016–8192 | — |
| length | INT | 811–8192 | — |
| clip_vision_outputopt | CLIP_VISION_OUTPUT | — | |
| hole_fillopt | COMBO | black | 2 options: black, gray |
| invert_maskopt | BOOLEAN | false | Flip valid/hole interpretation if the first run fills the wrong regions. Default: white=valid/known. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| positive | CONDITIONING | — |
| negative | CONDITIONING | — |
| latent | LATENT | — |