# A Desert in an Hourglass — `sand-hourglass@1.0.0`

Falling grains build a miniature dune country inside a brass hourglass: a sun and three camels walk the ridge, then a warm wind unthreads the caravan back into sand. Loops.

A brass-framed hourglass on a black-and-gold sand table. As the grains fall they pile into dunes in the lower bulb and a sun rises above them; three camels walk the ridge in a caravan. Then a warm wind lifts the grains, the caravan unthreads back into sand, and the sand returns to the upper bulb, so the 8 seconds loop. Individual grains, dune hatching and the camel silhouettes are all drawn in the shader. The film has no settings.

- Kind: background; status: published; digest sha256:cc1db86cfa5976e1cf33aac3de41c5ee80a579463bc8034b41c58c94f28e86ce
- Role: Shader film (three.js): Sand animation, a finished 8-second portrait film with no settings.
- Implementation: three; entry `src/sand-hourglass.js`
- Files: https://aipixelwizard.com/registry/sand-hourglass/1.0.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/sand-hourglass.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/sand-hourglass/versions/1.0.0
- Runnable demo: https://aipixelwizard.com/registry/sand-hourglass/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
- `createSandHourglass() => { scene, camera, setSize(width, height), update(time), dispose() }` — The film as one full-screen shader; render its scene with its camera straight to the canvas.

## Composition
- Inputs: The time in seconds, 0 to 8. The film has no other settings.
- Outputs: An opaque full-frame picture, already in display colours: render it straight to the canvas.
- Coordinates: Composed for a 4:5 portrait frame and measured by the frame height: in a wider frame the picture stays centred at full height and its background fills the sides; in a narrower one, such as 9:16, the sides are cropped.
- Lighting: A warm glow from the sun inside the glass, on a black sand-table ground.
- Timing: Grains fall and pile into dunes, a sun rises and three camels walk the ridge, then a wind unthreads the caravan back into sand.
- Works with: —
- The hourglass is a true twin-bulb silhouette with a brass frame.
- Grains falling and returning are individual points, not a texture.
- Every pixel is a function of the time alone, so frames can be rendered in any order.

## Output and loop
- 1080×1350, 30 fps, 8 s, procedural
- Seamless loop: yes — Every part of the film is a function of the time modulo its length, and every motion completes whole cycles, so the last frame meets the first.
- Verified 2026-10-10 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 on a canvas (no antialiasing), call createSandHourglass() once and film.setSize(width, height); then for each frame call film.update(timeInSeconds) and renderer.render(film.scene, film.camera).

Existing project: Copy src/sand-hourglass.js, which needs only three. Render film.scene with film.camera into your own canvas or render target; the output is opaque and already in display colours, so use no tone mapping or colour conversion.

Reuse ideas:
- Time-passing b-roll: the hourglass runs once per loop, which suits a "time is running out" beat.
- Seamless loop: the sand returns to the top, so it repeats for any length.
- Travel promo: the caravan on the dune ridge holds from about 3 s to 6 s.

## Limitations
- The film is finished: it has no settings. To change colours or timing, edit the shader.
- It is composed for a 4:5 portrait frame.
- Its length is fixed at 8 seconds; repeat the loop to fill a longer clip.

## License
MIT. Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.

Provenance: From the owner's collection Twenty Impossible Worlds: the original GLSL ES 3.00 shader of the film “A Desert in an Hourglass”, created with ChatGPT / Codex and used as published, wrapped for AI Pixel Wizard as a three.js full-screen shader in October 2026. The collection's synthesised soundtrack is not part of this ingredient.

