# Fireworks — `fireworks@1.0.0`

A fireworks show over a harbour at night: shells climb, burst into peonies, willows and rings, light the smoke and mirror in the water. Loops perfectly.

Rockets trailing sparks climb into a dark sky and burst into peonies, chrysanthemums, golden willows, rings, palms and crackling glitter. Every spark is white-hot when it is born, changes colour as it burns and cools to an ember, drawn as a trail that bends under gravity. The bursts flash the sky, light the smoke they leave and are mirrored in the water below a small harbour town, a city skyline or a ridge of pines. Choose the show (a mixed finale, peonies, willows or rings), the colours, how many shells, how wide they open, how long the trails are, how much smoke, the scenery and the mirror.

- Kind: background; status: published; digest sha256:1e0a227f2e4b933407f0a96989b6625800729065a2b756ab9c7abd4b3693e4e1
- Role: Background / effect (WebGL, full frame): a celebratory night scene for new year, festival, event and holiday content.
- Implementation: three; entry `src/fireworks.js`
- Files: https://aipixelwizard.com/registry/fireworks/1.0.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/fireworks.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/fireworks/versions/1.0.0
- Runnable demo: https://aipixelwizard.com/registry/fireworks/1.0.0/index.html (open over http; it imports sibling packages by relative path)
- Dependencies (exact): `three@0.185.1` (source) — Renderer, instanced ribbons and the bloom targets.; `apw-runtime@1.0.0` (demo) — Demo harness.

## Exports
- `createFireworks({ show?, palette?, shells?, size?, trails?, smoke?, scenery?, reflection?, seed?, aspect?, loopSeconds? }) => { scene, camera, plan, setSize(width, height), update(time, loopSeconds), dispose() }` — The whole show: a backdrop and instanced spark ribbons in one scene. Render it with its camera, ideally through createBloomPass.
- `createBloomPass(renderer, { width, height, glow?, exposure?, grain? }) => { render(scene, camera, output?), dispose() }` — A small bloom with filmic tone mapping and a fixed grain: draws a scene to the canvas with its glow.
- `planShow({ show?, palette?, shells?, size?, trails?, seed?, aspect?, loopSeconds? }) => [{ kind, launch, rise, x, y, size, sparks, colours }]` — The schedule of a show: when each shell launches, where it bursts, what kind it is and its colours.
- `PALETTES: { festival, gold, ice, sunset }` — Colour pairs: what a burst starts as and what it turns to.
- `SHOWS: { finale, peonies, willows, rings }` — The programmes: the kinds of shell, in order.
- `KINDS: ['peony', 'chrysanthemum', 'willow', 'ring', 'palm', 'crackle']` — The kinds of shell the shader draws.

## Parameters
- `show` (select one of finale | peonies | willows | rings, default "finale") — Show
- `palette` (select one of festival | gold | ice | sunset, default "festival") — Colours
- `shells` (integer 3–12, default 7) — Shells per loop
- `size` (number 0.7–1.4, default 1) — Burst size
- `trails` (number 0.5–1.6, default 1) — Trail length
- `smoke` (number 0–1.5, default 0.8) — Smoke
- `scenery` (select one of harbour | city | hills, default "harbour") — Scenery
- `reflection` (number 0–1, default 1) — Mirror in the water
- `seed` (integer 1–999, default 7) — Seed: Changes where and in which order the shells burst, their colours and the shore.

## Composition
- Inputs: Time within the loop; the show, colours, shell count, burst size, trails, smoke, scenery, mirror.
- Outputs: A full frame: the night, the shore and the water drawn by one shader, and every spark as an instanced ribbon drawn additively over it.
- Coordinates: Orthographic: x from -aspect to aspect, y from -1 to 1; the water line sits at y = -0.36 and bursts open between 0.04 and 0.52.
- Lighting: Self-lit: each burst flashes and lights the sky and its smoke in its own colour; the bloom adds the glow.
- Timing: update(time, loopSeconds) sets the time; each spark is a closed-form function of it, so frames render in any order.
- Works with: kinetic-title, number-reveal
- The sparks are not simulated: position follows x(t) = x0 + a t / k + (v0 - a / k)(1 - e^(-k t)) / k for gravity a and air drag k.
- Rockets shed their own falling sparks; bursts of every kind differ in drag, weight, life and trail so willows droop and peonies stay round.

## Output and loop
- 1080×1080, 30 fps, 12 s, procedural
- Seamless loop: yes — Every shell is scheduled round the loop and measures its own time with a modulo, so each is spent before its next launch comes round; the smoke drifts on a circle of the noise and the water ripples, the stars twinkle and the lights blink in whole cycles.
- 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, createFireworks({ aspect }) and createBloomPass(renderer, { width, height }); each frame call show.update(time, loopSeconds) then bloom.render(show.scene, show.camera).

Existing project: Copy src/fireworks.js; render show.scene with show.camera into a render target, or through the bloom pass, as an overlay of your scene.

Reuse ideas:
- New year countdown: Finale over the harbour behind a number reveal.
- Wedding or concert opener: Golden willows with a slow title.
- Festival video: New year over the city, shells set to 9.

## Limitations
- The sky, the town and the sparks are flat: the bursts are drawn face-on, not as spheres in depth.
- No sound.

## 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/objects-scenes/webgpu-fireworks (MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original closed-form show: shells scheduled round an exact loop, six kinds of burst, white-hot sparks that change colour and cool to embers, lit smoke, a mirrored harbour and three kinds of shore.

