Random Wang Boundaries (from Image)
Start a tile set from any texture
- image
- IMAGE
- MASK
- TILESET
If you want a set of tiles that mutually tile - not one self-tiling image, but a whole library of pieces that can be laid down in any order - this is the node you start from. Give it a source texture and it rips random strips off it, assembles them into Wang tile exterior boundaries, and hands you an inpaint mask so the diffusion model can fill the interiors. That boundary-inpainting trick is the whole method behind this pack (Sartor & Peers, ACM TOG 2024): fix the outside from real texture, let the model invent the middle. The result is a diverse tile set whose edges genuinely match, without you having to mirror or blur anything.
What it does
It takes your source image and makes 2 * colors random cuts of it (each resolution tall/wide with overlap), then combines those cuts edge-wise into colors**4 Wang tile boundary frames. Two cut modes:
- ortho constrained - one axis of randomness is shared across all cuts, so horizontal structure stays aligned. The paper's default and the one that usually looks best.
- arbitrary - every cut is independent. More variety, more chance of incoherent interiors.
With colors edge colors you get colors**4 tile variants; set colors to 1 and the tileset quietly becomes a self tiling set instead, which is a handy freebie. resolution is the target tile size in pixels (256 for the SD2 inpainting checkpoint the sample workflow uses). candidates emits candidates copies of every boundary so a later rejection node can rank them.
Inputs and outputs
- image (IMAGE) - your source texture. Any size works; it gets cut and resized internally.
- mode (enum) - "ortho constrained" or "arbitrary"
- colors (INT, 1–10, default 3)
- candidates (INT, default 1)
- resolution (INT, default 256)
Outputs are the triad that defines every boundary node here: IMAGE (the assembled exterior-boundary tiles), MASK (the region the inpainter should fill), and TILESET (kind wang/self, colors, resolution, candidates). Wire IMAGE + MASK into InpaintModelConditioning and a KSampler - or the pack's own RollingKSampler to help kill seam artifacts - then RejectCandidateTiles → TilePacking → RandomTiling.
Installing and gotchas
Standard pack install: git clone https://github.com/samsartor/content_aware_tiles into ComfyUI/custom_nodes (or ComfyUI Manager → "content_aware_tiles") and restart. No model downloads; the bundled workflow expects an SD2 inpainting checkpoint like 512-inpainting-ema.safetensors.
Where people trip: the TILESET output is not optional - the whole downstream chain (TilePacking, RandomTiling, even DualBoundaries) takes it as a forceInput port, so keep the wire intact. And because the source texture's random cuts seed everything, a small or heavily cropped source gives you repetitive boundaries; give the node a decent chunk of texture. Expect zero community help if it breaks - this pack has essentially no reddit footprint - but the source is short and readable, and the included content_aware_tiles_workflow.json shows the exact happy path.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mode | COMBO | 2 options: ortho constrained, arbitrary | |
| colors | INT | 31–10 | — |
| candidates | INT | 1 | — |
| resolution | INT | 256 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| MASK | MASK | — |
| TILESET | TILESET | — |