Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Shaders

Free

Hologram Shader for React

A sci-fi projection drawn on the GPU: soft diagonal interference bands in blue, teal and violet, with scan ripples, grain, a rim glow and a slow sweep. For React with Base UI, when a hero, a launch or a product page wants a holographic, futuristic backdrop.

Framework

Hologram Shader draws a sci-fi projection. Soft diagonal interference bands in royal blue and deep navy drift across the box, with teal, violet and the odd gold where the color channels disagree; broad scan ripples roll over them, fine grain shimmers, a cyan glow lines the edges, and a soft bright band sweeps up every five seconds. Now and then the power dips a little. Every pixel is computed each frame by a WGSL fragment shader on WebGPU: the bands are sums of sines, and red, green and blue each sample them at a different moment, which is where the colors come from.

Use it behind a dark hero, a launch or a product page with a futuristic feel. For iridescent foil in plain CSS, with your theme's colors and no GPU, use the Hologram background; for corrupted, glitching video instead of a clean projection, Glitch Shader. It runs only while it's on screen, holds a still frame with reduced motion, and shows a CSS gradient of the same bands in browsers without WebGPU.

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Usage

import { HologramShader } from "@/components/ui/hologram-shader";
<HologramShader className="flex min-h-[32rem] items-center justify-center">
  <h1 className="text-5xl font-semibold text-white">Project the future</h1>
</HologramShader>

Hologram Shader is a container: your content sits on top of the projection, 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 projection is dark in both color schemes, so use white text: it reads at 4.5:1 or better over 95% of the frame and at about 10:1 on half of it. The brightest cyan patches and the rim drop to about 2:1, so keep small body text away from the edges, or on a panel.

Demos

In a card

intensity={0.7} dims the projection for a small surface, like a classified file on a dark dashboard.

Preview width

Violet

color="#a78bfa" tints the projection violet, and the rim glow and the sweep follow as deeper tones of it. stability={0.8} makes the power a little less steady: the projection is slightly dimmer and dips more often.

Preview width

Performance

About 0.3 ms of GPU time a frame at 1280×720 on an M2 Max laptop; slower GPUs take several times longer. The bands are soft, so on a slow GPU quality={0.5} renders a quarter of the pixels and looks nearly the same. 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 the same diagonal bands and rim, in your color, 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 projection 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. Its flicker is built to stay well under three flashes a second: power dips and scan bursts each come at most once per two seconds, fade in and out over a few hundred milliseconds, and dim by at most 30%; speed is capped at 2, so that's at most one of each a second. The frame is dark (its mean relative luminance is under 0.08), so a dip changes it far less than the 10% that counts as a flash. For text contrast, see Usage.

FAQ

Is it safe for people sensitive to flicker?

It's built to be. Nothing strobes: the power dips by at most 30% and fades in and out, the scan bursts fade too, and each comes at most once per two seconds, or once a second at the top speed of 2. The frame is dark, so a dip stays far below the brightness change that counts as a flash. With reduced motion it draws one still frame.

How do I change the tint?

color takes any CSS color, theme variables included, such as var(--primary). It tints the whole projection, and the rim glow and the sweep take deeper tones of it, so one prop recolors everything; it follows a theme switch.

What does stability do?

It sets how steady the projector's power is, from 0 to 1. At 1 the projection is bright and dips rarely; lower, it's dimmer, dips more often and shows more darker patches. The dips are capped either way: see the flicker question above.

Where do the rainbow colors come from?

Red, green and blue each draw the same interference bands, but at a different moment in their motion, so where they disagree you see teal, violet or gold. split also shifts the three channels apart a little in space, from 0 to 2. It's a styling trick, not a simulation of real holography.

Will it slow my page down?

It costs about 0.3 ms of GPU time a frame at 1280×720 on a laptop, and the CPU only sets a few numbers each frame. speed and the other props don't change the cost; the resolution does. It stops when it's off screen.

What happens in browsers without WebGPU?

The box keeps its CSS gradient: diagonal bands and a rim glow in your color. Nothing errors: the root's data-state reads unsupported.

API Reference

HologramShader

data-slot="hologram-shader"

PropType
color?string

The projection's tint; the rim glow and the sweep are deeper tones of it. Any CSS color. @default "#4dccff".

Default
"#4dccff"
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

The projection's brightness, from 0 to 2. @default 1.

Default
1
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.

scanlines?number

How dense the drifting scan ripples are, from 0 (none) to 3. @default 1.

Default
1
speed?number

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

Default
1
split?number

How far apart red, green and blue sample the bands, from 0 to 2. @default 1.

Default
1
stability?number

How steady the power is, from 0 (dimmer, flickering often) to 1 (bright, rarely dipping). @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