three.js 카메라 강좌 예시 이미지

#07 이 영상 하나로 카메라 완벽 이해하기 – Three.js 강좌

안녕하세요. 이번에는 three.js에서 코드로 카메라를 설정하는 방법, 카메라의 위치 설정, 카메라 관련 반응형 코드 이해 등 카메라 개념과 상세한 예시를 통해 three.js에서 제공하는 카메라를 완벽히 이해하고 넘어갈 수 있습니다. fov가 뭔지, aspect가 뭔지 이런 개념은 조금 생소할 수 있는데, DSLR 활용해서 촬영을 해보셨거나 사진학을 배우신 분들이라면 좀 더 쉽게 배우실 수 있습니다.

*디자인 베이스 강좌는 Mac OS를 기준으로 해서 윈도우 사용자와 일부 차이가 있을 수 있습니다. 윈도우 사용자분들은 영상에서 커맨드(Cmd)라는 단축키 대신 컨트롤(Ctrl)을, 옵션(Option) 대신 알트(Alt)를 눌러주세요.

카메라 속성 및 개념 설명

카메라를 이해하면 Three.js에서 사용하는 개념도 조금은 쉽게 이해할 수 있지만, 필수는 아닙니다. 그래도 이해하면 원하는 화면을 구현하기 쉬우니까 깊이 있게 배워볼게요.

dslr 카메라
// 카메라 추가
const fov = 75; //화각 설정
const aspect = window.innerWidth / window.innerHeight;//종횡비
const near = 0.1; //가까이
const far = 1000; //멀리
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

// 위 코드와 동일
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

FOV (field of view)

우선 fov는 field of view의 약어 입니다. 쉽게 말하면 시야각 혹은 화각이라고 합니다. 인간의 시야 범위는 160도라고 하는데요, 카메라에서는 이러한 시야각을 구하는 공식은 매우 복잡합니다. 초점거리, 센서 길이 등과 관련이 있는데.. 수학적으로 접근하면 너무나 복잡하죠?

three.js 카메라 FOV 개념
FOV는 시야각 또는 화각이라고 합니다.

Three.js에서 fov값을 직접 수치를 넣어야 하는데 그 수치는 어디서 나온 건지 이해하려면 렌즈의 종류부터 이해해야 합니다. 예시를 통해 살펴볼게요.

크게 표준렌즈, 광각렌즈, 망원렌즈로 나뉩니다.

렌즈별 피사체 모습
렌즈에 따른 사진 결과 예시

이 개념이 중요한데, 일반적으로 렌즈 초점거리가 50mm 일때 일반인의 시야와 비슷해서 표준렌즈로 불리고, 35mm 이하는 광각렌즈, 85mm정도는 망원렌즈로 분류됩니다. 이러한 렌즈 분류와 화각을 붙여서 같이 생각해볼 필요가 있습니다.

화각 개념
렌즈 분류와 화각의 관계

1. 오브젝트를 가까이 크게 보이게 하고 싶다면?

망원으로 표현을 해야하는 데 그러기 위해서는 화각(Fov)이 좁아야 합니다. 대략 8~28도

three.js 카메라 FOV 개념 - 망원렌즈

2. 만약 평범하게 표준으로 하고 싶다면?

표준 렌즈로 표현하면 되는데, 이때 화각은 47도입니다.

three.js 카메라 FOV 개념 - 표준렌즈

3. 만약 오브젝트를 원근감을 주고 작게 보여주고 싶다면?

광각으로 하면되는데 이때 화각은 대략 63~84도입니다.

three.js 카메라 FOV 개념 - 광각렌즈

이제 코드에 fov 값을 조절해 보면서 어떻게 카메라에 피사체가 담기는지 확인하시면 완전히 이해되실 겁니다.

aspect (Aspect ratio)

대부분의 경우 요소의 높이와 너비에 맞추어 표시하게 할 텐데, 그렇지 않으면 와이드스크린에 옛날 영화를 트는 것처럼 이미지가 틀어져 보일 것입니다.  쉽게 말하면 가로 세로 비율입니다. 16:9나 4:3 같은… 그래서 three.js에서는 우리의 모니터 속 브라우저의 뷰포트 기준으로 해줘야 합니다. window.innerWidth / window.innerHeight;

near & far

카메라 near far 구분
Near와 Far 사이만 피사체가 보입니다.

near는 카메라의 시점이 시작되는 위치이며, far는 카메라의 시점이 끝나는 위치입니다.
무슨 뜻인가 하면, far 값 보다 멀리 있는 요소나 near 값보다 가까이 있는 오브젝트는 렌더링 되지 않는다는 뜻입니다. 지금 시점에서 이것까지 고려할 필요는 없지만, 앱 성능 향상을 위해 사용할 수 있습니다.그 지점을 벗어나면 요소가 안보이게 됩니다.
(영상에서는 이해를 위해 바닥을 추가 후 확인했습니다.)

카메라의 위치 조정

// 카메라 위치 변경
camera.position.x = 0; //카메라 좌우 이동
camera.position.y = 0.3; //카메라 상하 이동
camera.position.z = 1; //카메라 앞뒤 이동

camera.position.set(0,0.3,1); //위와 동일

카메라가 특정 지점을 바라보는 방법

camera.lookAt(new THREE.Vector3(0, 0, 0)); //특정 좌표를 쳐다보기

반응형

그동안 그냥 넘어갔던 반응형 관련 코드를 한번 살펴볼게요. onWindowResize 함수를 만들어서 윈도에 이벤트 리스너를 추가해서 리사이징 될 때마다 실행하게 했습니다. 그 안에 코드를 살펴보면, 카메라가 들어가 있죠. 종횡비도 지속적으로 업데이트를 해줘야 합니다.

// 반응형 처리
  function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  }
  window.addEventListener('resize', onWindowResize);

https://threejs.org/docs/#api/en/cameras/PerspectiveCamera.updateProjectionMatrix

camera.updateProjectionMatrix(); 이 함수는 카메라의 어떠한 파라미터값이 변경되는 경우가 생기면 꼭 필요합니다.