Nodes/ComfyUI-Przewodo-Utils/WanFirstLastFirstFrameToVideo
ComfyUI Node

WanFirstLastFirstFrameToVideo

Pin down the first and last frames, let the model fill the gap

By przewodo·Created about a year ago·Updated 4 months ago· 4
WanFirstLastFirstFrameToVideo
  • positive
  • negative
  • vae
  • clip_vision_start_image
  • clip_vision_end_image
  • start_image
  • end_image
  • positive
  • negative
  • latent
  • MASK
width832
height480
length81
first_end_frame_shift0
first_end_frame_denoise0.0000
fill_denoise0.50
generation_modeStart Image
clip_vision_strength1.0

Image-to-video on Wan has a real limitation: the model is happiest when you give it exactly one starting frame and let it wander. But the workflow you actually want is usually "start here, end there, and make the middle move sensibly between them." That's the first/last-frame (FFLF) pattern - anchor both ends, let the model interpolate the motion. This node is the FFLF builder for Wan: it takes your conditioning, VAE, and start/end images, and produces a latent plus masks that tell the sampler exactly which frames are sacred keyframes and which are free to be invented.

The name is a mouthful and it's clearly a personal-pack node (this pack has effectively no community footprint - you're on your own past the README), but the approach is sound and it's the same pattern the LTX world standardized on. If you've been fighting Wan's tendency to drift off your intended composition, anchoring both ends is the fix.

How it works

The node builds the generation inputs in three parts:

  1. Latent + keyframe placement. It allocates a latent of length frames at your width/height (Wan's VAE compresses 4× per axis, so the latent is length/4 × height/8 × width/8). A first_end_frame_shift adds padding frames around the edges so the keyframes sit inside the sequence rather than at the raw start/end.
  2. Denoise masks. The real magic. It paints your start_image and end_image into the frame sequence and builds a mask where keyframe regions get first_end_frame_denoise (default 0 - keep them untouched) and the in-between frames get fill_denoise (default 0.5). That's how a single sampler run keeps the anchors identical while letting the middle invent motion.
  3. Conditioning. It runs the frames through the Wan VAE (encode_tiled) and, if you supply them, mixes in CLIP vision encodings of the start/end images scaled by clip_vision_strength, so the model gets both a visual and a text description of what to do.

The generation_mode dropdown picks the pattern: Start Image (plain I2V), Start to End Image, End to Start Image, and Start to End to Start - the last one useful for loopable clips. Four outputs come out: positive/negative conditioning, the latent, and a MASK, which feed directly into a KSampler set to denoise the latent.

The inputs that matter

  • positive / negative - text conditioning from a CLIP text encode.
  • vae - the Wan VAE.
  • width, height, length - resolution and frame count. Length is stepped by 4 (Wan's VAE token framing).
  • generation_mode - the anchoring pattern.
  • first_end_frame_denoise (keep 0 to lock keyframes) and fill_denoise (how free the middle is).
  • start_image / end_image - your anchors (optional, depending on mode).
  • clip_vision_strength - how hard the CLIP vision encoding of the anchors pushes the result.

Installing it

Part of ComfyUI-Przewodo-Utils. ComfyUI Manager → search the pack, or:

cd ComfyUI/custom_nodes
git clone https://github.com/przewodo/ComfyUI-Przewodo-Utils.git

Restart. Note the pack declares heavier deps (teacache, comfyui-gguf, wanblockswap, ComfyUI-Rife-Tensorrt) - those are for the sibling Wan sampler, and this node's core encode path mostly needs standard ComfyUI + Wan support. Expect a restart if Manager updates dependencies.

Where people get tripped up

This is the "advanced" corner of a niche pack, so budget debugging time. The most common failure: first_end_frame_denoise above 0 erodes your keyframes - at 0 the anchors are locked, at 1 they're fully regenerated. If your start image comes out changed, check that value first. Also verify your length is a multiple of 4 and your resolution plays nice with the 4× VAE compression, or you'll get shape errors deep in the encode. And if you're coming from LTX-style FFLF workflows: the conditioning and mask semantics are similar but not identical - Wan's native sampling wants these masks wired exactly as the pack's example workflow does, so grab that workflow from the repo before improvising.

CategoryPrzewodoUtils/Wan

Inputs (15)

NameTypeDefaultDescription
positiveCONDITIONINGPositive conditioning for video generation
negativeCONDITIONINGNegative conditioning for video generation
vaeVAEVAE model for encoding/decoding video frames
widthINT83216–16384Width of the generated video in pixels (must be divisible by 2)
heightINT48016–16384Height of the generated video in pixels (must be divisible by 2)
lengthINT811–16384Number of frames in the generated video (step of 4 recommended for optimal performance)
first_end_frame_shiftINT00–80Frame shift offset for first and end frames positioning in the sequence
first_end_frame_denoiseFLOAT0.00000–1Denoising strength for first and end frames (0=no denoising, 1=full denoising)
fill_denoiseFLOAT0.500–1Denoising strength for intermediate frames between keyframes
generation_modeCOMBOStart ImageVideo generation pattern: start only, end only, start->end, end->start, or start->end->start
clip_vision_strengthFLOAT1.00.1–5Strength multiplier for CLIP vision influence on video generation
clip_vision_start_imageoptCLIP_VISION_OUTPUTCLIP vision encoding of the start image for enhanced conditioning
clip_vision_end_imageoptCLIP_VISION_OUTPUTCLIP vision encoding of the end image for enhanced conditioning
start_imageoptIMAGEStarting image/frame for the video sequence
end_imageoptIMAGEEnding image/frame for the video sequence

Outputs (4)

NameTypeDescription
positiveCONDITIONING
negativeCONDITIONING
latentLATENT
MASKMASK