개발 / / 2024. 5. 9. 09:19

Three.js TypeScript 시작 및 초기 세팅하기

반응형

 

오픈 소스 찾기

무엇이든 공부하는 입장에서 제로에서 시작하는 것은 바로바로 떠오르지 않는다. github 오픈소스를 찾아서 입맛에 맞는 초기 세팅으로 변경해서 사용하자.

 

 

 

위 두 개의 오픈소스 템플릿을 찾았다. 코드를 까서 구경해보자.

근데 둘 다 vite로 실행한다는 내용이 쓰여있는데, vite가 뭔지 잘 모른다.

vite란 

단순히 말하면 개발용 프론트엔드 서버 및 배포 번들링 기능을 지원하는 툴이다.

기존에 있는 툴인 Vue CLI를 대체하는 새로운 개발 서버 및 번들링 툴이다.

threejs start 템플릿 1번 : vite-threejs-ts-starter

실행하기

git clone을 받고 메뉴얼대로

 

npm install
npm run start

만 하면 vite든 뭐든 다 세팅되어 열린다.

코드구성

Demo.ts

스크립트는 main.ts → Demo.ts으로 이어지는 단순한 구조이다.

 

 

Shader.ts

glsl shader는 기본만 세팅되어있고, shader 코드를 읽어와서 ShaderMaterial을 적용하는 class인 Shader.ts가 있다.

 

constructor() {
    this.initScene();
    this.initStats();
    this.initListeners();
}

Demo.ts와 Shader.ts는 공통적으로 생성자에서 위 함수들을 세팅하고, initScene 마지막에서 animate 함수를 실행한다.

 

animate() {
    requestAnimationFrame(() => {
        this.animate();
    });

    this.cube.rotation.x += 0.01;
    this.cube.rotation.y += 0.01;

    if (this.stats) this.stats.update();

    if (this.controls) this.controls.update();

    this.renderer.render(this.scene, this.camera);
}

위 animate함수는 Demo.ts class의 함수이지만 Shader.ts에도 똑같은 구성으로 있다. 

형태가 똑같은 것을 보고 Shader.ts는 단순히 shader module 기능을 위한 것이 아니라. shadre가 들어가는 Demo 템플릿임을 알았다.

 

import './style.scss';

// Toggle commented out code to run alternate demo.
// import Demo from './Demo';
import Demo from './Shader';

window.addEventListener('DOMContentLoaded', () => {
	new Demo();
});

Demo와 똑같이 실행하는 구성이었던 것이다. 바꾸면 어떤 환경이 나올까?

 

그냥 pixel shader 좌표에 따라 color를 대입한 결과다. 

 

파일 구성도 그렇고 시작 프로젝트로써는 굳이 필요없는 파일들이 보인다.

오른쪽은 이제부터 볼 두 번째 템플릿인데 얼핏 봐도 구성이 깔끔하다. 

threejs start 템플릿 2번 : vite-threejs-ts-starter

실행하기

얼핏 봐도 기본적인 세팅과 기능들이 구현되어있다.

코드 구성을 보자.

코드 구성

canvas 세팅, lighting , loading, object, control 등 기능에 따라서 시작 코드가 scene.ts안에 잘 분리되어 있다.

 

function animate() {
  requestAnimationFrame(animate)

  stats.update()

  if (animation.enabled && animation.play) {
    animations.rotate(cube, clock, Math.PI / 3)
    animations.bounce(cube, clock, 1, 0.5, 0.5)
  }

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

  cameraControls.update()

  renderer.render(scene, camera)
}

분리된 기능들을 animate 함수에서 모두 동작시켜 알아보기 쉬운 템플릿 형태이다.

추후에 각 기능별로 모듈화 시켜서 관리하기에도 편하게 깔끔히 정리되어있다.

 

반응형

export function resizeRendererToDisplaySize(renderer: 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
}

화면에 따른 반응형 코드도 적용되어있어서 화면 크기 조절에 알맞게 잘 대응된다.

 

더 적당한 템플릿

두 번째 템플릿이 사용하기 더 편하고 간결하게 코드가 구성되어있다.

 

심지어는 이렇게 github에 template로 새로운 repo를 시작할 수 있도록 되어있고, 기존 template의 history를 초기화하는 방법도 알려준다.

 

바로 시작해보자.

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