본문 바로가기

Front-End: Web/JavaScript

Three.js 1: 시작하기

반응형

1. Three.js란?

1.1 OpenGL

Open Graphics Library.

2D, 3D 그래픽 라이브러리이자 API이며 범용성이 있어 광범위하게 사용되고 있다.

 

 

1.2 WebGL

Web Graphics Library.

WebGL은 이러한 OpenGL을 플러그인 도움 없이 사용할 수 있도록 만들어진 웹 기반의 그래픽 API이다.

자바스크립트로 작성된 제어 코드와 컴퓨터의 GPU에서 실행되는 특수한 효과를 내는 코드로 구성되어 있으며, HTML의 <canvas> 요소를 통해서 3D 렌더링을 할 수 있다. 대부분 최신 버전의 웹 브라우저라면 사용할 수 있으므로 호환성이 높은 편이다. 또한 WebGL 요소들은 HTML 요소들과 섞어서 함께 사용할 수도 있으므로 웹 페이지를 꾸미는데 사용할 수도 있다.

 

예시 웹 사이트

 

 

1.3 Three.js

Three.js는 WebGL을 사용하여 웹 페이지에 3D 객체를 쉽게 렌더링하도록 도와주는 자바스크립트 3D 라이브러리이다.

3D 객체를 렌더링하는데에 WebGL을 사용한다. WebGL은 점, 선, 삼각형만을 그리는 아주 단순한 시스템이므로 직접 무언갈 만들려면 상당히 많은 양의 코드를 짜야한다. 만약 씬(scenes), 광원, 그림자, 물체, 텍스처 등 3차원 세계를 구현한다면 머리도 꽤 복잡하겠거니와 코드 자체도 굉장히 복잡하다. Three.js는 이런 3D 요소들의 처리를 도와 직관적인 코드를 짤 수 있도록 도와준다.

따라서 3차원 세계를 보다 쉽게 만들고 싶다면 Three.js에 대해 공부하자!

공식 홈페이지에 들어가면 많은 예제들을 볼 수 있다. 하지만 간단해보이는 예제들도 코드가 짧진 않다(..) 3D 그래픽을 표현하려면 많은 공부가 필요하다.

 

 

1.4 목표

우선 공부하는 내용을 블로그에 수정하여 계속 정리할 것이다. 최종 목표는 LiDAR 데이터를 자바스크립트로 웹에 3D point cloud로 띄우는 것이다. 된다면 거리에 따라 컬러풀하게 색상도 나타낼 것이다.

개발 환경은 vscode이고, 브라우저는 Chrome를 사용할 것이다. 

 

 

 

2. Three.js 라이브러리 사용하기

Three.js 공식 홈페이지의 설치 메뉴얼을 따라 진행하였다.

Three.js의 모든 메서드들은 ES modules에 기반하고 있다. Three.js를 설치하는 방법은 아래와 같다.

  1. npm으로 설치하기
  2. CDN으로 설치하기
  3. Three.js github에서 파일 다운받기

세 가지 방법 모두 살펴보자.

 

 

2.1 HTML에 모듈 적용하기

HTML에 모듈을 적용하는 방법부터 알아야 한다. 우선 필요한 모듈을 설치하고 간단하게 서버를 구성하자.

npm init 을 입력하여 package.json을 생성한다.

npm init

그리고 필요한 모듈을 설치한다.

npm install -D nodemon
npm install --save three

package.json을 수정하여 npm start 명령어를 입력할 떄 nodemon server가 실행되도록 한다.

{
  "name": "start",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon server"
  },
  "author": "nno3onn",
  "license": "ISC",
  "dependencies": {
    "nodemon": "^2.0.7",
    "three": "^0.128.0"
  }
}

server.js 파일을 생성하고 아래와 같이 입력하여 서버를 구성한다.

const express = require('express');
const path = require('path');

const app = express();
app.set('port', process.env.PORT || 8080);
app.use(express.static('src'));

app.get('/', (req, res) => {
    res.sendFile('index');
});

const server = app.listen(app.get('port'), () => {
    console.log(`Application Running: http://localhost:${server.address().port}`);
});

이제 html을 작성한다. <script type="module">을 반드시 작성해야 한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./style.css"/>
</head>
<body>
    <P class="status"></P>
    <script type="module" src="./index.js"></script>
</body>
</html>

만약 script 태그에 type 속성값을 module로 명시해주지 않는다면 아래와 같은 에러가 발생한다.

Uncaught SyntaxError: Cannot use import statement outside a module

 

그리고 이 모듈은 해당 모듈 내에서만 접근할 수 있다. 그렇지 않으면 에러가 발생한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<script type="module">
    import * as THREE from 'https://cdn.skypack.dev/three@0.128.0';
</script>
<script type="module">
	const scene = THREE.Scene(); // 외부 모듈에서 THREE에 접근할 수 없다. 에러 발생.
</script>
</body>
</html>

모듈 외에서 접근 했을 경우에 발생하는 에러

 

이제 Three.js 관련 코드는 모두 index.js에 작성할 것이다.

 

 

2.2 npm으로 설치하기

2.1에서 이미 작성했듯이, npm을 통해 three 패키지를 설치할 수 있다.

npm install --save three

그러면 node_modules 폴더 내에 three 폴더가 생성된다. three의 메서드들을 사용하려면 node_modules/three/build/three.modules.js 를 가져오면 된다.

