hodgin_iquilezles · SmoothMinSDF
Smooth-Minimum SDF field
Two animated 2D SDF primitives (a moving circle and a translating slab) are blended with Quilez's quadratic-polynomial smooth-minimum and rendered as a scalar field. The mix factor (the blend weight returned by Quilez's vec2 smin) tints the field with the colour of the dominant primitive; iso-contours are drawn as thin highlight bands. The result is a slow, organic metaball-blob visual that breathes.
Original: https://iquilezles.org/articles/smin/
▶ 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.
Math essence
smin_quadratic(a, b, k) = min(a, b) - h*h*k/4 with h = max(k - |a-b|, 0)/k. The blend weight m = h*h*0.5 linearly interpolates the two primitives' materials. Field shading uses 0.5 - smin/k to highlight the zero-isosurface, with iso-contours drawn at fixed step intervals to evoke Quilez's SDF debug visualisations.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 360 | 120–800 | Square output size in pixels. |
radius_a | float | 60 | 10–140 | Radius of the moving circle SDF. |
radius_b | float | 50 | 8–140 | Half-width of the moving slab SDF. |
k | float | 35 | 1–120 | Smooth-minimum blend thickness (px). |
slab_halfwidth | float | 24 | 4–80 | Half-thickness of the slab SDF. |
color_a | tuple | 1,0.42,0.32 | null–null | RGB colour of primitive A (warm). |
color_b | tuple | 0.3,0.62,1 | null–null | RGB colour of primitive B (cool). |
background | tuple | 0.04,0.04,0.08 | null–null | Background RGB colour (used outside the field). |
contour_step | float | 4 | 1–16 | Iso-contour step size (in field units). |
Reference
First 60 lines of reference.py. Full source:
library_external/hodgin_iquilezles/SmoothMinSDF/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
def _smin_quadratic(a: np.ndarray, b: np.ndarray, k: float) -> np.ndarray:
kk = k * 4.0
h = np.maximum(kk - np.abs(a - b), 0.0) / kk
return np.minimum(a, b) - h * h * kk * 0.25
class SmoothMinSDF:
"""Smooth-Minimum SDF field — Inigo Quilez (iquilezles.org).
The "smooth-minimum" or "smooth-union" operator combines two signed
distance fields into a single field whose iso-zero surface melts and
blends the two primitives together (Quilez's *smin* article,
https://iquilezles.org/articles/smin/).
We render the *scalar field itself*: two animated 2D SDF metaballs —
a circle and a horizontal slab — blended with the popular
*quadratic-polynomial* smooth-minimum
smin(a, b, k) = min(a, b) - h*h*k/4, h = max(k-|a-b|, 0)/k.
Pixels are shaded by the field value using the "mix factor" trick
(the original Quilez vec2 smin that also returns the blend weight)
so the two primitives are coloured in their own hues across the
smooth transition.
"""
family: ClassVar[str] = "hodgin_iquilezles"
sketch: ClassVar[str] = "smoothminsdf"
def __init__(
self,
dim: int = 360,
radius_a: float = 60.0,
radius_b: float = 50.0,
k: float = 35.0,
slab_halfwidth: float = 24.0,
color_a: tuple[float, float, float] = (1.00, 0.42, 0.32),
color_b: tuple[float, float, float] = (0.30, 0.62, 1.00),
background: tuple[float, float, float] = (0.04, 0.04, 0.08),
contour_step: float = 4.0,
**_,
) -> None:
self.dim = dim
self.radius_a = float(radius_a)
self.radius_b = float(radius_b)
self.k = float(k)
self.slab_halfwidth = float(slab_halfwidth)
self.color_a = np.array(color_a, dtype=np.float32)
self.color_b = np.array(color_b, dtype=np.float32)
self.bg_color = np.array(background, dtype=np.float32)
self.contour_step = float(contour_step)
self.reset()
Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/hodgin_iquilezles/SmoothMinSDF/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from hodgin × iquilezles
Boids Flock (Hodgin Murmuration)
hodgin_iquilezles · BoidsFlock
A 2D flock of boids steered by Craig Reynolds' three classic rules (separation, alignment, cohesion) over a coarse spatial-hash neighbor query.
Fractional Brownian Motion noise
hodgin_iquilezles · FBMNoise
Quilez's canonical fBM: a 2D value-noise base summed over N octaves whose frequency doubles and amplitude is multiplied by G = exp2(-H) per octave.
Magneto Particles (Hodgin Magnetosphere)
hodgin_iquilezles · MagnetoParticles
Particles pulled and pushed by N orbiting magnetic anchors whose charges flip sign over time.
Mulberry32 PRNG (stratified scatter)
hodgin_iquilezles · Mulberry32RNG
Mulberry32 is a tiny 32-bit-state pseudo-random number generator popularised in the demoscene and used pervasively by Quilez and other graphics programmers as the RNG inside procedural sketches.
Saturn Rings (orbital resonance)
hodgin_iquilezles · SaturnRings
Thousands of particles are initialized in an annulus between inner_radius and outer_radius around a central mass, with circular orbital velocities v = sqrt(M/r).
Worley / Cellular Noise
hodgin_iquilezles · WorleyNoise
Quilez's classic 2D Worley noise: a unit grid of cells, each containing one pseudo-random feature point placed by a 2D integer hash.