updated_at: 2025-01-24 10:58

Angular에서 Three.js 사용하기

angular에서 three.js는 버전별로 충돌하는 것이 많아 사용이 용의하지는 않다.
여기서는 angular 19 를 위주로 설명드리며 three.js 버전별 호환성등을 별도로 설명드리겠습니다.

Install

npm i three  // 0.172.0 (이전에는 호환성 때문에 0.155.0 를 사용)
npm i --save-dev @types/three

Import

..........
import * as THREE from 'three';
..........
export class AppComponent {
}

기본적인 폼

기본 형식의 폼

three.js는 canvas에 그래픽을 출력하는 형태이다.
따라서 canvas를 지정해야 하는데 html이 로딩된 후 특정 html element 값을 사용해야 한다.

  • 1. scene 설정 : new THREE.Scene() - 디스플레이 할 화면의 크기등을 설정
  • 2. renderer 설정 : new THREE.WebGLRenderer() - 렌더링 설정
    • 2.1. this.domContainer.nativeElement.appendChild(renderer.domElement); // 설정된 renderer를 canvas에 결합하기
  • 3. camera 설정 : new THREE.PerspectiveCamera()
  • 4. Object 그리기
    • 4.1. scene.add( myObject ); object를 그린후 scene 에 추가
  • 5. Light 설정 : new THREE.AmbientLight(0xffffff, .9)
    • 5.1. scene.add( mylight ); Light를 설정후 scene 에 추가
  • 6. rendering 하기 : this.renderer.render(this.scene, this.camera); // 설정된 scene과 camera를 rendering 한다.
  • template(html)
<div #domContainer></div>
import { Component,OnInit,AfterViewInit,ViewChild,ElementRef} from '@angular/core';
import * as THREE from 'three';
..........
export class AppComponent implements OnInit, AfterViewInit {
  @ViewChild('domContainer', {
    static: true
  }) domContainer!: ElementRef < HTMLDivElement > ;

  ..........
  private renderer!: THREE.WebGLRenderer;
  private scene!: THREE.Scene;
  private camera!: THREE.PerspectiveCamera;
  ..........

  constructor() { }

  ngOnInit() {}
  ngAfterViewInit() {
    // scene(canvas)의 크기를 구한다.
    const sceneWidth = this.domContainer.nativeElement.offsetWidth;
    const sceneHeight = this.domContainer.nativeElement.offsetHeight;

    this.scene = new THREE.Scene(); // scene 설정
    
    // 카메라 설정 (아래 "camera 기능 활성화하기" 참조)....

    this.renderer = new THREE.WebGLRenderer({ // renderer 설정
      alpha: true,
      antialias: true
    });
    
    // 현재 renderer를 domContainer 에 넣음. 이렇게 함으로서 실제 graphic을 출력될 준비가 끝나는 상태가 됩니다.
    this.domContainer.nativeElement.appendChild(this.renderer.domElement); 
    // angular의 ElementRef 를 사용하지 않고 pure javascript를 사용할 경우 아래와 같이 처리하여도 됩니다.
    // const container = document.getElementById('domContainer'); // <div id="domContainer">
    // container.appendChild(this.renderer.domElement);

    // object 그리기 (아래 참조)

    // light 처리 (아래 참조)

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

camera 기능 활성화하기

scene의 설정이 끝났으면 camera를 설정해야 합니다.
Three.js는 이 camera 기능을 활용하여 다양한 효과를 제공하게 됩니다.(근/원거리, 속도, zoom 등..)

this.aspectRatio = this.WIDTH / this.HEIGHT;
this.fieldOfView = 50;
this.nearPlane = 1;
this.farPlane = 2000;
this.camera = new THREE.PerspectiveCamera(
  this.fieldOfView,
  this.aspectRatio,
  this.nearPlane,
  this.farPlane
);
this.camera.position.x = 0;
this.camera.position.z = this.cameraPosGame;
this.camera.position.y = 30;
this.camera.lookAt(new THREE.Vector3(0, 30, 0));

object 그리기

다양한 object를 그리면 됩니다.
여기서는 큐브를 그리도록 하겠습니다.

const geometry = new THREE.BoxGeometry( 50, 50, 50 ); 
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); 
const cube = new THREE.Mesh( geometry, material ); 
scene.add( cube ); // 만들어진 scene에 추가합니다.

light 처리

const globalLight = new THREE.AmbientLight(0xffffff, .9);

const shadowLight = new THREE.DirectionalLight(0xffffff, 1);
shadowLight.position.set(-30, 40, 20);
shadowLight.castShadow = true;
shadowLight.shadow.camera.left = -400;
shadowLight.shadow.camera.right = 400;
shadowLight.shadow.camera.top = 400;
shadowLight.shadow.camera.bottom = -400;
shadowLight.shadow.camera.near = 1;
shadowLight.shadow.camera.far = 2000;
shadowLight.shadow.mapSize.width = shadowLight.shadow.mapSize.height = 2048;

this.scene.add(globalLight);
this.scene.add(shadowLight);
평점을 남겨주세요
평점 : 2.5
총 투표수 : 1

질문 및 답글