Nodes/ComfyUI-WanAnimatePreprocessV2/Wan Face Controller 3D
ComfyUI Node

Wan Face Controller 3D

All-in-one face controller for the V2 pose pipeline. Combines four independent stages, applied in this order: (1) Optional reference-shape blend (mouth/brows/eyes/jaw). (2) 12 FACS-inspired expression dials via expression_coeffs_json. (3) 3-DoF head rotation (yaw/pitch/roll) using a canonical iBUG-68 depth map. (4) Gaze offset applied to iris_data pupil/iris keypoints. Leaving a stage's controls at their defaults makes that stage a no-op, so the same node covers any subset. Schemas: see source file docstring.

By Code2Collapse·Created 7 months ago·Updated 12 days ago· 17
Wan Face Controller 3D
  • pose_data
  • images
  • model
  • reference_pose_data
  • pose_data
  • info
  • coeff_time_series_json
  • preview_image
  • overlay_video
  • keyframes_csv
  • pose_diff_json
  • lp_rotate_pitch
  • lp_rotate_yaw
  • lp_rotate_roll
  • lp_pupil_x
  • lp_pupil_y
detection_threshold0.30
pose_threshold0.30
use_clahetrue
detect_rescale1.25
fallback_to_full_frametrue
fc3d_config_json{"expression_coeffs_json":"","expression_strength":1.0,"expression_clamp":1.5,"expression_clamp_per_axis_json":"","propagate_expression":"off","head_pose_json":"","head_yaw_deg":0.0,"head_pitch_deg":0.0,"head_roll_deg":0.0,"head_tx":0.0,"head_ty":0.0,"head_tz":0.0,"head_scale":1.0,"jaw_rot_deg":0.0,"neck_yaw_deg":0.0,"neck_pitch_deg":0.0,"propagate_head":"off","propagate_gaze":"off","gaze_json":"","gaze_yaw_deg":0.0,"gaze_pitch_deg":0.0,"blend_strength":0.0,"blend_mouth":true,"blend_brows":false,"blend_eyes":false,"blend_jaw":false,"use_metas":"edited","frame_start":-1,"frame_end":-1,"preview_frame_idx":0,"preview_size":512,"preview_max_video_frames":120}
landmark_overrides_json
pose_overrides_json
gaze_overrides_json
CategoryWanAnimatePreprocessV2/extras

Inputs (13)

NameTypeDefaultDescription
pose_dataoptPOSEDATAPre-detected pose bundle (iBUG-68 face landmarks). OPTIONAL if you wire `images` + `model` to detect inside this node.
imagesoptIMAGEVideo frames (B,H,W,3). Wire a video loader here to run ViTPose pose estimation INSIDE this node — no separate detector node needed.
modeloptPOSEMODELViTPose+YOLO bundle from 'ONNX Detection Model Loader (V2)'. Used for internal detection (when `images` is wired and `pose_data` is empty).
detection_thresholdoptFLOAT0.300–1Internal detection: YOLO person-detection confidence threshold.
pose_thresholdoptFLOAT0.300–1Internal detection: per-keypoint confidence threshold.
use_claheoptBOOLEANtrueInternal detection: CLAHE contrast enhancement on the pose crop.
detect_rescaleoptFLOAT1.251–2Internal detection: bbox padding factor before the ViTPose crop.
fallback_to_full_frameoptBOOLEANtrueInternal detection: run ViTPose on the full frame when YOLO finds no person.
reference_pose_dataoptPOSEDATAOptional single-frame POSEDATA used as a region-wise shape target.
fc3d_config_jsonoptSTRING{"expression_coeffs_json":"","expression_strength":1.0,"expression_clamp":1.5,"expression_clamp_per_axis_json":"","propagate_expression":"off","head_pose_json":"","head_yaw_deg":0.0,"head_pitch_deg":0.0,"head_roll_deg":0.0,"head_tx":0.0,"head_ty":0.0,"head_tz":0.0,"head_scale":1.0,"jaw_rot_deg":0.0,"neck_yaw_deg":0.0,"neck_pitch_deg":0.0,"propagate_head":"off","propagate_gaze":"off","gaze_json":"","gaze_yaw_deg":0.0,"gaze_pitch_deg":0.0,"blend_strength":0.0,"blend_mouth":true,"blend_brows":false,"blend_eyes":false,"blend_jaw":false,"use_metas":"edited","frame_start":-1,"frame_end":-1,"preview_frame_idx":0,"preview_size":512,"preview_max_video_frames":120}Editor-owned JSON for expression/head/gaze/blend/preview params. Synced automatically by face_controller_3d.js.
landmark_overrides_jsonoptSTRINGJSON {"frames":{"<idx>":{"<lm>":[x_img_norm,y_img_norm]}}} from the in-canvas face viewer (image-normalised 0..1). Empty = no override.
pose_overrides_jsonoptSTRINGJSON {"frames":{"<idx>":{"<joint>":[x_img_norm,y_img_norm]}}} from the in-canvas pose viewer (OpenPose-18).
gaze_overrides_jsonoptSTRINGJSON {"frames":{"<idx>":{"l":[yaw_rad,pitch_rad],"r":[yaw_rad,pitch_rad]}}} from the in-canvas gaze handles.

Outputs (12)

NameTypeDescription
pose_dataPOSEDATA
infoSTRING
coeff_time_series_jsonSTRING
preview_imageIMAGE
overlay_videoIMAGE
keyframes_csvSTRING
pose_diff_jsonSTRING
lp_rotate_pitchFLOATHead pitch for LivePortrait ExpressionEditor (clamped ±20°). Wire to rotate_pitch.
lp_rotate_yawFLOATHead yaw for ExpressionEditor (clamped ±20°). Wire to rotate_yaw.
lp_rotate_rollFLOATHead roll for ExpressionEditor (clamped ±20°). Wire to rotate_roll.
lp_pupil_xFLOATGaze→pupil_x for ExpressionEditor (clamped ±15). Wire to pupil_x.
lp_pupil_yFLOATGaze→pupil_y for ExpressionEditor (clamped ±15). Wire to pupil_y.