Galaxy Generator
Loading...
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