R3F(React Three Fiber) - Camera

H.GOO·2024년 4월 5일
1

WEB-3D-Project

목록 보기
6/10
post-thumbnail

🪴 Camera

three.js의 카메라 종류

three.js에서 일반적으로 사용하는 카메라는 두가지임.

  1. Perspective Camera(원근 투영 카메라)
    우리의 눈과 같은 원리
  2. Orthographic Camera(정사 투영 카메라)
    캐드 도면 또는 어떤 게임은 정사 투영 카메라로 만들어지기도 함.

절두체(Frustum)

두 카메라 모두 절두체(Frustum)라는 개념이 존재함. 위 사진에서 빨간 육면체가 절두체에 해당하는 영역. 즉, 최종 렌더링 화면은 절두체 안에 있는 것들만 포함됨.

=> 카메라를 정의한다 = 절두체를 정의한다


카메라 생성을 위한 파라미터

절두체를 정의하기 위한 값들임.




🪴 Perspective Projection (원근 투영 카메라)

  • 화각 Fovy
  • 화면 비율 Aspect
  • 절두체에 대한 가장 가까운 거리 zNear
  • 절두체에 대한 가장 먼 거리 zFar

R3F의 Canvas 컴포넌트는 Aspect를 자동으로 계산하기 때문에 3차원 장면이 렌더링되는 영역의 비율을 설정해줌.

=> 따라서 렌더링 요소들을 절두체 내부에 넣기위해서는 FovyzNear, zFar의 값을 잘 조절해야함.


Fovy

화각이 커질수록 장면이 작게 렌더링되며, 0 ~ 180 사이의 값임.

<Canvas
  camera={{
    fov: 75, // Fovy: 렌즈 화각, 단위는 degree
    position: [7, 7, 0], // 카메라 위치 좌표
  }}
>
  <Box />
</Canvas>

zNear

zNear가 특정 값보다 커지면 3D객체가 절두체에 벗어나게 돼서 렌더링 시 잘려서 나옴.

<Canvas
  camera={{
    fov: 75,
    near: 9, // zNear: 카메라와 절구체의 최소 거리
    far: 20,
    position: [7, 7, 0],
  }}
>
  <Box />
</Canvas>

zFar

zFar가 특정 값보다 작아지면 3D객체가 절두체에 벗어나게 돼서 렌더링 시 잘려서 나옴.

<Canvas
  camera={{
    fov: 75,
    near: 9,
    far: 10, // zFar: 카메라와 절구체의 최대 거리
    position: [7, 7, 0],
  }}
>
  <Box />
</Canvas>

lookAt

useThree로 camera 객체 접근하는 방법

R3F의 Canvas 컴포넌트 내부의 Scene에서 useThree 훅을 사용하여 camera 객체에 접근할 수 있음. 카메라의 위치와 카메라가 바라보는 타켓 위치를 변경할 수 있음.

const { camera } = useThree();
useControls({
  positionZ: {
    value: 0,
    min: -10,
    max: 10,
    step: 0.1,
    onChange: (v) => (camera.position.z = v),
  },
  targetZ: {
    value: 0,
    min: -10,
    max: 10,
    step: 0.1,
    onChange: (v) => camera.lookAt(0, 0, v),
  },
});

useFrame으로 state.camera 객체 접근하는 방법

R3F의 useFrame 훅을 사용하여 state.camera 객체에 접근할 수 있음. 매 프레임마다 카메라의 위치와 카메라가 바라보는 타겟 위치를 수정할 수 변경할 수 있음.

useFrame((state) => {
  const time = state.clock.elapsedTime;

  const target = new THREE.Vector3();
  // 빨간색 구의 좌표 추출하여 target 백터 객체에 저장
  smallSpherePivot.children[0].getWorldPosition(target);
  // 카메라 position에 적용
  state.camera.position.copy(target);

  const ghostSpherePivot = state.scene.getObjectByName('ghostSpherePivot');
  // 빨간색 구의 y회전 각도보다 30도 더 회전시킴
  ghostSpherePivot.rotation.y = THREE.MathUtils.degToRad(time * 50 + 30);
  // ghostSpherePivot의 좌표를 추출하여 target 백터 객체에 저장
  ghostSpherePivot.children[0].getWorldPosition(target);
  // 카메라의 타겟 좌표에 적용
  state.camera.lookAt(target);
});

빨간색 구가 토러스를 통과하는 중에 토러스가 잘림. 이를 해결하기 위해서 zNear의 값을 더 작게 변경하면 더 자연스러워짐.




🪴 Orthographic Camera (정사 투영 카메라)

  • 절두체의 xLeft, xRight: 절두체의 너비값 정의
  • 절두체의 yTop, tBottom: 절두체의 높이(길이)값 정의
  • 절두체에 대한 가장 가까운 거리 Near
  • 절두체에 대한 가장 먼 거리 Far

R3F의 Canvas 컴포넌트는 xLeft, xRight, yTop, tBottom을 자동으로 계산하기 때문에 3차원 장면이 렌더링되는 영역의 비율을 설정해줌.

=> 따라서 렌더링 요소들을 절두체 내부에 넣기위해서는 NearFar의 값을 잘 조절해야함.


orthographic, zoom

orthographic 카메라를 사용하기 위해서는 Canvas 태그에 orthographic 속성을 추가해줘야함. 추가후 렌더링해보면 크기가 매우 작게 표시되는데, 해당 카메라의 경우 xLeft, xRight, yTop, tBottom 를 자동으로 계산하기 때문에 값에 직접 접근하기보다는 zoom 속성을 사용하여 렌더링 크기를 변경하는 것이 좋음. 위 이미지처럼 원근감 없이 렌더링 되는 것을 확인할 수 있음.

<Canvas
  orthographic
  camera={{
    near: 0.1,
    far: 20,
    zoom: 100, // 배율
    position: [7, 7, 0],
  }}
>
  <Box />
</Canvas>


0개의 댓글