Nodes/BrainDead Nodes/BD SAM3 Multi-Prompt
ComfyUI Node

BD SAM3 Multi-Prompt

One node instead of twelve, and it votes on the mask

By BizaNator·Created 8 months ago·Updated 3 days ago· 15
BD SAM3 Multi-Prompt
  • image
  • color_reference_mask
  • silhouette_mask
  • combined_mask
  • masked_image
  • per_prompt_masks
  • status
  • silhouette_composite
promptsskin face neck arm leg hand foot
negative_prompts
combine_modeunion
vote_threshold1.0
vote_pos_min0.50
vote_neg_min0.50
color_filteroff
color_strength0.70
color_threshold0.30
color_modeadaptive_lab
adaptive_tolerance25
adaptive_sample_threshold0.50
adaptive_min_samples50
enforce_silhouettetrue
include_dilate_radius64
masked_image_bgwhite
invert_negatives_in_per_prompttrue
confidence_threshold0.50
deviceAuto
mask_blur0
mask_offset0
unload_modelfalse
invert_combinedfalse
mask_threshold0.00
silhouette_composite_enablefalse

SAM3 is the model that made text-to-mask boring: type skin, get a skin mask, no GroundingDINO, no point-click dance. The ComfyUI way to do multi-region segmentation with it is to wire one SAM3Segment node per region - people built 12-node chains for the classic "skin / face / neck / arms / legs" character split. BD SAM3 Multi-Prompt collapses that whole chain into a single node and adds the part nobody had: majority voting across overlapping detections.

What it is

A standalone SAM3 node that runs once per prompt line and combines the masks. "Standalone" is doing real work there - it loads the SAM3 model and its text encoder in-house and auto-downloads the official Comfy-Org/sam3.1 checkpoint on first use. No comfyui-rmbg, no separate model loader, no wiring.

How it works

You list one positive prompt per line in prompts (default: skin\nface\nneck\narm\nleg\nhand\nfoot - the classic character split). Each runs through SAM3, and combine_mode decides how they merge:

  • union (default) - OR everything together.
  • intersection - AND, keep only pixels every prompt agrees on.
  • subtract_first / first_only - niche single-mask modes.
  • vote - the interesting one. Each positive detection votes +1, each negative votes −1, and a pixel survives if net votes ≥ vote_threshold. Great when you have one strong positive and six negatives and you want the agreement, not the loudest voice.
  • weighted_vote - same idea but each detection contributes its continuous confidence instead of a binary vote.

Negatives (negative_prompts) are always unioned and subtracted - e.g. clothing\nglove\nshoe peels non-skin off a body mask. Then there's the color layer: color_filter with adaptive_lab samples the reference color from your positives and cleans the mask by LAB ΔE distance - it self-tunes per character, so "red jacket" learns red, "pale skin" learns pale. silhouette_mask + enforce_silhouette clamp every result inside a character outline so SAM3 can't detect skin in the background.

Inputs a beginner actually sets

  • prompts - the regions you want, one per line.
  • combine_mode - union to start, vote when overlapping prompts disagree.
  • negative_prompts - what to subtract.
  • mask_threshold - SAM3 confidence; lower keeps more area.
  • invert_combined - leave it OFF. The tooltip is emphatic about this: flip it on and any downstream BD_PartsBuilder gets an inverted silhouette that zeroes every real per-class mask, leaving one garbage full-image "part."

Outputs: combined_mask, masked_image (mask composited over a chosen bg for preview), per_prompt_masks (the batch of individual detections), status, and silhouette_composite (outline minus detected regions - handy for "head minus eyes" skin masks).

Gotchas

SAM3's license is worth knowing: SAM and SAM 2 are Apache 2.0, but SAM 3 is not - it ships under Meta's custom SAM Licence with its own acceptable-use terms. Fine for most internal and research work; read it before shipping something commercial. And the model is big - first run downloads it, so the first execution hangs for a while. Set unload_model when SAM3 won't be used again in the run to free the VRAM.

Installing it

ComfyUI Manager: search "BrainDead" → install. Manual:

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

