ComfyUI Node
BD MP Mouth Parts
Separate an isolated mouth render into lips / teeth / tongue by colour (no model) and pack them RGBA for the Unreal viseme atlas: R=lips, G=teeth, B=tongue, A=POM (wire depth into `pom`). Replaces the SAM3×3 → FillHoles → PackChannels chain. Tuned on the PinkF1 visemes; thresholds exposed for other palettes.
BD MP Mouth Parts
- image
- model
- pom
- lips
- teeth
- tongue
- rgb_packed
- rgba_packed
- debug_overlay
- status
◄enginecolor►
◄bg_v_min25►
◄teeth_s_max60►
◄teeth_v_min140►
◄tongue_h_lo325►
◄tongue_h_hi358►
◄tongue_s_min80►
◄tongue_s_max170►
◄tongue_v_min120►
◄lips_s_min85►
◄interior_frac0.060►
◄sam3_iters1►
◄bleed_guard24►
◄edge_smooth3►
◄fill_holestrue►
◄despeckle0.0008►
◄edge_refineoff►
◄refine_radius6►
◄refine_eps0.0001►
◄refine_threshold0.50►
◄vitmatte_modelsmall►
Category🧠BrainDead/Segmentation
Inputs (24)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Isolated mouth render (background near-black). Only image[0] is used. | |
| engineopt | COMBO | color | color — HSV classification, no model (default). sam3 — colour split SEEDS SAM3 (box + interior + sibling-negative points) for object-accurate boundaries. Auto-loads SAM3 in-house if `model` is unwired. |
| modelopt | MODEL | Comfy-core SAM3 model (override). Leave UNWIRED to auto-load + auto-download the official SAM3 checkpoint in-house (bd_sam3). Only used when engine='sam3'. | |
| pomopt | IMAGE | Optional POM / depth map (e.g. Lotus2 depth → NormLuma → CenterLuma) → packed into the A channel. Its luminance is used. If unwired, A = mouth foreground (lips∪teeth∪tongue). | |
| bg_v_minopt | INT | 250–128 | Background cutoff: pixels with HSV value ≤ this are background (black). Raise if the render has a lifted/grey background. |
| teeth_s_maxopt | INT | 600–255 | Teeth = saturation BELOW this (white/grey is desaturated). Raise to grab tinted teeth; lower if pale lip facets leak into teeth. |
| teeth_v_minopt | INT | 1400–255 | Teeth = value (brightness) ABOVE this. Raise to require brighter teeth. |
| tongue_h_loopt | INT | 3250–360 | Tongue warm-hue band low edge (°). The tongue is warmer (closer to red, ~338°) than the magenta lips (~310°); the |H≤6° wrap is always included. |
| tongue_h_hiopt | INT | 3580–360 | Tongue warm-hue band high edge (°). |
| tongue_s_minopt | INT | 800–255 | Tongue core min saturation (excludes near-grey). |
| tongue_s_maxopt | INT | 1700–255 | Tongue core MAX saturation — the tongue is LESS saturated than the lips, so this ceiling separates the salmon tongue from saturated magenta lips. |
| tongue_v_minopt | INT | 1200–255 | Tongue core min value (brightness). |
| lips_s_minopt | INT | 850–255 | Lips min saturation. Acts as the cavity guard: the dark, desaturated mouth interior falls below this so it is NOT labelled lips. Lower to include darker lip facets; raise if cavity bleeds in. |
| interior_fracopt | FLOAT | 0.0600–0.25 | Mouth-interior erosion (fraction of the longer side). The tongue core must lie inside the foreground eroded by this much — kills warm lip-corner highlights that would otherwise grow into a false tongue. 0 disables the gate. |
| sam3_itersopt | INT | 10–5 | engine='sam3' only: SAM decoder refinement passes. 1 = single pass (fullest part — extra passes tend to shrink small parts on stylized renders); a collapse-guard reverts any part the loop over-shrinks. |
| bleed_guardopt | INT | 240–200 | engine='sam3' only: dilate the colour mouth foreground by this many px, then clip each SAM3 part to it — stops SAM3 from escaping onto skin/specular. 0 = clip exactly to the colour foreground. |
| edge_smoothopt | INT | 30–15 | Morphological close radius (px) to seal jagged lip/tongue edges. 0 = none. |
| fill_holesopt | BOOLEAN | true | Fill interior holes so each part is solid (e.g. specular gaps in the tongue, gaps between teeth in the lips ring). |
| despeckleopt | FLOAT | 0.00080–0.05 | Drop connected components smaller than this fraction of the image (removes specular glints on the tongue that read as teeth and punch holes in it). 0 disables. Keep small so real (separate) teeth aren't removed. |
| edge_refineopt | COMBO | off | Snap each part's edge to the image colour/edges (shared with BD MP SAM3): off — colour masks as-is (fast) guided — guided filter (fast, edge-aware) matting — PyMatting closed-form (CPU, no model) vitmatte — VitMatte deep matting (GPU, auto-downloads). Each degrades to 'off' if its backend is missing. |
| refine_radiusopt | INT | 61–40 | Guided-filter radius / matting trimap band width (px). |
| refine_epsopt | FLOAT | 0.00010.000001–0.1 | Guided-filter edge sensitivity (smaller hugs edges harder). Ignored by matting. |
| refine_thresholdopt | FLOAT | 0.500.05–0.95 | Binarize the refined alpha at this level. |
| vitmatte_modelopt | COMBO | small | VitMatte variant for edge_refine='vitmatte' (auto-downloaded from the HF hub). |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| lips | MASK | — |
| teeth | MASK | — |
| tongue | MASK | — |
| rgb_packed | IMAGE | R=lips, G=teeth, B=tongue (no alpha). The PackChannels equivalent. |
| rgba_packed | IMAGE | R=lips, G=teeth, B=tongue, A=POM (from `pom`, else mouth foreground). The viseme-atlas cell contract. |
| debug_overlay | IMAGE | Render tinted by part (lips=R, teeth=G, tongue=B) for QC. |
| status | STRING | — |