Field Threshold
Select the Top 30% of Any Mask, Whatever Its Histogram
- field
- mask
The decision node
At some point every mask chain has to stop being a gradient and become a decision: this region, not that one. Field Threshold is that node. Four modes, and one setting - threshold_by - that makes it behave very differently from the threshold node you're used to.
Level vs coverage
In level mode, threshold is compared against the input directly. That's the straightforward thing, and it's exactly right straight out of Field Noise, where coverage has already normalised the field so 0.5 is a meaningful midpoint.
In coverage mode, the input is rank-transformed first, so threshold = 0.3 selects the top 30% of pixels whatever the input's histogram looks like. Your edge map with a median of 0.004, your distance field, your local-contrast map, a combination of all three - same slider, same meaning. That's the mode that saves you from the oldest annoyance in mask-making: re-tuning a level every time the source image changes.
There's a bonus that isn't obvious: in coverage mode, softness becomes quantile-valued. "The transition spans 10% of the image's pixels" is stable across content and resolution, instead of being a level offset that means something different on every image.
The author is honest about the precision. Coverage is exact to about 0.07% of pixels at 64×64 and better at higher resolution, because the rank transform runs through a 4096-bin table rather than sorting exactly. And on an already-binary input, coverage can't select more than the fraction of ones that input actually has - a mask that's 12% white can't be asked for the top 30%.
Modes
hard- a straight comparison. Binary output.smooth- the comparison ramped oversoftness. The ramp is the quintic6t⁵ − 15t⁴ + 10t³, not the cubic smoothstep, because the cubic's second-derivative jump shows up in anything slope-sensitive downstream and this pack exists to feed other nodes' maths.band- keeps values withinband_widthof the threshold, which is how you get contour strokes, or how you isolate a mid-tone wedge out of luma. It's also the right partner for circular quantities likehuefrom Field From Image or theangulargradient, where the interesting part is a slice rather than one side of a level.posterize- quantises intolevels(2 to 32) steps. Useful for building stepped, graphic masks and for seeing what a field's distribution actually looks like.
Widgets: field (MASK), mode, threshold_by, threshold (default 0.5), softness (default 0), band_width (default 0.25), levels (default 4). One output: mask.
Install
ComfyUI Manager → search ComfyUI Field, or:
cd ComfyUI/custom_nodes
git clone https://github.com/jeremieLouvaert/ComfyUI-Field
Restart. No model downloads, no dependencies. Under AKURATE/Fields/Reshape.
Where it earns its keep
Three places, mostly. First, right after Field Noise or Field Gradient when you want a hard selection out of soft noise - set threshold_by to coverage, threshold to 0.4, done, and it doesn't matter what octaves or gain you used. Second, after Field From Edges to turn an edge magnitude field into usable contours. Third, downstream of Field Distance in both mode, where the contour lands at exactly 0.5, so the default settings recover the original mask and any other value gives you a band around it.
Traps
Softness on a binary input does nothing you can see. If your input is already hard-edged, smooth and softness and band_width are all working on a step function, and the only visible change is where the step lands. Run Field Remap or Field Morphology's feather first if you want a ramp.
The plateau thing, again: a constant segment in a Field Gradient ramp is a plateau, so a coverage target that lands inside its mass steps across it rather than sliding smoothly. Same for any mask with large flat regions. It's documented behaviour shared with every histogram method in the pack, but it will absolutely look like a bug the first time it happens.
And if you've been assuming threshold is always a level - worth double-checking which threshold_by you're in before you spend ten minutes wondering why 0.9 doesn't mean "keep almost nothing". In coverage mode, 0.9 means "keep the top 10%".
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| field | MASK | — | |
| mode | COMBO | hard | 4 options: hard, smooth, band, posterize |
| threshold_by | COMBO | level | 2 options: level, coverage |
| threshold | FLOAT | 0.500–1 | — |
| softness | FLOAT | 0.000–1 | — |
| band_width | FLOAT | 0.250–1 | — |
| levels | INT | 42–32 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| mask | MASK | — |