Shaders
← Back to library
Open full screen ↗
This is the actual page the prompt produces — scroll and click inside it.
About this one
Exponential falloff around noise-displaced lines. It drifts like weather rather than sliding like an animation.
The prompt
THE ENGINE — about sixty lines, written by hand
Render a fragment shader across a full-bleed canvas behind the hero.
Raw WebGL, no Three.js: a 600KB scene graph to draw one quad is not a
trade worth making, and the shader is the entire effect anyway.
Set it up like this:
- One oversized triangle at (-1,-1), (3,-1), (-1,3). It covers the
viewport with no index buffer and no second draw call.
- Uniforms: u_res (vec2), u_time (float, seconds), u_mouse (vec2),
and three vec3 brand colours c1, c2, c3.
- Include a value-noise function and a 5-octave fbm built on it. Every
shader below is made of those two.
THE SHADER — curtains
For each of three curtains, define a line across the screen:
y = 0.45 + sin(uv.x * (2+i) + t * (1.3 + i*0.4)) * 0.14, displaced further
by an fbm sample so it drifts rather than oscillating cleanly.
Light each one with exp(-abs(uv.y - y) * (7 + i*3)). The exponential is the
point — a gradient stop cannot give you that soft vertical bleed, and every
attempt to fake it with a blur looks like a blur.
Sum the three, mix c1 to c2 horizontally, push toward c3 where the light is
strongest, and multiply by the summed band plus a small floor so the sky is
not pure black.
PERFORMANCE — this is where shader pages usually go wrong
Cost is per pixel, so resolution is the only dial that matters. Cap
devicePixelRatio at 1.5. Pause the render loop with IntersectionObserver
when the canvas leaves the viewport, and on document visibilitychange —
a shader burning the GPU behind a hidden tab is why laptops get hot on
portfolio sites.
If getContext('webgl') returns null, paint a layered CSS radial-gradient
in the same three colours instead. A static gradient is a fine outcome;
a black rectangle is not.
Under prefers-reduced-motion, draw exactly one frame at t=3.0 and stop.
THE PAGE ON TOP
Full-height hero with the content bottom-aligned, so the shader owns the
upper two-thirds. A linear-gradient veil from the background colour at
the bottom to transparent at 58%, so the type sits on solid colour while
the field stays visible above it.
Headline at clamp(3rem, 9vw, 8rem), weight 700, letter-spacing -0.035em,
capped at 11 characters per line, with one word carrying a gradient fill
from the same three colours.
A fixed nav with mix-blend-mode: difference, so the links invert against
whatever the shader is doing underneath and stay readable without a bar.
Below the hero, a marquee strip and three cards explaining the technique.
RULES
The canvas stays at every breakpoint — it is the reason the page works.
Drop the nav links and the card grid to one column below 880px.