LTX Multiple Controls
Four reference slots, one node call — because chaining them silently breaks
- model
- positive
- negative
- vae
- latent
- guide_video
- mask_video
- identity_image
- identity_mask_image
- model
- positive
- negative
- latent
- debug
LTX Multiple Controls is the node you use when one reference just isn't doing the job - when you need a guide video for motion, a mask for the replacement region, and a separate identity reference for who actually appears in it, all at once. It's built for the scail2v2-style LTX 2.3 identity/Edit-Anything LoRAs this pack supports, and it exists because of a nasty trap: chaining the pack's single-reference node (LTX Identity Transfer / LTXIdentityOverlapConditioning) in sequence does not combine the references. Each call overwrites the previous one's spec, so you're left with only the last thing you wired. This node takes all the slots and merges their RoPE reference specs in a single call, so they actually coexist.
How it works
Each slot - guide, mask, identity, identity_mask - gets its own source_id, phase_scale, layout, resize mode, and downscale factor. Nothing is hardcoded; the defaults just match the v13 training recipe the author tuned against: guide and mask at source_id 0 (no RoPE phase tag, because they line up frame-for-frame with the target), identity at source_id 2 (phase-tagged, because it has no positional correspondence with the target). If that paragraph reads like coordinates-speak, fine - the short version is "these defaults are what the checkpoint learned, change them only for a different recipe."
The one setting that makes or breaks identity transfer is auto_mask_guide, on by default. It paints guide_video black everywhere mask_video is white - an inpainting hole - so the model can't just copy the guide's own person into the replacement region and must pull identity from identity_image. That's how the training data was built, and the tooltip is blunt about it: this is the fix that made identity transfer actually work.
Inputs and outputs that matter
Required: model (after loading the LoRA), positive/negative, vae, latent - standard stuff. The optional slots are where the action is:
- guide_video - the motion/structure driving clip (an IMAGE batch, e.g. from GetVideoComponents). Unconnected = skip the slot.
- mask_video - per-frame replacement-region mask, same frame count as the guide. For the v13 recipe this must be a plain white-on-black binary silhouette; the tooltip explicitly warns not to use a colored mask - it leaks hue into generated clothing. If a recipe tells you to color masks, that's a different slot.
- identity_image - the appearance reference (face/character) that fills the hole. This is what you're usually after.
- identity_mask_image - a small flat color dot from LTX Color Mask (
flat_markerstyle), not a silhouette. Unused by v13 - leave it unconnected unless your checkpoint is older. - identity_temporal_offset_latents - default 0 (standard frame-zero placement). A negative value is the experimental knob for reducing the "reference briefly appears at the start of the clip" artifact.
Outputs are model, positive, negative, latent (straight into the sampler), plus a debug STRING that logs each active slot's spec. Turn on debug_log if the console is quiet.
Installing it
Same as every node in this pack - it's alisson-anjos/ComfyUI-BFSNodes:
cd ComfyUI/custom_nodes
git clone https://github.com/alisson-anjos/ComfyUI-BFSNodes.git
cd ComfyUI-BFSNodes
pip install -r requirements.txt
Or ComfyUI Manager → search "BFSNodes". Restart after. requirements.txt drags in insightface, onnxruntime, librosa and opencv-python for the pack's face/audio nodes even though this node doesn't touch them - the insightface pin is the most common install snag, and it's unrelated to the LTX work.
Common issues
Identity ignored entirely → wrong layout or downscale_factor. These must match the checkpoint's training recipe - wrong values aren't a quality hit, they're coordinate positions the model never learned. The node's own debug log even reminds you: connect negative and run CFG 3–5, and skip LightX2V LoRAs. If you crank reference_guidance_scale above 1, know it costs an extra forward pass per step (that's ST-DRC-style reference-CFG, same units as sampler CFG).
Also temper expectations on hardware. These LTX 2.3 identity workflows are genuinely VRAM-hungry - people have reported OOMs even on a 4090 at 768px with the EditAnything LoRAs - so budget for fp8/GGUF weights and maybe a lower resolution before blaming the node.
Inputs (35)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| vae | VAE | — | |
| latent | LATENT | — | |
| guide_videoopt | IMAGE | Motion/structure driving video frames (IMAGE batch, e.g. from GetVideoComponents). Leave unconnected to skip the guide slot. Gets auto-masked black in the replacement region (see auto_mask_guide) unless disabled. | |
| guide_source_idopt | FLOAT | 00–8 | v13 recipe default: 0 (no RoPE phase tag at all -- must stay source_phase=false so the guide's positions line up with the target frame-by-frame). Non-zero only for older/experimental checkpoints. |
| guide_phase_scaleopt | FLOAT | 1.00–4 | — |
| guide_layoutopt | COMBO | overlap | 3 options: overlap, st_drc, strata |
| guide_ref_resize_modeopt | COMBO | match_target | 3 options: match_target, match_target_letterbox, native_resolution |
| guide_downscale_factoropt | INT | 11–8 | Encode at target_size/N instead of full res (cheaper VRAM). Must match whatever the checkpoint was trained with -- 1 for the no-downscale recipes, 2 for the earlier downscaled-guide recipes. Wrong value = positions the model never learned, not just a quality hit. |
| mask_videoopt | IMAGE | Per-frame replacement-region mask, same frame count/alignment as guide_video -- v13 expects a plain WHITE-on-black binary silhouette (person white, background black). Do NOT use a colored mask (see Color Mask node) -- confirmed to leak hue into the generated clothing during training. Also drives auto_mask_guide's black-out of guide_video. Leave unconnected to skip. | |
| mask_source_idopt | FLOAT | 00–8 | v13 recipe default: 0 (same non-tagged group as guide -- both need exact positional correspondence with the target). Non-zero only for older/experimental checkpoints. |
| mask_phase_scaleopt | FLOAT | 1.00–4 | — |
| mask_layoutopt | COMBO | overlap | 3 options: overlap, st_drc, strata |
| mask_ref_resize_modeopt | COMBO | match_target | 3 options: match_target, match_target_letterbox, native_resolution |
| mask_downscale_factoropt | INT | 11–8 | Same as guide_downscale_factor -- match the checkpoint's training recipe. |
| auto_mask_guideopt | BOOLEAN | true | v13 requirement: paints guide_video BLACK wherever mask_video is white, before encoding -- an inpainting hole, so the model can't just copy guide's own person into the replacement region and must pull identity from identity_image instead (matches how the training data was built). Turn off only if guide_video is already pre-masked upstream. |
| mask_white_threshopt | FLOAT | 0.500–1 | auto_mask_guide only -- mask_video pixels with mean brightness >= this (0-1 scale) count as foreground (person) and get blacked out in guide. |
| identity_imageopt | IMAGE | Appearance reference (face/character), no positional correspondence with the target needed -- this is what fills auto_mask_guide's hole. Leave unconnected to skip. | |
| identity_source_idopt | FLOAT | 20–8 | v13 recipe default: 2. Nonzero = tagged with its own RoPE phase (matches source_phase=true, since identity has no positional correspondence with the target). |
| identity_phase_scaleopt | FLOAT | 1.00–4 | — |
| identity_layoutopt | COMBO | overlap | 3 options: overlap, st_drc, strata |
| identity_ref_resize_modeopt | COMBO | native_resolution | 3 options: match_target, match_target_letterbox, native_resolution |
| identity_downscale_factoropt | INT | 11–8 | Same as guide_downscale_factor -- match the checkpoint's training recipe. |
| identity_mask_imageopt | IMAGE | scail2-style color-pointer marker for the identity slot (small flat color dot/blob, NOT a body silhouette -- a body-shaped mask here would re-inject a competing pose signal, exactly the bug the flat-marker design fixes on the training side). Same source_id/phase as identity_image by default (they're trained as one group) -- override identity_mask_source_id if your checkpoint used a different grouping. Leave unconnected to skip. | |
| identity_mask_source_idopt | FLOAT | -1-1–8 | -1 = inherit identity_source_id/identity_phase_scale (matches training, where ref+ref_mask share one group). Set >=0 to give it its own separate phase. |
| identity_mask_phase_scaleopt | FLOAT | 1.00–4 | — |
| identity_mask_layoutopt | COMBO | overlap | 3 options: overlap, st_drc, strata |
| identity_mask_ref_resize_modeopt | COMBO | native_resolution | 3 options: match_target, match_target_letterbox, native_resolution |
| identity_mask_downscale_factoropt | INT | -1-1–8 | -1 = inherit identity_downscale_factor. Same meaning otherwise as guide_downscale_factor -- match the checkpoint's training recipe. |
| crop_anchoropt | COMBO | center | Shared by all slots using ref_resize_mode=match_target with a mismatched aspect ratio -- which part of the source survives the crop. |
| reference_guidance_scaleopt | FLOAT | 1.01–10 | ST-DRC-style reference-CFG applied to the WHOLE combined reference set (all active slots together). 1.0 = off. |
| debug_logopt | BOOLEAN | false | — |
| identity_temporal_offset_latentsopt | INT | 0-16–16 | Temporal RoPE offset for appearance/reference tokens only, in VAE latent-time steps. 0 keeps the standard frame-0 placement used by existing LoRAs. -1 places the reference one latent step before frame 0 (normally -8 pixel frames), which can be tested to reduce overlap frame-0 reference leakage. Guide, mask, and target positions are never changed. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |
| positive | CONDITIONING | — |
| negative | CONDITIONING | — |
| latent | LATENT | — |
| debug | STRING | — |