22sook00 logo
SookDev
🪐

Three.js 큐브 애니메이션

tag
3d
date
Jan 23, 2024

01_정적인 큐브 애니메이션

notion image
하나의 정적인 큐브가 카메라에 담겨있다.
정적큐브에 애니메이션 효과를 주기 위해 여러개의 정적인 큐브를 시간의 흐름에따라 여러장을 찍은 다음 하나로 모아 붙이는 개념을 사용하여 보여주도록 할것이다.
즉, 애니메이션은 연속된 정적인 사진 여러장의 모음 이라고 볼 수 있다.
큐브를 살짝 회전시키고 렌더메소드를 호출하는 행위를 짧은시간 내 반복하고 여러장 이어붙이면 된다.
이를 브라우저에서 제공하는 window.requrestAnimationFrame() 함수를 이용한다.
브라우저에게 애니메이션 프레임(각각의 사진 한장한장)을 요청하는 함수이다.
해당 프레임을 FPS 단위로 표현하는데, 일반적으로 브라우저는 60 FPS 를 지원하고 있다.
예를들어 60 FPS 라고 한다면 1초에 총 60장의 정지된 사진을 렌더할 수 있다는 뜻이다.
window.requestAnimationFrame(callback)
 
Three.js 에서 rotation 은 우리가 흔히 아는 도(deg)단위가 아닌, 라디얀 단위이기 때문에 각도로 변환해주는
MathUtils.degToRad() 라는 함수를 이용할 수 있다.
function render() { //큐브를 회전시키는 코드 cube.rotation.x = 45 //45도가 아닌, 45 라디얀 만큼 움직인다. (3.14) cube.rotation.x = THREE.MathUtils.degToRad(45) ... }
하지만 60 FPS 를 지원하지 않는 브라우저의 경우 애니메이션의 재생속도에는 차이가 날 수 밖에 없다.
이럴경우 Date.now() 내장메소드와 Three.js의 Clock()메소드를 통해 해결할 수 있다.
//큐브를 회전시키는 여러가지방법 cube.rotation.x = 45 //45도가 아닌, 45 라디얀 만큼 움직인다. (3.14) cube.rotation.x += 0.01; cube.position.y = Math.sin(cube.rotation.x); //1 to -1 cube.scale.x = Math.cos(cube.rotation.x); cube.rotation.x = Date.now() / 1000; //Date.now 는 밀리세컨 단위기 때문에 나누기 1000을 해주어 속도를 조절할 수 있다. cube.rotation.x = clock.getElapsedTime(); //인스턴스가 생성된 시점으로부터 경과한 시간을 초단위로 반환한다. cube.rotation.x += clock.getDelta(); //회전하는 값을 더해주는 형태로 사용가능하다.

02_OrbitControls

카메라가 대상 물체의 주변을 궤도를 돌듯이 빙빙 돌 수 있도록 만들어주는 컨트롤
addOn 과 같은 기능이기때문에 THREE 인스턴스가 아닌 import 하여 별도로 가져와야 한다.
마우스를 드래그 할때마다 카메라가 물체 주변을 돌며 관찰한다.
이때 매쉬가 움직인다고 착각할 수 있지만 카메라가 움직이는것이다.
이해를 돕기 위해 THREE.AxesHelper 메소드를 사용하여 축을 관찰할 수 있다.
사진에서 보이는것처럼 빨간색은 x축, 연두색은 y축, 파란색은 z축 이다.
만약 카메라가 아닌 Mesh 가 움직이는 거라면 같은방향을 유지해야 하지만 드래그할때마다 변한다.
//orbit control const controls = new OrbitControls(camera, renderer.domElement); const axesHelper = new THREE.AxesHelper(5); scene.add(axesHelper);
notion image
notion image

03_GUI controll pannel 속성 추가

생산성 향상을 위한 GUI, lil-gui
속성 하나씩 바꾸기 위해 일일히 코드를 수정하는것은 매우 번거롭다.
이를 해결하고 더 나은 생산성을 위해 GUI 를 추가할 수 있다.
npm i lil-gui

add()

import GUI from "lil-gui"; //GUI controll const gui = new GUI(); gui.add(cube.position, "y", -3, 3, 0.1); //위치,좌표,최소,최대,움직이는범위
한꺼번에 사용도 가능하지만 가독성을 위해 체이닝 형태로 사용가능하다
gui .add(cube.position, "y") .min(-3) .max(3) .step(0.1)
visible
내가 지정한 값을 보이거나 안보이도록 설정 가능한 옵션디아.
gui.add(cube, "visible");

addColor()

addColor 는 16진수만 인식이 가능하기 때문에 디폴트값을 설정하여 변형작업을 거치는것이 좋다.