Three.js Galaxy Spiral — Procedural WebGL Spiral Galaxy Particles

Three.js Galaxy Spiral · Animations · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Radius-driven spiral formula: spin angle grows with distance from center, the mathematical basis of a logarithmic spiral
Power-curve density distribution: particles concentrate near the core, matching real galaxy density
Radius-scaled randomness: scatter shrinks toward the outer edge for crisp arms and a fuzzy, bright core
Radius-driven color gradient: warm inner color blends to a cool outer color via THREE.Color.lerp()
Differential rotation: inner particles orbit faster than outer ones, avoiding a rigid-disc look
Additive blending: overlapping particles brighten together instead of occluding one another
OrbitControls with auto-rotate: damped drag-to-inspect with idle rotation when not in use
Fully procedural: no textures, models, or external datasets — every particle is generated from formulas

About this UI Snippet

How to Build a Procedural Three.js Spiral Galaxy

Screenshot of the Three.js Galaxy Spiral snippet rendered live

The Three.js Galaxy Spiral snippet procedurally generates 12,000 particles into a convincing spiral-galaxy shape — dense glowing core, four sweeping arms, warm-to-cool color gradient — using nothing but a radius-driven spin formula and additive blending, with core Three.js and OrbitControls loaded from a CDN.

The entire spiral shape comes from one line: spin angle grows with radius

The defining formula of this snippet is deceptively simple: each particle's final angle around the center is armAngle + radius * SPIN. Because particles further from the core have a larger radius, they've been rotated further around their arm than particles close in — and that difference in rotation-per-radius is the *entire* mathematical definition of a logarithmic spiral. Multiple arms come from assigning each particle to one of ARMS evenly-spaced starting angles via (i % ARMS) / ARMS, so the same spin formula, applied to four different starting angles, produces four parallel spiral arms rather than one.

A power-curve radius distribution, not a uniform one

Radius is sampled as Math.random() ** 1.6 * RADIUS rather than plain Math.random() * RADIUS. Raising a 0–1 random value to a power greater than 1 biases the result toward zero — concentrating far more particles near the galactic core and thinning them out toward the edge, matching how real galaxies are visibly denser at the center. A plain linear distribution would produce an unrealistic, evenly-spread disc instead.

Randomness that shrinks toward the edges

Each particle gets a small random X/Y/Z jitter added on top of its ideal spiral position, but that jitter's magnitude is itself scaled by (1 - r/RADIUS) — particles near the core get more scatter, particles near the outer edge get almost none. This produces a galaxy that looks appropriately "fuzzy" and turbulent near its bright center while its outer arms stay crisp and well-defined, rather than uniform noise applied everywhere.

Color mixed by radius, not randomly assigned

Every particle's color is a linear interpolation between a warm inner color and a cooler outer color, using radius / RADIUS as the mix factor via THREE.Color.lerp(). Because that same radius value also drives the spiral math, color and shape share one underlying number — exactly the same principle used in the particle wave snippet's height-to-color link, applied here to radial position instead of elevation.

Differential rotation: inner particles orbit faster than outer ones

Real galaxies don't rotate as a rigid disc — stars closer to the center complete an orbit much faster than stars near the edge. The animation loop gives each particle a rotation speed of 1 / (0.3 + radius), so particles near the core visibly race around while outer-arm particles drift slowly, which is what keeps the spiral arms from ever looking like they're rigidly spinning in lockstep.

Additive blending makes overlapping particles glow

The PointsMaterial uses THREE.AdditiveBlending, which sums overlapping particle colors instead of one drawing over another. Wherever many particles cluster densely — especially near the bright core — their colors add together into a genuinely brighter glow, rather than the topmost particle simply hiding the ones behind it.

Where this generation technique applies

The radius-driven-angle-plus-power-curve-density formula generalizes to any spiral or vortex shape — hurricane visualizations, whirlpool effects, or abstract vortex loaders. Pair it with a starfield warp for a "traveling toward a galaxy" scroll sequence, or contrast its particle-based density against the smooth, continuous surface of the morphing blob.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not have to reverse-engineer the spiral-galaxy math by staring at the formulas alone. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why raising a random value to a power biases particle density toward the core, or how the differential rotation speed formula keeps inner and outer particles from spinning in rigid lockstep. The same assistant can help optimize it, for instance checking whether the per-particle position rewrite in the animation loop could be restructured to avoid the redundant angle recomputation, or whether particle count could scale down automatically on lower-end GPUs. It is also useful for extending the effect: ask it to add a second, counter-rotating galaxy for a colliding-galaxies visual, tie the color gradient to a different property like particle speed instead of radius, or add a subtle bulge by lifting particles near the core slightly along the Y axis. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a procedural "spiral galaxy" in plain HTML, CSS, and JavaScript using Three.js and its OrbitControls addon, both loaded from a CDN (no bundler, no build step, no external textures or datasets).

