๐ญ Smart USDU Differential Diffusion
Keep the building, redo the sky
- image
- model
- conditionings
- negative
- vae
- upscale_model
- denoise_mask
- IMAGE
The problem with normal tiled upscaling is that denoise is a blunt instrument. You set it to 0.2 and the whole image gets the same light touch - great for keeping a building's geometry intact, useless for rebuilding a blown-out sky. Differential diffusion is the fix: instead of one denoise value for the whole canvas, you supply a mask and the sampler varies how much it changes per pixel. White regions get denoised hard, black regions barely at all. This node is Smart USDU with that wired in - Ultimate SD Upscale tiling plus a per-pixel denoise mask, in one node.
That's a genuinely useful combo for architecture shots, which is this pack's home turf. Upscale a render, mask the sky in white, leave the building black, and the pass adds detail to the sky while the structure stays put.
How it works
The differential diffusion part is a direct port of KJNodes' DifferentialDiffusionAdvanced - the source even keeps the comment "DO NOT MODIFY THIS CODE." It patches the model with a denoise-mask function that computes a per-step threshold, so at each sampling step, pixels above the threshold are denoised and below aren't. Your mask is upscaled to the output size, then cropped per tile so each tile's sampling uses the right region. Everything else is the USDU machinery: mode_type (Linear/Chess/None), tile size, padding, and seam fix, all the same as the base Smart USDU.
This variant also does its own pixel upscale: upscale_by (default 2) plus a required upscale_model input. If you're getting your upscale from the Smart Tile Solver instead, that's the No Upscale variant.
The inputs that matter
denoise_mask(optional MASK) - white = more denoise, black = less. No mask and the node behaves exactly like plain Smart USDU, so it's safe to leave disconnected.multiplier(default 1.0) - this is the knob people get backwards. The tooltip says it straight: below 1 is stronger, above 1 is weaker. Start at 1.0 and nudge down if the mask isn't changing enough.conditionings- aCONDITIONING_LISTin row-major tile order, matching tile count. Reuses the last entry if the list is short.denoise(default 0.2) - the baseline for the unmasked regions; the mask modifies from there.seam_fix_mode-Half TileorBand Passwhen tile edges show.
Output is a single IMAGE. Everything else is the standard sampler block: steps, cfg, sampler_name, scheduler, seed, and the tile/seam knobs.
Installing it
Ships in ComfyUI-ArchAi3d-Qwen by Amir Ferdos (ArchAi3d). ComfyUI Manager โ search "ArchAi3d Qwen" โ install โ restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/amir84ferdos/ComfyUI-ArchAi3d-Qwen.git
cd ComfyUI-ArchAi3d-Qwen
pip install -r requirements.txt
The heavy deps in requirements.txt (sam3, opencv, timm, google-genaiโฆ) are for the pack's other nodes, not this one - torch, numpy and Pillow cover it. Personal/non-commercial use is free; commercial work needs a paid license.
Where it trips people up
The mask has to match your output dimensions conceptually - it gets resized automatically, but a mask drawn on a tiny preview gets mushy when stretched, so draw it at a decent resolution. And if nothing changes no matter what you do with the mask, check multiplier: since the effect strength flips around 1.0, an accidentally-high value can blunt the whole mask. Also remember the mask only guides denoise - it doesn't protect content the way a true inpaint mask does, so for "don't touch this region at all" you still want low denoise there, not just a black mask.
Inputs (27)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | โ | |
| model | MODEL | โ | |
| conditionings | CONDITIONING_LIST | โ | |
| negative | CONDITIONING | โ | |
| vae | VAE | โ | |
| upscale_by | FLOAT | 2.000.05โ4 | โ |
| seed | INT | 00โ18446744073709550000 | โ |
| steps | INT | 201โ10000 | โ |
| cfg | FLOAT | 8.000โ100 | โ |
| sampler_name | COMBO | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 | |
| scheduler | COMBO | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 | |
| denoise | FLOAT | 0.200โ1 | โ |
| upscale_model | UPSCALE_MODEL | โ | |
| mode_type | COMBO | 3 options: Linear, Chess, None | |
| tile_width | INT | 51264โ8192 | โ |
| tile_height | INT | 51264โ8192 | โ |
| mask_blur | INT | 80โ64 | โ |
| tile_padding | INT | 320โ8192 | โ |
| seam_fix_mode | COMBO | 4 options: None, Band Pass, Half Tile, Half Tile + Intersections | |
| seam_fix_denoise | FLOAT | 1.000โ1 | โ |
| seam_fix_width | INT | 640โ8192 | โ |
| seam_fix_mask_blur | INT | 80โ64 | โ |
| seam_fix_padding | INT | 160โ8192 | โ |
| force_uniform_tiles | BOOLEAN | true | โ |
| tiled_decode | BOOLEAN | false | โ |
| denoise_maskopt | MASK | Optional mask for per-pixel denoise. White=more denoise, Black=less | |
| multiplieropt | FLOAT | 1.000-10โ10 | Controls effect strength. <1=stronger, >1=weaker |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | โ |