Conditioning Mask Combine (dynamic) π
Stop stacking Conditioning (Set Mask) nodes β do the whole regional chain in one node
- positive_1
- negative_1
- mask_1
- positive_2
- negative_2
- mask_2
- positive_3
- negative_3
- mask_3
- positive_4
- negative_4
- mask_4
- positive_5
- negative_5
- mask_5
- positive_6
- negative_6
- mask_6
- positive_7
- negative_7
- mask_7
- positive_8
- negative_8
- mask_8
- positive_9
- negative_9
- mask_9
- positive_10
- negative_10
- mask_10
- combined_positive
- combined_negative
If you've built a multi-region workflow in ComfyUI, you know the ritual: for every region you add a Conditioning (Set Mask) node, then a tower of Conditioning (Combine) nodes to merge the positive side, and another tower for the negative side. Three regions means six-plus nodes of spaghetti just to reach the KSampler. Conditioning Mask Combine (dynamic) collapses that whole chain into a single node. You connect a (positive, negative, mask) triplet per region and it hands the sampler one combined positive and one combined negative.
It's the final link in the Momo Nodes regional pipeline - RGB Mask Editor paints the map, RGB Mask Splitter pulls per-color masks out, and this node turns those masks into regional conditioning. The pack's README frames it exactly as a drop-in replacement for chained Set Mask + Combine, and that's what it is.
How it works
Under the hood it's not doing anything exotic - which is reassuring, because it means the behavior is predictable. For each triplet where all three of positive_i, negative_i, and mask_i are connected, it clones the conditioning entries and stamps on the exact same fields ComfyUI's Conditioning (Set Mask) sets: the mask, set_area_to_bounds, and mask_strength. Then it appends everything into one list per side. Effectively you're getting Set Mask followed by Combine, minus the nodes.
The "dynamic" part is front-end, a little JavaScript that ships with the pack. The node starts with a single triplet slot visible, and every time you connect an input to it, the next triplet's inputs appear - up to 10. No scrolling through 40 empty sockets, no accidentally forgetting which number you're on.
The inputs that matter
For each triplet i you've got:
mask_i_strength- float, 0 to 10, default 1.0. This is the Set Mask strength: 1.0 applies the mask fully, 0 means no masking at all. Dialing a region below 1 lets its prompt leak outward a little; cranking above 1 pins it down harder.set_cond_area_i-defaultormask bounds. "mask bounds" restricts the conditioning area to the mask's bounding box, which tightens the region's footprint; "default" leaves it at the full area.
Outputs are combined_positive and combined_negative, which wire straight into your KSampler's positive/negative inputs.
Where people get burned
Incomplete triplets are skipped silently. If you connect positive_2 and mask_2 but forget negative_2, that whole region quietly vanishes from the conditioning - no error, no warning. The README advertises this as a feature (unused slots never block the workflow), and it is - but it's also the most likely reason a region just doesn't show up. Check all three inputs before blaming the prompt.
Strength is per-triplet, which is a feature. The old chain-of-Set-Mask approach often shares one global setting or forces you to sprinkle in math nodes; here each region keeps its own strength and area mode, so you can hold one region hard while letting another blend. Regional-prompting lore says holding hard masks through the whole sample is what produces the collaged, seamed look - with per-region strength you can soften individual regions without rebuilding the graph.
It's regional conditioning, not layout control. If your problem is a single subject coming out wrong, or you need pose/structure guidance, this won't help - that's prompt/ControlNet territory. This node exists purely to give each painted region its own prompt.
Installing it
One install covers the whole pack, no model downloads. ComfyUI Manager: search Momo Nodes. Or manually:
cd ComfyUI/custom_nodes/
git clone https://github.com/Phykrex/ComfyUI-Momo-Nodes.git
Restart ComfyUI and hard-refresh the browser - the dynamic-slot behavior lives in JS. No extra Python dependencies beyond Pillow/torch/numpy. The node sits under MomoNodes/conditioning.
One caveat: this pack is brand new and has no community footprint to speak of yet, so you're an early adopter. The code is small and readable, the mechanics match the native nodes exactly, and the dynamic slots are a genuine quality-of-life win. For a multi-region pipeline it's the one node in the pack I'd reach for even alone, without the editor and splitter - just feed it masks from anything.
Inputs (50)
| Name | Type | Default | Description |
|---|---|---|---|
| positive_1opt | CONDITIONING | β | |
| negative_1opt | CONDITIONING | β | |
| mask_1opt | MASK | β | |
| mask_1_strengthopt | FLOAT | 1.000β10 | β |
| set_cond_area_1opt | COMBO | default | 2 options: default, mask bounds |
| positive_2opt | CONDITIONING | β | |
| negative_2opt | CONDITIONING | β | |
| mask_2opt | MASK | β | |
| mask_2_strengthopt | FLOAT | 1.000β10 | β |
| set_cond_area_2opt | COMBO | default | 2 options: default, mask bounds |
| positive_3opt | CONDITIONING | β | |
| negative_3opt | CONDITIONING | β | |
| mask_3opt | MASK | β | |
| mask_3_strengthopt | FLOAT | 1.000β10 | β |
| set_cond_area_3opt | COMBO | default | 2 options: default, mask bounds |
| positive_4opt | CONDITIONING | β | |
| negative_4opt | CONDITIONING | β | |
| mask_4opt | MASK | β | |
| mask_4_strengthopt | FLOAT | 1.000β10 | β |
| set_cond_area_4opt | COMBO | default | 2 options: default, mask bounds |
| positive_5opt | CONDITIONING | β | |
| negative_5opt | CONDITIONING | β | |
| mask_5opt | MASK | β | |
| mask_5_strengthopt | FLOAT | 1.000β10 | β |
| set_cond_area_5opt | COMBO | default | 2 options: default, mask bounds |
| positive_6opt | CONDITIONING | β | |
| negative_6opt | CONDITIONING | β | |
| mask_6opt | MASK | β | |
| mask_6_strengthopt | FLOAT | 1.000β10 | β |
| set_cond_area_6opt | COMBO | default | 2 options: default, mask bounds |
| positive_7opt | CONDITIONING | β | |
| negative_7opt | CONDITIONING | β | |
| mask_7opt | MASK | β | |
| mask_7_strengthopt | FLOAT | 1.000β10 | β |
| set_cond_area_7opt | COMBO | default | 2 options: default, mask bounds |
| positive_8opt | CONDITIONING | β | |
| negative_8opt | CONDITIONING | β | |
| mask_8opt | MASK | β | |
| mask_8_strengthopt | FLOAT | 1.000β10 | β |
| set_cond_area_8opt | COMBO | default | 2 options: default, mask bounds |
| positive_9opt | CONDITIONING | β | |
| negative_9opt | CONDITIONING | β | |
| mask_9opt | MASK | β | |
| mask_9_strengthopt | FLOAT | 1.000β10 | β |
| set_cond_area_9opt | COMBO | default | 2 options: default, mask bounds |
| positive_10opt | CONDITIONING | β | |
| negative_10opt | CONDITIONING | β | |
| mask_10opt | MASK | β | |
| mask_10_strengthopt | FLOAT | 1.000β10 | β |
| set_cond_area_10opt | COMBO | default | 2 options: default, mask bounds |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| combined_positive | CONDITIONING | β |
| combined_negative | CONDITIONING | β |