Nodes/ComfyUI-productfix/Apply latent injection (middlek)
ComfyUI Node

Apply latent injection (middlek)

Keep your product intact while everything around it changes

By MiddleKD·Created 2 years ago·Updated about a year ago· 21
Apply latent injection (middlek)
  • model
  • latents
  • inject_image_embed
  • inject_mask
  • MODEL
  • LATENT
start_sigma15.00
end_sigma0.00
remain_injectedtrue

This is the node the pack is named around. ApplyLatentInjection hijacks the KSampler so that, during sampling, your original product's latent gets re-injected where the product actually is - while the rest of the frame gets regenerated with the lighting, background, and composition you asked for. It's the difference between "the bottle is still recognizable" and "the bottle is a deformed suggestion of a bottle."

Why it exists

Plain inpainting preserves an input by compositing the original latent back into the masked region at each sampling step. That works, but if your input is a low-quality phone photo, you're gluing a low-quality latent into your output - the regeneration can't fix it. IC-Light solved the quality side by relighting the subject, but relighting regenerates the foreground too, which is exactly where text and logos get mangled.

Latent injection threads the needle. It's a Kandinsky-2.2-style idea (the pack's README credits that lineage): instead of re-injecting the raw original latent, it re-injects the original latent noise-scaled to the scheduler's current sigma, so the preserved region stays consistent with the sampling noise. And it only does this inside a sigma window - skipping the very first and very last steps so IC-Light's global lighting changes can still bake in. The result: the product keeps its detail, the world around it gets rebuilt.

How it actually works under the hood

The node patches KSamplerX0Inpaint.__call__ globally with a wrapper. When the model's options contain the is_latent_inject marker, every sampling step inside your start_sigmaend_sigma window does:

x = x * denoise_mask + noise_scaled(product_latent) * (1 - denoise_mask)

In plain words: where the mask says "generate," it generates; where the mask says "keep," it writes back the noise-scaled original product latent instead of the plain inpainting latent. When remain_injected is False, the original __call__ is restored automatically at the end of the run. (Default is True, which leaves the patch in place - harmless, because the wrapper only acts when the is_latent_inject marker is present, and re-patching is idempotent.)

The inputs that matter

  • model - your model, ideally after IC-Light has been applied (ICLightApply from ComfyUI-IC-Light-Native, in the shipped workflow).
  • latents - the latent the KSampler will denoise. In the pack's workflow this is the VAE-encoded product image.
  • inject_image_embed - the product's latent that gets noise-scaled and re-injected. Also a VAE-encoded version of the product.
  • inject_mask - the mask telling the sampler where to generate. The demo inverts the product mask before feeding this in, so generation happens around the product and the product region is what stays pinned.
  • start_sigma / end_sigma - the injection window. Defaults are 15.0 and 0.0; the shipped workflow uses 10 and 0.4. Lower end_sigma (toward 0) enforces product detail for more of the run; raising it lets the final steps relight and harmonize more aggressively.
  • remain_injected - optional, True/False.

Outputs: a patched MODEL (feed that into the KSampler) and a LATENT (the input latents with samples replaced by the injection embed and the noise mask set).

Install

The pack's usual path:

cd ComfyUI/custom_nodes
git clone https://github.com/MiddleKD/ComfyUI-productfix
pip install -r requirements.txt

Restart. The full workflow additionally wants the IC-Light SD1.5 fc model, a depth ControlNet, a detail LoRA, and companion packs (ComfyUI-IC-Light-Native, Impact Pack, essentials, controlnet_aux) - but the node itself only needs the two-pack dependency install above.

Common issues

  • Text still warps - the injection window is too narrow or the region isn't masked right. Check that inject_mask actually covers the product, and consider pairing with DetailTransferAdd + GetTextMask to transplant crisp text back afterwards.
  • Result looks pasted-on / disconnected - end_sigma too high means the final harmonizing steps never run. Nudge it down.
  • Other inpaint workflows behave oddly after this runs - only if remain_injected is True and you're worried: the patch is a no-op without the injection marker, so it's effectively invisible. Set remain_injected to False to restore eagerly anyway.

It's fiddly, it's sigma-dependent, and it's a genuinely niche technique from a tiny pack - but if you're compositing product shots against new backgrounds with IC-Light, it's the only tool doing this job. The author's demo images speak for themselves.

Categoryproductfix

Inputs (7)

NameTypeDefaultDescription
modelMODEL
latentsLATENT
inject_image_embedLATENT
inject_maskMASK
start_sigmaFLOAT15.00
end_sigmaFLOAT0.00
remain_injectedoptCOMBOtrue2 options: true, false

Outputs (2)

NameTypeDescription
MODELMODEL
LATENTLATENT