# Chladni Plate — `chladni-plate@1.0.0`

A metal plate shaken at the pitch of a note, sand running into fine lines and lattices, then thrown and settling into the next figure. Loops perfectly.

The classic experiment of Ernst Chladni, as a quietly hypnotic loop: a square brass (or steel, or copper) plate lies under a soft sliding light, clamped by a bolt at its middle. Each note it is shaken at makes the plate move in some places and stand still along lines; the sand on it runs from the moving places to the still ones and draws the figure. Every few seconds the note changes: the plate is shaken hard, the sand is thrown across it and runs again into a new, more or less intricate figure of lines, crossings and lattices, until the loop comes back to the first. Choose the look (brass, steel, copper or glowing neon sand), how many figures a loop holds, how intricate they are, how much sand there is and how big its grains, how wide the bands are, how violently it is thrown, how much the metal shimmers and the seed that picks the figures.

- Kind: background; status: published; digest sha256:5fe5b44a93067851c05cea7b7ad07776c6cabc2d0e44169ae646f6d6f91bf51d
- Role: Background (WebGL, full frame): a calm, scientific, satisfying loop for music, sound, physics and meditation content.
- Implementation: three; entry `src/chladni-plate.js`
- Files: https://aipixelwizard.com/registry/chladni-plate/1.0.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/chladni-plate.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/chladni-plate/versions/1.0.0
- Runnable demo: https://aipixelwizard.com/registry/chladni-plate/1.0.0/index.html (open over http; it imports sibling packages by relative path)
- Dependencies (exact): `three@0.185.1` (source) — Renderer, the plate shader, the sand points and the bloom targets.; `apw-runtime@1.0.0` (demo) — Demo harness.

## Exports
- `createChladniPlate({ look?, modes?, order?, grains?, grainSize?, spread?, shake?, shimmer?, seed? }) => { scene, camera, sequence, setSize(width, height), update(time, loopSeconds), dispose() }` — The plate, its table and bolt on a full-screen quad and the sand as points moved by a vertex shader: render its scene with its camera after setSize and update, ideally through createBloomPass.
- `createBloomPass(renderer, { width, height, glow?, exposure?, grain? }) => { render(scene, camera, output?), dispose() }` — A small bloom with filmic tone mapping: draws a scene to the canvas with its glow.
- `planModes({ count?, order?, seed? }) => [n, m, sign][]` — The figures of a loop: modes cos(nπx)cos(mπy) + sign·cos(mπx)cos(nπy), more intricate as order rises, none repeated.
- `LOOKS: { brass, steel, copper, neon }` — Plate, sand and table colours (sRGB hex) for each look.

## Parameters
- `look` (select one of brass | steel | copper | neon, default "brass") — Look
- `modes` (integer 2–5, default 3) — Figures: How many different notes (figures) one loop holds.
- `order` (integer 1–6, default 3) — Intricacy: How fine the figures are: higher notes draw more lines.
- `grains` (integer 10000–100000, default 26000) — Sand: The number of grains: finer figures need more.
- `grainSize` (number 0.6–1.6, default 1) — Grain size
- `spread` (number 0.4–2, default 1) — Band width: How wide the bands of sand are round the lines.
- `shake` (number 0–1.6, default 1) — Shake: How violently the sand is thrown between figures.
- `shimmer` (number 0–1.5, default 0.6) — Shimmer: How much the metal shimmers with the vibration.
- `seed` (integer 1–999, default 7) — Seed

## Composition
- Inputs: Time within the loop; the look, the number and intricacy of the figures, the amount and size of the sand, the width of its bands, the shake, the shimmer and the seed.
- Outputs: A full frame: the plate and its table drawn by one shader, the sand as points drawn over it.
- Coordinates: The plate is a square centred on the frame, 86 % of its height wide, with coordinates 0 … 1 across; the bolt is at its middle. Each figure is the zero set of cos(nπx)cos(mπy) + s·cos(mπx)cos(nπy).
- Lighting: Self-lit: a soft light from the upper left with a band of light that slides over the brushed metal once per loop; the neon look glows and blooms.
- Timing: update(time, loopSeconds) sets the loop phase; frames render in any order.
- Works with: kinetic-title, number-reveal
- For each note a grain starts at a hashed place and takes 20 regularised Newton steps along the slope of the vibration towards the nearest zero of the figure; the grain then moves from its start to that rest by a smooth easing. Nothing is simulated, so any frame renders alone.
- Each note: the plate is shaken (first 5 % of its time), a tenth of the sand is thrown to random places in the air (to 10 %) and runs to the lines (to 42 %); the rest fades out where it lay and fades in near the new lines; then everything rests until the next note.
- A few grains stop short on the way and the bolt in the middle keeps the sand off.

## Output and loop
- 1080×1080, 30 fps, 15 s, procedural
- Seamless loop: yes — Each figure owns an equal share of the loop; every grain's place is a formula of the position in the loop (its walk to the nearest line is a fixed number of steps), the hop of the grains is a sine of whole cycles per loop and the light slides as a sine of the loop, so the last frame meets the first.
- Verified 2026-10-06 in Chrome 154.0.8037.97 headless on Linux 7.0.0-38-generic (x64), Node 22.14.0 (WebGL 2 via SwiftShader (software)); deterministic: yes; loop check: Frame 0 vs end state (progress 1): mean |Δ| 0.0000, max |Δ| 0 of 255.

## Use it
New project: Create a WebGLRenderer, createChladniPlate() and createBloomPass(renderer, { width, height }); call plate.setSize(width, height), then each frame plate.update(time, loopSeconds) and bloom.render(plate.scene, plate.camera).

Existing project: Copy src/chladni-plate.js; render plate.scene with plate.camera into a render target (or through the bloom pass) as the backdrop of your scene.

Reuse ideas:
- Ambient music backdrop: Brass plate, three figures.
- Physics explainer on resonance: Salt on steel.
- Sound or tech title: Glowing neon sand.

## Limitations
- The figures are the ideal modes of a plate (cosines), not a simulation of a real clamped plate.
- The sand is drawn as round points a few pixels wide, so very high intricacy with little sand looks sparse: raise the sand with the intricacy.
- The transitions (sand in the air, lines forming) are the costly frames to encode: a loop with more figures or much more sand makes a much larger video.

## License
MIT. Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.

Provenance: Adapted from the owner's threejs-sketches/audio-musical/webgpu-chladni-plate and physics-simulation/chladni-patterns (MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original scene: every grain's place a formula of the time (no particle simulation), figures chosen and sequenced by a seed, an exact loop, a bolted brushed-metal plate and the frame/time contract.

