Nodes/Difforum/Difforum · Symmetry
ComfyUI Node

Difforum · Symmetry

Mirrors and kaleidoscopes, and the version that compounds

By chillithebillis·Created 4 months ago·Updated 11 days ago· 10
Difforum · Symmetry
  • image
  • image
◄symmetrykaleidoscope►
◄segments6►
◄mix1.00►
◄flipfalse►
◄center_x0.50►
◄center_y0.50►
◄angle0►

Kaleidoscope video is one of the few effects the community never stopped asking for, and it's also one of the easiest ways to make generated footage look like something you meant. Difforum · Symmetry does it either as a finishing pass on a frame or a batch, or - and this is the version that matters - inside the feedback loop, where it compounds.

The modes

mirror_h and mirror_v reflect one half of the image over the other along a horizontal or vertical axis. mirror_quad does both, which gives you a four-fold pattern. kaleidoscope folds the image into radial wedges around a centre, and segments (2-64, default 6) is how many. mix decides how much of the symmetric result is used over the original, and that's your only real "strength" control - there's no half-mirror, you crossfade between the untouched image and the fully folded one.

The optional inputs are where the precision lives: flip mirrors the other way (for a mirror, which half survives; for a kaleidoscope, the handedness of the fold), center_x and center_y (0-1 across and down) move the fold centre off the middle, and angle rotates the whole symmetry axis in degrees.

Setting the centre off the middle is the difference between a decoration and a composition. A kaleidoscope centred on the subject's eye reads as deliberate; centred dead middle on a frame where nothing of interest is in the middle reads as a screensaver.

How it works

The mirror modes are index selection - one half of the tensor is sampled backwards into the other, so nothing is interpolated and the seam is exact. Kaleidoscope is a proper fold: each output pixel gets converted to polar coordinates around your centre, its angle is folded into a single wedge with a mirror, and the pixel is sampled from the source at the folded coordinate. Because that's a resampling operation, segments too low and pixels too small and you'll see softening where the sampling grid doesn't line up. That's a physical property of the transform, not a bug, and it's why 6 segments on a 1024-wide frame looks cleaner than 64.

In the loop, or after it

The standalone node is a finishing effect. What you see is what you get: the frame is folded, and the fold is done.

Feed symmetry through the Feedback Sampler instead (that's symmetry and symmetry_segments on Render Options) and something different happens. The folding is applied inside the loop, so each folded frame is then re-diffused, and the next frame folds the result. The diffusion heals the fold seams, and the geometry walks with the camera, and the pattern evolves instead of merely being decorated. The pack makes the distinction explicit in the node's own description, and it's the reason both exist: mandalas, installations and anything meant to run for hours want the in-loop version; a single symmetric image or a music-video insert wants this one.

Install

ComfyUI Manager → search Difforum, or:

cd ComfyUI/custom_nodes
git clone https://github.com/chillithebillis/Difforum.git difforum

Restart. It's pure tensor maths with no OpenCV, no model, no extra dependency beyond the numpy the pack already declares - so it works on any install and it's fast enough to leave in a workflow you're not sure about. It sits under Difforum/7 · Post, which is also where you'll find the other finishing nodes (Detail Guard, Flow Stabilize, Echo Trails) if you're building a post chain and want to know what's available.

Where people get burned

The obvious one first: 2 or 3 segments looks like a rendering error, not a design choice, because the fold is coarse enough that you recognise the source image twice. Six to twelve is the range where it reads as intent. If you want the classic mandala, go high - 16 to 32 on a square frame.

Then the one that costs real time. Applying this per frame to a moving clip makes the mirror axis static while the content moves through it, which looks fine for a static shot and distinctly odd the moment something crosses the centre - you get a wet kiss of a reflection that reads as a glitch. Either move the effect into the loop (Render Options symmetry) so the camera composes the pattern as it goes, or choose a shot where the action stays on one side of the axis.

And a small ordering note: this is a pixel effect, so it belongs after the render and before the upscale, not after. Upscale first and you're folding interpolated detail, which costs more and looks softer. The final image output wires on into Upscale or straight into your save node, and it keeps the batch dimension - hand it 120 frames and you get 120 symmetric frames back.

CategoryDifforum/7 · Post

Inputs (8)

NameTypeDefaultDescription
imageIMAGEAn image or a batch of frames.
symmetryCOMBOkaleidoscopeMirror or kaleidoscope the image.
segmentsINT62–64Kaleidoscope segments.
mixFLOAT1.000–1How much of the symmetric image is used.
flipoptBOOLEANfalseMirror the other way.
center_xoptFLOAT0.500–1Symmetry centre, 0-1 across.
center_yoptFLOAT0.500–1Symmetry centre, 0-1 down.
angleoptFLOAT0-360–360Rotation of the symmetry axes, degrees.

Outputs (1)

NameTypeDescription
imageIMAGE—