ComfyUI Node

BD Face Fit

Turn landmarks into an actual head mesh to bake onto

By BizaNator·Created 8 months ago·Updated 3 days ago· 15
BD Face Fit
  • landmarks_batch
  • face_fit
  • status
mesh_sourcemediapipe_canonical
mesh_obj_path
ict_landmark_warp1.00

Landmarks tell you where the features are, but to bake a texture you need a surface. BD Face Fit is the step between: it takes a LANDMARKS_BATCH (from BD Face Landmarks) and a head mesh, and produces a FACE_FIT - the canonical mesh plus per-view vertex positions that the texture-bake node can rasterize against. It's the node that decides how much of the head your wrap actually covers.

Two mesh sources, and the tradeoff is coverage vs. precision

The mesh_source combo is the interesting decision:

  • mediapipe_canonical (default) - the 468-vertex face shell whose vertices are the MediaPipe landmarks. Pure assembly, zero optimization: each view's landmarks directly position the shell. It's geometrically honest to the photo, but it's a face only - no ears, no scalp, no back of head.
  • ict_facekit - ICT-FaceKit's neutral head skin (MIT, bundled with the pack). Full head including ears, scalp, and back, which gives the bake somewhere to put the rear and ear pixels. It's Procrustes-fitted (similarity transform) to the MediaPipe landmarks per view, so it poses the neutral head rather than being per-subject shape-accurate.

ict_landmark_warp (default 1.0, ict_facekit only) is the fix for that last caveat: it's a landmark-exact thin-plate-spline warp applied after the rigid fit, so at 1.0 the 68 landmarks hit MediaPipe's targets exactly - killing the "neutral-shape face distortion" the plain rigid fit leaves behind. At 0.0 you get the older, looser pure-Procrustes pose. You almost always want it at or near 1.0. mesh_obj_path lets you override the mesh entirely if you have your own.

Both sources emit the same FACE_FIT contract, and the downstream nodes (texture bake, blend, transfer) don't care which one produced it. Outputs: face_fit and status.

Installing

Part of ComfyUI-BrainDead - ComfyUI Manager → search "BrainDead", or:

cd ComfyUI/custom_nodes
git clone https://github.com/BizaNator/ComfyUI-BrainDead
cd ComfyUI-BrainDead
pip install -r requirements.txt

Restart. The ict_facekit TPS warp path wants scipy - if you see it skip the refinement and fall back to a rigid fit, pip install scipy.

Where people get burned

The coverage decision is the one that bites. People bake with mediapipe_canonical, hit the edge of the face shell, and wonder where the ears went - that's expected, the canonical mesh doesn't have them. If you need a full-head wrap (hairline, ears, neck), pick ict_facekit even though it's a posed neutral shape; for a pure face-plate texture the canonical shell is faster and tighter. And keep the landmarks and the mesh in the same pipeline run - a mismatched batch/view count is the usual "bake comes out scrambled" cause.

Category🧠BrainDead/FaceWrap

Inputs (4)

NameTypeDefaultDescription
landmarks_batchBD_LANDMARKS_BATCHOutput of BD_FaceLandmarks (per-view 478 landmarks).
mesh_sourceCOMBOmediapipe_canonicalWhich head mesh to fit. ict_facekit adds ear/scalp/back coverage the canonical face shell lacks.
mesh_obj_pathoptSTRINGOverride path to the mesh .obj. Empty = use the bundled asset for the selected mesh_source.
ict_landmark_warpoptFLOAT1.000–1ict_facekit only: strength of the landmark-exact TPS warp applied after the rigid fit. 1.0 = the 68 landmarks hit MediaPipe's targets exactly (fixes neutral-shape face distortion); 0.0 = pure rigid Procrustes (the older, more distorted fit). Ignored for mediapipe_canonical.

Outputs (2)

NameTypeDescription
face_fitBD_FACE_FIT
statusSTRING