Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Shaders

Pro

Sphere Field Shader for React

A fisheye flight through a lattice of glowing spheres drawn on the GPU: warm cores ringed with electric-blue halos that swell as they rush past. For React with Base UI, when a dark hero, a music or an event page wants depth and glow behind its copy.

Framework

Sphere Field Shader flies a fisheye camera through an endless lattice of spheres on black. Each sphere glows like a hot bulb, cream where it faces you and amber at its rim, with a thin electric-blue halo around it and faint webs of blue light in the gaps. Small, dim spheres crowd the centre of the view and swell as they rush out past the edges, and the whole field rolls slowly. A WGSL fragment shader on WebGPU marches each pixel's ray only nine short steps, bending it outward at every step, so the rays never quite settle at the rims: those leftover distances are what paint the halos and the webs.

Use it behind a dark hero, a music or event page, or a launch that should feel deep and electric. For soft out-of-focus lights in plain CSS, with no GPU, use the Bokeh background; for a flight through patterned planes, Starry Planes Shader. It runs only while it's on screen, holds a still frame with reduced motion, and shows a CSS gradient of glowing spheres in browsers without WebGPU.

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Usage

import { SphereFieldShader } from "@/components/ui/sphere-field-shader";
<SphereFieldShader 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">Live tonight</h1>
  </div>
</SphereFieldShader>

Sphere Field Shader is a container: your content sits on top of the spheres, 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 field is black in both color schemes, so use white text, but the spheres are nearly white themselves: put copy on a panel, like the bg-black/60 one above.

Demos

Dense

sphereSize={0.6} shrinks the spheres and spacing={0.7} packs the lattice closer, so many more, smaller lights fill the view and the halos and webs between them carry more of the picture.

Preview width

In a card

The field scales with its box. glowColor="#d946ef" turns the halos and webs magenta, and speed={0.6} slows the flight for a small surface. It keeps full quality: the shader is light, and the thin halos go soft at half resolution.

Preview width

Performance

About 0.25 ms of GPU time a frame at 1280×720 on an M2 Max laptop, at the default quality={1}: every pixel takes nine steps through the lattice, whatever the props. Slower GPUs take several times longer, which still leaves plenty of room. 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 gradient of two glowing spheres round a dim centre, in your sphereColor and glowColor, 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 field is decoration: it's hidden from assistive tech and lets every click through to your content. With reduced motion it draws one still frame, a ring of glowing spheres round the dim centre, and stops. Nothing flashes: at the default speed the nearest spheres glide out of view over about four seconds, and the roll turns 3° a second. The background is black, so white text is above 13:1 on three quarters of the frame, but it drops to nearly 1:1 on the spheres. A bg-black/60 panel keeps white text above 5.7:1 even over the brightest sphere, and bg-black/70 above 8.5:1.

FAQ

Why does it look so rich with so few steps?

Each pixel's ray takes only nine steps through the lattice, and at every step it bends outward by the distance it just covered. Rays aimed at the middle of a sphere still land on it, and are shaded as a glowing ball. Rays that pass near a rim run out of steps before they settle, and the distance they have left decides their color: a soft amber bloom, then a dark gap, a blue halo, and faint webs further out. Those "unfinished" distances are the art.

How do I change the spheres?

sphereSize scales them, from 0.3 (specks) to 2.5 (nearly touching). spacing sets the gap between them, from 0.5 (packed) to 2 (sparse); larger values show fewer, lonelier spheres. Both change the look, not the cost.

Can I change the colors?

sphereColor sets the hot cores, and their amber rims are a warmer, darker shade of it. glowColor sets the halos and the webs. Both take any CSS color and follow a theme switch, so var(--primary) works. Keep the background dark: the field is lit spheres on black, and the colors only add light.

Can I stop it moving?

speed={0} or paused holds the current frame, and time={2.5} draws one fixed moment. spin={0} stops only the roll, so the camera keeps flying straight. With reduced motion, the shader draws its still frame and stops on its own.

Why is the view curved like a fisheye?

The rays fan out by angle rather than across a flat screen: the farther a pixel is from the centre, the more sideways its ray looks. That's why the spheres at the edges stretch into big ovals as they pass, and why the lattice seems to stream out of one point.

Will it slow my page down?

No: it's one of the lightest shaders, about 0.25 ms of GPU time a frame at 1280×720 on an M2 Max laptop, and the CPU only sets a few numbers each frame. It stops when it's off screen. On a very slow GPU, quality={0.75} draws about half as many pixels; the soft glows hide it, and only the thin halos soften.

Credits

Inspired by a sphere-field shader by nocrex on Shadertoy (opens in a new tab), through shadcn.io's version. The idea, a short march through repeated spheres with rays that bend outward and colors read from the distance left over, is the same; the code, the lattice flight, the shading and the palette are ours, written from scratch.

API Reference

SphereFieldShader

data-slot="sphere-field-shader"

PropType
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.

glowColor?string

The halos round the spheres and the webs between them. Any CSS color. @default "#3b6cff".

Default
"#3b6cff"
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.

spacing?number

The gap between spheres, from 0.5 (packed) to 2 (sparse). @default 1.

Default
1
speed?number

Animation speed: 1 is normal, 0 holds the frame. @default 1.

sphereColor?string

The glowing cores of the spheres. Any CSS color. @default "#fff1cc".

Default
"#fff1cc"
sphereSize?number

The spheres' size, from 0.3 (specks) to 2.5 (nearly touching). @default 1.

Default
1
spin?number

How fast the field rolls, on top of speed: 1 is 3° a second, 0 holds it level. @default 1.

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.

All 101 shaders