DOGMA Fast Dual Mask v34 — GPU / Opaque Core
One mask in, two masks out (and one of them must be opaque)
- mask
- generation_mask
- stitch_mask
- info
Most pipelines use one mask for two jobs and then wonder why something looks wrong. The job of a mask during sampling and the job of a mask during compositing want opposite things. Sampling wants generosity: a wide, generous region so the model has context to reason with. Compositing wants stinginess: paste only what you're sure about, and feather the rest.
This node just makes both, from one input mask, with a threshold and three integer dials.
How it works
Take the input mask, binarize at threshold. That hard core is the truth. Everything else is derived from it:
- generation_mask = the core dilated by generation_grow pixels (default 12). Hard-edged dilation via max-pooling, so it's growth without softening. This is the one you feed into the sampler's mask input - it's deliberately bigger than the object so the model gets neighbourhood.
- stitch_mask = the core dilated by stitch_grow (default 2), then smoothed outward by stitch_feather (default 8) using two average-pool passes, and finally
max(core, blur).
That last max is the design decision worth knowing about. A naive blur alone would soften the inside of the mask too, which means the middle of your repair region gets pasted at 70% opacity - the exact failure DOGMAExactCoreStitchV35 exists to avoid. Taking the elementwise maximum against the core keeps the semantic middle exactly opaque while letting the edges ramp. The info line calls it "opaque core," and that's the guarantee.
Thresholding happens on GPU when CUDA is available. That's not incidental: a comment in the source says the previous VLM-based mask processor was a major CPU bottleneck, and this node is the replacement for it. It's cheap - two pool operations - which is the point of the "fast" in the name.
Inputs and outputs
- mask (
MASK) - anything, including a soft SAM output. It gets binarized here. - threshold (
FLOAT, default 0.5, 0.01–0.99) - where the core boundary sits. Lower it if a soft mask is losing thin parts of the object. - generation_grow (
INT, default 12, 0–96) - how much padding the sampler sees. Bigger means more context and more chance of the model touching things you didn't ask for. - stitch_grow (
INT, default 2, 0–48) - the hard part of the pasted boundary. - stitch_feather (
INT, default 8, 0–48) - the soft ramp outside it.
Outputs: generation_mask (MASK) → into your inpaint conditioning; stitch_mask (MASK) → into the stitch node's masks input; info (STRING) → a one-line receipt of the three values you set.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/axior/ComfyUI-DOGMA-Nodes
Or ComfyUI Manager → DOGMA Nodes, or in the Comfy registry as comfy node install comfyui-dogma-nodes. No Python dependencies: requirements.txt is a comment line, pyproject.toml declares dependencies = [], and the node only needs torch. Nothing to download, MIT licensed, and it doesn't care which model or segmenter produced the mask.
Where people get burned
Sending both outputs to the same place. The whole value is that they differ. If your stitch node is getting generation_mask, you're compositing outside the region you asked the model to rebuild, and you'll see brackets of invented content around every object.
Cranking stitch_grow to hide a seam. Adding hard dilation doesn't blend anything - it just moves the hard edge outward, into a region the model never changed, which is where it shows most. Seam fixing is stitch_feather's job. Growth is for coverage.
Treating the defaults as universal. They're sized for one workflow's mask scale. A mask from a 1080p pass and a mask from a 4K pass need different pixel counts for the same visual effect; double all three when you double resolution, or the padding evaporates.
And note the sibling. DOGMAFastDualMaskV35 does the same thing but derives its grow and feather values from a category string instead - cars get 24/3/8, faces get 12/1/5. If you've already got category strings in your graph, that's less to tune by hand. This one is for when you want to see the numbers.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | — | |
| threshold | FLOAT | 0.500.01–0.99 | — |
| generation_grow | INT | 120–96 | — |
| stitch_grow | INT | 20–48 | — |
| stitch_feather | INT | 80–48 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| generation_mask | MASK | — |
| stitch_mask | MASK | — |
| info | STRING | — |