art_blocks · HobbsWatercolorBlob
Hobbs Watercolor Blob
Layered translucent Gaussian blobs with watercolor-style alpha falloff. Inspired by Tyler Hobbs’ exploration of pigment-density accumulation in his Watercolor series.
Original: https://tylerhobbs.com
▶ 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
A small set of large, overlapping radial splats are drawn with translucent pigments. Each splat has a position, a soft Gaussian falloff, and a sampled color from a curated palette.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 256 | 64–1024 | Canvas side length. |
n_splats | int | 200 | 10–5000 | Number of watercolor blobs to deposit. |
splat_radius | float | 60 | 5–200 | Soft radius of each blob (gaussian sigma). |
splat_jitter | float | 0.4 | 0–1 | Position jitter for blob centers (proportional). |
palette_size | int | 6 | 2–16 | Number of colors in the palette. |
seed | int | 7 | 0–2147483647 | PRNG seed. |
Reference
First 60 lines of reference.py. Full source:
library_external/art_blocks/HobbsWatercolorBlob/reference.py
"""HobbsWatercolorBlob — Tyler Hobbs' layered watercolor "blobs".
A second implementation of Tyler Hobbs' 2017 watercolor recipe,
distinct from HobbsWatercolorEdge (which produces watercolor ink
edges via Sobel detection). HobbsWatercolorBlob instead produces
**filled watercolor blobs** by stacking many translucent,
noise-deformed filled polygons — the technique Hobbs used in his
*Isohedral* series (2017) and the core of his watercolor aesthetic.
Hobbs's recipe (2017 essay):
"The technique to simulate watercolor in generative art consists of
stacking lots of nearly transparent layers on top of each other. ...
The core of the watercolor technique is a recursive polygon
deformation algorithm. ... Depending on the variation in your
Gaussian distribution and the recursion depth, this will produce a
polygon with jagged, detailed edges."
For each blob:
1. Choose an N-gon centred on a random canvas position.
2. Run ~7 rounds of recursive polygon deformation (midpoint
Gaussian jitter with sigma proportional to segment length).
3. Rasterise the deformed polygon to a mask.
4. Stamp the mask at low alpha (~4%) with a per-layer tint.
5. Repeat for `num_layers` layers, optionally interleaving
different colours to produce blended watercolor regions.
The implementation here uses ~30–100 layers (Hobbs' range) at
4% alpha each, producing the soft pigment-on-paper look of his
*Isohedral XI* and *Linear II* works.
Reference:
- https://www.tylerxhobbs.com/words/a-guide-to-simulating-watercolor-paint-with-generative-art
"""
from __future__ import annotations
from typing import ClassVar
import numpy as np
def _deform_polygon(
pts: np.ndarray, depth: int, sigma_frac: float, rng: np.random.Generator
) -> np.ndarray:
"""Hobbs' recursive polygon deformation: midpoint Gaussian jitter,
repeated `depth` times. Output has N * 2^depth vertices.
"""
out = pts.astype(np.float64).copy()
for _ in range(int(depth)):
n = out.shape[0]
mids = np.empty((n, 2), dtype=np.float64)
for i in range(n):
x0, y0 = out[i]
x1, y1 = out[(i + 1) % n]
mx, my = 0.5 * (x0 + x1), 0.5 * (y0 + y1)
seg_len = np.hypot(x1 - x0, y1 - y0)
sigma = sigma_frac * seg_len
mids[i, 0] = mx + rng.normal(0, sigma)
mids[i, 1] = my + rng.normal(0, sigma)
new = np.empty((2 * n, 2), dtype=np.float64) Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/art_blocks/HobbsWatercolorBlob/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from art blocks
Cherniak Ringers (Dmitri Cherniak — Ringers)
art_blocks · CherniakRingers
An implementation of Dmitri Cherniak's *Ringers* algorithm (Art Blocks Curated, January 2021, 1,000 NFTs) — one of the most-cited generative-art projects of the NFT era, and the source of *Ringers #879* ('The Goose') and *Ringers #962* (acquired by LACMA).
Chromie Squiggle (Snowfro / Cherniak — Squiggles)
art_blocks · CherniakSquiggles
An implementation of the squiggle-generation kernel used in Snowfro's *Chromie Squiggle* (Art Blocks #0, November 2020) — the on-chain generative-art project that launched the Art Blocks platform itself and was the work Dmitri Cherniak cited (alongside *Genesis*) as his inspiration for Ringers.
Genesis (DCA — Day-Zero Art Blocks)
art_blocks · DcaGenesis
An interpretation of DCA's *Genesis* (Art Blocks #1, November 2020) — one of three Day-Zero collections (alongside Snowfro's Chromie Squiggle and Jeff Davis's Construction Token) that minted in the first 24 hours of the Art Blocks platform.
Hobbs Flow Field (Tyler Hobbs — Incomplete Control / Fidenza)
art_blocks · HobbsFlowField
The canonical perlin-noise flow-field algorithm described by Tyler Hobbs in his 2020 essay 'Flow Fields', and the algorithmic backbone of his Art Blocks Curated works *Incomplete Control* (Bright Moments, 2021) and *Fidenza* (Art Blocks, 2021).
Hobbs Watercolor Edge (Tyler Hobbs — Soft Textures / Watercolor)
art_blocks · HobbsWatercolorEdge
An implementation of Tyler Hobbs' 2017 'watercolor' technique: a recursive polygon-deformation algorithm whose midpoints are jittered by Gaussian noise across many passes, then stacked with low alpha (4% per layer, 30–100 layers total) to produce the soft, ink-bleed look of wet pigment on paper.
Penne 80s Vector (Aaron Penne — outrun perspective wireframe)
art_blocks · Penne80sVector
The 80s-synthwave outrun grid, the visual aesthetic Aaron Penne references in his generative-art practice (notably in *Apparitions* and his broader body of work).