Three.js로 무언가를 표현하려면, scene, camera, renderer가 필요하다. 이를 통해 카메라로 장면을 구현할 수 있다. 큐브 돌리기 예제로 설명하도록 하겠다.
const h_scr = window.innerWidth;
const v_scr = window.innerHeight;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, h_scr/v_scr, 0.1, 1000);
camera.position.z = 5;
PerspecticeCamera는 원근법이 적용된 카메라로, 각 파라미터 값은 다음과 같다.
✅ 1st parameter : Field of View (FOV) (시야각)
✅ 2nd parameter : aspect ratio (종횡비)
✅ 3rd & 4th parameter : near & far 절단면
const renderer = new THREE.WebGLRenderer({canvas: HelloCanvas});
renderer.setSize( h_scr, v_scr );
렌더러는 기본적으로 WebGL의 렌더러를 사용한다. 이때 주어진 파라미터는 연결된 HTML에서 id=HelloCanvas 인 canvas에 그려달라고 요청하는 것이다.
renderer 인스턴스를 생성함과 동시에, 렌더링 할 곳의 크기를 설정해줘야 한다. 여기서의 높이와 너비는 각각 브라우저 윈도우의 높이와 너비가 된다.
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
Mesh를 만드려면 Geometry와 Material이 필요하다.
큐브를 만들고 싶으면 BoxGeometry, 구를 만들고 싶으면 SphereGeometry, 원뿔을 만들고 싶으면 ConeGeometry 등을 사용할 수 있다. 여기서는 큐브를 만들기 위해 BoxGeometry를 이용했으며, 여기에는 큐브에 필요한 모든 꼭짓점(vertices)와 면(faces)이 포함되어 있다.
geometry와 더불어, 큐브를 색칠해줄 요소가 필요하다. 여러가지 material이 있는데, 여기서는 가장 기본적인 단색 material인 MeshBasicMaterial을 사용해 큐브를 빨간색으로 만들어 줄 것이다.
이렇게 만들어놓은 Geometry와 Material을 이용해 새로운 Mesh를 생성할 수 있다.
생성한 큐브를 앞서 만들어둔 scene에 추가해주었다. 기본 설정상 scene.add() 로 scene에 추가된 보든 것들은 (0,0,0)의 위치를 가진다. 이렇게 되면 카메라와 오브젝트의 위치가 겹치게 될 수 있다. 따라서 위에서 카메라의 z position을 약간 움직여두었다.
const animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
렌더링하기 위해서는 render loop 또는 animate loop가 필요하다.
renderer.render( scene, camera ) 를 통해 renderer에게 이 scene을 이 camera로 그려주세요~라고 하는 것이고 requestAnimationFrame() 이라는 함수를 통해 계속해서 렌더링을 해준다. 일반적인 웹 브라우저의 경우 1/60초마다 한 번씩 무한루프처럼 렌더링된다.
여기서는 animate가 실행될 때마다 rotation의 x, y 값을 0.01씩 증가시켜주는 코드도 포함되어 있다. 이런식으로 x, y, z축으로 분리된 Rotation을 오일러 회전이라고 한다. 하지만 각 축으로 분리된 회전은 불규칙하고 이상하게 보일 수 있다. 실제로 각 축으로 같은 정도만큼 돌게 해보면 왼쪽으로 돌다 오른쪽으로 돌다 아래로 돌다 하는 것처럼 보인다. 각 축은 고정되어 있는데 3개의 방향으로 회전을 시키면 그 모션이 어디로 가는지 예측하는 것은 굉장히 어렵다. 따라서 복잡한 회전을 다룰 때에는 오일러 앵글을 이용하는 것이 아닌, quarternion 회전을 이용하는 경우가 많다.
[파일명] : 01_rotate_box.js
const h_scr = window.innerWidth;
const v_scr = window.innerHeight;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, h_scr/v_scr, 0.1, 1000);
camera.position.z = 5;
const renderer = new THREE.WebGLRenderer({canvas: HelloCanvas});
renderer.setSize( h_scr, v_scr );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
const animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
[파일명] : 01_rotate_box.html
<html>
<head>
<meta charset="utf-8">
<title>Rotating Box</title>
<style>body { margin: 0; }</style>
</head>
<body>
<script src="js/three.js"></script>
<canvas id="HelloCanvas"></canvas>
<script src="01_rotate_box.js"></script>
</body>
</html>
코드를 실행하면 회전하는 큐브를 확인할 수 있다.
