Gen2 LanPaint Soft Denoise Patch
A soft-denoise patch for LanPaint inpainting that learns as it goes
- model
- soft_mask
- model
If you do Qwen-Image-Edit inpainting on ComfyUI, you've probably met LanPaint - the crop-and-stitch workflow that became the standard for getting clean edits out of QwenEdit, which has no native inpaint mode. This node is a patch for that world: Gen2_LanPaintSoftDenoisePatch takes your model and a soft mask and wraps the sampler in a clone-local soft-denoise layer. It's in the "Gen2 Sampling" section but it's really a quality-of-life surgery for the mask-based inpainting that still beats edit models at bit-identical edits and controlled denoise.
How it works
The core problem with any masked inpaint: a hard mask produces hard seams, and the standard fix - a feathered mask - still leaves the model fighting the boundary. This patch's approach is a dual-mask soft patch with adaptive references. It keeps a reference of what the region should look like (your original image, the latest generated result, or an EMA-smoothed version of it) and uses it during sampling, with independently scheduled input and output blending. Input blending controls how much of the original leaks into the denoise at each step; output blending controls how strongly the result preserves the source as it approaches the end. The defaults tell the story: input blend holds at 1.0 throughout, output blend starts at 1.0 and fades to 0.0 - i.e., lean on the source early, then let the sampler commit to the generation.
The "adaptive" part is where it gets interesting. In ema_generated mode (the default reference mode) the patch maintains an EMA of the generated output, so mid-sample the reference adapts to what the model is actually producing rather than chasing a fixed target. This is the mechanism that smooths away seam drift over many steps - especially handy on the independently-sampled tile boundaries LanPaint's crop-and-stitch style creates.
Two things to know before you touch it. First, it's experimental, and it shows: roughly thirty optional parameters, several of which (the mixed_original_latest output mode, the reference selector curves) are opt-in experimental paths the author kept behind defaults precisely because they aren't validated. Second, it patches against LanPaint's sampler interface - it checks for LanPaint runtime attributes (PaintMethod, latent_image, noise, inner_model, sigmas, LanPaint_early_stop) and fails with a clear message if LanPaint's interface has changed. It's clone-local, like everything in this pack: no global patching, so it survives ComfyUI updates and won't bleed into other workflows.
The inputs that matter
model- the model you're inpainting with. WireLoad Diffusion Model → this node → sampler.soft_mask- your feathered inpainting mask. This is the region the patch treats as editable.
From the long optional list, the four you'll actually touch:
reference_mode-original_source(classic),latest_generated, orema_generated(default, the adaptive one).enable_input_blend/enable_output_blend- master switches for the two blending stages; toggle to A/B whether blending is helping.output_blend_strength_end- default 0.0; raise it if you want the final pass to keep more of the source.schedule_end_step- 0 means "use the last outer step," per the description; set an explicit step to end the schedule early.
Output: a patched model - same shape in, patched sampler behavior out.
Install
ComfyUI Manager: search ComfyUI-gen2. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/petmycat/ComfyUI-gen2.git
cd ComfyUI-gen2
pip install -r requirements.txt
Restart. The scipy in that requirements file is for the pack's tiling section, not this one. The real dependency is a working LanPaint setup to patch against. And since this node is essentially undocumented by the README (it ships in source but not in the pack's node list), lean on the defaults and one change at a time - with this many knobs, turning several at once is how you end up unable to tell which one fixed it.
Inputs (37)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| soft_mask | MASK | — | |
| reference_modeopt | COMBO | ema_generated | 3 options: original_source, latest_generated, ema_generated |
| reference_warmup_stepsopt | INT | 00–10000 | — |
| reference_ema_momentumopt | FLOAT | 0.700–0.99 | — |
| enable_input_blendopt | BOOLEAN | true | — |
| input_blend_strength_startopt | FLOAT | 1.000–1 | — |
| input_blend_strength_endopt | FLOAT | 1.000–1 | — |
| enable_output_blendopt | BOOLEAN | true | — |
| output_blend_strength_startopt | FLOAT | 1.000–1 | — |
| output_blend_strength_endopt | FLOAT | 0.000–1 | — |
| blend_schedule_typeopt | COMBO | linear | 3 options: constant, linear, cosine |
| schedule_start_stepopt | INT | 00–10000 | — |
| schedule_end_stepopt | INT | 00–10000 | — |
| adaptive_region_modeopt | COMBO | soft_band_only | 3 options: soft_band_only, soft_nonzero, hard_edit_region |
| adaptive_update_sourceopt | COMBO | raw_generated_output | 2 options: raw_generated_output, blended_output |
| lock_original_outside_adaptive_regionopt | BOOLEAN | true | — |
| adaptive_reference_initopt | COMBO | original_source | 2 options: original_source, first_generated_after_warmup |
| debug_loggingopt | BOOLEAN | false | — |
| output_reference_modeopt | COMBO | legacy | legacy preserves the existing output path; mixed_original_latest enables the new opt-in spatial mixture. |
| reference_selector_curveopt | COMBO | smoothstep | Shapes how the soft mask chooses original versus latest reference. |
| reference_selector_lowopt | FLOAT | 0.000–0.99 | — |
| reference_selector_highopt | FLOAT | 1.000.01–1 | — |
| reference_selector_gammaopt | FLOAT | 1.000.1–8 | — |
| latest_reference_ratio_at_soft_minopt | FLOAT | 0.000–1 | — |
| latest_reference_ratio_at_soft_maxopt | FLOAT | 1.000–1 | — |
| invert_reference_selectoropt | BOOLEAN | false | — |
| mixed_output_blend_strength_startopt | FLOAT | 1.000–1 | — |
| mixed_output_blend_strength_endopt | FLOAT | 0.200–1 | — |
| mixed_output_blend_scheduleopt | COMBO | cosine | 5 options: constant, linear, cosine, smoothstep, smootherstep |
| mixed_output_blend_schedule_startopt | FLOAT | 0.150–0.99 | — |
| mixed_output_blend_schedule_endopt | FLOAT | 0.750.01–1 | — |
| mixed_output_schedule_domainopt | COMBO | normalized_sigma | Uses sigma trajectory progress for the new mixed-output schedule; normalized_step is available for direct step timing. |
| output_blend_mask_curveopt | COMBO | legacy | Spatially reshapes output preservation without changing input blending. |
| output_blend_mask_lowopt | FLOAT | 0.000–0.99 | — |
| output_blend_mask_highopt | FLOAT | 1.000.01–1 | — |
| output_blend_mask_gammaopt | FLOAT | 1.000.1–8 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |