# Faraday Wave — `faraday-wave@1.0.1`

A pool of liquid shaken into standing patterns that flow between squares, hexagons and stars as the surface heaves. Loops perfectly.

A shallow pool of liquid shaken from below, the way Michael Faraday did it: above a certain shaking the surface breaks into a standing pattern that pulses with the shaking, as squares, hexagons or ten-pointed stars. Here the three patterns flow into one another around the loop while the surface heaves up and down, lit like a pool of mercury, ink, honey or lagoon water. Choose the liquid, the number of cells across the picture, how many heaves per loop, how steep the surface looks and the brightness of its reflections.

- Kind: background; status: published; digest sha256:76f968a5e4723b366b9a268c7cadc297170c74e63db64b1d6ebc15eb275ed6d7
- Role: Shader background (three.js): a hypnotic physics pattern for science, music and ambient content.
- Implementation: three; entry `src/faraday-wave.js`
- Files: https://aipixelwizard.com/registry/faraday-wave/1.0.1/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/faraday-wave.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/faraday-wave/versions/1.0.1
- Runnable demo: https://aipixelwizard.com/registry/faraday-wave/1.0.1/index.html (open over http; it imports sibling packages by relative path)
- Dependencies (exact): `three@0.185.1` (source) — Renderer and a full-screen shader material.; `apw-runtime@1.0.0` (demo) — Demo harness.

## Exports
- `createFaradayWave({ liquid?, cells?, cycles?, heave?, gain? }) => { scene, camera, setSize(width, height), update(time, loopSeconds), dispose() }` — The pool as one full-screen shader; render its scene with its camera, ideally through createBloomPass.
- `createBloomPass(renderer, { width, height, glow?, exposure?, grain? }) => { render(scene, camera, output?), dispose() }` — A small bloom with tone mapping and a fixed grain.
- `LIQUIDS: { mercury, ink, honey, lagoon }` — Base, sky and light colours for each liquid.

## Parameters
- `liquid` (select one of mercury | ink | honey | lagoon, default "mercury") — Liquid
- `cells` (number 4–10, default 5) — Cells across
- `cycles` (integer 2–8, default 4) — Heaves per loop
- `heave` (number 0.2–1.2, default 0.55) — Steepness
- `gain` (number 0.5–1.6, default 1) — Reflections

## Composition
- Inputs: Time within the loop; the liquid, cells, heaves, steepness and reflections.
- Outputs: A full-frame shader image through a bloom pass.
- Coordinates: Screen-centred, ±1 vertically; waves are plane waves of wavelength 2 / cells at fixed angles.
- Lighting: A fixed light from the upper left lights the slope of the liquid, with a sky reflection by slope and a Fresnel rim.
- Timing: update(time, loopSeconds) sets the loop phase; frames render in any order.
- Works with: kinetic-title, number-reveal
- Heights and slopes are computed analytically from the sum of plane waves, so there are no texture lookups.

## Output and loop
- 1080×1080, 30 fps, 12 s, procedural
- Seamless loop: yes — The three patterns are crossfaded with weights of whole cycles of the loop, the pool heaves a whole number of times per loop and the pattern's small rotation is a sine of the loop, so the last frame meets the first.
- Verified 2026-10-08 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, createFaradayWave() and createBloomPass(renderer, { width, height }); call pool.setSize(w, h) and each frame pool.update(time, loopSeconds) then bloom.render(pool.scene, pool.camera).

Existing project: Copy src/faraday-wave.js and render pool.scene with pool.camera into your own target.

Reuse ideas:
- Science backdrop: Mercury, five cells.
- Dark ambient: Ink, fine pattern.
- Warm ambient: Honey, slow heave.

## Limitations
- The surface is a closed-form sum of waves, not a fluid simulation; the patterns are idealised.
- Reflections use a fixed light and sky rather than real environment mapping.

## 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/physics-forces/faraday-wave (MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original shader: hexagon, square and ten-fold standing-wave patterns crossfaded on an exact loop and lit as a liquid surface.

