Three.js 강좌 #4 씬그래프(Scene Graph)를 이용한 공간구성

zzzzsb·2021년 11월 28일
0

Three.js

목록 보기
5/5

three.js의 기본 구성요소

  • Geometry: material과 함께 mesh를 구성하는 요소, 3차원 객체의 형상 정의
  • Material: 3차원 객체의 색상이나 투명도 등을 정의함
  • Mesh: 3차원 객체를 화면에 표시하기 위한 클래스, Object3D의 파생클래스

Object3D의 파생 클래스

  • Mesh 뿐만 아니라 Line, Points 등이 있음

  • Mesh: 삼각형 면으로 구성된 객체

  • Line: 선형 객체를 표현

  • Points: 점을 표현

  • 3차원 객체는 3차원 공간상에 놓여지게 됨

3D Object가 3차원 공간 상에 놓여지기 위해 필요한 값

  • Mesh 등의 부모클래스인 Object3D는 위치, 회전, 크기 속성값을 가짐
  1. position: xyz축에 대한 위치값(기본값 모두 0)
  2. rotation: xyz축에 대한 회전값(기본값 모두 0)
  3. scale: xyz축에 대한 크기의 배수값(기본값 모두 1, 값은 원래 크기를 의미함)

    scale값을 xyz축에 대해 모두 2로 지정하면 3D객체는 2배크기로 표시됨

  • position, rotation, scale은 4x4 크기의 행렬 정보로 변환됨

Three.js의 xyz축 좌표 구성

  • x축은 화면의 오른쪽이 +, 왼쪽이 -
  • y축은 위쪽이 +, 아래쪽이 -
  • z축은 모니터 바깥방향 +, 안쪽방향 -

scene graph를 통한 3차원 객체의 공간 구성

xyz 공간상에 3D 객체 여러개 구성하기

예제: 태양 - 지구 - 달

  • 태양은 자전
  • 지구는 태양 중심으로 공전하며 자전
  • 달은 지구 중심으로 공전

태양-지구-달에 대한 scene graph

  • 회색 글자: 클래스 타입
  • 검은색 글자: 오른쪽의 클래스로 생성된 객체의 이름
  • 화살표: 자식을 가리킴

03-scenegraph.js의 _setupModel()

_setupModel() {
    // Object3D 타입의 solarSystem 객체 생성
    const solarSystem = new THREE.Object3D();
    this._scene.add(solarSystem);

    // 구 모양 지오메트리 생성
    const radius = 1;
    const widthSegments = 12;
    const heightSegments = 12;
    const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments);

    // 태양 재질 생성
    const sunMaterial = new THREE.MeshPhongMaterial({ emissive: 0xffff00, flatShading: true }); 

    // sunMesh 객체 생성
    const sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial);
    // xyz에 대해 3,3,3 설정 -> 원래 지오메트리 크기보다 3배의 크기로 표시
    sunMesh.scale.set(3, 3, 3);
    solarSystem.add(sunMesh);

    // Object3D 타입의 earthOrbit 객체 생성
    const earthOrbit = new THREE.Object3D();
    // 생성한 earthOrbit 객체를 solarSystem의 자식으로 추가함 
    solarSystem.add(earthOrbit);

    // 지구 재질 생성
    const earthMaterial = new THREE.MeshPhongMaterial({ color: 0x2233ff, emissive: 0x112244, flatShading: true });

    // earthMesh 생성
    const earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial);
    // 태양에서 x축으로 거리 10만큼 떨어진 위치에 지구가 배치되도록 하기 위함
    earthOrbit.position.x = 10;
    // earthMesh 객체를 earthOrbit의 자식으로 추가
    earthOrbit.add(earthMesh);

    // Object3D 타입의 moonOrbit 객체 생성
    const moonOrbit = new THREE.Object3D();
    /* 
    moonorbit은 earthOrbit의 자식이므로, earthOrbit 기준으로 x축 거리 2만큼 떨어진 곳에 배치됨
    태양 관점에서 보면 moonOrbit은 거리 12만큼 떨어진 곳에 배치됨
    */
    moonOrbit.position.x = 2;
    // 생성한 moonOrbit 객체를 earthOrbit의 자식으로 추가함
    earthOrbit.add(moonOrbit);

    // 달 재질 생성
    const moonMaterial = new THREE.MeshPhongMaterial({ color: 0x888888, emissive: 0x222222, flatShading: true });

    // moonMesh 생성
    const moonMesh = new THREE.Mesh(sphereGeometry, moonMaterial);
    // 원래 구 반지름 절반 크기로 달이 생성됨
    moonMesh.scale.set(0.5, 0.5, 0.5);
    // moonMesh를 moonOrbit의 자식으로 추가
    moonOrbit.add(moonMesh);

    // 객체를 다른 메서드에서 참조할수 있도록함
    this._solarSystem = solarSystem;
    this._earthOrbit = earthOrbit;
    this._moonOrbit = moonOrbit;
}

camera.position.z=25;

  • 현재 카메라가 태양 내부에 있기 때문에 카메라 포지션을 수정해주어야함

03-scenegraph.js의 update(time)

생성한 객체들을 회전시키기 위해(공전, 자전) update 함수 수정 필요

update(time) {
    time *= 0.001;
    // solarSystem은 y축에 대해 계속 회전
    this._solarSystem.rotation.y = time / 2;
    // 지구의 자전
    this._earthOrbit.rotation.y = time * 2;
    // 달의 자전
    this._moonOrbit.rotation.y = time * 5;
}

  • scene graph를 이용하면 3차원 객체를 원하는 공간 상에 구성할때 복잡한 수학적 변환식을 사용하지 않아도 됨
  • 3차원 그래픽에서는 scene graph를 이용한 3차원 객체의 공간 구성이 매우 중요함
profile
성장하는 developer

0개의 댓글