HomeJournalThis post

Blue-Noise Stippling on Canvas

Separate tone from spacing, sample candidates deterministically, vary radius without clumps, preserve image provenance, and export reproducible stipple editions.

JP
JP Casabianca
AI Engineer and Product Designer · full-stack delivery · Bogotá

Blue-noise stippling creates tonal fields from marks that feel irregular without collapsing into random clumps or marching along a visible grid. This tutorial separates spacing from tone, uses deterministic sampling, and archives enough parameters to reproduce an authored Canvas edition.

Blue-noise stippling separates density from disorder

A stipple field needs two decisions: where marks are allowed and how closely they may approach. Tone controls the expected density or local radius; a blue-noise distribution controls spatial regularity so the marks avoid both hard lattice lines and accidental clusters. Blue-noise stippling is not one magic random function. It is an authored relationship between image luminance, distance constraints, dot geometry, and output scale.

Begin with a clean grayscale source whose use rights and crop are recorded. Decide whether dark pixels receive more dots, larger dots, or both. Mixing those encodings without a rule can crush shadows. Compare the Canvas dithering approach when a fixed pixel grid is part of the desired texture.

Synthetic edition fixture (not a completed artwork): use a 512×512 portrait-shaped crop and encode darkness only through local spacing, with every mark a 1.25-pixel circle. The constructed expected output accepts 1,832 points. Those constraints make density carry tone while mark shape remains constant; an actual source image must supply its own licensed provenance and measured result.

blue-noise stippling operating modelTone means Sample; Radius means Map; Points means Reject; Marks means Curate.ToneSampleRadiusMapPointsRejectMarksCurate
  • Tone: Sample
  • Radius: Map
  • Points: Reject
  • Marks: Curate
Figure 1: blue-noise stippling connects Tone → Radius → Points → Marks as one inspectable argument.

Prepare a linear-light tonal field

Decode the source, apply orientation, crop to the target aspect ratio, and sample pixels at a bounded analysis resolution. Convert color to relative luminance in a declared color space; ordinary encoded RGB averages can misrepresent perceived tone. Preserve alpha by compositing against the intended paper color before measuring darkness. Save that paper value with every deterministic edition receipt.

The MDN Canvas pixel-manipulation guide documents image-data access and security restrictions. Canvas tonal sampling requires a same-origin or CORS-approved source to avoid a tainted canvas. Blue-noise stippling should fail with a clear message rather than silently exporting an empty or security-blocked edition.

Synthetic tone fixture (not sampled photograph data): composite constructed pixels onto warm white #f5f0e6, convert to linear sRGB, and reduce them to luminance with declared coefficients. Apply a three-pixel Gaussian blur as an example parameter. The analysis buffer and Canvas should share one normalized transform, with a generated checkerboard fixture verifying coordinate mapping rather than claiming that portrait detail was empirically preserved.

Sample candidates with a seeded generator

Use a small explicit pseudorandom generator whose seed is stored in the edition receipt. Math.random cannot reproduce a composition across sessions. Candidate generation, active-list choice, and angle selection must all consume the same documented stream in a stable order. A code refactor that changes random-call order creates a new edition even with the same visible seed.

The seeded generative randomness guide develops that provenance contract. Deterministic stipple art also stores algorithm version, analysis dimensions, and source hash. Blue-noise stippling becomes reproducible when another renderer can regenerate coordinates, not merely approximate the mood of a screenshot.

Synthetic generator fixture (not measured artwork data): seed 0x1d29c4a7 begins with accepted coordinates (0.514, 0.482), (0.503, 0.465), and (0.532, 0.469). The expected deterministic output keeps coordinate hash 7e3a…91bf across three fixture invocations. Changing the candidate budget from 24 to 30 intentionally defines a different expected edition even though the seed remains fixed; both example manifests retain their algorithm versions.

Use a grid accelerator without showing a grid

Bridson's algorithm maintains an active list and proposes candidates in an annulus around accepted samples. A background acceleration grid stores nearby points so each candidate checks a small neighborhood rather than the entire set. The Bridson Poisson disk paper explains the efficient method and its parameters.

The grid is an index, not the composition. Cell size follows the minimum distance, while accepted coordinates remain continuous. Poisson disk stippling rejects candidates closer than the local rule and eventually removes exhausted active points. Blue-noise stippling needs bounds on attempts, point count, and runtime so a dark high-resolution source cannot freeze the browser.

With a four-pixel absolute minimum, the accelerator cell is 2.828 pixels and each proposal inspects at most the neighboring cells that can contain a violating point. The run stops at 2,200 accepted marks or 180 milliseconds, whichever comes first. A timeout preserves the partial coordinates and labels the edition incomplete rather than looping invisibly.

FieldClumpsGridBlue noise
RandomHighNoneNo
JitterLowVisiblePartial
PoissonBoundedHiddenYes
Figure 2: The blue-noise stippling decision matrix compares Random, Jitter, Poisson without hiding the operating trade-off.

Map tone to distance with bounded contrast

Define minimum distance as a curve of darkness: shadows receive a smaller radius and highlights a larger one, with absolute lower and upper bounds tied to export size. A smoothstep or gamma-shaped curve gives more control than a linear mapping. Sample the radius consistently at candidate or pair locations and document the choice; variable-radius Poisson rules can become asymmetric otherwise.

