Geometry는 여러가지가 존재하는데 각 자세한 내용들은 Three.js의 공식 홈페이지를 참고하고 지금은 Geometry을 어떤식으로 사용할 수 있는지 확인해보자!
Geometry에는 세그먼트라는 개념이 있는데 이는 나누는 것을 의미한다. 세그먼트를 기본, 2개, 16개로 나누어 적용해보면 아래처럼 표시가 된다.
const geometry = new THREE.BoxGeometry(1, 1, 1); // 기본
const geometry = new THREE.BoxGeometry(1, 1, 1, 2, 2, 2); // 2개
const geometry = new THREE.BoxGeometry(1, 1, 1, 16, 16, 16); // 16개
그럼 세그먼트를 왜 나눌까?
세그먼트를 나눈다는 것 자체가 좌표를 추가한다는 의미이다. 따라서 이 좌표들을 수정하면 멋진 효과를 줄 수 있다.
태양이 이글거린다던지, 바다가 출렁거리는 것 같은 효과!
아래 실습을 통해서 태양이 이글거리는 효과를 적용해보자.
오렌지 색상의 원을 추가한다. 그리고 flatshading 옵션을 true로 활성화해서 폴리곤 효과를 적용해준다.
const geometry = new THREE.SphereGeometry(5, 64, 64);
const material = new THREE.MeshStandardMaterial({
color: "orangered",
side: THREE.DoubleSide,
flatShading: true,
});
세그먼트들을 콘솔로 찍어보면 아래처럼 좌표값을 얻을 수 있는데 3개가 x,y,z를 이루는 하나의 점이라고 생각하면된다.
위의 점들을 변경해주면 아래와 같은 결과 값을 얻을 수 있게된다.
const positionArray = geometry.attributes.position.array;
for (let i = 0; i < positionArray.length; i += 3) {
positionArray[i] += (Math.random() - 0.5) * 0.2;
positionArray[i + 1] += (Math.random() - 0.5) * 0.2;
positionArray[i + 2] += (Math.random() - 0.5) * 0.2;
}
이제 이글거리는 효과를 주기 위해서 sin 또는 cos의 삼각함수를 적용해주면 x값은 각도를 의미하고 y는 값을 의미하기 때문에 커지고 작아지는 효과를 줄 수 있다. 따라서 이글거리는 효과를 적용해 줄 수 있는데 초기의 랜덤값을 지정해주고 시간이 지남에 따라 값을 변경해주면 된다.
const positionArray = geometry.attributes.position.array;
// 초기 랜덤값을 지정해주고 그 값을 변화시킴
const randomArray = [];
for (let i = 0; i < positionArray.length; i += 3) {
positionArray[i] += (Math.random() - 0.5) * 0.2;
positionArray[i + 1] += (Math.random() - 0.5) * 0.2;
positionArray[i + 2] += (Math.random() - 0.5) * 0.2;
randomArray[i] = (Math.random() - 0.5) * 0.2;
randomArray[i + 1] = (Math.random() - 0.5) * 0.2;
randomArray[i + 2] = (Math.random() - 0.5) * 0.2;
}
// 그리기
const clock = new THREE.Clock();
function draw() {
const time = clock.getElapsedTime() * 3;
// 여기서는 변하는 함수를 넣어줘야함 따라서 삼각함수인 sin, cos 그래프를 넣어줄거임
for (let i = 0; i < positionArray.length; i += 3) {
positionArray[i] += Math.sin(time + randomArray[i] * 100) * 0.001;
positionArray[i + 1] += Math.sin(time + randomArray[i + 1] * 100) * 0.001;
positionArray[i + 2] += Math.sin(time + randomArray[i + 2] * 100) * 0.001;
}
geometry.attributes.position.needsUpdate = true;
renderer.render(scene, camera);
renderer.setAnimationLoop(draw);
}