본문 바로가기
공부/etc

Three.js and TypeScript (3)

by Piva 2024. 11. 13.
  • Udemy의 Three.js and TypeScript 강의를 듣고 정리한 내용을 기록한다.
    • 10. Camera 를 듣고 정리한 내용이다.

Camera

  • Three.js에는 다양한 타입의 카메라가 존재한다.
    • Perspective, Orthographic, Stereo Camera…
  • 이번 강의에서는 Perspective / Orthographic 위주로 살펴본다.
  • Camera의 각종 속성을 통해, 렌더링되는 Scene 내부의 차원(Dimension)인 ‘절두체(Frustum)’를 설정하는 것이 가능하다.
    • 즉, 카메라를 통해 보일 영역을 설정 가능하다는 의미인 것 같다.
모든 카메라 클래스는 Camera 클래스를 확장하고, 지난 번에 살펴본 Scene처럼 Camera 또한 Object3D를 확장한다. 따라서 카메라 클래스에서 Object3D의 속성이나 메서드를 사용하는 것이 가능하다.

 

 

Perspective Camera

  • 원근 투영(Perspective Projection): 인간이 눈이 세상을 바라보는 방법을 흉내낸 방식으로, 간단히 말해 3D 개체를 2D 평면에 투영하는 방식을 의미한다.
  • Perspective Camera는 이 방식에 기반한 카메라로, 3D Scene을 렌더링할 때 가장 흔히 사용되는 카메라이다.
  • Three.js에서는 PerspectiveCamera 클래스를 통해 사용할 수 있다.
  • Perspective Camera를 설정할 때 아래와 같은 항목들을 고려한다.
    1. Near plane(가까운 평면), Far plane(먼 평면): 렌더링 될 물체가 얼마나 멀고 가까운지를 의미한다.
    2. Field of View (FoV): 카메라를 통해 보일 영역의 크기를 결정한다. 크면 클 수록 더 넓은 영역을 보여주게 된다. 정확한 정의는 ‘카메라 아래부터 위까지, 도 단위로 표시되는 수직 시야’ 인데 이에 관해선 후술.
    3. Aspect Ratio: 카메라 영역의 가로 세로 비를 뜻한다. (너비 / 높이)
    → 위의 항목들이 그대로 PerspectiveCamera 생성자의 인자로 들어간다.

Perspective Projection 의 형상

 

import * as THREE from 'three';

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
  • PerspectiveCamera 생성자에 차례대로 fov, aspect, near, far에 해당하는 인자를 전달한다.
  • 위 코드에서는 aspect(가로 세로 비)에 (window 창 너비 / 높이)를 전달하고 있다.

 

Perspective Camera로 육면체를 바라보는 모습

  이 상태에서 각 인자를 조작했을 때 어떤 변화가 일어나는지 살펴본다.

 

 

FoV(Field of View)

  • fov 값을 조정할 경우 아래와 같은 변화가 일어난다.
    • fov 값을 높일 경우, 물체가 멀어진 것 같은(혹은 작아진 것 같은) 변화를 보인다.
    • → 실제로 물체 크기에 영향을 미친 것이 아니라, 윈도우의 크기는 변함이 없는 반면 카메라가 보이는 Scene 속 영역의 크기는 커졌기 때문에, 상대적으로 물체의 크기가 보이는 영역에 비해 작게 보이는 것이다.
    • 반대로 fov 값을 낮출 경우 물체가 더 가까이 있는 것 같은(혹은 커진 것 같은) 변화를 보인다.
  • fov 값은 ‘도 단위’로 나타낸다. 기본 값은 50으로 설정되어있다.
FoV 값을 높였을 때 FoV 값을 낮췄을 때 

 

+) FoV에 대해 잠시 이해를 정리한 부분

더보기

강의만 봤을 때는 'FoV 값을 도로 표현한다는 부분'이 이해가 안 가서 고민 좀 했다. 내가 헷갈린 점은 크게 2가지.

  1. FoV를 카메라 영역 크기와 관련된 값으로 인지하고 있었기에, 왜 갑자기 도 단위로 표시한다는 건지 이해가 가질 않았음.
  2. (1번이 이해가 안 갔으므로) FoV값을 180도로 설정했을 때 왜 아무것도 보이게 되지 않게 되는지 이해가 안 갔음.

