Week 1. Two fragment shaders that run on any DOM element.
The element is rasterized to a texture with SVG foreignObject, then a fullscreen
triangle does the rest. Fire gets the word FRAG; drip gets an orb.
Thursday shader series · Week 1
Fire & Drip
Two fragment shaders that run on any DOM element
🔥 Fire fragment shader
Layered noise scrolls upward through a black → red → orange → pale-yellow ramp.
Flame columns rise from the letters themselves, the type ignites from the base up, and embers drift skyward.
Source element (plain DOM)
→
fire.frag · live WebGL
💧 Drip fragment shader
Slow and viscous. The orb sags under its own weight, thick strands swell and recede,
and glossy droplets form necks, detach, and fall — tinted with the orb’s own color.
Source element (plain DOM)
→
drip.frag · live WebGL
How it works
Rasterize. The source element’s HTML (inline styles only, so it survives
serialization) goes into an SVG foreignObject, drawn to a 2D canvas at 2x. That canvas
becomes the WebGL texture. No screenshots, no html2canvas.
Shade. A single fullscreen triangle runs the fragment shader. Uniforms are just
the element texture, time, resolution, the element’s rectangle, and its average color.
Fire scrolls noise upward; drip displaces the sample coordinate downward.
Respect motion. If prefers-reduced-motion is set, time freezes and
one composed frame renders. The pause button does the same on demand.
fire.fragdrip.frag
In this series
Week 1 — Fire & Drip · shaders on any DOM element (this page)