Galaxy Generator

import { OrbitControls, useTexture } from '@react-three/drei'
import { Canvas } from '@react-three/fiber'
import { useMemo, useRef } from 'react'
import { AdditiveBlending, BufferAttribute, Color, Points } from 'three'

const Exp = () => {
  const particles = useRef<Points>(null!)
  const map = useTexture('https://safinettah.s3.eu-west-3.amazonaws.com/public/textures/4.png')

// Can't use leva for now
 const {
      size = 0.02,
      count = 10000,
      radius = 5,
      branches = 5,
      spin = 0.5,
      randomnessPower = 3, 
      insideColor = '#ff6030',
      outsideColor = '#1b3984'
    } = {}

  const [positions, colors] = useMemo(() => {
    const positions = new Float32Array(count * 3)
    const colors = new Float32Array(count * 3)

    const colorInside = new Color(insideColor)
    const colorOutside = new Color(outsideColor)

    for (let i = 0; i < count; i++) {
      const i3 = i * 3
      /**
       * Pour assigner les vertices a chaque tour de boucle
       * [1,2,3 -> 4,5,6 -> 7,8,9 ...]
       */

      const r = Math.random() * radius
      const branchAngle = ((i % branches) / branches) * Math.PI * 2 // Pi * 2 = un cercle entier
      const spinAngle = r * spin

      const randomX = Math.pow(Math.random(), randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
      const randomY = Math.pow(Math.random(), randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
      const randomZ = Math.pow(Math.random(), randomnessPower) * (Math.random() < 0.5 ? 1 : -1)

      positions[i3] = Math.cos(branchAngle + spinAngle) * r + randomX // x
      positions[i3 + 1] = randomY // y
      positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * r + randomZ // z

      // color
      const mixedColor = colorInside.clone()
      mixedColor.lerp(colorOutside, r / radius)

      colors[i3] = mixedColor.r
      colors[i3 + 1] = mixedColor.g
      colors[i3 + 2] = mixedColor.b
    }
    return [positions, colors]
  }, [count, insideColor, outsideColor, radius, branches, spin, randomnessPower])

  const attributes = useMemo(
    () => ({ position: new BufferAttribute(positions, 3), color: new BufferAttribute(colors, 3) }),
    [colors, positions]
  )

  return (
    <>
      <points ref={particles}>
        <bufferGeometry attributes={attributes}></bufferGeometry>
        <pointsMaterial
          map={map}
         //  alphaMap={map}
          blending={AdditiveBlending}
          vertexColors
          // alphaTest={0.001}
          // depthTest={false}
          depthWrite={false}
          transparent
          // color='#ff88cc'
          size={size}
          sizeAttenuation={true}
        ></pointsMaterial>
      </points>
    </>
  )
}

function GalaxyGen() {
  return (
    <Canvas
      className='full-bleed'
      style={{ height: '512px' }}
      shadows
      camera={{ far: 200, near: 0.1, position: [1, 2, 6] }}
    >
      <color args={['#000']} attach='background'></color>
      <OrbitControls makeDefault></OrbitControls>
      <ambientLight></ambientLight>
      <Exp></Exp>
    </Canvas>
  )
}

export default GalaxyGen