Requirements:
- A full-viewport canvas with a WebGLRenderer sized to match it, updated on window resize including camera aspect ratio, plus OrbitControls with damping and idle auto-rotation enabled.
- Generate at least 10,000 particles procedurally. For each particle: sample a radius using a random value raised to a power greater than 1 (so density concentrates toward the center rather than being uniform), assign it to one of several evenly-spaced "arm" starting angles using its index modulo the arm count, and compute its final angle as that arm's starting angle plus the radius multiplied by a spin constant — so particles further from the center are rotated further around, forming a logarithmic spiral.
- Add a small random position offset to each particle, scaled down as radius approaches the maximum radius, so scatter is more pronounced near the core and minimal near the outer edge.
- Color each particle by linearly interpolating between a warm inner color and a cooler outer color based on that particle's radius divided by the maximum radius, using the color interpolation method on Three.js's color class.
- Render all particles as a single THREE.Points object with vertex colors enabled and additive blending, so overlapping particles in dense regions brighten together rather than occluding each other.
- Every animation frame, rotate each particle around the center at a speed inversely related to its radius (smaller radius means faster rotation), so the galaxy exhibits differential rotation rather than spinning as one rigid disc.
- Add a small glowing sphere at the center representing the galactic core, with a subtle pulsing scale animation.

Step by step

How to Use

  1. 1
    Load both CDN scriptsAdd three.min.js and OrbitControls.js from the CDN panel, in that order.
  2. 2
    Paste HTML, CSS, and JSA 12,000-particle spiral galaxy appears immediately, slowly rotating.
  3. 3
    Drag to orbit, scroll to zoomManually inspect the galaxy from any angle; release to resume auto-rotation.
  4. 4
    Adjust arm count and spinChange ARMS and SPIN to produce tighter, looser, or more numerous spiral arms.
  5. 5
    Retint the galaxyEdit INSIDE_COLOR and OUTSIDE_COLOR for a different core-to-edge color gradient.
  6. 6
    Resize the windowRenderer size and camera aspect ratio update automatically.

Real-world uses

Common Use Cases

Space and astronomy education sites
A procedurally accurate spiral galaxy is a strong, explorable centerpiece for science and education content.
Music, event, and festival sites
A glowing, rotating galaxy suits ambient, electronic, or cosmic visual branding far better than a static image.
Teaching procedural generation
A complete, focused example of building complex organic shapes from simple formulas rather than authored data.
Portfolio and agency showpieces
Demonstrates both procedural generation skill and WebGL particle performance in one striking visual.
Game menu and loading backgrounds
A slowly rotating, explorable galaxy gives a loading or title screen a genuinely premium feel.
Sci-fi and space-travel narratives
Pair with a starfield warp intro so visitors "arrive" at the galaxy after scrolling through hyperspace.

Got questions?

Frequently Asked Questions

Every particle's final angle is its starting arm angle plus its radius multiplied by a spin constant. Because particles further from the center have a larger radius, that formula rotates them further around — the defining property of a logarithmic spiral. Assigning particles to several evenly-spaced starting arm angles turns one spiral formula into several parallel arms.

Raising a 0-1 random value to a power greater than 1 (1.6 in this snippet) skews the result toward zero, so far more particles land near the galactic core than near the edge — matching how real spiral galaxies are visibly denser at their center. Sampling radius with plain Math.random() would instead produce an unrealistic, evenly-spread disc of particles.

Each particle's random position jitter is multiplied by (1 - radius/RADIUS), which is close to 1 near the core and close to 0 near the outer edge. This produces a galaxy that looks appropriately turbulent and fuzzy near its bright center while its outer spiral arms stay crisp and well-defined.

Real spiral galaxies exhibit differential rotation — stars closer to the center complete an orbit much faster than stars further out. The animation loop gives each particle a rotation speed of 1 divided by (a small constant plus its radius), so smaller radii produce visibly faster rotation, which keeps the arms from looking like a single rigid, uniformly-spinning disc.

THREE.AdditiveBlending sums the colors of overlapping particles instead of the frontmost particle simply hiding the ones behind it. In densely packed regions — especially near the bright core — many overlapping particles' colors add together into a genuinely brighter glow, which is what gives the core its luminous look.

Yes. Click JSX for a React component, Vue for a Vue 3 SFC, Angular for a standalone component, or Tailwind for a React + Tailwind CSS utility-class version. Build the particle buffers and controls inside a mount effect so the generation formula only runs once, and call controls.dispose() plus renderer.dispose() on cleanup.