# Halftone

Aperveil / Light, shaped for the web.

A procedural halftone background for React with drifting tones and interactive dots. Adjust screen angle and dot gain, then export the WebGPU shader.

[Aperveil integration guide](https://www.aperveil.com/docs)

## What it does

Halftone translates a generated drifting tone field into dots. Screen angle rotates the sampling grid, density sets the pattern and dot gain changes how strongly the tones fill each cell.

## Choose it for

Build an event poster that lives on the web. Use a large editorial heading above the dot field and keep dates and ticket links in a clear HTML layer.

## Limits

It does not convert uploaded images into halftone and is not a CMYK print-separation tool. The tone source is procedural.

## Current look

Default. Color Looks change colors only; motion, geometry and typography remain unchanged.

[Open editor](https://www.aperveil.com/shaders/halftone/edit?look=default)

## Install

Download the Export Kit from the editor. No shader-specific npm package or CLI is published yet.

```sh
npm install ./vendor/aperveil-runtime-0.1.0.tgz ./vendor/aperveil-react-0.1.0.tgz
```

Every control in the editor is a typed prop. Leave a prop out to keep the value you exported; change one and the running shader updates without restarting. Give the surface a size and pass fallback for browsers without WebGPU.

```tsx
"use client";

import Halftone from "./Halftone";

export default function Hero() {
  return (
    <Halftone
      className="hero-shader"
      density={60} paperColor="#0f1119ff"
      fallback={<div className="hero-shader-fallback" />}
    />
  );
}

// .hero-shader { width: 100%; height: 560px; }
```

Component props: `paperColor`, `inkLow`, `inkHigh`, `density`, `dotGain`, `screenAngle`, `toneScale`, `flowSpeed`, `openStrength`, `openReach`, `opacity`, `className`, `style`, `paused`, `fallback`, `onReady`, `onError`.

Raw WGSL is included for a custom WebGPU host; it is not CSS. Keep semantic headings and links in HTML.

## Controls

- Paper (`paperColor`, color): Colour of the paper behind the dots.
- Ink low (`inkLow`, color): Ink colour of the smallest dots.
- Ink high (`inkHigh`, color): Ink colour of the largest dots and of those swelled by the cursor.
- Screen density (`density`, slider): Dots per unit across the rotated screen.
- Dot gain (`dotGain`, slider): How large a dot grows for a given tone.
- Screen angle (`screenAngle`, slider): 25 degrees is the classic single-plate angle. Near 0 or 90 the rows align with the pixel grid and moire.
- Tone scale (`toneScale`, slider): Size of the light and dark areas in the field; higher values make them smaller.
- Flow speed (`flowSpeed`, slider): How fast the field drifts; 0 holds it still.
- Cursor opening (`openStrength`, slider): How much the dots swell around the cursor.
- Opening reach (`openReach`, slider): How far around the cursor the dots swell.
- Opacity (`opacity`, slider): Opacity of the complete effect, including its background.

## Compatibility

WebGPU rendering requires a supported browser and secure context. The landing shows a real poster for the selected Look when live rendering is unavailable. The standard exported component does not bundle a poster fallback. Supply your own fallback in the host layout. Text exports also retain readable HTML typography.

## Performance

0.404 ms legacy timing (method not recorded; not a pure GPU measurement). 1440x900 @ dpr 2; Metal driver on macOS Version 26.6.2 (Build 25G83); measured 2026-09-02. This is a recorded headless sample, not a browser FPS or mobile-performance guarantee.

## Questions

### Can I apply the dots to a photograph?

Not with this shader's current interface. It generates its own tone field. Its screen angle and dot controls shape that field rather than filtering an image.

### What should I not use Halftone for?

It does not convert uploaded images into halftone and is not a CMYK print-separation tool. The tone source is procedural.

### What happens without WebGPU?

This landing shows a still poster of your selected Color Look. The raw WGSL needs a WebGPU host. Landing posters are not bundled in the Export Kit: add your own fallback around the exported component.

### Can I use this shader commercially?

Part of the Free collection for Aperveil 1.0. Public live preview and Color Looks are open. Free Export Kits do not require an account. Purchasing is not available yet. Follow the license notices supplied with the source you download. The planned Free collection permits personal and commercial interface projects. An alpha access grant is not a purchase or a replacement for those license terms.

## License

Part of the Free collection for Aperveil 1.0. Public live preview and Color Looks are open. Free Export Kits do not require an account. Purchasing is not available yet. Follow the license notices supplied with the source you download. The planned Free collection permits personal and commercial interface projects. An alpha access grant is not a purchase or a replacement for those license terms.

## Related shaders

- [Dither](https://www.aperveil.com/shaders/dither)
- [Dot Grid](https://www.aperveil.com/shaders/dot-grid)
- [Grain Gradient](https://www.aperveil.com/shaders/grain-gradient)
