Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Shaders

Pro

Embers Shader for React

A bed of glowing coals drawn on the GPU: lumps of charcoal under grey ash, glowing orange through their cracks as the heat swells and sinks, with a few sparks lifting. For React with Base UI, when a cosy, seasonal or after-dark hero wants warmth that moves slowly.

Framework

Embers Shader draws a bed of coals seen from above at a slant, the way you'd look down into a fire pit. Each lump of charcoal is rounded and lit from above; some are hot right through and glow a mottled orange, others are nearly dead, dark under grey ash with red cracks across them, and the gaps between them glow brightest at the heart of the bed, low in the middle. The heat swells and sinks through the bed in slow waves, as if someone were blowing on it, and now and then a spark lifts and winks out. The coals are Voronoi cells projected onto a tilted ground, the cracks a second, finer cell pattern, and the glow is black-body light from Planck's law, computed for every pixel, every frame, by a WGSL fragment shader on WebGPU.

Use it behind a cosy product, a winter or holiday page, a "fireside" story or an after-dark hero. The bed fades into darkness toward the top, which leaves room for a headline. For a river of lava with drifting plates, use Magma Shader; for open flame, Fire 3D Shader or Sparks Drifting Shader; for a fire in plain CSS, with no GPU, the Fireplace background. It runs only while it's on screen, holds a still frame with reduced motion, and shows a warm glow over dark 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 { EmbersShader } from "@/components/ui/embers-shader";
<EmbersShader className="flex min-h-[32rem] items-start justify-center pt-24">
  <h1 className="text-5xl font-semibold text-white">Gather round</h1>
</EmbersShader>

Embers Shader is a container: your content sits on top of the coals, 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 bed is dark in both color schemes and brightest low in the middle, so put white or light text in the upper half.

Demos

Dying fire

temperature={900} cools the bed to a dull red, ash={0.8} coats more of each coal in grey, breathing={0.5} calms the swell, and sparks={0.1} sends up only the odd spark: a fire that's nearly out.

Preview width

In a card

The bed is sized to the box's height, so a card shows the same few rows of coals, closer up. intensity={1.3} brightens the glow for the small surface, and sparks={0.8} sends up more sparks.

Preview width

Performance

About 1.5 ms of GPU time a frame at 1280×720 on an M2 Max laptop; slower GPUs take several times longer. The cracks are fine lines, so it renders at full resolution by default: quality={0.5} costs a quarter as much, but softens them. 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, an orange glow at the bottom fading to near black at the top, 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 coals are decoration: they're hidden from assistive tech and let every click through to your content. With reduced motion it draws one still frame, three seconds in, and stops. Nothing flashes: the heat swells over several seconds, and the sparks are a few pixels wide. In the upper 45% of the frame, white text reaches 4.5:1 everywhere we measured but the sparks themselves; over the whole frame it's 4.5:1 on 96%, so keep text off the bright heart at the bottom.

FAQ

How are the coals drawn?

Each pixel casts a ray from a camera tilted down at the ground, and finds which Voronoi cell, or coal, it lands in, and how far it is from that coal's edge. That distance shapes each coal into a dome, lit from above and shadowed where it meets the next one. A finer cell pattern draws the cracks, noise lays the ash, and each coal's own heat, the heart of the bed and a slow swell set its temperature, which Planck's law turns into color.

What does breathing do?

It sets how strongly the heat swells and sinks: slow waves of noise drift across the bed, and where one passes the coals and gaps run hotter and brighter. At 0 the heat is steady and only the sparks move; at 2 the swells are deep, from dull red to orange-yellow. speed scales how fast they travel.

Can I change the colors?

coalColor sets the charcoal, ashColor the ash on top, and tintColor multiplies the glow: white keeps the black-body colors. They take any CSS color and follow a theme switch. The glow's own color comes from temperature: 800 K is a dim red, the default 1100 K orange, and 1600 K orange-yellow. intensity sets its strength, from 0, dead coal, to 2.

How do I control the sparks?

sparks sets how many are in the air, from 0 to ten at a time. Each rises from the bed, wobbles a little and burns out within a few seconds. They're a few pixels wide at any screen density, so they stay sparks on a large screen.

Will it slow my page down?

It costs about 1.5 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. sparks adds a little, at most ten points; ash, breathing and temperature change the look, not the cost. On a slow GPU, quality={0.5} renders a quarter of the pixels, with softer cracks.

What happens in browsers without WebGPU?

The box keeps its CSS gradient, an orange glow along the bottom fading to near black, so the page still looks finished. Nothing errors: the root's data-state reads unsupported.

API Reference

EmbersShader

data-slot="embers-shader"

PropType
ash?number

How much grey ash coats the coals, from 0 (bare black coal) to 1 (thick ash). @default 0.5.

Default
0.5
ashColor?string

The ash on top of the coals. Any CSS colour. @default "#8f8780".

Default
"#8f8780"
breathing?number

How strongly the heat swells and sinks through the bed, from 0 (steady) to 2. @default 1.

Default
1
coalColor?string

The coals under the ash. Any CSS colour. @default "#17110f".

Default
"#17110f"
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 coals glow, from 0 (dead coal) 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.

sparks?number

How many sparks lift from the bed, from 0 (none) to 1 (ten at a time). @default 0.5.

Default
0.5
speed?number

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

temperature?number

The bed's temperature in kelvin, from 800 (a dim red) to 1600 (orange-yellow): it sets the glow's colour. @default 1100.

Default
1100
time?number

A fixed moment, in seconds: draws it and doesn't animate.

tintColor?string

Multiplies the glow's colour: white keeps the black-body colours. Any CSS colour. @default "#ffffff".

Default
"#ffffff"
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