D2 Moss Item
Let the mask do the bounding-box math
- mask
- moss_item
The problem this thing solves
MOSS-Image, OpenMOSS's open image model, has an experimental party trick: alongside a normal prompt you can hand it a JSON layout - a list of items, each with its own bounding box - and it tries to put each thing in its own box. If you've ever fought regional prompting, you know why that's appealing. Prompt adherence is global, so two subjects in one prompt cheerfully swap hair colours and poses, and the standing fix has been to bolt region masks onto the attention layers. Here the model takes the box natively - the same direction Ideogram went by making bounding boxes part of its caption schema.
The catch is arithmetic. MOSS wants absolute pixel coordinates with the canvas centre as the origin, ordered [y_min, x_min, y_max, x_max] - so a 1024×1024 canvas runs -512 to +512 on both axes. Nobody can eyeball that for six elements and get it right.
D2 Moss Item deletes the arithmetic. You give it a mask; it measures the bounding rectangle around everything non-zero in it and writes the coordinates in exactly the format MOSS expects. That's the whole node. It samples nothing, loads no model, calls no API. It's a very good measuring tape.
How it works
The heavy lifting is one function in the pack's nodes/modules/moss_util.py: take the mask tensor, drop to the first frame if it's a batch, find the min and max of the non-zero pixels, add one to the max values so the right and bottom edges land on pixel boundaries, then subtract half the width and height to move the origin to the centre.
Two consequences follow. An all-zero mask is treated as the whole canvas rather than as an error, so a forgotten connection gives you a full-frame box. And the box is computed in the mask's own pixel space, so draw the mask at the resolution you're actually generating at.
The output is a D2_MOSS_ITEM - a custom type carrying the finished item dict plus the mask's width and height. Those dimensions are for the next node's sanity check, not for you.
The inputs you actually set
mask - the rectangle you painted. Comes from D2 Create Masks in the same pack (drag boxes on a canvas, get mask_1…mask_N), or Load Image plus the mask editor, or a segmenter like SAM.
label - object or text. object draws a thing; text renders literal glyphs, which is the reason people get excited about MOSS in the first place.
caption - how that one element looks: size, colour, style, angle. Line-leading # and // get stripped as comments here, so don't start a caption line with a hash and expect it to survive.
text - only read when label is text, ignored otherwise. It's a single-line widget, so you type the two characters \n where you want a line break and the node converts them to a real newline. Leave it empty with label set to text and you get an error.
Output is the single moss_item socket, and it only fits D2 Moss Prompt - you can't preview it or feed it to a string node. That's expected, not a broken install.
Installing it
Both Moss nodes live in the same pack, so this is one install. In ComfyUI Manager, search the title D2 Nodes ComfyUI and install. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/da2el-ai/D2-nodes-ComfyUI
Restart ComfyUI and look under D2/Text. Dependencies are light - requirements.txt lists piexif and charset-normalizer, both probably already in your environment.
One version note that bites people: from v32.0.0 the pack migrated to ComfyUI's V3 node-authoring schema, and the README says plainly that older ComfyUI builds won't run it. If the import fails, update ComfyUI or check out a tag before v32.0.0.
Where people get burned
Mask size versus generation size. Coordinates are relative to the mask's own dimensions. Draw masks at 1024×1024 and generate at 1216×832, and the layout is quietly skewed - everything shifted towards where the box was on the square canvas. Nothing errors.
Mismatched item sizes. Masks of different dimensions mean coordinate origins that no longer agree. The check that catches it lives in D2 Moss Prompt, not here, and the message prints in Japanese:
[D2 Moss Prompt] アイテムのマスクサイズが揃っていません: 1024x1024, 640x480
That's "the item mask sizes don't match" followed by the sizes it saw. Same story for the empty-text error - Japanese traceback, fix is to fill the field.
An empty mask is a full-canvas item. If one element lands dead centre and huge regardless of what you asked, check that its mask is both connected and painted.
Blaming the node for the model. Layout prompts are experimental upstream. MOSS-Image's guide wants roughly a million pixels at multiples of 16, 50+ steps, CFG 3.0, Euler. Feed it a 20-step CFG 7 run and boxes get loosely interpreted, which reads like broken coordinates when they aren't.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | — | |
| label | COMBO | object | 2 options: object, text |
| caption | STRING | — | |
| text | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| moss_item | D2_MOSS_ITEM | — |