ꘇ top.convolve
Nine numbers, and every blur/sharpen/edge kernel you'll ever need
- image
- image
A 3×3 convolution is the most reusable primitive in image processing, and almost nothing in ComfyUI exposes it raw. top.convolve does: nine float boxes, k0 through k8, row-major, plus normalize/bias/mix. Blur, sharpen, emboss, edge detection, outline - all the same node with different numbers. If you understand what the nine boxes mean, you stop hunting for a dedicated node for each effect.
It lands squarely in the layer the KB calls the deterministic pixel ops: blur is blur, unsharp masking is literally blur-and-difference, and once you can write the kernel you can read any preprocessor's behaviour instead of guessing.
How it works
The kernel is laid out like the pixels it samples:
k0 k1 k2 top row
k3 k4 k5 middle row (k4 = centre pixel)
k6 k7 k8 bottom row
Each output pixel is the weighted sum of itself and its eight neighbours, per RGB channel, with boundary pixels clamped (edge sampling repeats the border instead of fading). normalize divides the result by the kernel sum - with one deliberate exception: if the kernel sums to zero, the division is skipped, because that's exactly the case for edge and laplacian kernels, where dividing by zero would be nonsense. bias adds a constant (useful for sinking a signed result back into range). mix blends the convolved result back toward the source, so 0 is a bypass and 1 is full effect. Alpha is preserved.
There's also a nice detail for cut-out images: where a neighbouring pixel is transparent, the kernel uses the centre pixel's colour in its place. That's the standard trick for stopping dark fringes appearing around the edge of an alpha'd subject.
Recipes to paste in:
box blur 1 1 1 / 1 1 1 / 1 1 1 + normalize
gaussian 1 2 1 / 2 4 2 / 1 2 1 + normalize
sharpen 0 -1 0 / -1 5 -1 / 0 -1 0 (normalize off - sum is 1)
laplacian 0 -1 0 / -1 4 -1 / 0 -1 0 + bias 0.5, mix ~1
outline 1 1 1 / 1 -8 1 / 1 1 1 + bias 1.0
The inputs that matter
Nine kernel values, then three switches. In practice you set the kernel and normalize, and only touch bias/mix when the result is clipping or too hot. Output is a single image - feed a sharpen result into top.composite over the original, or a laplacian into top.colormap if you want a false-colour read of the edges.
Install
Manager → search ꘇ Genereti → install, or from your ComfyUI directory:
git clone https://github.com/languel/genereti.git custom_nodes/genereti
./.venv/bin/python -m pip install -r custom_nodes/genereti/requirements.txt
Restart, refresh the browser. The pack's requirements are a single frontend-version pin; no model files, no extra services. You'll find the node as ꘇ top.convolve under Genereti / TOP - search genereti because the name starts with a glyph the node list sorts badly.
Traps
The output clamps to 0..1, so a laplacian kernel (which is signed) throws away everything below zero unless you raise bias. If your edge pass looks "half missing", that's why - top.edge handles this for you; raw convolution doesn't.
Kernel range is ±16, which is far more than you need and a great way to clip an image into a posterised mess. Keep to the recipes until you know why you're deviating.
Live vs Queue. Live mode runs the convolution on the browser GPU; Queue runs the PyTorch equivalent. Live intermediate textures are 8-bit and Queue is float, so a heavy kernel can look very slightly different between the two. Not a bug.
Prematurely fancy kernels. A 3×3 can't do a real Gaussian, only a crude one, and it can't do a bilateral. If you need edge-preserving smoothing, the KB's point stands: reach for a bilateral/guided filter, not a bigger convolution.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| k0 | FLOAT | 0.00-16–16 | — |
| k1 | FLOAT | 0.00-16–16 | — |
| k2 | FLOAT | 0.00-16–16 | — |
| k3 | FLOAT | 0.00-16–16 | — |
| k4 | FLOAT | 1.00-16–16 | — |
| k5 | FLOAT | 0.00-16–16 | — |
| k6 | FLOAT | 0.00-16–16 | — |
| k7 | FLOAT | 0.00-16–16 | — |
| k8 | FLOAT | 0.00-16–16 | — |
| normalize | BOOLEAN | false | — |
| bias | FLOAT | 0.00-1–1 | — |
| mix | FLOAT | 1.000–1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |