Dual Boundaries (Latent)
Skip the VAE round trip
- tiles
- tileset
- vae
- LATENT
- TILESET
Every image-space node in this pack has a latent twin, and Dual Boundaries (Latent) is the one that shows you why the twins exist. In the image version you build exterior boundaries, hand the IMAGE and MASK to an inpainting sampler, and eat a decode + re-encode on the way. This node does the same job entirely in latent space, and it bakes the mask straight into the latent object as a noise_mask. You get the exact same Dual Wang boundary generation - corner colors, interior + cross tiles, the whole paper trick - without touching pixels until you're done.
What it does
It takes a latent batch of tiles (from an earlier stage of a content_aware_tiles workflow, or any latent tiles you have) plus its TILESET, and emits new latent "outsides" - the boundary images with the interior carved out - alongside an updated TILESET declaring kind: dual. The subtle but important detail: the returned LATENT carries a noise_mask inside it. Standard ComfyUI samplers honor that automatically, so you connect this node's LATENT directly into a KSampler and the masked region gets inpainted without any separate mask plumbing. That's genuinely nicer than the image-space route, where you're juggling IMAGE + MASK into InpaintModelConditioning.
Inputs and outputs
- tiles (LATENT) - your latent tile batch
- tileset (TILESET, forceInput) - the metadata bundle (kind, colors, resolution, candidates); it has to come from another node
- vae (VAE) - used only to convert pixel resolution to latent resolution (
resolution // vae.downscale_ratio), since the TILESET stores resolution in pixels - candidates (INT, default 1) - how many candidate versions of each boundary to emit
Outputs: LATENT (boundaries + noise_mask, ready for a sampler) and TILESET (now kind: dual). From there the obvious continuation is KSampler → RejectCandidateTiles → LatentTilePacking or LatentRandomTiling, staying in latent space the whole way.
Installing and practical notes
Install is the pack standard: git clone https://github.com/samsartor/content_aware_tiles into ComfyUI/custom_nodes (or find "content_aware_tiles" in ComfyUI Manager) and restart. No model files required - you use whatever checkpoint and VAE are already in your setup; the bundled workflow pairs it with an SD2 inpainting checkpoint.
Keep in mind that the noise_mask depends on the downstream sampler honoring it, which stock ComfyUI does. And the same constraint as the image version applies further down the line: a dual tile set needs the full colors**4 * 2 interior + cross tiles before LatentTilePacking or LatentRandomTiling will touch it. If you see that ValueError, you under-generated - bump the sampler's batch to cover both sets. This is research-grade code with close to zero community footprint, so treat the workflow JSON as your map and don't expect forum threads to bail you out.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| tiles | LATENT | — | |
| tileset | TILESET | — | |
| vae | VAE | — | |
| candidates | INT | 1 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |
| TILESET | TILESET | — |