ComfyUI Node

Draw ViT Pose (V2)

Render the detected skeleton, face landmarks, iris pupils and gaze arrows onto a clean canvas at the target Wan 2.2 latent resolution. Outputs an IMAGE batch ready to drop into a Wan-Animate sampler.

By Code2Collapse·Created 7 months ago·Updated 12 days ago· 17
Draw ViT Pose (V2)
  • pose_data
  • face_images
  • pose_images
  • face_video
  • face_cfg_scale
  • critic_report_json
  • worst_aus_csv
  • overall_mae
width832
height480
retarget_padding16
body_stick_width-1
hand_stick_width-1
draw_headtrue
pose_draw_threshold0.30
draw_iristrue
draw_gazetrue
iris_radius4
gaze_arrow_len30
iris_min_confidence0.05
iris_colorwhite
face_cfg_scale1.0
enforce_512_facetrue
reference_expression_coeffs_json
segment_length77
top_k_aus10
apply_pose_edits_to_facewarp
CategoryWanAnimatePreprocess_V2

Inputs (21)

NameTypeDefaultDescription
pose_dataPOSEDATAFrom Pose and Face Detection (V2).
widthINT83264–2048Render canvas width (px). Match the sampler latent size.
heightINT48064–2048Render canvas height (px). Match the sampler latent size.
retarget_paddingINT160–512Padding (px) added around the body bbox when retargeting. Larger = more headroom for big motions.
body_stick_widthINT-1-1–20Body skeleton stick width in px. -1 = auto from canvas size.
hand_stick_widthINT-1-1–20Hand skeleton stick width in px. -1 = auto.
draw_headBOOLEANtrueDraw the head/face skeleton (eyes, nose, ears).
pose_draw_thresholdFLOAT0.300–1Per-keypoint score threshold for drawing.
draw_irisoptBOOLEANtrueDraw iris/pupil markers from MediaPipe iris_data.
draw_gazeoptBOOLEANtrueDraw gaze direction arrows from iris_data.
iris_radiusoptINT41–20Pupil circle radius in pixels.
gaze_arrow_lenoptINT304–200Length of gaze direction arrow in pixels.
iris_min_confidenceoptFLOAT0.050–1Skip iris frames whose detection confidence is below this.
iris_coloroptCOMBOwhiteColor of the drawn pupil; magenta gives strongest sampler signal.
face_imagesoptIMAGEOPTIONAL face crop IMAGE batch (typically the face_images_512 output of PoseAndFaceDetectionV2). When wired, the node validates frame-count parity with the pose batch, optionally force-resizes to 512x512, and forwards it on the 'face_video' output so a single DrawViTPoseV2 can feed the Wan-Animate sampler's pose+face inputs in one place.
face_cfg_scaleoptFLOAT1.01–10Passthrough face CFG scale, CONNECTION-ONLY (forceInput) so there is exactly one source of truth: PoseAndFaceDetectionV2.face_cfg_scale. It used to be a second independently-editable widget with the same default, so you could set 2.0 upstream, leave 1.0 here, and get no warning that they had diverged. Unconnected = 1.0 (no-op), which matches the old default. NOTE: Kijai's ComfyUI-WanVideoWrapper has no face-CFG input to wire this into today — for real control over expression adherence use WanVideoAnimateEmbeds.face_strength (spec 2.2's stronger, more direct block-scale lever) instead.
enforce_512_faceoptBOOLEANtrueIf True and 'face_images' is provided at a non-512 size, force-resize each frame to 512x512 (bilinear) before forwarding. Default True so the encoder always sees the trained input shape.
reference_expression_coeffs_jsonoptSTRINGWan-Animate spec 3.1 (closed-loop critic): wire in the 'expression_coeffs_json' output of a PoseAndFaceDetectionV2 run (export_expression_coeffs=True) on the SOURCE driving video. When non-empty, this node measures ARKit-52 blendshapes from ITS OWN pose_data.iris_data (i.e. the GENERATED Wan-Animate output side, since this node is downstream of the generation pass) and reports per-AU + per-segment error against the reference — a numeric fidelity signal instead of eyeballing frames. Leave empty to skip entirely (zero extra cost).
segment_lengthoptINT771–100000Frames per segment for the critic's worst-segment breakdown — match WanVideoAnimateEmbeds.frame_window_size (default 77) so segments line up with Wan-Animate's own splice boundaries (spec 2.5/3.5). Only used when reference_expression_coeffs_json is wired.
top_k_ausoptINT101–52How many worst-tracked AUs the critic reports, worst-first. Only used when reference_expression_coeffs_json is wired.
apply_pose_edits_to_faceoptCOMBOwarpExpression-edit DELIVERY (2026-07-24). When pose_data carries edited face landmarks (WanFaceController3DV2 expression dials / dragged landmarks) AND face_images is wired, 'warp' moves the ACTUAL face-crop pixels from the original landmark positions to the edited ones (same Delaunay piecewise-affine engine as FC3D's preview), so the Wan-Animate face encoder sees the edit. Without this, landmark edits only change the drawn skeleton — the photographic face crop stays neutral and the sampler follows the crop, i.e. your expression edits silently do nothing. No-op when landmarks are unedited (zero cost), so the default stays 'warp'.

Outputs (6)

NameTypeDescription
pose_imagesIMAGERendered skeleton IMAGE batch. Feed into your Wan 2.2 Animate sampler.
face_videoIMAGEPassthrough face IMAGE batch (512x512 if enforce_512_face). Empty single-frame zero tensor if 'face_images' was not wired.
face_cfg_scaleFLOATPassthrough face_cfg_scale (Wan-Animate paper Sec. 4.3). 1.0 = CFG off.
critic_report_jsonSTRINGWan-Animate spec 3.1 closed-loop critic report (JSON): per-AU mean-absolute-error, per-frame error curve, per-segment breakdown worst-first. '{}' when reference_expression_coeffs_json was not wired.
worst_aus_csvSTRINGCSV 'name,mae' for the top_k_aus worst-tracked AUs, worst first. Empty string when the critic did not run.
overall_maeFLOATMean of all per-AU MAE values (0.0 = perfect match to the reference). 0.0 when the critic did not run.