DOGMA NativeChunkCrops v2
Cut a 4K frame into native-resolution tiles without downscaling anything
- image
- masks
- crops
- crop_masks
- stitch
- info
What it is
Take a big photo, take the masks for one category, and produce a set of crop tiles - plus the masks that belong to them and a metadata bundle for pasting them back. The constraint that makes it interesting: nothing gets downscaled. Every tile is a native-resolution window of the source, chosen to cover the masked regions and to stay inside a per-tile render budget you set.
That's the anti-Tiled-Diffusion design. Tiled upscalers usually shrink the whole image and blow it back up, or feed overlapping tiles with a control image to stop them drifting; both approaches lose detail or fight seams. This does neither - it decides which windows actually need re-rendering, crops them at 1:1 (or up to 2× toward the budget, never below 1:1), pads them to legal dimensions, and hands you the map to reassemble.
How the windows get chosen
Masks are unioned and thresholded (mask_threshold, default 0.3 - so soft matter masks work), then the union's bounding box is covered with a grid of core cells:
side = target_long_side(rounded down to 32) is the tile budget.contextis the surround kept around each core so a tile isn't a hard cut:min((side - 128) / 2, context_px).coreis what's left for actual content:side - 2 × context.
If your masked region is compact enough to fit one core, you get one window with full context around it. Otherwise it tiles: core-sized cells across the bbox, empty cells skipped, then windows ranked by how much mask they contain before max_chunks trims the list.
Two details that matter for seam quality. Each tile's crop mask is limited to its own core ± 32 px, so adjacent tiles deliberately share a 32px ownership strip instead of one claiming the boundary. And every crop is padded to multiples of 32 (replicate for the image, zeros for the mask) - which is why you can feed these straight to a VAE.
Inputs
image(IMAGE) - the source frame. Note it takes the first image of a batch and ignores the rest.masks(MASK) - the approved instances for this category.categoryandkind(STRING, forced inputs) - carried through from the selection stage. Worth knowing:categorylabels the reports, andkindis accepted but this version doesn't branch on it.target_long_side(INT, 512–4096, step 32, default 2048) - the per-tile render budget, and the reason you can run this on a consumer card.context_px(INT, default 160) - surround kept around each core, clamped by the budget.max_chunks(INT, 1–24, default 4) - hard ceiling on tiles. This is the knob you'll actually tune.mask_threshold(FLOAT, default 0.3) - where the union flips from "part of this region" to "not".group_gap_pxandmax_objects_per_chunkare in the schema but unused here - object grouping isDOGMAObjectNativeCropsV111's job. This node is purely spatial.
Outputs
crops(IMAGE, list) - the tiles.crop_masks(MASK, list) - the masked region inside each tile, 32px ownership strip included.stitch(DOGMA_STITCH, list) - per-tile metadata: source x/y, crop width/height, source dimensions, right/bottom pad, andmodel_mode='native_or_upscale_only'. Wire it to a stitch node to paste back; if you're pasting by hand, those fields are all you need.info(STRING) - e.g.person: 3/9 native spatial windows; render limit 2048px, budget 4. No downscale of any source region. 6 windows deferred, their pixels preserved.
That last sentence is the trap and the feature at the same time. Deferred windows are simply not rendered. Their pixels survive untouched, but if your mask spans a wall of buildings and max_chunks is 4, you get four tiles and a note about the six you didn't get. On a first run, set max_chunks high and target_long_side low, watch the info string, then dial it back to whatever your VRAM tolerates.
If the masks are empty you get sentinels - a 1×64×64 image, a zero mask, [{'noop': True}], and no approved region, no diffusion required - so a category that got culled upstream won't blow up the render branch.
Install
Manager → search DOGMA Nodes (publisher axior), or:
cd ComfyUI/custom_nodes
git clone https://github.com/axior/ComfyUI-DOGMA-Nodes
# restart ComfyUI
requirements.txt declares scipy>=1.10, which is the pack's only Python dependency; nothing is downloaded to models/. This node's own imports are numpy/torch, and it depends on nothing outside the pack.
One caveat specific to the design: "no downscale" is a real cost, not a free win. If your subject spans more pixels than your budget allows, you get more tiles at native resolution, which means more render time and more VRAM per tile - the opposite of what tiled upscalers give you. The KB's comparison is the useful frame here: tiled diffusion buys arbitrary output size by trading away native detail, and this node refuses that trade. Pick whichever your goal actually needs.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| masks | MASK | — | |
| category | STRING | — | |
| kind | STRING | — | |
| target_long_side | INT | 2048512–4096 | — |
| group_gap_px | INT | 1800–1200 | — |
| context_px | INT | 16032–640 | — |
| max_objects_per_chunk | INT | 61–20 | — |
| max_chunks | INT | 41–24 | — |
| mask_threshold | FLOAT | 0.300.05–0.8 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| crops | IMAGE | — |
| crop_masks | MASK | — |
| stitch | DOGMA_STITCH | — |
| info | STRING | — |