Skip to content
blur

blur

Mojo module 🡭

blur

Gaussian blur, approximated by three successive box blurs, and draw_shadowed, the drop-shadow / glow composite built on it.

blur() modifies the entire pixel buffer and ignores the active clip and transform. draw_shadowed applies the destination’s clip and blend mode when compositing the shadow and source layer.

The three-box approximation

Three successive box blurs approximate a Gaussian.

The box widths are derived from the desired standard deviation sigma by P. Kovesi, “Fast Almost-Gaussian Filtering”, DICTA 2010: for n boxes,

w_ideal = sqrt(12 * sigma^2 / n + 1)
wl = w_ideal rounded down to the nearest odd number
wu = wl + 2
m  = round((12*sigma^2 - n*wl^2 - 4*n*wl - 3*n) / (-4*wl - 4))

and m boxes use width wl, with the remaining n - m using wu. Odd widths keep every box centered on its output pixel.

Following CSS blur(), sigma is half of radius.

Premultiplied alpha and edge handling

Blur operates on premultiplied color (channel * alpha / 255) so transparent pixels do not contribute hidden color.

Each 1-D box average clamps samples outside the buffer to its nearest edge pixel.

Box blurs commute, so the three horizontal sweeps run back to back and then the three vertical ones, rather than alternating. Away from the edges the result is the same as alternating; at an edge the clamp meets an intermediate rather than the original, a difference of at most a few levels within the outermost _shadow_pad pixels (draw_shadowed pads by that much, so its shadows are unaffected).

Each row band begins r0 + r1 + r2 rows above its output range so the vertical sliding windows are populated before its first output row.

Functions