Circular blur kernel optimizer

Disc kernels as sums of phased Gaussians (cos(c r²)·rw + sin(c r²)·iw)·e−b r² and, optionally, components with a repeated rate (multiplicity m up to 10) and extra r², r⁴, … terms. For rendering, the components are transformed together into separable channels, each a horizontal and a vertical complex 1-D pass, by a fixed linear map (reported with the kernel) chosen so that the passes stay about as small as the kernel and 16-bit intermediates suffice. Global search by differential evolution over decays and frequencies, with exact minimax weights solved by Remez exchange on CPU workers (or over all parameters on the GPU with jax-js-nonconsuming), then local Remez refinement or gradient fine-tuning; the blur demo is plain WebGPU shaders. After Olli Niemitalo: Circularly symmetric convolution and lens blur.

Blur demo WebGPU, using the current kernel

Shader code (WGSL)

The compute shader follows the intermediate storage and radius-interpolation settings. Its header describes the buffers, tap tables built from the separable channels under "Current kernel", and dispatch order.

Kernel optimizer fits the disc

Starting…

2-D kernel normalized to its peak: positive values in gray levels, negative values in red, on the same brightness scale.

Current kernel

How the kernel is formed

Each component is separable on its own, but optimized components often have large weights, and their imaginary parts cancel: the kernel is only the real part of the sum. Passes that large would lose the kernel in 16-bit intermediates. So the blur instead uses channels from a joint eigendecomposition of the real kernel, whose passes are no larger than the kernel needs, at the same channel count. Each image below is normalized to its own peak (shown below it), in the colors of the 2-D kernel above, over the support |x|, |y| ≤ 1 + transition.

Components

Each component's own separable form: one complex channel √a0 eλx² × √a0 eλy² for a single component (the article's), or m channels x2j eλx² × Qj(y²) eλy² for multiplicity m, summed into the component u, and the components into the kernel K. Rows are real terms h(x) v(y) as in Channels; their sizes show any cancellation between components. The blur doesn't compute these: this is the math view, showing that each component (the sum of its terms) is circularly symmetric.

Channels

The blur's separable passes, transformed from the components as a whole. Each row is a horizontal 1-D kernel h(x) times a vertical one v(y); pairs of these real terms are the complex channels Re[h(x) v(y)] = hrevre − himvim, summed into K as the shader accumulates them. The shader never forms the two terms of a channel separately: its horizontal pass filters with complex h, and its vertical pass multiplies by complex v and keeps the real part, which is their sum. A channel alone is not circularly symmetric; only K is. Compare the peaks with those of the components' own forms.