# Hypnotic Spiral — `hypnotic-spiral@1.0.0`

A tunnel of spiralling colour bands rushing inwards with glowing edges and cycling colours. Loops perfectly.

A tunnel of spiralling bands that pulls the eye down into the centre. The arms of the spiral sweep round, the bands race inwards in perspective and the colours cycle through a ramp while a glowing edge rides each arm. The swirl, the rush and the colour cycle each complete whole turns per loop. Choose the number of arms, the colours (candy, fire, ocean or mono), the swirl, the rush, the colour cycle, the twist of the tunnel and the ring density.

- Kind: background; status: published; digest sha256:7e58a6f908e2d2c3ecb018c4b811fd7407fde02d49f6fbef4073f9f8bcafeca0
- Role: Shader background (three.js): a hypnotic, high-energy tunnel for music, party and attention-grabbing content.
- Implementation: three; entry `src/hypnotic-spiral.js`
- Files: https://aipixelwizard.com/registry/hypnotic-spiral/1.0.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/hypnotic-spiral.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/hypnotic-spiral/versions/1.0.0
- Runnable demo: https://aipixelwizard.com/registry/hypnotic-spiral/1.0.0/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
- `createHypnoticSpiral({ arms?, palette?, swirl?, rush?, cycle?, depth?, bands? }) => { scene, camera, setSize(width, height), update(time, loopSeconds), dispose() }` — The tunnel 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.
- `PALETTES: { candy, fire, ocean, mono }` — Four-colour ramps cycled round the bands.

## Parameters
- `arms` (integer 2–12, default 5) — Arms
- `palette` (select one of candy | fire | ocean | mono, default "candy") — Colours
- `swirl` (integer -3–3, default 1) — Swirl: Whole turns of the swirl per loop; negative reverses it.
- `rush` (integer 1–6, default 3) — Rush: Bands passing per loop.
- `cycle` (integer 0–3, default 1) — Colour cycle: Whole trips round the colour ramp per loop.
- `depth` (number 0.5–2, default 1) — Twist
- `bands` (number 0.5–2, default 1) — Ring density

## Composition
- Inputs: Time within the loop; the arms, colours, swirl, rush, colour cycle, twist and ring density.
- Outputs: A full-frame shader image through a bloom pass.
- Coordinates: Screen-centred, ±1 vertically; the tunnel's axis points into the screen at the centre; distance down it is 0.35 / radius.
- Lighting: Self-lit; the bloom gives the glow.
- Timing: update(time, loopSeconds) sets the loop phase; frames render in any order.
- Works with: kinetic-title, number-reveal
- Colour is a smooth function of position within each band, so it has no tile index that could jump at the loop.

## Output and loop
- 1080×1080, 30 fps, 12 s, procedural
- Seamless loop: yes — The swirl, the rush and the colour cycle are whole numbers of turns per loop and the arms count is whole, 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, createHypnoticSpiral() and createBloomPass(renderer, { width, height }); call spiral.setSize(w, h) and each frame spiral.update(time, loopSeconds) then bloom.render(spiral.scene, spiral.camera).

Existing project: Copy src/hypnotic-spiral.js and render spiral.scene with spiral.camera into your own target.

Reuse ideas:
- Music visual: Candy, five arms.
- Dramatic transition: Fire, reverse swirl.
- Calmer: Ocean, many arms.

## Limitations
- Strobing patterns of this kind can be uncomfortable for some viewers; keep the rush low for sensitive audiences.
- The centre is darkened rather than resolving into a point.

## 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/shaders-backgrounds/hypnotic-spiral (MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original shader: twisted perspective bands with whole-turn swirl, rush and colour cycle on an exact loop.

