개발 · 컴퓨터공학/three.js / / 2024. 10. 5. 11:19

Threejs TypeScript 설치환경 시작하기

728x90
반응형

threejs를 typescript에서 이용하기 위한 초기 세팅을 알아보도록 한다.

github 등에 다른 사람들이 올려놓은 template를 가져와서 사용하는 것이 빠르고 좋다.

하지만 그 template의 기본적인 설정 조차도 ground부터 하나하나씩 올려놓고 싶은, 백지 상태에서 출발해보고자 한다면 다음과 같은 방법으로 threejs를 typescript를 이용해서 시작해보도록 한다.

 

package.json 만들기

npm init

npm으로 package.json을 만들어준다. 

 

Threejs 설치

npm i three

 

typescript threejs를 사용하기 위해서는 three 모듈 뿐 아니라 @types/three라는 threejs type을 개발 package로 받아야한다.

TypeScript Threejs 설치

npm i @types/three

types/three를 설치해주면 이제 typescript에서 threejs를 사용하기 위한 기초 준비는 끝났다.

개발 서버 설치

개발 서버 구동을 위해서 vite를 사용한다.

 

 

npm i vite
npx vite

단순히 vite를 npm으로 설치하고 실행하면 로컬 서버가 구동된다.

 

package.json depenencies와 devDependencies 차이

  "devDependencies": {
    "@types/three": "^0.163.0",
    "typescript": "^5.4.5",
    "vite": "^5.2.9"
  },
  "dependencies": {
    "lil-gui": "^0.19.2",
    "three": "^0.163.0"
  }

간혹 보면 package.json에 dependency와 devDependency가 따로 있다.

 

  "dependencies": {
    "@types/three": "^0.164.0",
    "three": "^0.164.1",
    "vite": "^5.2.11"
  }

방금 위에 명령어들로 설치하면 이렇게 dependencies에만 추가되는데 무슨 차이일까 

dev가 붙어있다는 것은 개발 전용인데, 개발과 구분되는 개념은 빌드이다.

 

즉 build시 포함되는 것은 dependencies에  빌드에 포함되지 않아야 하는 것은 구분해서 devDependencies로 설치한다.

devDependencies로 분리하기

  "dependencies": {
    "@types/three": "^0.164.0",
    "three": "^0.164.1",
    "vite": "^5.2.11"
  }

그렇다면 방금 설치한 것들 중에서 개발에만 필요한게 무엇이 있을까.

일단 개발 전용 호스팅 서버인 vite가 있다.

 

vite 삭제

npm uninstall vite

vite를 dependencies에서 삭제하고

 

npm i --save-dev vite

devDependencies로 설치한다.

typescript의 dependencies

그리고 나서 typescript를 사용하고 있다는 점을 유의해야한다.

typescript는 무엇인가? 

 

typescript라는 것은 컴파일 할 때 javascript로 변환된다. 즉 런타임에서는 typescript는 아무런 의미가 없는 것이다.

 

오로지 컴파일을 위해서 사용되는 규칙과 같은 것이기 때문에, typescript도 마찬가지로 개발할 때만 사용하는 패키지이다.

 

npm i --save-dev typescript

--save-dev를 이용해서 devDependencies로 설치한다.

threejs typescript 삭제

npm uninstall @types/three

마찬가지로 삭제하고,

 

npm i --save-dev @types/three

 devDependencies로 설치

 

threejs의 경우는 빌드에서 필요한 패키지이므로 dependencies에 남겨둔다.

 

package.json

{
  "name": "three.js-fluid-simulation",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "devDependencies": {
    "@types/three": "^0.163.0",
    "typescript": "^5.4.5",
    "vite": "^5.2.9"
  },
  "dependencies": {
    "gl-matrix": "^3.4.3",
    "lil-gui": "^0.19.2",
    "three": "^0.163.0"
  }
}

이렇게 현재 package.json의 상태가 되었고,

위 코드를 복사해서 package.json을 만들어서 npm i 를 통해 한 번에 모듈을 설치해도 된다.

 

index html 화면 canvas 띄우기

