ComfyUI Node

LC Mask Pass

Kill a Matte Without Rewiring Your Mask Bank

By lonecatone23·Created 2 months ago·Updated 2 days ago· 18
LC Mask Pass
  • mask
  • mask
enabletrue

If you run a mask bank - one detector feeding a colour match, a tone match, a skin pass and an upscaler - you already know which wire you touch most. The mask. Turn it off for one consumer and you're dragging wires around; leave it on and every node gets re-graded through the same matte whether you wanted that or not.

LC Mask Pass is the switch. Same mask in, same mask out, with a toggle that mutes the node so the consumer upstream of the toggle behaves as if nothing were plugged in.

Why you'd reach for it

Masked post-processing is the standard way to fix the small broken parts of a good generation without touching anything else, and the modern toolkit makes the mask cheap - a person matte from a detector, a face/body split, a chroma key. The friction isn't making the mask, it's the fourth consumer. You want the colour grade masked to the face, but the tone match to run full frame because your reference is a full frame. Now you need one masked feed and one unmasked feed from the same matte, and the unmasked one has to survive being toggled back and forth while you iterate.

That's two Passes and a Y-split, instead of a lot of unplugging.

How it works

Like its sibling LC Image Pass, this is two layers doing different jobs.

LCMaskPass.run(mask, enable=True) returns the mask unchanged. Both branches return the same object, so there is no backend logic here at all - it isn't normalising channels, inverting, blurring, resizing or fixing a 3-channel mask for you. Identity means identity.

The switch is web/lc_pass.js, which drives the node's execution mode from the enable widget: on = live, off = muted. It syncs both directions, so right-clicking → Mute on the node flips the widget to false and the two stay consistent, and because mode is stored in the saved workflow your taps come back in the same position on reload.

What "muted" means downstream is the crux. A muted node doesn't run, so it produces nothing, and the consumer's optional mask input reads None. For the LC nodes in this pack that's the documented fallback: LC Color Match with mask=None regrades the full frame, and LC Tone Match with mask=None locks the whole frame. No mask = full frame, which is the behaviour you want about half the time and the exact cause of "why is my whole image slightly off?" the other half.

Inputs and output

  • mask (MASK, required) - the matte you're gating.
  • enable (BOOLEAN, default true) - off mutes this node only. The author's tooltip: "Off mutes this node only - Color Match / Tone Match then run with mask=None (full frame)."
  • Out: mask - unchanged.

Install

Manager → search ComfyUI LC123 Nodes, or the manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/lonecatone23/ComfyUI_LC123_nodes
# restart ComfyUI, then hard-refresh the browser

No extra pip packages; the pack runs on ComfyUI's own environment. Your mask sources are separate installs though - a person-mask node (PersonMaskUltra and friends), SAM, a controlnet preprocessor - and this node passes whatever they hand it, including something the consumer can't use. Since the toggle is JavaScript, hard-refresh after any pack update or the widget will move while the node keeps running.

The trap the author warns about

Don't put this on the only mask wire into Skin Beauty or Skin Upscale if those have to stay masked. Their mask inputs are optional, so muting the Pass doesn't throw an error - it quietly drops your external matte and lets those nodes fall back to their internal behaviour. You get a plausible-looking, subtly wrong result, which is the worst kind of failure to debug.

The intended pattern instead: leave the masker live, and put one Pass per consumer you want to be able to unmask. PersonMaskUltra stays on; the Pass in front of the colour match becomes your full-frame button.

And skip it entirely where the mask is a required input - inpainting encode nodes, masked compositing, anything that treats a missing MASK as invalid. Muting a Pass there doesn't degrade gracefully, it fails validation and the whole prompt stops.

What it doesn't do

It doesn't repair a matte. Inverted, barely feathered, wrong format - it passes the problem along perfectly faithfully. It isn't a routing node either: it doesn't choose between two masks or merge two. You're buying a toggle, not a mask toolkit.

And it's typical of this pack: a single-maintainer, working-publisher toolkit that mostly solves the author's own friction, with almost no community chatter to fall back on. So read the tooltips, and when a Pass seems to do nothing, look at what the consumer does with the absence of a mask - that's where the behaviour actually lives.

CategoryLC123/mask

Inputs (2)

NameTypeDefaultDescription
maskMASK
enableoptBOOLEANtrue

Outputs (1)

NameTypeDescription
maskMASK