Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Shaders

Pro

Cloud Rays Shader for React

A sun behind broken cloud drawn on the GPU: warm shafts fan down through the gaps and slide as the clouds drift, over a hazy sky. For React with Base UI, when a nonprofit, faith, travel or wellness hero wants hopeful, moving light.

Framework

Cloud Rays Shader puts the sun behind a broken bank of cloud high in the frame. Warm shafts fan down through the gaps across a hazy sky and slide as the clouds drift; the edges that face the sun glow gold, the cloud bodies are slate, and the sky deepens to blue-gray at the bottom. The clouds are five octaves of fractal noise, cut by coverage and thinned round the sun so some light always gets through. The shafts are a screen-space light-shaft integral: for each pixel, 28 taps along the line to the sun, through a cheaper copy of the clouds near it, add up how much of the light is blocked, so the haze is lit where the sun shines through a gap. A WGSL fragment shader on WebGPU draws every pixel each frame.

Use it behind a nonprofit, faith, travel or wellness hero, or any page that wants hopeful, moving light. For a dusk desert instead, use Mirage Shader; for film light leaking in from the edges, Light Leak Shader; for a sun with rays and nothing in the way, in plain CSS, the Corona background. It runs only while it's on screen, holds a still frame with reduced motion, and shows a CSS sun with faint rays 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 { CloudRaysShader } from "@/components/ui/cloud-rays-shader";
<CloudRaysShader className="flex min-h-[32rem] items-center justify-center">
  <div className="rounded-xl bg-black/50 px-8 py-6">
    <h1 className="text-5xl font-semibold text-white">Ship faster</h1>
  </div>
</CloudRaysShader>

Cloud Rays Shader is a container: your content sits on top of the sky, 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". White text reads on the dusky sky, about 5:1 in the middle of the frame at the median, but a shaft or the sun can light up behind it, so give copy a panel: bg-black/50 keeps white text above 5.5:1 in the middle of the frame and above 4.4:1 anywhere. The palette is the same in both color schemes.

Demos

Dawn

hazeColor="#ffc2c2" turns the shafts and the light round the sun pink, and skyColor="#3a4a7a" makes the sky a deeper blue: early morning instead of late afternoon.

Preview width

In a card

sunPosition={[0.5, 0.12]} centers the sun over a narrow card, so the shafts fan down both sides. quality={0.5} renders at half resolution: the clouds and shafts are soft, so it looks the same for a quarter of the pixels.

Preview width

Performance

About 2 ms of GPU time a frame at 1280×720 on an M2 Max laptop at its default quality of 0.75, and 3 to 4 ms at quality={1}; slower GPUs take several times longer. Most of it is the 28 taps per pixel that trace the shafts. The scene is soft, so it renders at three-quarter resolution unless you set quality, and you can't tell. 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 sun with a warm haze and faint rays over the same sky, which follows your color props, 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 sky is decoration: it's hidden from assistive tech and lets every click through to your content. With reduced motion it draws one still frame, shafts falling from a sun half hidden by cloud, and stops. Nothing flashes: the clouds drift across the sun over many seconds, so the shafts brighten and fade slowly. White text on a bg-black/50 panel stays above 4.4:1 everywhere in the frame.

FAQ

How do I move the sun?

sunPosition takes [x, y], fractions of the box from the top left: [0.65, 0.1] is the default, high and right of center. The shafts always fan away from it, so a sun on one side throws them across the frame.

How do I get more or fewer clouds?

coverage sets how much of the bank is cloud, from 0 (a few wisps, the sun in the open) to 1 (overcast, with rare gaps). The clouds always thin a little round the sun, so some shafts get through.

How do I make the shafts longer or stronger?

rays sets how far they reach from the sun, from 0 to 2, and intensity how bright they are, from 0 (none) to 2.

Can I change the colors?

Yes: skyColor is the sky, hazeColor the shafts and the light round the sun, glowColor the sun and the gold on the cloud edges, and cloudColor the cloud bodies. They take any CSS color, var(--primary) included, and follow a theme switch.

Will it slow my page down?

It costs about 2 ms of GPU time a frame at 1280×720 on a laptop at its default three-quarter resolution, and the CPU only sets a few numbers each frame. It stops when it's off screen. On a slow GPU, quality={0.5} roughly halves that again, and the soft sky looks the same.

What happens in browsers without WebGPU?

The box keeps its CSS still: a pale sun with a warm haze and faint rays over a sky gradient, in your colors, so the page still looks finished. Nothing errors: the root's data-state reads unsupported.

API Reference

CloudRaysShader

data-slot="cloud-rays-shader"

PropType
cloudColor?string

The cloud bodies, in shadow. Any CSS colour. @default "#3a3e52".

Default
"#3a3e52"
coverage?number

How much of the bank is cloud, from 0 (a few wisps) to 1 (overcast, with rare gaps). @default 0.55.

Default
0.55
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 sun, and the gold on the cloud edges that face it. Any CSS colour. @default "#fff1c9".

Default
"#fff1c9"
hazeColor?string

The shafts and the hazy light round the sun. Any CSS colour. @default "#f0b27f".

Default
"#f0b27f"
intensity?number

How bright the shafts are, from 0 (none) 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.

Default
0.75
rays?number

How far the shafts reach from the sun, from 0 to 2. @default 1.

Default
1
skyColor?string

The sky, deepening toward the bottom. Any CSS colour. @default "#2e3a56".

Default
"#2e3a56"
speed?number

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

sunPosition?readonly [number, number]

Where the sun sits, as [x, y] fractions of the box from the top left. @default [0.65, 0.1].

Default
[0.65
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