Lerp

Dithered AI-background hero

Demo
Palette
Source
One dot per cell; about 3 px on phones reads as texture.
Share of the cell a dot fills; 1 is solid pixels.
Higher shows fewer dots.
The video steps its frames at 11 fps: the stepping is part of the look.

One generated clip, dithered live into a two-tone dot field behind crisp type.

How it works

Background · WebGL· 7 sites

Video: The Viral $1 Website Effect That Looks Like $10K, Nick Saraev

How it works

One generated clip, dithered live into a two-tone dot field behind crisp type.In 6 steps.

Generate one image, turn it into a short locked-off clip, and play the clip as a field of dots in two close tones. The texture reads as atmosphere rather than noise, so a large serif headline sits on it untouched. The dots come from an ordered (Bayer 8×8) dither computed on the GPU every frame, so the palette, the dot size and the threshold stay live.

  1. 01

    Generate one image

    A single subject with a hard light and a lot of dark: a sphere, a field of wheat, a dome. Contrast matters more than detail, because the dither keeps only light and dark.

  2. 02

    Animate it without moving the camera

    Image-to-video with the same image as the first and the last frame gives a clip that loops seamlessly. Ask for motion inside the frame (light sweeping, wheat swaying), never a camera move.

  3. 03

    Cut it into greyscale frames

    48 frames at 11 fps, small (320 px wide is plenty), packed into one WebP atlas of 8 × 6 cells. Colour is thrown away here: the palette comes later, so lossy compression is harmless.

  4. 04

    Dither on the GPU

    For each cell of the canvas, read the frame's brightness at the cell's centre and compare it with the Bayer 8×8 threshold for that cell. Above it, draw a dot: a square inside the cell with a gap around it, in the ink tone; the brightest dots take the accent.

  5. 05

    Keep type out of it

    The canvas is a background layer. The headline, nav and buttons stay ordinary HTML on top, in the palette's text colour, so they stay sharp, selectable and accessible.

  6. 06

    Start politely

    Load the atlas after the page's largest paint, pause when the hero leaves the screen or the tab hides, and hold a still frame for reduced motion.

Code

The code

The engine is the file the demo above runs, framework-agnostic; the Svelte and React tabs wire it into a component.

Pro

Copy the engine, React or Svelte version.

Unlock code with Pro

US$60/year or US$8/month. Cancel anytime.

Prompt

Prompt pack

One generated clip, dithered live into a two-tone dot field behind crisp type.

3 prompts in Pro Generated 25 Sep 2026

  • Build it with a coding agentThe whole effect, as a brief for Claude Code, Cursor or any coding agent.
  • Background imageThe still the clip starts and ends on. Any image model; 16:9, very high contrast.
  • Loop footageImage-to-video with the same image as the first and last frame, so the clip loops without a seam.

Pro opens every prompt, with the measured values filled in and ready to paste into your coding agent.

Unlock prompts with Pro

US$60/year or US$8/month. Cancel anytime.

Performance & accessibility

Performance

One full-screen quad and a fragment shader of a few dozen operations: it holds 60 fps on mid-range phones at device pixel ratio 2 (capped there). The engine only redraws when the frame index or a setting changes, so at 11 fps it draws 11 times a second, not 60. The atlas is the only download, about 100–150 kB, and it is greyscale WebP. Load it after the largest contentful paint, pause off screen and in hidden tabs, and cap the pixel ratio at 2.

Reduced motion

Under prefers-reduced-motion draw one frame and stop: the texture stays, the movement goes. Without WebGL, fall back to a flat ground colour or a pre-rendered still, never a blank hero. The headline is plain HTML, so contrast and reading are unaffected either way.

Source

Source, credited

The approach and the look (a generated image, animated with a locked-off camera, cut into greyscale frames, dithered live with a Bayer 8×8 matrix and drawn as dots in two close tones) are from the video. This demo is an independent implementation: a GPU dither with square dots inside their cells, an optional accent on the brightest dots, and a bottom-edge fade drawn in the shader.

Key frames from the video, linked to their moment. The video itself is on YouTube, by Nick Saraev.

Seen in the library

Sites using this effect.