Skip to content
Sample of Bokeh Blur with Light Leaks

shader_legends_3 · TaterBokeh

Bokeh Blur with Light Leaks

A 2D bokeh effect built by stamping 50-200 soft Gaussian discs onto a near-black backdrop, each at a hash-determined centre, radius, and warm-to-cool colour. The discs are additively blended so overlapping regions glow with a light-leak intensity. Per-disc slow drift animates each circle in a slightly different direction, producing the look of out-of-focus Christmas lights or a lens-flare test chart.

Original: https://www.shadertoy.com/results?query=tater+bokeh

▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.

Family
shader_legends_3
Source
shader_legends_3
Evolution
particle
Render
additive_field
Complexity
medium
Agents
120
Year
2015
Author
Dave 'Tater' Hoskins (Shadertoy user 'Tater')

Math essence

For each circle c with centre (cx_c, cy_c), radius r_c, colour col_c and peak i_c: stamp(c) = col_c * i_c * exp(-((p - centre_c) / r_c)^2 * tightness). canvas = background + sum_c stamp(c). canvas := canvas / (1 + 0.6 * canvas) (Reinhard tonemap), then multiply by a soft radial vignette.

Parameters

Name Type Default Range Description
dim int 400 160–800 Square output size in pixels.
n_circles int 120 20–300 Number of bokeh circles.
base_radius float 0.1 0.03–0.3 Base Gaussian radius in canvas units.
radius_jitter float 0.6 0–1.5 Per-circle radius randomness (0 = all same size).
drift float 0.005 -0.05–0.05 Per-step drift of each circle's centre (animated on a torus).
warm_color rgb 1,0.55,0.2 null–null Warm end of the colour palette.
cool_color rgb 0.3,0.7,1 null–null Cool end of the colour palette.
accent_color rgb 0.95,0.9,0.7 null–null Accent colour for the upper-mid range.
background rgb 0.02,0.02,0.06 null–null Backdrop colour.
tightness float 2.5 0.5–8 Gaussian falloff exponent: higher = tighter, more ring-like.

Reference

First 60 lines of reference.py. Full source: library_external/shader_legends_3/TaterBokeh/reference.py

from __future__ import annotations

from typing import ClassVar

import numpy as np


def _hash11(x: np.ndarray, seed: int) -> np.ndarray:
    p = np.int64(x) * np.int64(374761393) + np.int64(seed) * np.int64(668265263)
    p = p & np.int64(0xFFFFFFFF)
    p = (p ^ (p >> np.int64(13))) * np.int64(1274126177)
    p = p & np.int64(0xFFFFFFFF)
    p = p ^ (p >> np.int64(16))
    return (p & np.int64(0xFFFFFFFF)).astype(np.float32) / np.float32(0xFFFFFFFF)


def _hash12(x: np.ndarray, y: np.ndarray, seed: int) -> np.ndarray:
    p = np.int64(x) * np.int64(374761393) + np.int64(y) * np.int64(668265263) + np.int64(seed)
    p = p & np.int64(0xFFFFFFFF)
    p = (p ^ (p >> np.int64(13))) * np.int64(1274126177)
    p = p & np.int64(0xFFFFFFFF)
    p = p ^ (p >> np.int64(16))
    return (p & np.int64(0xFFFFFFFF)).astype(np.float32) / np.float32(0xFFFFFFFF)


class TaterBokeh:
    """Bokeh blur with light leaks — Dave "Tater" Hoskins (Shadertoy).

    Tater (Dave Hoskins) wrote several *bokeh* shaders that draw
    50-200 soft Gaussian circles on a dark backdrop, where each
    circle's colour is drawn from a warm-to-cool palette and
    overlapping circles add their intensities (additive blending)
    to produce a *light leak* effect at the intersection.  The
    trick is that the circles are *not* all the same size: a
    per-circle hash picks both a centre, a radius, and a colour,
    and a slow per-circle drift animates each disc in a slightly
    different direction.

    The output looks like out-of-focus Christmas lights or a
    lens-flare test chart.

    Math essence:

        for each circle c:
            h = hash(c)
            centre_c = (h.x, h.y)
            r_c = base_radius * (0.4 + 0.9 * h.r)
            col_c = palette(h.hue)
            drift_c = (h.dx, h.dy) * speed
            for each pixel p:
                d = |p - centre_c(t)|
                intensity = exp(-(d/r_c)^2)
                canvas += col_c * intensity

    We render the additive accumulation efficiently by stamping
    each circle into its own per-circle buffer and summing them.
    """

    family: ClassVar[str] = "shader_legends_3"
    sketch: ClassVar[str] = "taterbokeh"

Try running it locally

The reference implementation is self-contained Python with numpy. Install the package and run:

python library_external/shader_legends_3/TaterBokeh/reference.py

Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.

More from shader_legends_3

Sample of Animated FBM Nebula with Chromatic Aberration

Animated FBM Nebula with Chromatic Aberration

shader_legends_3 · AshleyGAnimNebula

A multi-coloured, slowly rotating cosmic gas cloud built from 5 layers of FBM noise at different scales, each layer rotated by a different angle that varies with time.

View →
Sample of Atmospheric Perspective Landscape

Atmospheric Perspective Landscape

shader_legends_3 · HubertyAtmospheric

A painterly 2D landscape built from depth-graded FBM bands: a soft sky gradient with a sun disc and cloud streaks, a low-amp haze band in the upper-middle, rolling green midground hills, and a sharp foreground silhouette of trees and grass.

View →
Sample of Hash-driven Procedural City Skyline

Hash-driven Procedural City Skyline

shader_legends_3 · DaveHoskinsHashCity

A 2D orthographic night-time cityscape whose per-column building heights come from 1D FBM noise and whose lit windows are a per-cell hash threshold.

View →
Sample of Recursive Spherical Displacement Wireframe

Recursive Spherical Displacement Wireframe

shader_legends_3 · IQDisplacementSphere

A wireframe sphere whose surface is recursively displaced by spherical harmonics of the form amp * sin(N * theta) * cos(M * phi), rendered as overlapping latitude and meridian polylines plus random surface dots.

View →
Sample of Volumetric Clouds from Cellular + FBM

Volumetric Clouds from Cellular + FBM

shader_legends_3 · BigWingsClouds

A painterly cumulus-cloud sky built from a Worley/cellular noise layer (cloud puffs) gated by a low-frequency FBM (large-scale cloud coverage) and a high-frequency FBM (in-cloud detail).

View →

See all shader_legends_3 artworks →