shadcn.io is not affiliated with official shadcn/ui
Worley Noise Shader draws cellular noise: a random point in every cell of a grid, and each pixel shaded by its distance to the nearest one. That makes a dense field of dark pits, each brightening in a soft cone toward its neighbors, and a glowing web of seams where two cells meet. Every point circles slowly inside its cell while the whole field drifts down and to the left, so the web ripples in place. A WGSL fragment shader on WebGPU draws every pixel each frame, for under half a millisecond of GPU time.
Use it as a texture behind a hero, a stat card or a section header, in monochrome or in your theme's colors. For glowing, embossed cells in hot colors, use Three-Tap Voronoi Shader; for flowing contour lines over a blended cell field, Smooth Voronoi Contours Shader; for lit glass cells in plain CSS, the Voronoi background. It runs only while it's on screen, holds a still frame with reduced motion, and shows a CSS grid of the same pits in browsers without WebGPU.
Installation
Usage
import { WorleyNoiseShader } from "@/components/ui/worley-noise-shader";<WorleyNoiseShader className="flex min-h-[32rem] items-center justify-center">
<div className="rounded-xl bg-black/60 px-8 py-6">
<h1 className="text-5xl font-semibold text-white">Ship faster</h1>
</div>
</WorleyNoiseShader>Worley Noise Shader is a container: your content sits on top of the texture, in normal flow. It fills its own box, so give it a height or content. For a backdrop behind the whole page, render it empty with className="fixed inset-0 -z-10". The texture runs from near black to near white every few pixels, so no text color reads on it bare: put copy on a panel, like the bg-black/60 one above, which keeps white text above 6:1 everywhere.
Demos
Themed
cellColor="var(--background)" and edgeColor="var(--primary)" draw the web in your theme's colors, and they follow a switch between light and dark. contrast={1.6} deepens the pits so more of the box is your background color and the web stands out as thin lines.
In a card
cellSize={96} makes the cells three times bigger, so a few large pits fill the card, and contrast={2} keeps the seams thin at that size. It keeps full quality: the seams are fine lines and go soft at half resolution, and a card-sized box costs the GPU next to nothing.
Performance
About 0.4 ms of GPU time a frame at 1280×720 on an M2 Max laptop; slower GPUs take several times longer. Each pixel measures its distance to the 9 points around it, whatever the cellSize. Keep quality at 1: the seams are thin lines that blur at half resolution, and the shader is cheap enough not to need it. The animation stops when the shader scrolls out of view, and the browser pauses it in a hidden tab. Every shader on a page shares one GPU device and one frame loop, and vgpu (about 50 KB gzipped) loads only when the first one mounts.
Browser support
The shader needs WebGPU: Chrome and Edge, Safari 26 and later, and Firefox on Windows and macOS. Elsewhere, and until the first frame, the box shows a CSS grid of dark pits in the same two colors, so the layout never jumps. data-state on the root reads unsupported there, if you want to style around it. See Shader Canvas.
Accessibility
The texture is decoration: it's hidden from assistive tech and lets every click through to your content. With reduced motion it draws one still frame and stops. Nothing flashes: the field drifts about 2 pixels a second and the points circle over 10 to 25 seconds. The contrast inside the texture is high and changes every few pixels, so never set text on it bare: a bg-black/60 panel keeps white text above 6:1, and bg-black/70 above 8.9:1. With your own colors, pick a scrim that darkens or lightens both of them.
FAQ
What is Worley noise?
A cellular texture Steven Worley described in 1996. Scatter random points, then shade each pixel by its distance to the nearest point: near a point it's dark, and where two points are equally far, at the seam between two cells, it's brightest. This shader also measures the distance to the second-nearest point, which is what makes the seams glow as a thin web.
How are the points placed?
The screen is cut into a grid, and each cell's integer coordinates go through an integer hash, which gives every cell its own fixed random spot and a slow circle around it. There's no texture and no state, so the pattern is the same on every load, and each pixel only needs to check its own cell and the 8 around it.
How do I change the cell size?
cellSize is the distance between cells in CSS pixels, from 8 to 160, so the texture looks the same on a retina screen and a standard one. Pair large cells with a higher contrast to keep the seams thin.
Can I use my brand colors?
Yes: cellColor is the dark center of each cell and edgeColor the web where they meet. They take any CSS color, var(--primary) included, and follow a theme switch. brightness and contrast set how much of the box each color takes.
Credits
Inspired by a Worley noise shader (opens in a new tab) by Xor on Shadertoy. This is a new shader written from the idea, not a port: its own hash, moving points, seam glow, drift and colors.
API Reference
WorleyNoiseShader
data-slot="worley-noise-shader"
brightness?number
Overall lightness, from 0.5 (dim) to 2 (washed toward edgeColor). @default 1.
- Default
1
cellColor?string
The centres of the cells. Any CSS colour. @default "#0a0a0a".
- Default
"#0a0a0a"
cellSize?number
How far apart the cells are, in CSS pixels, from 8 to 160. @default 32.
- Default
32
contrast?number
How deep the pits are against the seams, from 0.5 (flat and milky) to 3 (deep, with thin bright seams). @default 1.
- Default
1
edgeColor?string
The seams where the cells meet. Any CSS colour. @default "#f5f5f4".
- Default
"#f5f5f4"
fallback?string
What shows until the first frame and in browsers without WebGPU: a CSS
background value (gradients, sizes, a colour) that looks like the
shader. It can use the colour props' --shader-<field> variables.
interactive?boolean
Whether u.pointer follows the pointer. @default false.
paused?boolean
Holds the current frame. @default false.
quality?number
Render scale, from 0.25 to 1, of the screen's pixels (capped at 2×). @default 1.
speed?number
Animation speed: 1 is normal, 0 holds the frame. @default 1.
time?number
A fixed moment, in seconds: draws it and doesn't animate.
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Forwarded to the part.
Related
- Pro


Three-Tap Voronoi Shader
Patterns & tilingsGlowing, embossed cells in hot colors
- Pro


Smooth Voronoi Contours Shader
Patterns & tilingsContour lines over a blended cell field


Noise Shader
Flow & gradientsOrganic fractal color, free
- Pro


Cellular Tiled Tunnel Shader
Tunnels & 3DThe same cells, wrapped round a tunnel
- Pro


Magma Shader
Ink, smoke & fireCells as drifting lava plates


Orb Grid Shader
GeometryA clean grid for a section header, free