이제 index에 canvas element 하나를 type/three를 이용해서 화면을 띄워 볼 것이다.

 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>three.js project</title>
  </head>
  <body>
    <canvas id="scene"></canvas>
    <script type="module" src="/src/test-scene.ts"></script>
  </body>
</html>

위 규격의 html 코드에 canvas id에 접근하여 rendering을 하자

프로젝트 폴더 안에 index.html을 만들어서 위 코드를 넣고

 

이제 ts파일을 만든다

scene.ts 추가하기

src폴더를 만들고 그 안에 test-scene.ts 파일을 만든다.

 

import * as THREE from 'three'

가장 우선은 three.js import 코드이다.

이걸 가지고 모든 three.js 요소들을 사용하자.

 

//#region render setting (scene, canvas, renderer)
const canvas_id = 'scene'

const canvas: HTMLElement = document.querySelector(`canvas#${canvas_id}`)!
const renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true })
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap
const scene: THREE.Scene = new THREE.Scene()

//#endregion

먼저 화면을 렌더링할 render setting을 해준다.

이걸로 scene, canvas, renderer를 만들어준다.

 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>three.js project</title>
    <style>
      body,
      html {
        height: 100%;
      }      
      canvas {
        height: 100%;
        width: 100%;
        outline: none;

        background: rgb(34, 193, 195);
        background: linear-gradient(
          0deg,
          rgb(8, 163, 166) 0%,
          rgba(79, 166, 167, 0.849) 8%,
          rgba(61, 79, 94, 0.885) 40%,
          rgb(17, 19, 23)
        );
      }
    </style>
  </head>
  <body>
    <canvas id="scene"></canvas>
    <script type="module" src="/src/test-scene.ts"></script>
  </body>
</html>

캔버스의 크기를 페이지의 전체 100%로 설정해준다.

그리고 캔버스의 경계가 어디까진지 잘 보이도록 css로 채색해주자.

 

이건 three.js에서 설정한게 아니라 CSS 스타일로 적용한 배경색이다.

three.js 에서도 배경색을 설정할 수는 있다.

 

object 렌더링하기

//#region camera
const camera = new THREE.PerspectiveCamera(50, canvas.clientWidth / canvas.clientHeight, 0.1, 1000)
camera.position.set(0,0,5)
//#endregion

//#region object 
const cube = new THREE.Mesh(
  new THREE.BoxGeometry(1,1,1),
  new THREE.MeshBasicMaterial({color: 'red'})
)
scene.add(cube)
//#endregion

//#region animate
function animate() {
  requestAnimationFrame(animate);

  // 박스 회전
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  renderer.render(scene, camera);
}
animate();
//#endregion

물체를 띄우기 위해 camera와 object, 

그리고 scene을 지속적으로 update해줄 animation 함수가 필요하다.

 

위 코드를 적용하면 이렇게 빨간 박스가 회전하는 모습을 보인다.

근데 왜인지 화질이 구리다. 

해상도를 조정하도록 하자.

 

해상도 조정하기 resize 

function resizeRendererToDisplaySize(renderer: THREE.WebGLRenderer) {
  const canvas = renderer.domElement
  const width = canvas.clientWidth
  const height = canvas.clientHeight
  const needResize = canvas.width !== width || canvas.height !== height
  if (needResize) {
    renderer.setSize(width, height, false)
  }
  return needResize
}

위 함수에서 renderer.setSize가 해상도를 조절해서 이렇게 깔끔하게 해상도가 바뀌게 해준다. 

요 resizeRendererToDisplaySize 함수를 가지고 animation안에서 camera가 변경된 canvas크기에 맞추어 update해주도록 설정해주어야한다.

 

//#region animate
function animate() {
  requestAnimationFrame(animate);

  if (resizeRendererToDisplaySize(renderer)) {
    const canvas = renderer.domElement
    camera.aspect = canvas.clientWidth / canvas.clientHeight
    camera.updateProjectionMatrix()
  }

  // 박스 회전
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  renderer.render(scene, camera);
}
animate();
//#endregion

animate 함수에 위 코드를 추가한다. 

 

 

이렇게 기본적인 three.js 화면을

typescript로 띄우기 성공했다. 

728x90
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유