Galaxy Generator

Procedural spiral galaxy with customizable arms and particle distribution.

What this code does

- Spiral Structure: mathematical generation of galaxy arms with configurable parameters.
- 50,000 Stars: massive particle system for realistic stellar density.
- Color Gradient: stars transition from hot core colors to cool outer rim colors.
- Spiral Mathematics: branch angle and spin factor create authentic spiral patterns.
- Randomness Control: adjust star scattering and clustering for natural distribution.
- Galaxy Presets: Milky Way, Andromeda, and Pinwheel galaxy configurations.

JavaScript (plain)

const scene = new THREE.Scene()
scene.background = new THREE.Color(0x000008)
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 150)
camera.position.set(0, 14, 34)
camera.lookAt(0, 0, 0)
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(width, height)

document.querySelector('#app').appendChild(renderer.domElement)

// Galaxy generation
const galaxyGeometry = new THREE.BufferGeometry()
const count = 50000
const positions = new Float32Array(count * 3)
const colors = new Float32Array(count * 3)

const colorInside = new THREE.Color(0xff6030)
const colorOutside = new THREE.Color(0x1b3984)

for (let i = 0; i < count; i++) {
  const i3 = i * 3
  const radius = Math.random() * 15
  const spinAngle = radius * 1.2
  const branchAngle = (i % 4) / 4 * Math.PI * 2

  positions[i3] = Math.cos(branchAngle + spinAngle) * radius
  positions[i3 + 1] = 0
  positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * radius

  const mixedColor = colorInside.clone()
  mixedColor.lerp(colorOutside, radius / 15)
  colors[i3] = mixedColor.r
  colors[i3 + 1] = mixedColor.g
  colors[i3 + 2] = mixedColor.b
}

galaxyGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
galaxyGeometry.setAttribute('color', new THREE.BufferAttribute(colors, 3))

const galaxyMaterial = new THREE.PointsMaterial({
  size: 0.01,
  sizeAttenuation: true,
  depthWrite: false,
  blending: THREE.AdditiveBlending,
  vertexColors: true
})

const galaxy = new THREE.Points(galaxyGeometry, galaxyMaterial)
scene.add(galaxy)

function animate() {
  requestAnimationFrame(animate)
  galaxy.rotation.y += 0.001
  renderer.render(scene, camera)
}
animate()