Nodes/ComfyUI Wan VACE Prep/πŸͺ Wan First/Middle/Last Frame to Video (Experimental)
ComfyUI Node

πŸͺ Wan First/Middle/Last Frame to Video (Experimental)

Keyframe control done right

By stuttlepressΒ·Created 8 months agoΒ·Updated 25 days agoΒ· 100
πŸͺ Wan First/Middle/Last Frame to Video (Experimental)
  • positive
  • negative
  • vae
  • start_image
  • middle_image
  • end_image
  • clip_vision_start_image
  • clip_vision_middle_image
  • clip_vision_end_image
  • positive
  • negative
  • latent
β—„width832β–Ί
β—„height480β–Ί
β—„length81β–Ί
β—„batch_size1β–Ί
β—„middle_frame0.50β–Ί

ComfyUI ships a native WanFirstLastFrameToVideo node that lets you pin the first and last frames of a generation. This node is that, plus a middle frame, and it's the version the pack's author actually recommends over the VACE-driven keyframe approach. The whole point: you give it up to three reference images, it folds them into the conditioning latents, and Wan generates a video that starts, passes through, and ends where you told it to - with proper motion instead of the stiff linear interpolation you get from VACE keyframes.

The class name is WanFMLF2V (displayed as πŸͺ Wan First/Middle/Last Frame to Video (Experimental)). The "FML" acronym is unfortunate; the idea is sound.

How it works

This is a conditioning-prep node, which means it doesn't sample anything itself. It builds three things: an empty latent tensor at your requested width/height/length (Wan's VAE compresses time by 4, so the latent's temporal axis is (length-1)/4 + 1), a gray placeholder "image," and a mask that marks where your reference frames live. Your start, middle, and end images are upscaled to the target size, dropped into the placeholder, and the whole thing is VAE-encoded into concat_latent_image. That gets attached to both your positive and negative conditioning, which is how ComfyUI's Wan path does frame pinning.

The middle frame gets an extra knob: middle_frame (default 0.5) positions it along the timeline as a fraction of total length. And if you connect CLIP vision outputs for your reference images, their penultimate hidden states are concatenated and set on the conditioning too, which strengthens how well the model actually follows the keyframes.

The inputs and outputs that matter

  • positive / negative - your text conditioning. Both get the reference image conditioning attached; you never touch that wiring.
  • vae - the Wan VAE used to encode the reference composite.
  • width / height (defaults 832Γ—480), length (default 81), batch_size - the latent you get back.
  • start_image / middle_image / end_image - all optional. Supply one, two, or all three; the node handles subsets.
  • middle_frame (default 0.5) - where the middle reference sits as a fraction of the timeline.
  • clip_vision_start_image / clip_vision_middle_image / clip_vision_end_image - optional CLIP vision outputs that boost keyframe adherence.

Outputs: positive, negative (now carrying the frame conditioning), and latent. Wire those three into a KSampler with the Wan VACE or base Wan model - the node replaces the native WanFirstLastFrameToVideo in your existing workflow, so the downstream is unchanged.

Install

ComfyUI Manager β†’ search "Wan VACE Prep" β†’ install β†’ restart, or:

cd /path/to/comfyui/custom_nodes
git clone https://github.com/stuttlepress/ComfyUI-Wan-VACE-Prep

No pip dependencies; it uses ComfyUI's own conditioning helpers. You need the Wan model and VAE, of course, and a CLIP vision model if you want the extra guidance.

Common issues

  • It's experimental - flagged as such by the author; inputs and behavior could shift without notice.
  • Reference images don't stick - if keyframes are being ignored, the usual culprit is not connecting the CLIP vision inputs. They're optional but they do a lot of the anchoring work.
  • Length is 4n+1 - the latent's temporal axis follows Wan's (length-1)/4 + 1 compression, so keep length on the 1, 5, 9, … pattern that everything else in this pack assumes.
CategoryWan VACE Prep/conditioning

Inputs (14)

NameTypeDefaultDescription
positiveCONDITIONINGβ€”
negativeCONDITIONINGβ€”
vaeVAEβ€”
widthINT83216–16384β€”
heightINT48016–16384β€”
lengthINT811–16384β€”
batch_sizeINT11–4096β€”
start_imageoptIMAGEβ€”
middle_imageoptIMAGEβ€”
middle_frameoptFLOAT0.500–1β€”
end_imageoptIMAGEβ€”
clip_vision_start_imageoptCLIP_VISION_OUTPUTβ€”
clip_vision_middle_imageoptCLIP_VISION_OUTPUTβ€”
clip_vision_end_imageoptCLIP_VISION_OUTPUTβ€”

Outputs (3)

NameTypeDescription
positiveCONDITIONINGβ€”
negativeCONDITIONINGβ€”
latentLATENTβ€”