Jurdns Frequency Split
Split a latent into low, mid, and high frequency — the detail knob nobody gives you
- latent
- low_freq
- mid_freq
- high_freq
Frequency separation is one of the most useful tricks in the whole image pipeline. Photographers have done it in Photoshop for decades: blur a copy, subtract it, and you've split a picture into "shape and lighting" (low frequency) and "texture and detail" (high frequency). In ComfyUI it's the backbone of IC-Light relight workflows - keep the high-frequency detail from the original, take the new lighting from the relight, sew the two together. Jurdns Frequency Split is the same idea, except it does the splitting inside the latent, before the VAE ever touches pixels.
That's the thing that makes this node interesting and a little spicy at once. Frequency separation is normally a pixel-space operation - you can see the bands, they're predictable. Here you're splitting a compressed latent that's roughly 8x smaller per side than the image, with 4 channels on SD/SDXL or 16 on Flux. So "frequency" in the latent is not the same as frequency in the picture; the boundaries you set map to features that are coarser than you'd guess. Keep that in the back of your head - it's the first thing that'll bite you.
How it works
The math is straightforward and the whole pack is one file, so there's no black box. The node takes your latent, runs torch.fft.fftn over its two spatial dimensions, and gets the frequency spectrum. It then builds three radial masks over that grid - low frequencies live at the center of the grid, high frequencies at the edges - applies each mask to the spectrum, and transforms each band back with an inverse FFT, keeping only the real part. Three latents out: low_freq, mid_freq, high_freq.
The band edges are soft, not hard cuts. The overlap input controls exactly that softness: it's the width of the sigmoid transition between bands. A tiny overlap gives you a nearly surgical cut; a bigger one gives you feathered, natural-feeling boundaries. This is deliberate - the author picked sigmoids so you don't get ringing artifacts from hard frequency clipping, the kind of thing that shows up as wobbly halos around edges.
The inputs that matter
Four inputs, and you'll tune three of them:
latent- whatever latent you want carved up. From aVAE Encodefor img2img, or from anEmpty Latentbefore your first sampling pass.low_freq_end(default 0.15) - how much of the radius from the grid center counts as "low". Lower = low band only holds the very coarsest structure.mid_freq_end(default 0.4) - where mid ends and high begins. Between these two numbers is your mid band.overlap(default 0.1) - the feather width between bands, as discussed above.
Outputs are three LATENTs named low_freq, mid_freq, high_freq. They feed either the pack's own Jurdns Frequency Combine, or - and this is a legitimately fun trick - straight into a KSampler. Sampling from just the high band gives you a texture-only image; sampling from just the low gives you a color-and-shape blob. Neither is usually a finished picture, but seeing each band on its own is the fastest way to build intuition for what your low_freq_end and mid_freq_end actually do.
Installing it
The good news: this pack has zero dependencies beyond what ComfyUI already ships. There's no requirements.txt, no model files, nothing to download - just torch, which you already have.
ComfyUI Manager: Install Custom Nodes → search "Jurdns" → Jurdns-Frequency-Split-Nodes, then restart. Or do it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/jurdnf/Jurdns-Frequency-Split-Nodes
# restart ComfyUI
That's the entire install. It's Apache-2.0 licensed and a single 150-line file, so it's easy to read if you ever want to know exactly what it's doing.
Common issues
- Latent frequency is not pixel frequency. Your high band in a 4-channel latent does not equal "sharp edges in the final image." Because the VAE compresses everything, what counts as high frequency is model- and VAE-dependent. Expect to experiment with the two
_endvalues when you switch checkpoints. - The round trip isn't lossless. The three masks don't sum to exactly 1 at the band boundaries, so a split followed by a
frequency_domaincombine loses a little energy at the seams. It's close - fine for creative work - but don't treat it as a perfect identity operation. - It's a niche node. No real community discussion, zero impressions, one author. If you hit weirdness, you'll be debugging against the source yourself - which, again, is one small file, so that's survivable.
If you want to separate frequency in pixels instead, the IC-Light frequency-separation workflows are more battle-tested. This node is for when you specifically want to manipulate the latent before sampling. Different tool, different job.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| latent | LATENT | — | |
| low_freq_end | FLOAT | 0.150.05–0.5 | — |
| mid_freq_end | FLOAT | 0.400.1–0.8 | — |
| overlap | FLOAT | 0.100–0.3 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| low_freq | LATENT | — |
| mid_freq | LATENT | — |
| high_freq | LATENT | — |