import * as THREE from './node_modules/three/build/three.module.js';

window.onload = init();

function init() {
   console.log('init');
   const scene = new THREE.Scene();
}

다음과 같이 작성하면 Three 모듈을 불러올 수 있다.

src 폴더 아래에 index.html 파일을 생성하고 아래와 같이 입력한다.

import * as THREE from './node_modules/three/build/three.module.js';

window.onload = init();

function init() {
   console.log('init');
   const scene = new THREE.Scene();
}

콘솔에 npm start를 입력하고 localhost:8080에 접속하자. 클라이언트 측 콘솔을 확인해보면 에러 없이 서버가 잘 실행된다.

즉, THREE 모듈을 사용하는데에 에러가 없다는 것이다.

 

다른 컴포넌트를 가져올 때에도 위의 방법처럼 작성하면 된다. OrbitControls 컴포넌트는 three/examples/jsm/controls/OrbitControls.js 를 통해 가져오면 된다.

import { OrbitControls } from './node_modules/three/examples/jsm/controls/OrbitControls.js';

 

그런데 이렇게 하면 에러가 발생한다.

Uncaught TypeError: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".

구글링하고 여러 가지 찾아봤는데 아직 해결하지 못했다. 웹팩이 연관되어 있는 문제인 것 같은데..

답변으로는 대부분 CDN으로 가져오는 방법으로 해결하라고 한다.

 

 

2.3 CDN으로 설치하기

먼저 이 페이지에 방문하여 Three.js의 최신 버전을 확인하자.

글 작성 기준(21-05-16)으로 최신 버전은 three@0.128.0 이다. 따라서 해당 버전을 작성하여 모듈을 가져오자.

import * as THREE from 'https://cdn.skypack.dev/three@0.128.0';

window.onload = init();

function init() {
   console.log('init');
   const scene = new THREE.Scene();
}

만약 다른 컴포넌트를 사용하지 않고 Three.js만 사용할 경우에는 html에 해당 코드를 작성하면 된다. 그러면 type="module" 속성을 주지 않고도 자바스크립트 코드를 작성하면 된다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./style.css"/>
</head>
<body>
    <P class="status"></P>
    <!-- Three.js -->
    <script src="https://threejs.org/build/three.js"></script>
    <script src="./index.js"></script>
</body>
</html>

 

다른 컴포넌트를 가져올 때에는 다음과 같이 작성하면 된다. 아래는 OrbitControls를 불러오는 경우이다.

import { OrbitControls } from 'https://cdn.skypack.dev/three@0.128.0/examples/jsm/controls/OrbitControls.js';

페이지에 따르면, 다른 컴포넌트를 가져올 때마다 동일한 버전으로 작성하라고 엄청 엄청 주의하고 있다! 다른 버전으로 작성하면 안된다고 한다.

 

아래 링크를 참고하면 클래스로 잘 정돈하여 코드를 작성할 수 있다.

 

Edit fiddle - JSFiddle - Code Playground

 

jsfiddle.net

 

 

2.4 Three.js github에서 파일 다운받기

Three.js 깃허브에서 파일을 다운 받아 모듈을 가져오는 방법이다. 깃허브의 파일을 다운받고 폴더 내로 옮긴다.

index.html이 있는 src 폴더 내에 build 폴더examples 폴더를 옮긴다. build 폴더 내에는 three.module.js 파일만 있어도 된다.

그리고 해당 파일이 있는 디렉토리로 import를 작성한다.

// index.js
import * as THREE from './build/three.module.js';
import { PCDLoader } from './examples/jsm/loaders/PCDLoader.js';

window.onload = init();

function init() {
    console.log('init');
    const scene = new THREE.Scene();
    const loader = new PCDLoader();
}

 

 

2.5 어떤 방법이 가장 좋을까?

three.js 공식 페이지에 따르면 npm을 통한 설치가 가장 좋다고 한다.

 

하지만 나는 위에서 발생한 에러를 아직 해결하지 못했다. 나의 경우, 2.2와 2.4의 방법을 사용했을 때 해당 문제가 발생하였다. 따라서 앞으로 하는 모든 공부는 2.3 CDN으로 설치하기 방법으로 공부를 진행할 것이다.

 



 


참고 자료

- HTML에 모듈 적용하기

 

자바스크립트 모듈(Module) 학습 내용 간단 요약

main.png 📣 주의사항 > 1. 이 글은 핵심만 추린 요약글입니다. 자세한 내용과 예시는 참조의 링크를 확인하세요 > 2. 오류가 없도록 최선을 다했지만 공부가 부족해 틀린 부분이 있을 수 있습니다.

velog.io

 

- CORS policy 에러

 

로컬에서 CORS policy 관련 에러가 발생하는 이유

🚀 발단 위와 같은 html 파일을 로컬환경에서 크롬 브라우져로 실행시켰더니 >Access to script at 'file:///C:/경로/js/module.js' from origin 'null' has been blocked by CORS policy: Cr

velog.io

 

반응형

'Front-End: Web > JavaScript' 카테고리의 다른 글

객체(Object)  (0) 2021.05.26
Three.js 2: PCD(Point Cloud Data)Loader  (0) 2021.05.16
JavaScript란?  (0) 2021.04.25
JSON와 JSON 메서드  (0) 2021.04.16
JSON과 Javascript Object의 차이  (0) 2021.04.16