# Prism Dispersion — `prism-dispersion@1.0.0`

A white beam enters a glass prism and fans out into a rainbow, the prism turning slowly so the spectrum swings. Loops perfectly.

A beam of white light climbs out of the dark, enters a glass prism, is bent and spread into every colour from violet to red and falls across a wall. The optics are traced for real: forty wavelengths are refracted with Snell's law through glass whose index falls with wavelength, carried across the prism and refracted out again, so the spectrum has the true order and spread; as the prism turns the fan swings and, at the extreme, the violet (the most bent) is caught inside by total internal reflection and thrown out of the base as a violet beam. Dust turns in the beam. Choose the glass (crown, flint or diamond), how strongly it spreads the colours, how far the prism turns, the beam width, the haze and dust, whether there is a wall and the glow.

- Kind: background; status: published; digest sha256:a02c5cdf36fd71a4d886d3b7e4b6207542862447677d957c5f347d974ca5d084
- Role: Background (WebGL, full frame): an elegant, physical light scene for science, music, album-art and title content.
- Implementation: three; entry `src/prism-dispersion.js`
- Files: https://aipixelwizard.com/registry/prism-dispersion/1.0.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/prism-dispersion.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/prism-dispersion/versions/1.0.0
- Runnable demo: https://aipixelwizard.com/registry/prism-dispersion/1.0.0/index.html (open over http; it imports sibling packages by relative path)
- Dependencies (exact): `three@0.185.1` (source) — Renderer, the full-screen shader and the bloom targets.; `apw-runtime@1.0.0` (demo) — Demo harness.

## Exports
- `createPrism({ glass?, dispersion?, rotation?, beam?, haze?, wall?, glow?, aspect? }) => { scene, camera, material, setSize(width, height), update(time, loopSeconds), dispose() }` — The whole scene: the physics is traced in update() and drawn by one shader. Render it with its camera, ideally through createBloomPass.
- `traceSpectrum({ centre?, radius?, angle?, glass?, dispersion?, source?, beamAngle?, wallX? }) => { vertices, entry, reflected, rays }` — Traces forty wavelengths of a white beam through an equilateral prism: refraction in and out, total internal reflection, and where each colour lands on the wall.
- `wavelengthToRGB(nm) => [r, g, b]` — The colour of a wavelength in nanometres, dimmer at the ends of the visible range.
- `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.
- `GLASSES: { crown, flint, diamond }` — Cauchy coefficients (n = A + B / λ², λ in micrometres) of each glass.

## Parameters
- `glass` (select one of crown | flint | diamond, default "flint") — Glass
- `dispersion` (number 0.5–1.6, default 1.1) — Dispersion: How strongly the glass spreads the colours.
- `rotation` (number 0–1.6, default 1) — Turn: How far the prism turns to and fro.
- `beam` (number 0.6–2, default 1) — Beam width
- `haze` (number 0–1.6, default 1) — Haze and dust
- `wall` (boolean, default true) — Wall
- `glow` (number 0.5–1.6, default 1) — Glow

## Composition
- Inputs: Time within the loop; the glass, dispersion, how far the prism turns, beam width, haze, wall and glow.
- Outputs: A full frame: forty rays traced once per frame in JavaScript and drawn as soft beams by one shader on a full-screen quad.
- Coordinates: Screen space, y from -1 to 1: the prism (an equilateral triangle of circumradius 0.4) centred just above the middle, the beam entering from the lower left, the wall on the right at x = 0.86 (times the aspect when wider).
- Lighting: Self-lit: the beam, the spectrum and the glints of the glass add light; the bloom softens them.
- Timing: update(time, loopSeconds) traces the rays for that moment, so frames render in any order.
- Works with: kinetic-title, number-reveal
- Index of refraction n = A + B / λ² (Cauchy): violet is bent most, red least; the coefficients are exaggerated a little (flint, B = 0.028 µm²) so the fan is wide enough to see.
- At the extremes of the turn the violet meets the second face at more than the critical angle and is totally internally reflected out of the base.

## Output and loop
- 1080×1080, 30 fps, 12 s, procedural
- Seamless loop: yes — The prism's angle and the beam's tilt are sines of the loop phase, and the dust moves on paths of whole numbers of cycles, 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, createPrism({ aspect }) and createBloomPass(renderer, { width, height }); call prism.setSize(width, height), then each frame prism.update(time, loopSeconds) and bloom.render(prism.scene, prism.camera).

Existing project: Copy src/prism-dispersion.js; render prism.scene with prism.camera into a render target (or through the bloom pass) as the backdrop of your scene; traceSpectrum() can be used on its own.

Reuse ideas:
- Physics explainer on light and colour: Flint glass prism.
- Music or album-art style loop: Diamond fire.
- Calm presentation backdrop: Crown glass, soft haze.

## Limitations
- The scene is two-dimensional: the light travels in the plane of the frame and the prism is a triangle with no depth.
- Intensity along each ray is a simple fade; reflections other than the first face and the total internal one are not traced.

## License
MIT. Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.
- three.js 0.185.1: MIT (https://github.com/mrdoob/three.js)

Provenance: Adapted from the owner's threejs-sketches/light-atmosphere/prism-rainbow (with webgpu-rainbow-prism and light-prism, MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original scene: forty wavelengths traced with Snell's law and a Cauchy index, total internal reflection, soft beams, dust, an exact loop and the frame/time contract.