Restart, find it under 🧠BrainDead/Segmentation, and let the first run download the checkpoint. From there it feeds the whole BD parts pipeline - BD Parts Refine, BD Parts Builder, BD Parts Export - or just drives a mask-to-RGBA graph for character cutouts.

Category🧠BrainDead/Segmentation

Inputs (28)

NameTypeDefaultDescription
imageIMAGE
promptsSTRINGskin face neck arm leg hand footOne positive prompt per line. SAM3 runs once per non-empty line.
negative_promptsoptSTRINGOne negative prompt per line. SAM3 runs each, then their union is SUBTRACTED from the combined positive mask. Use to explicitly remove regions, e.g. 'clothing\nglove\nshoe' to peel non-skin off a body mask.
combine_modeoptCOMBOunionHow to combine positive prompts (and how negatives are applied): union — OR all positives, then SUBTRACT negatives cumulatively. Single strong positive overrides many weak negatives. intersection — AND all positives. Then subtract negatives. subtract_first — first positive MINUS all others (then subtract negatives too). first_only — return positive #1, ignore the rest. vote — MAJORITY VOTE. Each positive detection = +1, each negative = -1. Pixel kept if net votes >= vote_threshold. Use when you have many prompts and want agreement (e.g. 1 positive vs 6 negatives → removed even if positive was strong). weighted_vote — like vote but each detection contributes its CONTINUOUS value, not binary. Soft detections weigh proportionally.
vote_thresholdoptFLOAT1.0-20–20Vote-mode threshold. Pixel kept if (positive_votes - negative_votes) >= this. Default 1 = need at least one MORE positive than negative. Lower (0, -1) = positives win ties / get a head start. Higher (2+) = need stronger positive consensus.
vote_pos_minoptFLOAT0.500–1In 'vote' mode, a positive prompt's mask must have a pixel value >= this to count as a vote. Higher = only confident positives count.
vote_neg_minoptFLOAT0.500–1In 'vote' mode, a negative prompt's mask must have a pixel value >= this to count as a vote. Higher = only confident negatives count.
color_filteroptCOMBOoffColor-aware mask refinement. Works for ANY positive-prompt category — the reference color is sampled from your positives (or color_reference_mask if provided), so red jacket → red ref, pale skin → pale ref, dark skin → dark ref, etc. off — no filtering. exclude — KEEP pixels matching the reference, suppress non-matching (cleans bleed in mask). exclude_hard — same but binary threshold (use color_strength=1). include — ADD pixels matching reference into the mask (catches what SAM3 missed). exclude_and_include — combine: keep matching AND add matching pixels SAM3 missed. remove_matching — REMOVE pixels matching reference from the mask. Use case: pass color_reference_mask=ear_region to subtract ear-colored pixels from a skin detection.
color_strengthoptFLOAT0.700–1How aggressive 'exclude' is. 0 = no effect, 1 = fully suppress non-matching pixels. Try 0.5 for stylized art that doesn't match the reference range strictly.
color_thresholdoptFLOAT0.300–1Threshold for binary color modes (exclude_hard, include). Pixels with color-match likelihood above this count as 'matches reference'. Lower for stylized art (try 0.15-0.25).
color_modeoptCOMBOadaptive_labHow the color filter scores match likelihood: adaptive_lab — GENERIC, works for ANY positive-prompt category. Samples reference color from the current combined mask (or color_reference_mask if provided), then scores every image pixel by CIE LAB ΔE distance. Self-tunes per character/object. fixed_hsv — SKIN-SPECIFIC. Hard-coded HSV ranges from the legacy GLSL shader. Only use this for skin detection on photo-trained characters; fails on very pale/dark skin and on non-skin categories entirely. both — multiply the two likelihoods (strictest, skin-only). Falls back to fixed_hsv if not enough confident pixels for adaptive sampling.
color_reference_maskoptMASKOptional explicit color reference mask. When provided, adaptive_lab samples reference color from this region (useful when you want to lock the reference to a specific area, e.g. a face mask for skin, a swatch region for clothing). When NOT provided, samples from the current SAM3 combined mask — which is normally what you want, since the positives ALREADY found the category you're refining.
adaptive_toleranceoptFLOAT252–100LAB ΔE distance at which adaptive likelihood = 0.5. ΔE 2.3 = just-noticeable, 25 = clearly different but related (typical skin variation), 50+ = very loose. Tighten for strict skin matching, loosen for shadowed/rim-lit skin.
adaptive_sample_thresholdoptFLOAT0.500–1Only mask pixels above this value are used as reference samples for adaptive sampling. Higher = use only the most confident pixels (better reference, fewer samples).
adaptive_min_samplesoptINT5010–10000Minimum number of confident skin pixels needed for adaptive mode. If fewer, falls back to fixed_hsv.
silhouette_maskoptMASKOptional character outline mask. When provided AND enforce_silhouette=True, the final combined_mask is multiplied by this silhouette as the LAST step — any SAM3 false positives outside the character (e.g. detecting 'skin' in the background) are zeroed. Also constrains the color filter's 'include' zone to within the silhouette.
enforce_silhouetteoptBOOLEANtrueWhen True (and silhouette_mask is non-blank): EVERY SAM3 result (positive and negative) AND the colour filter are clamped to the silhouette immediately after inference — combined_mask reflects 'what SAM3 found INSIDE the character only'. When False: the silhouette does NOT restrict SAM3 or any mask function (raw SAM3 output, including outside the outline). The silhouette is still available — wire silhouette_composite_enable to punch the detected regions OUT of the silhouette (silhouette − combined) via the silhouette_composite output. So: enforce ON = clamp; enforce OFF = don't clamp, optionally use the outline only for the composite.
include_dilate_radiusoptINT640–512When 'include' has no silhouette_mask: how far (in pixels) to dilate the SAM3 mask to define the 'candidate zone' for adding skin pixels. Higher = pulls in more distant skin (good for filling chest/torso when SAM3 only got arms/legs).
masked_image_bgoptCOMBOwhiteBackground composited under the mask in masked_image. masked_image is literally combined_mask used as alpha to blend image over this color (transparent = RGBA output with mask as alpha channel). Continuous mask values produce continuous alpha blending — no threshold trickery.
invert_negatives_in_per_promptoptBOOLEANtrueWhen True, negative prompts in per_prompt_masks are inverted before batching: white = pixels KEPT after subtraction, black = pixels REMOVED. Makes it visually obvious which areas each negative is excluding when previewed as a batch. Set False to get raw 'white-where-detected' for both positives and negatives.
confidence_thresholdoptFLOAT0.500–1
deviceoptCOMBOAuto3 options: Auto, CPU, GPU
mask_bluroptINT00–64
mask_offsetoptINT0-64–64
unload_modeloptBOOLEANfalseUnload SAM3 from VRAM after this node finishes. Useful when SAM3 won't be used again this Run.
invert_combinedoptBOOLEANfalseInvert the FINAL combined mask. Global flip — turns 'detected' into 'not detected'. WARNING: if you wire combined_mask into BD_PartsBuilder.combined_mask downstream, leaving this ON will INVERT the silhouette and zero every real per-class mask. Symptom: only one full-image leftover part survives. Keep this OFF for Parts pipeline workflows.
mask_thresholdoptFLOAT0.000–1Binarize the combined mask at this value. 0.0 = off (continuous, current behaviour). Any value > 0 snaps every pixel to 0 or 1 at that cutoff — removes the grey semi-transparency that causes color bleed when the mask is used in color transfer or GLSL. Try 0.5 as a starting point.
silhouette_composite_enableoptBOOLEANfalseEnable silhouette_composite output. When True: computes silhouette_mask − combined_mask (clamped 0-1) so the detected regions are punched out of the outline. Example: head silhouette minus eyes/mouth/brows = clean skin-only mask for color transfer. Requires silhouette_mask to be wired. Off = output zeros.

Outputs (5)

NameTypeDescription
combined_maskMASK
masked_imageIMAGE
per_prompt_masksMASK
statusSTRING
silhouette_compositeMASKsilhouette_mask − combined_mask, clamped to [0,1]. When silhouette_composite_enable=True: gives you the outline region with the detected parts punched out — e.g. head silhouette minus eyes/mouth/brows = skin-only mask, ready for color transfer. When silhouette_composite_enable=False or no silhouette provided: outputs zeros.