[Three.js] 01. Hello Box - 간단한 예제로 배우는 코드 구성

juuns·2024년 1월 18일
0

Three.js

목록 보기
2/5
post-thumbnail

1. Scene Graph Components


📌 렌더러 (Renderer)

  • 렌더링 작업을 통해 이미지를 만드는 부분으로서, 대상이 되는 장면(Scene)과 카메라(Camera)로 구성
  • Three.js에서는 기본적으로 WebGL 렌더러를 사용한다.

📌 장면 (Scene)

  • 카메라(Camera), 메쉬(Mesh), 조명(Light)로 구성
  • 메쉬(Mesh)는 물체의 형상과 재질 정보를 가지고 있다.

📌 카메라 (Camera)

  • 카메라의 위치와 방위, 투사(projection) 방법 등을 정의

📌 조명 (Light)

  • 광원의 종류와 위치, 방향 등을 정의

📌 메쉬 (Mesh)

  • 물체의 모양을 정의하는 형상(Geometry)과
  • 색상 등에 대한 정보를 갖고 있는 재질(Material)을 통해서 만들어진다.

📌 형상 (Geometry)

  • 꼭짓점(Vertex)들과 이들이 모여서 만든 면(Face)으로 구성된다.

📌 재질 (Material)

  • 형상(Geometry)이 갖는 색상, 렌더링 방식 등에 대한 정보를 지정한다.
  • 텍스쳐(Texture)라 불리는 이미지(Image)로 표현

2. 기본 코드 구조 설명


Three.js로 무언가를 표현하려면, scene, camera, renderer가 필요하다. 이를 통해 카메라로 장면을 구현할 수 있다. 큐브 돌리기 예제로 설명하도록 하겠다.

2.1. Scene과 Camera 만들기

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;

📌 PerspectiveCamera

PerspecticeCamera는 원근법이 적용된 카메라로, 각 파라미터 값은 다음과 같다.

✅ 1st parameter : Field of View (FOV) (시야각)

  • FOV는 해당 시점의 화면이 보여지는 정도로 나타낸다. 값은 각도 값으로 설정한다.

✅ 2nd parameter : aspect ratio (종횡비)

  • 가로/세로
  • 대부분의 경우 요소의 높이와 너비에 맞추어 표시한다. 그렇지 않으면 이미지가 틀어져 보일 수 있다.

✅ 3rd & 4th parameter : near & far 절단면

  • far값보다 멀리 있는 요소나 near 값보다 가까이 있는 오브젝트는 렌더링 되지 않는다.
  • 지금 시점에서 이것까지 고려할 필요는 없지만, 앱 성능 향상을 위해 사용할 수 있다.

2.2. Renderer 만들기

const renderer = new THREE.WebGLRenderer({canvas: HelloCanvas}); 
renderer.setSize( h_scr, v_scr );

렌더러는 기본적으로 WebGL의 렌더러를 사용한다. 이때 주어진 파라미터는 연결된 HTML에서 id=HelloCanvas 인 canvas에 그려달라고 요청하는 것이다.

renderer 인스턴스를 생성함과 동시에, 렌더링 할 곳의 크기를 설정해줘야 한다. 여기서의 높이와 너비는 각각 브라우저 윈도우의 높이와 너비가 된다.

2.3. Mesh 만들기

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을 약간 움직여두었다.

2.4. Scene 렌더링

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 회전을 이용하는 경우가 많다.

2.5. 전체 코드

[파일명] : 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>

코드를 실행하면 회전하는 큐브를 확인할 수 있다.

참고: [SWTT] Three.js 튜토리얼

0개의 댓글