Depth-of-field blur with focal target

A depth-of-field blur effect where the focal plane is driven by a live world-space position. The scene is rendered into a p5.Framebuffer, then a p5.strands DOF pass is applied via pipe(). The magenta sphere is the focal target — its screen-space z is recomputed every frame with mapLocation() and fed directly into the shader, so the blur follows the sphere continuously. A first-person directional light tracks the viewer using mapDirection(). The shader as a strands callback The DOF pass is authored as a p5.strands callback on baseFilterShader().modify(). There is no raw GLSL string — the algorithm is expressed in JavaScript using the strands DSL, which compiles it to WebGL2 under the hood. ...

April 9, 2026 · 3 min · Theme PaperMod

Post-effects pipeline

Multi-pass post-processing with p5.strands and pipe(). Three filter passes — depth-of-field blur, value-noise warp, and pixelation — are chained over a scene framebuffer. Each pass is a baseFilterShader().modify() callback; createPanel wires their uniforms automatically. Press 1, 2, or 3 to rotate the pass ordering at runtime. Shader passes as strands callbacks Each post-processing pass is a baseFilterShader().modify() callback — a plain JavaScript function using the p5.strands DSL. The framework compiles each callback to WebGL2 at startup; no raw GLSL strings are needed. ...

April 9, 2026 · 2 min · Theme PaperMod

Toon shading

Toon shading, or cel shading, gives 3D geometry a flat, cartoon-like look by quantizing diffuse reflection into a finite number of discrete shades. In this p5.js v2 version the shader is written as a baseMaterialShader().modify() hook using the p5.strands DSL — no raw GLSL strings, no hand-written vertex shader. createPanel wires the color and shades controls to the shader automatically each frame. Toon shader The combineColors hook in baseMaterialShader().modify() receives the eye-space vNormal varying directly — no vertex shader boilerplate required. Diffuse intensity is the dot product of the surface normal and the (normalized) light direction; it is then snapped into discrete bands to produce the cel-shading look. ...

April 9, 2026 · 3 min · Theme PaperMod

3D Brush Painting in VR

A 3D brush painting sketch that uses depth control for VR-style experiences. mapLocation() converts screen-space mouse coordinates and a depth slider value directly into world-space positions, so each brush stroke is placed precisely in 3D. Press r to toggle recording, c to clear, f to re-focus the camera on the world origin. Screen-to-world mapping with mapLocation The core of the brush is a single mapLocation call that lifts the 2D mouse position — together with a depth value from the slider — into 3D world space each frame: ...

April 9, 2026 · 2 min · Theme PaperMod

p5.tree.js

p5.tree is a render pipeline layer for p5.js v2 — pose and camera interpolation, coordinate-space conversions between WORLD / EYE / SCREEN / NDC, frustum visibility, HUD, multi-pass post-processing, picking, and declarative control panels. The demo below exercises all of it at once. Under the hood it’s three independent packages: a renderer-agnostic numeric core (@nakednous/tree — math, spaces, keyframes, visibility), a lightweight DOM layer (@nakednous/ui — sliders, transport), and a p5.js v2 bridge that wires them to the canvas. The dependency direction is strict and one-way — the core knows nothing about p5 or the DOM — which is what lets the same keyframe interpolation that drives a camera path also animate any object, and lets the whole stack run headless or in a future renderer without touching the math. ...

February 17, 2026 · 7 min · Theme PaperMod