이래저래 찾아보며 이해한 것이;

  • FoV는 ‘각도’를 나타내는 값이 맞다. 동시에 카메라 영역 크기에 관여하는 값도 맞음.
  • 카메라에서 Plane까지 카메라가 비출 영역의 각도를 나타내는 값. 따라서 키우면 키울수록 보이는 영역의 크기가 커짐.
    • PerspectiveCamera의 FoV값은 수직(vertical) 각도 값이고, 영역의 비율은 별도의 값 (가로 세로 비를 결정하는 aspect)으로 관리되기 때문에 FoV값을 조정하면 수평각도 같이 영향을 받음. 그래서 영역 전체에 변화가 생김.
  • FoV를 180도로 설정하면 절두체가 거의 평면이 됨. Near plane과 Far plane이 겹쳐지게 되고, 그 사이에 카메라에 비출 물체를 캡처할 수 없게 되며 아무것도 보이지 않게 되는 것.

 

이게 Vertical FoV이다.

 

aspect

  • 화면의 종횡비.
  • 일반적으로는 위 코드처럼 화면의 width와 height를 나누어 비율을 맞추는 듯 하다.
  • resize 이벤트를 통해 윈도우 창 크기가 바뀔 때마다 업데이트 하지 않을 경우, 렌더링 된 화면이 일그러질 수 있다.

 

near / far

  • 절두체 내 Near plane과 Far plane의 위치를 결정한다.
  • 기본적으로 Near plane과 Far plane 사이에 위치한 물체만이 카메라에 보이게 된다.
    • 따라서 Near plane 값은 항상 Far plane 값보다 작아야 한다.
  • Near plane과 Far plane 바깥에 위치한 물체는 잘려 보이지 않게 된다.

 

속성 및 메서드 예시

.position

: 정확히는 카메라의 속성은 아니고, Object3D 클래스의 속성. 현재 오브젝트의 로컬 위치를 반환한다. 별도로 설정해주지 않았을 경우 기본값은 (0, 0, 0)이다.

  • set 메서드를 통해 원하는 좌표로 position을 설정할 수 있다.

 

.lookAt()

: Object3D 클래스의 메서드. 인자로 물체가 바라볼 곳의 월드 좌표(x, y, z)를 넘기면 물체가 그 방향을 바라보도록 회전시킨다.

 

 

.updateProjectionMatrix()

: 카메라의 속성을 변경했을 때, 변경된 속성값을 적용하기 위해 호출해야 하는 메서드.

  • 즉 어떤 값이든 변경 후 이 메서드를 호출하지 않으면 변경된 값이 적용되지 않는다.
// 윈도우 창 크기가 변화할 때마다 Camera의 aspect를 바꾸는 이벤트 리스너
// updateProjectionMatrix가 사용되지 않으므로 변경값이 적용되지 않는다
window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  // camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
})

 

 

 

Orthographic Camera

  • 직교 투영(Orthographic Projection): 원근 투영과 같이 3D 개체를 2D 평면에 투영하는 방식을 의미한다. 다만 원근 투영처럼 대상의 원근감이 드러나지 않는다.
  • 원근 투영에서 보여지는 영역이 절두체의 형태라면, 직교 투영은 육면체 형태라고 할 수 있다.
  • OrthographicCamera 클래스를 통해 사용할 수 있다.
  • 다음과 같은 항목들을 인자로 받는다.
    1. left
    2. right
    3. top
    4. bottom
    5. near
    6. far
    → 이 값들은 카메라의 좌표값에 대해 상대적인 값이다. (월드 좌표계 기준이 아니라는 뜻 같다)
  • PerspectiveCamera 와는 달리 aspect가 존재하지 않아 윈도우 크기를 바꿀 때 화면 비율을 조정하기 어렵다.
    → 따라서 고정된 창 크기를 가진 환경에서 사용하기 쉽다.

Orthographic Camera로 육면체를 보는 모습


  • 전에 그래픽스 수업을 들을 때 배운 OpenGL 내용을 떠올렸다. 그 때 배웠던 내용을 다시 되새겨보는 기분.

'공부 > etc' 카테고리의 다른 글

Electron + Vite + React 환경 세팅 살펴보기  (2) 2024.11.15
Three.js and TypeScript (4)  (0) 2024.11.14
Three.js and TypeScript (2)  (0) 2024.11.12
Three.js and TypeScript (1)  (1) 2024.11.09
크롬 개발자 도구 코드 붙여넣기 이슈  (1) 2024.09.08