Skip to content

GaussBlur

dnjulek edited this page Jul 9, 2026 · 2 revisions

Separable Gaussian blur.

Blurs each processed plane with a normalized Gaussian kernel, computed as two separable (vertical then horizontal) passes. Two internal paths are chosen automatically by radius: a fused shared-memory kernel for small sigma and two global-memory passes for large sigma (so it stays fast at any sigma).

Usage

vszipcl.GaussBlur(vnode clip[, float[] sigma=0.5, int device_id=0, int num_streams=1, int[] tune])

Parameters

  • clip:
    Clip to process. 8/16-bit integer, 16-bit half, or 32-bit float; Gray / YUV / RGB.

  • sigma: (Default: 0.5)
    Standard deviation of the Gaussian, resolved per plane:

    • plane 0 default 0.5;
    • plane 1 (chroma) default = sigma[0] / sqrt((1<<subW)*(1<<subH)) (accounts for chroma sub-sampling);
    • plane 2 default = plane 1's value.

    Pass an array to set each plane independently. A plane whose sigma is ~0 (< FLT_EPSILON) is copied through untouched; all planes unprocessed is an error.

  • device_id / num_streams: see Home.

  • tune: (Default: unset)
    Launch-geometry override — [blk_x, blk_y, vrt, large_r, threshold] (work-group shape + per-thread outputs + the small→large radius crossover). The ship defaults are the measured Ampere values used on every vendor, so you can retune at runtime — especially on AMD / Apple — instead of rebuilding. ⚠ threshold moves a path boundary (re-check hash); the rest is byte-identical untuned. See Tune for the full table, ranges, and vendor starting points.

Examples

out = core.vszipcl.GaussBlur(src)                     # sigma 0.5, all planes
out = core.vszipcl.GaussBlur(src, sigma=2)            # stronger
out = core.vszipcl.GaussBlur(src, sigma=[2, 0, 0])    # luma only (chroma copied)
out = core.vszipcl.GaussBlur(src, sigma=[3, 1.5, 1.5])
out = core.vszipcl.GaussBlur(src, sigma=80)           # large-sigma path

Notes

  • The blur pipeline (tile, intermediate buffer, weight table) is always f32 regardless of the input format.

Benchmark

1080p YUV420, fps (higher is better), RTX 3070 Ti — see Benchmarks for method. No comparable GPU Gaussian is installed (tcanny absent; placebo/vszip have none), so these are vszipcl-only figures across three sigmas — sigma=1 is the fused small-radius smem kernel, sigma=100/250 take the large separable path.

Implementation u16 f16 f32
σ=1 (s=1) 522.2 544.2 320.9
σ=1 (s=2) 501.8 503.6 326.7
σ=100 (s=1) 266.1 264.1 203.8
σ=100 (s=2) 268.2 273.4 213.5
σ=250 (s=1) 148.1 153.0 128.7
σ=250 (s=2) 153.4 156.3 133.8

Throughput falls with radius. num_streams=2 is neutral for the saturated small-σ kernel and gives only a few percent on the large separable path.

Clone this wiki locally