DPR KSampler Advanced
The Sampler That Swaps Your Watermarked Noise In
- model
- positive
- negative
- latent_image
- watermarked_latent_noise
- LATENT
What it actually does
Here's the thing that trips everyone up about Gaussian Shading watermarks: the watermark isn't in the image. It's in the noise. This node is a drop-in clone of ComfyUI's built-in KSamplerAdvanced with one extra input, watermarked_latent_noise, and one extra toggle, use_dprw_noise. Flip the toggle to enable and it starts sampling from your noise tensor instead of ComfyUI's random seed noise. That's the whole trick.
It looks identical to a normal generation because the "watermarked noise" is statistically indistinguishable from real Gaussian noise - the core promise of the Gaussian Shading paper (CVPR 2024) that this pack reimplements. Your output is supposed to be on par with a normal run, which is what makes it interesting versus older pixel-space watermarks.
How it works
Under the hood it's a thin wrapper over ComfyUI's own comfy.sample.sample. With use_dprw_noise on and a watermarked latent connected, it swaps the noise ComfyUI would normally synthesize from a seed for the tensor coming out of DPR_GS_Latent. Everything else is stock KSamplerAdvanced semantics: start_at_step / end_at_step for partial denoise, add_noise, return_with_leftover_noise.
The inputs that actually matter:
use_dprw_noise- the master switch.enablemeans "use my noise, not yours."watermarked_latent_noise- wire the LATENT output of DPR_GS_Latent in here. This is the noise your watermark is baked into.sampler_name,scheduler,steps- keep these deterministic. euler, dpmpp_2m and DDIM are all fine. Ancestral samplers (euler_ancestral, dpmpp_sde) inject fresh randomness mid-trajectory, which scrambles the watermark trace - extraction has to walk the exact same trajectory backwards.add_noise- the example workflows leave this atdisable. Withuse_dprw_noiseon, the watermarked noise already plays the role of the initial noise, so this toggle becomes mostly moot.
Output is a single LATENT that feeds straight into VAEDecode.
Where people get burned
noise_seedis decorative whileuse_dprw_noiseis on. The seed that actually controls the noise lives in DPR_GS_Latent. If your image changes between runs, that's the seed you're looking for, not this one.- Write down the sampler, scheduler and step count. Extraction via DPR_Extractor only works if the inversion uses the same settings - get them wrong and the recovered "watermark" is garbage.
- A shape mismatch between
watermarked_latent_noiseandlatent_imageproduces a confusing torch dimension error mid-graph. Keep DPR_GS_Latent's width, height and channels in lockstep with your EmptyLatentImage and model.
Install
This is one of three nodes in ComfyUI-GaussianShadingWatermark, an unofficial reimplementation of the Gaussian Shading paper by GitHub user lthero-big. One install gets you all three (this sampler, DPR_GS_Latent and DPR_Extractor):
cd ComfyUI/custom_nodes/
git clone https://github.com/lthero-big/ComfyUI-GaussianShadingWatermark.git
Restart ComfyUI after cloning, or use ComfyUI Manager and search "GaussianShadingWatermark". Dependencies are a handful of common scientific packages (scipy, cryptography, numpy, Pillow) that ComfyUI mostly ships with already - no model downloads, no API keys. It's a hobby-scale research pack, so treat it as "does the one trick, mostly works" rather than production-grade provenance tooling.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| use_dprw_noise | COMBO | 2 options: enable, disable | |
| add_noise | COMBO | 2 options: enable, disable | |
| noise_seed | INT | 420–18446744073709550000 | — |
| steps | INT | 201–10000 | — |
| cfg | FLOAT | 8.00–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 | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| latent_image | LATENT | — | |
| watermarked_latent_noise | LATENT | — | |
| start_at_step | INT | 00–10000 | — |
| end_at_step | INT | 100000–10000 | — |
| return_with_leftover_noise | COMBO | 2 options: disable, enable |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |