- 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를 설정할 때 아래와 같은 항목들을 고려한다.
- Near plane(가까운 평면), Far plane(먼 평면): 렌더링 될 물체가 얼마나 멀고 가까운지를 의미한다.
- Field of View (FoV): 카메라를 통해 보일 영역의 크기를 결정한다. 크면 클 수록 더 넓은 영역을 보여주게 된다. 정확한 정의는 ‘카메라 아래부터 위까지, 도 단위로 표시되는 수직 시야’ 인데 이에 관해선 후술.
- Aspect Ratio: 카메라 영역의 가로 세로 비를 뜻한다. (너비 / 높이)
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 창 너비 / 높이)를 전달하고 있다.
이 상태에서 각 인자를 조작했을 때 어떤 변화가 일어나는지 살펴본다.
FoV(Field of View)
- fov 값을 조정할 경우 아래와 같은 변화가 일어난다.
- fov 값을 높일 경우, 물체가 멀어진 것 같은(혹은 작아진 것 같은) 변화를 보인다.
- → 실제로 물체 크기에 영향을 미친 것이 아니라, 윈도우의 크기는 변함이 없는 반면 카메라가 보이는 Scene 속 영역의 크기는 커졌기 때문에, 상대적으로 물체의 크기가 보이는 영역에 비해 작게 보이는 것이다.
- 반대로 fov 값을 낮출 경우 물체가 더 가까이 있는 것 같은(혹은 커진 것 같은) 변화를 보인다.
- fov 값은 ‘도 단위’로 나타낸다. 기본 값은 50으로 설정되어있다.
FoV 값을 높였을 때 | FoV 값을 낮췄을 때 |
+) FoV에 대해 잠시 이해를 정리한 부분
더보기
강의만 봤을 때는 'FoV 값을 도로 표현한다는 부분'이 이해가 안 가서 고민 좀 했다. 내가 헷갈린 점은 크게 2가지.
- FoV를 카메라 영역 크기와 관련된 값으로 인지하고 있었기에, 왜 갑자기 도 단위로 표시한다는 건지 이해가 가질 않았음.
- (1번이 이해가 안 갔으므로) FoV값을 180도로 설정했을 때 왜 아무것도 보이게 되지 않게 되는지 이해가 안 갔음.
이래저래 찾아보며 이해한 것이;
- FoV는 ‘각도’를 나타내는 값이 맞다. 동시에 카메라 영역 크기에 관여하는 값도 맞음.
- 카메라에서 Plane까지 카메라가 비출 영역의 각도를 나타내는 값. 따라서 키우면 키울수록 보이는 영역의 크기가 커짐.
- PerspectiveCamera의 FoV값은 수직(vertical) 각도 값이고, 영역의 비율은 별도의 값 (가로 세로 비를 결정하는 aspect)으로 관리되기 때문에 FoV값을 조정하면 수평각도 같이 영향을 받음. 그래서 영역 전체에 변화가 생김.
- FoV를 180도로 설정하면 절두체가 거의 평면이 됨. Near plane과 Far plane이 겹쳐지게 되고, 그 사이에 카메라에 비출 물체를 캡처할 수 없게 되며 아무것도 보이지 않게 되는 것.
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 클래스를 통해 사용할 수 있다.
- 다음과 같은 항목들을 인자로 받는다.
- left
- right
- top
- bottom
- near
- far
- PerspectiveCamera 와는 달리 aspect가 존재하지 않아 윈도우 크기를 바꿀 때 화면 비율을 조정하기 어렵다.
→ 따라서 고정된 창 크기를 가진 환경에서 사용하기 쉽다.
- 전에 그래픽스 수업을 들을 때 배운 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 |