# Firefly Meadow — `firefly-meadow@1.0.0`

Fireflies blinking over a moonlit meadow of swaying grass, drifting into step once in the loop. Loops perfectly.

A summer night in a meadow: tall grass swaying in a slow wind under a bright moon, misty hills behind, and fireflies drifting through the air. Each firefly flashes on its own rhythm; once in the loop they fall into step until the whole meadow blinks together, then drift apart again. Near fireflies are big soft discs, far ones pinpoints, the grass in front hides them and the grass near a flash catches its light. Choose the glow (yellow-green, amber, aqua or green and amber), how many fireflies, how often they flash, how far they synchronise, the wind, the height of the grass, the moonlight, the mist and the brightness of the fireflies.

- Kind: background; status: published; digest sha256:b2ca4851b5a4b4c8cab8c983e83d58f9c8b4a57d1ab7fa789a4c5bb40ba83345
- Role: Background (WebGL, full frame): a calm, magical night scene for storytelling, wellness, nature and fantasy content.
- Implementation: three; entry `src/firefly-meadow.js`
- Files: https://aipixelwizard.com/registry/firefly-meadow/1.0.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/firefly-meadow.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/firefly-meadow/versions/1.0.0
- Runnable demo: https://aipixelwizard.com/registry/firefly-meadow/1.0.0/index.html (open over http; it imports sibling packages by relative path)
- Dependencies (exact): `three@0.185.1` (source) — Renderer, instanced grass and fireflies, and the bloom targets.; `apw-runtime@1.0.0` (demo) — Demo harness.

## Exports
- `createFireflyMeadow({ palette?, fireflies?, flashes?, sync?, wind?, grass?, moon?, mist?, glow?, seed?, aspect? }) => { scene, camera, setSize(width, height), update(time, loopSeconds), dispose() }` — The whole meadow: a sky, instanced grass and instanced fireflies 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: draws a scene to the canvas with its glow.
- `PALETTES: { classic, amber, aqua, mixed }` — The glow of the fireflies.

## Parameters
- `palette` (select one of classic | amber | aqua | mixed, default "classic") — Glow
- `fireflies` (integer 10–200, default 90) — Fireflies
- `flashes` (integer 3–9, default 5) — Flashes per loop
- `sync` (number 0–1, default 0.8) — Falling into step: How far the fireflies synchronise in the middle of the loop.
- `wind` (number 0–1.6, default 1) — Wind
- `grass` (number 0.6–1.5, default 1) — Grass height
- `moon` (number 0.3–1.6, default 1) — Moonlight
- `mist` (number 0–1.6, default 1) — Mist
- `glow` (number 0.5–1.6, default 1) — Firefly brightness
- `seed` (integer 1–999, default 8) — Seed

## Composition
- Inputs: Time within the loop; the glow, number and rhythm of the fireflies, how far they synchronise, wind, grass height, moonlight, mist.
- Outputs: A full frame: a sky and hills drawn by a shader, 16,000 blades of grass and the fireflies as instanced geometry positioned in the vertex shader.
- Coordinates: Perspective, 46° field of view; the camera stands 1 unit above the grass 4.2 from the origin; grass fills x ±2 to ±12, z +2.3 to -16; fireflies roam z +3 to -11 and up to 2.6 high.
- Lighting: Self-lit fireflies; the grass is lit by a moon and, with an inverse-square falloff, by twelve of the fireflies.
- Timing: update(time, loopSeconds) sets the loop time; every position and brightness is a closed-form function of it, so frames render in any order.
- Works with: kinetic-title, number-reveal
- A firefly flashes with phase = flashes × t + offset × (1 − s(t)), where s rises from 0 at the loop start to the Falling-into-step amount in the middle and falls back: the offsets are all gone when s = 1 and the meadow flashes as one.
- The grass hides the fireflies behind it (the fireflies are depth-tested, not written to the depth buffer).

## Output and loop
- 1080×1080, 30 fps, 12 s, procedural
- Seamless loop: yes — The grass is bent by waves that travel a whole number of cycles per loop; each firefly follows a Lissajous path of whole numbers of cycles and flashes a whole number of times per loop, with a phase offset that fades to zero at the loop's middle and returns; the stars twinkle in whole cycles and the camera sways in 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, createFireflyMeadow({ aspect }) and createBloomPass(renderer, { width, height }); call meadow.setSize(width, height), then each frame meadow.update(time, loopSeconds) and bloom.render(meadow.scene, meadow.camera).

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

Reuse ideas:
- Sleep or meditation loop: Summer night.
- Fantasy or children's story: Aqua glow behind a title.
- A moment of wonder: Synchrony, with the title appearing at the flash in the middle of the loop.

## Limitations
- The grass is shaded blades with no texture or variation in colour beyond a little hue; flowers and insects are not drawn.
- Only twelve of the fireflies light the grass.

## 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/nature-organic/firefly-meadow (with webgpu-firefly-sync, MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original scene: grass and fireflies solved in closed form in vertex shaders, flashes that fall into step once a loop, a moonlit sky with hills and mist, an exact loop and the frame/time contract.

