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')
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
const r = Math.random() * radius
const branchAngle = ((i % branches) / branches) * Math.PI * 2
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
positions[i3 + 1] = randomY
positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * r + randomZ
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}
blending={AdditiveBlending}
vertexColors
depthWrite={false}
transparent
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