Nodes/ComfyUI-MultiMaskOps/Mask Sort By Position
ComfyUI Node

Mask Sort By Position

Sort masks left-to-right so 'the second character' finally means something

By INuBq8·Created 2 months ago·Updated 2 months ago· 0
Mask Sort By Position
  • masks
  • masks
  • debug_image
reference_point
sort_left_to_righttrue
sort_top_to_bottomtrue
primary_axis_horizontaltrue
flatten_before_sortfalse
drop_below_thresholdfalse
threshold0.50

"Apply this to the leftmost character" is a maddening thing to wire up in ComfyUI, because segmentation doesn't return masks in any useful order. It returns them in whatever order the model felt like. Mask Sort By Position fixes that: it sorts a list of masks by where they actually sit in the frame, so you can reliably address subjects as "first from the left," "top-most," and so on.

That ordering is what makes the rest of the pack usable. Feed the sorted list into Mask Pick By Index and 0 becomes "leftmost" and -1 becomes "rightmost" regardless of how many subjects were detected. This is the node that turns position into an address.

How it works

Each mask gets assigned a reference point, and the list is sorted by those points. Two modes for the point:

  • centroid - the value-weighted center of the mask. Soft or feathered masks are handled correctly (brighter pixels pull the point toward them); a plain binary mask reduces to the geometric mean. This is the sensible default.
  • extreme_point - the outermost pixel along the primary sort direction, e.g. the leftmost pixel when sorting left-to-right. Good when you care about where a mask starts, not where its mass is.

From there: sort_left_to_right and sort_top_to_bottom set each axis's direction, and primary_axis_horizontal decides which axis sorts first, with the other breaking ties. The sort is stable, so full ties fall back to original order - you won't get random reshuffling on identical masks.

Inputs that matter

You'll touch four of these, and can ignore the rest:

  • masks - the list to sort (convert a batch with Mask Batch To List first).
  • reference_point - centroid or extreme_point, described above.
  • sort_left_to_right / sort_top_to_bottom - direction per axis.
  • primary_axis_horizontal - which axis wins when two masks share a coordinate.

The remaining three - flatten_before_sort, drop_below_threshold, and threshold - exist for fiddly cases: flatten_before_sort binarizes each mask before computing its sort point, and drop_below_threshold ignores faint pixels. Worth knowing they only affect sorting; the output masks are always your originals, just reordered. Easy to misread them as editing the masks.

The debug output

The second output, debug_image, is a white canvas with a black dot marking each mask's sort point, drawn in sorted order. This is not decoration - wire it into a PreviewImage once and you'll instantly see whether "leftmost" is what you think it is. Particularly with extreme_point on feathered masks, where a stray faint pixel far from the subject can claim the extreme; that's exactly when flatten_before_sort earns its keep.

Installation and notes

Same as the rest of the pack - clone, restart, no extra deps:

cd ComfyUI/custom_nodes
git clone https://github.com/INuBq8/ComfyUI-MultiMaskOps

Nodes land under MultiMaskOps; Manager search "MultiMaskOps" is the easier route once the listing is live. Empty masks sort to the origin (0, 0) by design, so a blank mask will sort as "top-left" - deduplicate or drop empties first if that skews your order. The pack is young (one commit as of mid-2026) and this node has no usage history to speak of, but the source is a clean ~30 lines of sort logic, and the debug output makes it self-verifying.

CategoryMultiMaskOps

Inputs (8)

NameTypeDefaultDescription
masksMASKA list of masks to sort by spatial position.
reference_pointCOMBOWhich point of each mask to sort by. 'centroid' = value-weighted center of the mask. 'extreme_point' = the outermost pixel along the primary sort direction (e.g. leftmost pixel when sorting left-to-right).
sort_left_to_rightBOOLEANtrueHorizontal direction. True = left to right, False = right to left.
sort_top_to_bottomBOOLEANtrueVertical direction. True = top to bottom, False = bottom to top.
primary_axis_horizontalBOOLEANtrueWhich axis sorts first. True = sort horizontally first, then vertically to break ties. False = vertical first, then horizontal.
flatten_before_sortBOOLEANfalseIf enabled, each mask is binarized at 'threshold' before its sort point is computed. Only affects sorting; output masks are unchanged.
drop_below_thresholdBOOLEANfalseIf enabled (and not flattening), pixels below 'threshold' are ignored when computing the sort point (a thresholded ReLU). Only affects sorting; output masks are unchanged.
thresholdFLOAT0.500–1Cutoff used by flatten_before_sort and drop_below_threshold to decide which pixels count when computing each mask's sort point.

Outputs (2)

NameTypeDescription
masksMASKThe input masks reordered by spatial position.
debug_imageIMAGEA white image with a black dot marking each mask's sort reference point, in sorted order. For debugging.