Galaxy
- Generate random position particle
- dispose
- spheral galaxy
- one line
- color
- lerp
Generate random position particle
- Particle 객체 생성하려면 geometry와 material이 필요하다
- geometry는 BufferGeometry생성하고
- Material은 PointsMaterial로 생성한다.
- 그리고 이 Particle을 random위치에 생성하려면 x,y,z 값이 random으로 필요하다
- Float32Array를 count의 3배(xyz)로 만들고 geometry position에 적용해준다.
const geometry = new THREE.BufferGeometry()
const positions = new Float32Array(parameters.count * 3)
for(let i = 0; i < parameters.count; i++)
{
const i3 = i * 3
positions[i3 ] = (Math.random() - 0.5) * 3
positions[i3 + 1] = (Math.random() - 0.5) * 3
positions[i3 + 2] = (Math.random() - 0.5) * 3
}
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
const material = new THREE.PointsMaterial({
size: parameters.size,
sizeAttenuation: true,
depthWrite: false,
blending: THREE.AdditiveBlending
})
const points = new THREE.Points(geometry, material)
scene.add(points)
![](https://velog.velcdn.com/images/magpies1221/post/a9c1fbc7-85cd-406e-9689-59384ac60502/image.png)
dispose
- Three.js에서 scene에서 없앤다고해서 object를 자동적으로 처리하지 않는다.
- 그래서 수동적으로 처리해주어야한다.
geometry.dispose()
material.dispose()
scene.remove(points)
spheral galaxy
- one line
- branch
- spin
- randomness
one line
- 우선, particle들을 한줄에 랜덤으로 세워보자
- 간단하다 x 좌표를 random * radius로 설정한다.
for(let i = 0; i < parameters.count; i++)
{
const i3 = i * 3
const radius = Math.random() * parameters.radius
positions[i3 ] = radius
positions[i3 + 1] = 0
positions[i3 + 2] = 0
}
![](https://velog.velcdn.com/images/magpies1221/post/704b31d6-30c1-4fc5-82a0-1fb2bd590a12/image.png)
branch
- 그 다음엔 한 줄로 되어있는 particle들을 여러개의 branch로 나누어보자
- branch로 사용할 변수를 index의 나머지 연산을 한다.
(branch가 3이면 0,1,2로 구성된다.)
- 이 나머지 값을 branch 개수로 나누면 0, 1/3, 2/3이 되고
- 여기에 2 PI를 곱하면 360도에서 0도, 120도, 240도로 나뉜다.
for(let i = 0; i < parameters.count; i++)
{
const i3 = i * 3
const radius = Math.random() * parameters.radius
const branchAngle = (i % parameters.branches) / parameters.branches * Math.PI * 2
positions[i3 ] = Math.cos(branchAngle) * radius
positions[i3 + 1] = 0
positions[i3 + 2] = Math.sin(branchAngle) * radius
}
![](https://velog.velcdn.com/images/magpies1221/post/67ad9076-b69f-4afc-9af3-5c3aeb3d3c96/image.png)
spin
- 다음으로, 각가의 branch들의 particle들이 나선형을 이루도록 한다.
- 멀어질 수록 더 spin되어야하므로 spin 값에 radius를 곱하고
- cos, sin을 활용하여 나선형 값을 구한다.
for(let i = 0; i < parameters.count; i++)
{
const i3 = i * 3
const radius = Math.random() * parameters.radius
const spinAngle = radius * parameters.spin
const branchAngle = (i % parameters.branches) / parameters.branches * Math.PI * 2
positions[i3 ] = Math.cos(branchAngle + spinAngle) * radius
positions[i3 + 1] = 0
positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * radius
}
![](https://velog.velcdn.com/images/magpies1221/post/8850d564-0847-4146-a8d3-d9e42ee0cbfa/image.png)
randomness
- 마지막으로 나뉘어진 branch들의 particle들에게 무작위 변수를 부여하여 조금 흩어지도록 설정한다.
- spin과 마찬가지로 randomness도 원점으로부터 멀어질 수록 심해져야하므로, radius * randomness로 한다.
for(let i = 0; i < parameters.count; i++)
{
const i3 = i * 3
const radius = Math.random() * parameters.radius
const spinAngle = radius * parameters.spin
const branchAngle = (i % parameters.branches) / parameters.branches * Math.PI * 2
const randomX = (Math.random() - 0.5) * parameters.randomness * radius
const randomY = (Math.random() - 0.5) * parameters.randomness * radius
const randomZ = (Math.random() - 0.5) * parameters.randomness * radius
positions[i3 ] = Math.cos(branchAngle + spinAngle) * radius + randomX
positions[i3 + 1] = randomY
positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * radius + randomZ
}
![](https://velog.velcdn.com/images/magpies1221/post/d3e7205b-77b6-4f62-8e17-537350cda6ef/image.png)
- 그러나 아직 패턴을 눈으로 볼 수 있다.
- random 정도를 더 증가시키기 위해서 power 함수를 사용한다.
const randomX = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : - 1) * parameters.randomness * radius
const randomY = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : - 1) * parameters.randomness * radius
const randomZ = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : - 1) * parameters.randomness * radius
![](https://velog.velcdn.com/images/magpies1221/post/ed8b6978-fa36-4de3-a381-5afa696e2e9d/image.png)
color
- inner color와 outer color를 구분하여서 원점과 가장자리의 색이 점차 달라지게 하였다.
- color를 사용하기 위해서 pointMaterial의 vertexColor를 true로 설정한다.
- 중간에 있는 particle의 색상은 중간이 되어야하기 때문에 color.lerp 함수를 활용한다.
- lerp 함수는 (color, value)로 구성되어있다. value는 0~1 사이 값이다.
const colorInside = new THREE.Color(parameters.insideColor)
const colorOutside = new THREE.Color(parameters.outsideColor)
const mixedColor = colorInside.clone()
mixedColor.lerp(colorOutside, radius / parameters.radius)
colors[i3 ] = mixedColor.r
colors[i3 + 1] = mixedColor.g
colors[i3 + 2] = mixedColor.b
https://18-galaxy-hwangsangjins-projects.vercel.app/