ComfyUI Node

CPA MaskMax

Two Masks Walk In, One Mask Walks Out

By rik-python·Created about a month ago·Updated 9 days ago· 50
CPA MaskMax
  • a
  • b
  • mask

This is the simplest node in the pack and one of the most useful: it takes two masks and returns the elementwise maximum. a, b, out comes mask. That's the whole schema, and the whole implementation is torch.maximum.

Why does that deserve a node? Because it's how this pack says "and also this bit". The generator tracks several objects - your subject, plus every add-click and cut-click and excluded subject - each as its own SAM 3 track, and a track gives you a mask per frame. To treat three of them as one selection you need a union. Max is the right union operator here for a reason that's easy to miss.

Max, not add

If you add two masks, pixels where both are 1 come out as 2, and then everything downstream is calibrated for 0–1. If you OR them as booleans, you throw away the soft values that matter - these masks are the SAM 3 output after some smoothing, with fractional values along the edges, and the pack's downstream stages care about that (trimap construction, the blend).

Max gives you: 1 where either mask is solid, the larger soft value where they overlap, and no overshoot. On hard masks it is the union. On soft masks it's the union with the more confident edge winning, which is what you want when one click's track is cleaner than the other's.

Where it's used

The generator's union() helper wraps it and folds a list:

out = first mask
for each remaining mask:  out = MaskMax(out, that mask)

Three places call it. The adds union - your shift-clicks, a hand SAM 3 missed, a held prop you want in the same matte. The cuts union - alt-clicks, someone else's hand inside the subject's mask. And the others union - every other subject SAM 3 found and excluded, which then becomes the mask that gets painted out of the isolated plate. Stacking a man, his glass and a table into one matte is this node doing the work.

Outside the generator it's an obvious utility: union two SAM 3 detections, or combine a person mask with a prop mask before feeding anything that takes one mask.

Hand-wiring it

You can't find it in the node menu - it's an /internal stage, flagged deprecated so search stays clean - so the way you use it manually is to copy it out of an expanded graph, or to accept that this pack wants you to use its own nodes. Both inputs are required, both are MASK, and there are no widgets to get wrong, which is more than you can say for most of the pack.

Both sides need to be the same shape: this is elementwise max with no resampling, so a 49-frame mask and a 250-frame mask are not going to become a sensible 250-frame union by themselves. Batch one frame against many and you'll get broadcasting, not a merge across time.

Install

Part of the pack:

cd ComfyUI/custom_nodes
git clone https://github.com/rik-python/ComfyUI-Comfy-Pro-Alpha-Generator.git
pip install -r ComfyUI-Comfy-Pro-Alpha-Generator/requirements.txt

Restart ComfyUI. Nothing else - no model, no extra Python package, no VRAM.

Why it exists as a node at all

Same reason as everything else in this pack's internals: caching. Each union step is a cached node, so adding a fourth click to your subject re-runs the fourth track and the final max, not the three tracks that didn't change. On a 250-frame shot where each track is a SAM 3 propagate, that's the difference between a two-second edit and a coffee break.

It's also a small, honest reminder of how much of a working ComfyUI pipeline is plumbing. The interesting node in this pack is the one with the picker and the render button. The one that makes it bearable is a torch.maximum wrapped in a schema.

CategoryComfy Compositing/internal

Inputs (2)

NameTypeDefaultDescription
aMASK—
bMASK—

Outputs (1)

NameTypeDescription
maskMASK—