A camera lens, written by hand.
No 3D model, no Three.js. The barrel, the knurling, the nine iris blades and the coated glass are all maths in a single fragment shader, drawn fresh every frame.
Scroll the page and the iris opens, holds wide, then stops down again.
Move your mouse over it · scroll to drive the aperture
- Library
- None
- Weight
- ~6 KB gzipped
- Technique
- SDF raymarch
- API
- WebGL2
How it works
Every pixel fires a ray into the scene and steps along it until it hits a surface. The surfaces are signed distance functions: a hollow cylinder for the barrel, a nine-sided polygon cut out of a thin plate for the iris, two intersected spheres for the rear element. Knurling is a sine wave subtracted from the barrel's distance.
Each iris blade is its own slightly tilted facet with a groove at the seam. Without that, the iris reads as one flat disc and catches the light like a lens cap.
Keeping it fast
Rays are tested against a bounding sphere before marching, so the large empty part of the screen costs almost nothing. Resolution is capped, the frame rate is held at 36, and the loop stops completely in a hidden tab. On a GTX 1060 a frame takes about 3 ms at 3.2 megapixels.
When it can't run
If the browser would render WebGL on the CPU — hardware acceleration switched off — it doesn't try. You get the same lens as a pre-rendered image, gently drifting, made from this exact shader. Reduced-motion settings are respected; the chip in the corner switches motion on or off at any time.