Reserve white space intentionally. Clamp near-white pixels to no marks and cap shadow density so individual dots survive. Evenly irregular dots create tone through accumulation, but black regions should not become a solid fill unless that is an authored exception. Blue-noise stippling benefits from a small curve editor with histogram and accepted-point preview.

The edition maps darkness d to radius 11.5 − 7.5·smoothstep(d), then clamps the result to 4–11.5 pixels. Samples lighter than 0.96 receive no proposal. A symmetric pair test uses the larger of the two local radii, preventing a dark-region candidate from crowding a highlight point whose own sampled radius is wider.

Run the bounded teaching fixture before adapting the pattern to production.

Runnable artifact — blue-noise-sampler.test.mjs

import assert from "node:assert/strict";let state=29;const rnd=()=>((state=Math.imul(state,1664525)+1013904223>>>0)/2**32);const points=[];for(let n=0;n<500&&points.length<24;n++){const p=[rnd(),rnd()];if(points.every(q=>Math.hypot(p[0]-q[0],p[1]-q[1])>=.14))points.push(p)}for(let i=0;i<points.length;i++)for(let j=i+1;j<points.length;j++)assert.ok(Math.hypot(points[i][0]-points[j][0],points[i][1]-points[j][1])>=.14);assert.ok(points.length>12);console.log("PASS: deterministic points respect minimum distance");

Run node blue-noise-sampler.test.mjs. Expected receipt: PASS: deterministic points respect minimum distance.

Choose mark shape as material language

Circles are easy to measure, but short dashes, tapered ellipses, or pressure-like specks can introduce direction and print character. Drive orientation from a separate field such as image gradient or a gentle authored flow, never from unbounded random rotation if the thesis depends on form. Keep size and elongation within legibility limits at final output.

Compare Voronoi stippling density when iterative centroid relaxation and cell mass are the artistic method. Blue-noise stippling is faster and preserves irregular spacing, while centroidal methods can distribute points differently. Name the technique accurately so the visual claim does not borrow mathematics the implementation never uses.

Synthetic art-direction comparison (not a recorded user test): compare circles, 2:1 ellipses aligned to image gradient, and short round-ended dashes. In the teaching fixture, ellipses are designated as sharpening hair direction while making skin look engraved; circles are designated as keeping facial tone quieter. Recording that hypothetical rejection in an edition manifest demonstrates why swapping mark language is an artistic revision, not a harmless renderer optimization.

Draw diagnostics before the final image

Provide overlays for local exclusion radii, acceleration cells, rejected candidates, density histogram, minimum-distance violations, and source-tone difference. A nearest-neighbor distance plot can reveal grid bands or clusters that look subtle in the finished portrait. Compare three panels with identical point count: uniform random, jittered grid, and the accepted field.

The Canvas 2D context standard is the platform reference for the drawing surface. Blue-noise stippling diagnostics should use the same coordinate transform and device-pixel treatment as final rendering. A preview that samples one resolution and exports another can conceal collisions or sparse holes.

Synthetic diagnostic fixture (not empirical output): the expected field report uses a 4.02-pixel minimum nearest-neighbor distance, 6.84-pixel median, and zero rule violations after export scaling. Its illustrative mean absolute tone error is 0.071 across 32×32 bins, with a 0.19 worst-bin value assigned to a dark jacket edge. A constructed random baseline contains 47 sub-four-pixel collisions at the same point count; the runnable artifact can be used to generate real diagnostics for an actual source.

  1. 1Tone

    Build linear-light field

  2. 2Propose

    Seed annulus candidates

  3. 3Reject

    Enforce local distance

  4. 4Edition

    Archive points and marks

Figure 3: The blue-noise stippling proof runs Tone → Propose → Reject → Edition before it can claim a result.

Export coordinates, not only pixels

Save the accepted points with normalized x, y, radius, angle, tone sample, and stable index. Raster PNG or AVIF can serve the web, while the coordinate list supports SVG, plotter, or higher-resolution re-rendering without rerunning sampling. Include the source hash, license note, seed, algorithm version, tone curve, palette, dimensions, and point count.

The WebGPU vs Canvas comparison is relevant if point count exceeds the comfortable Canvas range, but choose a renderer after preserving the edition contract. Blue-noise stippling coordinates should yield the same composition even when a faster backend changes how marks are rasterized.

Synthetic export budget (not generated file evidence): assign 138 KB uncompressed, 31 KB Brotli, and 38 KB AVIF as teaching thresholds. The expected SVG draws 1,832 fixture circles from normalized coordinates and includes a coordinate hash. An actual generator run must establish file sizes, point counts, nearest-neighbor bounds, and plotter compatibility before those become evidence.

Curate a reproducible stipple edition

Render thumbnail, article, social, print-preview, light, dark, and high-contrast contexts. Inspect the subject at viewing distance and the mark field at zoom. Record runtime, memory, points, nearest-neighbor distribution, tone error, source crop, and any manual masks. Invite critique of composition rather than presenting low numeric error as artistic success.

Revisit blue-noise stippling when the source, tone curve, sampling algorithm, renderer, or output medium changes. The piece is successful when its tonal structure reads from afar, its evenly irregular marks remain alive up close, and every deliberate parameter can be recovered without pretending the algorithm made the artistic decisions alone.

Synthetic critique scenario (not participant research): imagine five review notes, three identifying the silhouette and eye line and two flagging a jacket as too dense. The fixture's documented art-direction decision retains density to protect the shoulder contour while softening the crop mask. This hypothetical choice sits beside numerical diagnostics to show how measurement can inform composition without pretending to settle it.