Mask Batch Union
Merge a whole batch of masks into one — without writing a custom script
- masks
- MASK
You've got a stack of masks and you want one mask. Every frame of a 24-frame clip has its own subject mask and you want the whole motion path in a single region. A SAM detector spat out five overlapping segmentations and you want the union for one inpaint pass. That's the whole job of Mask Batch Union, and it's about as unglamorous as a node gets - which is exactly why it's worth knowing. Combining masks is one of those asks that shows up over and over on r/comfyui ("How to combine two masks into one?", "combine masks from multiple video frames into a single flow mask"), and it's fiddly enough that people end up with three-node workarounds or a half-remembered script.
This one collapses an entire batch of masks down to a single mask with two merge strategies. No dependencies, no model files, nothing to tune. You plug masks in, pick a mode, get a mask out.
How it works
Under the hood it's a couple of torch ops, and the source is short enough to read in one sitting. A MASK tensor shaped [B, H, W] gets flattened to (-1, H, W) - collapsing every batch entry into one big dimension - and then merged along that dimension:
- max (default): pixel-wise maximum across the batch. A pixel is white if any mask covers it. This is the boolean OR of your masks - the classic union.
- sum_clamp: adds all the masks together, then clamps to
[0, 1]. Overlapping regions keep stacking intensity until they hit full white, so a pixel covered by two soft-edged masks ends up brighter than one covered by a single faint mask.
It also quietly accepts a single 2D mask (it unsqueezes it), so the node is safe to drop into a workflow that sometimes gives you a batch and sometimes gives you one. Output is a standard MASK with the batch dimension collapsed to 1.
The two inputs that matter
- masks - a
MASKtensor. This is the one to think about before you wire anything up: it's a single MASK input carrying a batch dimension, not multiple mask sockets. If you have several separate mask wires you want to merge, you need to batch them into one tensor first (there are node packs for exactly that), then feed the result here. This node won't combine two unrelated wires by itself. - mode -
maxorsum_clamp. Default ismax. When in doubt,maxis what you want: it's the honest "union" and it behaves identically no matter how many masks overlap. Reach forsum_clampwhen you actually want additive intensity - say, feathering soft masks together so their overlaps read brighter before a blur step.
The single output is the merged MASK, ready to wire into an inpaint workflow, a mask-based ControlNet, or anything else that wants one clean region instead of a batch.
Installing it
No heavy lift. It's on the GitHub repo, and you can grab it either way:
ComfyUI Manager - search "Mask Batch Union", install, restart. That's it.
Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/kevinkessler/comfyui-mask-batch-union
Then restart ComfyUI. There's no requirements.txt, no models to download, and the only dependency is torch - which you already have, since ComfyUI runs on it. The node shows up under the mask category as "Mask Batch Union".
Where people get burned
The classic mistake is treating it like a multi-input combiner. It takes one MASK tensor - if your masks arrive as a list of separate tensors (some packs output lists rather than batches), you have to batch them first or this node just merges nothing useful. If you're coming from the old CombineSegMasks (clIPSeg-era) or the two-input AddMask/bitwise approach, think of this as the version for an unbounded number of masks at once - up to however many fit in the batch.
One thing to keep in mind with sum_clamp: because it clamps at 1.0, heavy overlaps saturate to pure white just like max does. The difference only shows in regions with partial coverage, so if you're debugging why the two modes look identical on your case, that's usually why. It's a tiny node with a narrow job - but when the job is "make this batch of masks into one mask," it's the fastest path that exists.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| masks | MASK | — | |
| mode | COMBO | max | 2 options: max, sum_clamp |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MASK | MASK | — |