# Jellyfish — `jellyfish@1.0.0`

Bioluminescent jellyfish pulsing and drifting through deep water, their tentacles trailing beads of light, shafts of light far above. Loops perfectly.

Translucent jellyfish with scalloped bells ribbed by radial canals and a glowing ring inside, pulsing in sharp squeezes and long rests, long tentacles with waves running down them and beads of light travelling along, frilly oral arms, marine snow falling through the water and shafts of light from far above. They drift on slow loops at different depths, the nearer ones bigger and brighter, the far ones fading into the blue, while the camera sways a little. Choose the colours (deep blue, violet, aqua, warm or a mix), how many jellyfish, their size, how fast they pulse, how many tentacles, the marine snow, the light from above and the glow.

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

## Exports
- `createJellyfish({ palette?, count?, size?, pulse?, tentacles?, snow?, shafts?, glow?, seed?, aspect? }) => { scene, camera, swarm, setSize(width, height), update(time, loopSeconds), dispose() }` — The whole sea: bells, tentacles, marine snow and the water 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.
- `planSwarm({ count?, size?, pulse?, palette?, seed?, aspect? }) => [{ position, scale, pulses, phase, tilt, orbit, seed, palette }]` — Where each jellyfish drifts and how it pulses.
- `PALETTES: { blue, violet, aqua, warm }` — Colours of a jellyfish: its body, its glow and its rim light.

## Parameters
- `palette` (select one of blue | violet | aqua | warm | mixed, default "blue") — Colours
- `count` (integer 1–8, default 5) — Jellyfish
- `size` (number 0.7–1.4, default 1) — Size
- `pulse` (integer 3–9, default 6) — Pulses per loop
- `tentacles` (integer 6–28, default 16) — Tentacles
- `snow` (number 0–1.5, default 1) — Marine snow
- `shafts` (number 0–1.5, default 1) — Light from above
- `glow` (number 0.6–1.6, default 1) — Glow
- `seed` (integer 1–999, default 6) — Seed

## Composition
- Inputs: Time within the loop; the colours, number and size of jellyfish, pulse rate, tentacles, snow, light shafts and glow.
- Outputs: A full frame: a backdrop of water and light, then bells, tentacles and marine snow drawn additively.
- Coordinates: Perspective, 38° field of view, the camera 7.5 units from the origin; the jellyfish drift between z = -4.5 and z = 0.5.
- Lighting: Self-lit: every surface glows (a rim light that grows with the angle, canals, a ring of organs); distance dims them into the blue.
- Timing: update(time, loopSeconds) sets the loop time; every position is a closed-form function of it, so frames render in any order.
- Works with: kinetic-title, number-reveal
- The bell is a surface of revolution drawn in the vertex shader from a grid of (down the dome, round it), outside and in, squeezed by a contraction pow(0.5 + 0.5 sin φ, 2.4): sharp, then a long rest.
- Tentacles are ribbons of 26 pieces of constant pixel width, thinner at the tip; beads of light are bumps that run down them.

## Output and loop
- 1080×1080, 30 fps, 12 s, procedural
- Seamless loop: yes — Every jellyfish pulses a whole number of times per loop; the waves in the tentacles and the beads of light run a whole number of times down them; each jellyfish drifts on a loop of one cycle; the marine snow is a field that repeats every slab and falls one slab per loop; 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, createJellyfish({ aspect }) and createBloomPass(renderer, { width, height }); call sea.setSize(width, height), then each frame sea.update(time, loopSeconds) and bloom.render(sea.scene, sea.camera).

Existing project: Copy src/jellyfish.js; render sea.scene with sea.camera into a render target (or through the bloom pass) as a backdrop or an overlay.

Reuse ideas:
- Sleep or meditation loop: Deep blue drift, slow.
- Ocean documentary title: Rainbow swarm with a kinetic title.
- Fantasy scene: Warm abyss.

## Limitations
- Everything is drawn additively, so the jellyfish are all glow with no solid body; they cannot pass in front of a bright background.
- The bells are shells with no internal organs other than a ring and canals.

## 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/bioluminescent-jellyfish (with webgpu-jellyfish-bloom, MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original scene: a bell drawn from a surface of revolution in the vertex shader, pixel-width tentacle ribbons with travelling waves and beads of light, marine snow, shafts of light, an exact loop and the frame/time contract.

