# Particle Galaxy — `particle-galaxy@1.0.0`

A spiral galaxy of tens of thousands of glowing stars turning with differential rotation: the inner stars lap the outer ones. Loops perfectly.

A spiral galaxy of tens of thousands of glowing particles. Stars are scattered along logarithmic arms round a hot core, golden near the middle and blue-white in the arms, with a thin disc of haze, and the whole galaxy turns with differential rotation: the inner stars lap the outer ones, so the arms wind and unwind as it goes. Choose the number of stars, the number of arms, the colours (classic, rose, emerald or mono), how tightly the arms wind, how many laps the outer stars make per loop, the seed and whether the camera sways.

- Kind: background; status: published; digest sha256:64a097fe1b4c937368956f0f884e4dadcb51734cce24d4557a2665a7b4638c46
- Role: Scene (3D, three.js): a cosmic, high-impact space backdrop for science, music and sci-fi content.
- Implementation: three; entry `src/particle-galaxy.js`
- Files: https://aipixelwizard.com/registry/particle-galaxy/1.0.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/particle-galaxy.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/particle-galaxy/versions/1.0.0
- Runnable demo: https://aipixelwizard.com/registry/particle-galaxy/1.0.0/index.html (open over http; it imports sibling packages by relative path)
- Dependencies (exact): `three@0.185.1` (source) — Renderer, points and shader materials.; `apw-runtime@1.0.0` (demo) — Demo harness.

## Exports
- `createParticleGalaxy({ stars?, arms?, palette?, twist?, laps?, seed? }) => { group, setProgress(progress), setView(heightPx, fovDeg), dispose() }` — The galaxy as one Points object plus a core glow, about 16 across in the xz plane; call setView with the render height and field of view; render through createBloomPass.
- `createBloomPass(renderer, { width, height, glow?, exposure?, grain? }) => { render(scene, camera, output?), dispose() }` — A small bloom with an anti-aliased, depth-tested scene target.
- `PALETTES: { classic, rose, emerald, mono }` — Colours of the core, the arms' middle and their outer edge.

## Parameters
- `stars` (integer 4000–60000, default 24000) — Stars
- `arms` (integer 1–6, default 3) — Arms
- `palette` (select one of classic | rose | emerald | mono, default "classic") — Colours
- `twist` (number 0.4–2, default 1) — Arm winding
- `laps` (integer 1–3, default 1) — Outer laps per loop
- `seed` (integer 1–999, default 15) — Seed
- `orbit` (boolean, default true) — Camera sway

## Composition
- Inputs: Time within the loop; the stars, arms, colours, winding, laps, seed and camera sway.
- Outputs: A full frame rendered in 3D through an anti-aliased bloom.
- Coordinates: The galaxy lies in the xz plane centred on the origin, stars out to a radius of 8; the camera looks down at about 36° from 28 away.
- Lighting: Self-lit additive points; the bloom gives the glow.
- Timing: setProgress(progress) sets one uniform; the star positions are worked out in the vertex shader; frames render in any order.
- Works with: kinetic-title, number-reveal
- Stars are drawn as soft round points sized in the shader and tinted by their radius.

## Output and loop
- 1080×1080, 30 fps, 14 s, procedural
- Seamless loop: yes — Every star makes a whole number of laps per loop (the inner ones more), its twinkle runs whole cycles and the camera tilt is 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, createParticleGalaxy() and createBloomPass(renderer, { width, height }); call galaxy.setView(height, fov) once, then each frame galaxy.setProgress(progress) and bloom.render(scene, camera).

Existing project: Copy src/particle-galaxy.js; add galaxy.group to your scene, call setView and render through createBloomPass.

Reuse ideas:
- Space title: Classic, three arms.
- Dreamy: Rose, tight arms.
- Dense: Emerald, two arms.

## Limitations
- Star sizes are set in the shader from a scale you give with setView; change the render size and call it again.
- The stars follow circular orbits; there is no gravity simulation.

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

Provenance: Adapted from the owner's threejs-sketches/particle-systems/particle-galaxy (MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original scene: logarithmic spiral arms of shader-driven point stars with whole laps per star on a differential rotation, through a bloom, on an exact loop.

