AngelPlayer`s Diary

Three.js는 기존의 web에서 3D 객체를 띄우기 위한 라이브러리인 WebGL의 불편함을 개선하고 직관적인 코드를 작성할 수 있도록 만들어진 JS 라이브러리입니다.

 

 

 

 

1. Three.js 다운로드

https://threejs.org/

 

Three.js – JavaScript 3D Library

 

threejs.org

Three.js를 사용하기 위해서는 우선 다운로드가 필요합니다.

 

위 링크로 들어가셔서 Code - Download를 통해 파일을 다운로드합니다.

 

 

 

다운로드 받은 파일을 압축을 푼 후 사용하시면 됩니다.

 

압축을 풀었을 때 라이브러리 파일이 나타나는 위치를 기반으로 파일을 작성하시면 됩니다.

 

 

 

 

2. Three의 기본 요소

 

Scene : 3차원 객체로 구성되는 장면

Render : Scene을 출력장치에 출력을 하기 위한 렌더

Camera : Scene을 보는 시점

Light : 광원

Mesh

- Geometry : 형상

- Material : 색상, 투명도 정의

 

 

 

3. 예제 코드

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
		<link rel="stylesheet" href="./app.css" />
		<script type="module" src="./app.js" defer></script>
		index page
	</head>
	<body>
		<div id="webgl-container"></div>
	</body>
</html>

index.html 에서는 화면에 출력할 3D 모델이 적용될 div DOM을 하나 생성합니다.

 

 

 

/* app.css */
* {
  outline: none;
  margin: 0;
}

body {
  overflow: hidden;
}

#webgl-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

css는 앞서 html 파일에서 생성한 DOM이 전체 페이지를 차지할 수 있도록 작성되어 있습니다.

 

 

 

// app.css
import * as THREE from "../build/three.module.js";

class App {
	constructor() {
		const divContainer = document.querySelector("#webgl-container");
		// _divContainer 필드화
		this._divContainer = divContainer;

		// antialias: true == 렌더링 시 오브젝트 경계선이 계단 현상 없이 표현됨
		const renderer = new THREE.WebGLRenderer({ antialias: true });
		// 화면(os)에 적용된 배율을 받아옴
		renderer.setPixelRatio(window.devicePixelRatio);
		divContainer.appendChild(renderer.domElement);
		this._renderer = renderer;

		const scene = new THREE.Scene();
		// _scene 객체 필드화
		this._scene = scene;

		// 카메라, 광원, 모델 메소드 호출
		this._setupCamera();
		this._setupLight();
		this._setupModel();

		// 창 크기가 변경될 때마다 resize 해주는 기능
		window.onresize = this.resize.bind(this);
		this.resize();

		// 렌더 메소드를 requestAnimationFrame에 넘겨줌
		requestAnimationFrame(this.render.bind(this));
	}

	_setupCamera() {
		// 3차원 그래픽을 출력할 영역의 가로/세로 크기 받아옴
		const width = this._divContainer.clientWidth;
		const height = this._divContainer.clientHeight;
		console.log(width);
		console.log(height);
		// 카메라 객체 생성
		const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 100);
		camera.position.z = 2;
		this._camera = camera;
	}

	// 광원 생성
	_setupLight() {
		const color = 0xffffff; // 광원 색상
		const intensity = 1; // 광원 세기
		// 광원 생성
		const light = new THREE.DirectionalLight(color, intensity);
		light.position.set(-1, 2, 4); // 광원 위치
		this._scene.add(light); // sence 객체의 구성 요소로 추가
	}

	_setupModel() {
		// 가로 세로 깊이 값
		const geometry = new THREE.BoxGeometry(1, 1, 1);
		// 색상 적용
		const material = new THREE.MeshPhongMaterial({ color: 0x44a88 });
		// geometry와 material를 통해서 Mesh를 만듦
		const cube = new THREE.Mesh(geometry, material);

		this._scene.add(cube);
		this._cube = cube;
	}

	// 창 크기 변경시 호출되는 메소드
	resize() {
		const width = this._divContainer.clientWidth;
		const height = this._divContainer.clientHeight;

		// 카메라 속성값 수정
		this._camera.aspect = width / height;
		this._camera.updateProjectionMatrix();

		this._renderer.setSize(width, height);
	}

	render(time) {
		// 렌더러가 카메라 시점을 이용하여 씬을 렌더링하라
		this._renderer.render(this._scene, this._camera);
		// 업데이트 메소드 안애서 속성 값을 변경시켜 애니메이션틀 구현함
		this.update(time);
		// 렌더 메소드를 무한으로 반복하여 호출
		requestAnimationFrame(this.render.bind(this));
	}

	update(time) {
		time *= 0.001; // ms => s 단위로 표기
		// 회전값에 시간을 지정 -> 값이 계속 바뀜
		this._cube.rotation.x = time;
		this._cube.rotation.y = time;
		// this._cube.rotation.z = time;
	}
}

window.onload = function () {
	new App();
};

Three.js의 기본 요소인 Scene, Render, Camera 등을 작성해줍니다.

 

기본적으로 각 요소들은 THREE에서 작성할 수 있는 문법을 제공하므로, Document를 통해서 필요한 기능을 검색하고 사용할 수 있습니다.

 

 

 

 

Three.js를 사용하면 기본 요소들을 기존 WebGL에 비해 손쉽게 생성하고 구현할 수 있다는 점에서 매우 편리합니다.

 

다만 앞에서 .js 파일을 통해서 알 수 있듯이, 처음 학습을 할 때 여전히 길고 불편한 코드를 작성해야 합니다.

 

React에서 사용 가능한 R3F는 이러한 문제를 해결하여 Component를 통해 손쉽게 요소들을 생성하고 3D 객체를 띄울 수 있습니다. 

 

 

 

 

 

 

공유하기

facebook twitter kakaoTalk kakaostory naver band