Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Shaders

Pro

Lattice Light Shader for React

Late sun through a carved screen, drawn on the GPU: a slanted patch of amber light in eight-point stars on a blue-grey wall, sharp near the window and softer further off. For React with Base UI, when an architecture, hotel or wellness page wants warm, quiet light.

Framework

Lattice Light Shader draws the light of a late sun falling through a carved window screen, a mashrabiya of eight-point stars, onto a plain wall. Sunlight is parallel, so the screen's shadow is a sheared, stretched copy of it: its verticals stay upright and its rows slant down across the wall. The edges are crisp on the side nearest the window and soften with the distance the light has crossed, warming to orange where they blur; a faint haze hangs in the beam, the plaster has a soft grain, and the whole patch drifts as the sun moves. A WGSL fragment shader on WebGPU draws every pixel each frame.

Use it behind an architecture, interior, hotel or wellness hero, a seasonal page or a testimonial that wants warmth and calm rather than motion. For stage lights sweeping a section, use the Spotlight background; for shafts of light through cloud, Cloud Rays Shader. It runs only while it's on screen, holds a still frame with reduced motion, and shows a soft CSS pool of slanted light 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 {
  LatticeLightShader,
} from "@/components/ui/lattice-light-shader";
<LatticeLightShader className="flex min-h-[32rem] items-end p-12">
  <h1 className="text-5xl font-semibold text-white">Stay a while</h1>
</LatticeLightShader>

Lattice Light Shader is a container: your content sits on top of the wall, 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 light falls right of center and the lower left stays in shade, so white text reads there, like the heading above: the bare wall gives it 9:1 to 13:1. Over the light itself, put copy on a panel: bg-black/50 keeps white text above 5.3:1 anywhere in the frame.

Demos

Window grid

pattern="grid" swaps the stars for square panes, like an old window, and softness={1.6} blurs the far edges further. Here lightColor, wallColor and shadowColor set pale morning light on a warm taupe wall, behind a quote or a testimonial.

Preview width

In a card

pattern="hex" casts a honeycomb screen, scale={0.8} makes its openings bigger so they read at card size, and intensity={1.2} brightens the light a little. The patch keeps its place in any box: in a narrow one the view widens so the light still fits.

Preview width

Performance

About 0.2 ms of GPU time a frame at 1280×720 on an M2 Max laptop: a few box distances per pixel and a little noise for the plaster. Slower GPUs take several times longer. It keeps full quality: the near edges are sharp and would soften at half resolution, though the far side is soft anyway. 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 soft CSS pool of slanted light on the same wall, 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 light 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 sun's slow sway takes about two minutes to come back round. With interactive, the pointer moves the sun, eased, so the light glides rather than jumps. White text reads on the shaded wall, above 9:1; over the light, use a panel.

FAQ

Which screens are there?

pattern picks the screen the light falls through: "star", eight-point stars split by thin bars with small diamonds between them, the classic mashrabiya; "grid", square panes like an old window; or "hex", a honeycomb. scale sets the size of the openings.

Why are some edges sharp and others soft?

The sun isn't a point: it's a small disc, so a shadow's edge blurs more the further the light travels past the screen. The window is off to the upper left, so the edges nearest it are crisp and the far ones soft, warming to orange where they blur. softness scales that blur, from 0 (sharp everywhere) to 2.

Can visitors move the light?

Yes: with interactive, the pointer moves the sun. Left and right change how steeply the light slants, and up and down how far it stretches; when the pointer leaves, the light settles back. Without it, the sun drifts on its own.

Can I change the colors?

Yes: lightColor is the sunlight, wallColor the wall around it, and shadowColor the wall in shade, inside the patch and toward the corners. They take any CSS color, var(--primary) included, and follow a theme switch. Keep the wall darker than the light: intensity sets how bright it is, and past 1 the light starts to blow out.

Where should my text go?

On the shade. The patch falls right of center and the lower left stays dark, where white text reads at 9:1 or better. To set text over the light, put it on a panel such as bg-black/50.

Will it slow my page down?

It costs about 0.2 ms of GPU time a frame at 1280×720 on a laptop, and the CPU only sets a few numbers each frame. It stops when it's off screen, so it's light enough to keep behind a full-page hero on most devices.

API Reference

LatticeLightShader

data-slot="lattice-light-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.

intensity?number

How bright the sunlight is, from 0 (none) to 2 (blown out). @default 1.

Default
1
interactive?boolean

Whether u.pointer follows the pointer. @default false.

lightColor?string

The sunlight. Any CSS color. @default "#ffc685".

Default
"#ffc685"
pattern?keyof typeof PATTERNS

The screen the light falls through: eight-point stars, square panes or a honeycomb. @default "star".

Default
"star"
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.

scale?number

The size of the lattice's openings, from 0.5 (big) to 2 (fine). @default 1.

Default
1
shadowColor?string

The wall in shade, inside the patch of light and toward the corners. Any CSS color. @default "#232a38".

Default
"#232a38"
softness?number

How soft the far edges get, from 0 (sharp everywhere) to 2 (very soft). @default 1.

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.

wallColor?string

The wall around the light. Any CSS color. @default "#2e3a4d".

Default
"#2e3a4d"
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