three.js에서 일반적으로 사용하는 카메라는 두가지임.
두 카메라 모두 절두체(Frustum)라는 개념이 존재함. 위 사진에서 빨간 육면체가 절두체에 해당하는 영역. 즉, 최종 렌더링 화면은 절두체 안에 있는 것들만 포함됨.
절두체를 정의하기 위한 값들임.
R3F의 Canvas 컴포넌트는 Aspect
를 자동으로 계산하기 때문에 3차원 장면이 렌더링되는 영역의 비율을 설정해줌.
Fovy
와 zNear
, zFar
의 값을 잘 조절해야함.화각이 커질수록 장면이 작게 렌더링되며, 0 ~ 180
사이의 값임.
<Canvas
camera={{
fov: 75, // Fovy: 렌즈 화각, 단위는 degree
position: [7, 7, 0], // 카메라 위치 좌표
}}
>
<Box />
</Canvas>
zNear가 특정 값보다 커지면 3D객체가 절두체에 벗어나게 돼서 렌더링 시 잘려서 나옴.
<Canvas
camera={{
fov: 75,
near: 9, // zNear: 카메라와 절구체의 최소 거리
far: 20,
position: [7, 7, 0],
}}
>
<Box />
</Canvas>
zFar가 특정 값보다 작아지면 3D객체가 절두체에 벗어나게 돼서 렌더링 시 잘려서 나옴.
<Canvas
camera={{
fov: 75,
near: 9,
far: 10, // zFar: 카메라와 절구체의 최대 거리
position: [7, 7, 0],
}}
>
<Box />
</Canvas>
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),
},
});
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의 값을 더 작게 변경하면 더 자연스러워짐.
R3F의 Canvas 컴포넌트는 xLeft
, xRight
, yTop
, tBottom
을 자동으로 계산하기 때문에 3차원 장면이 렌더링되는 영역의 비율을 설정해줌.
Near
와 Far
의 값을 잘 조절해야함.orthographic 카메라를 사용하기 위해서는 Canvas 태그에 orthographic
속성을 추가해줘야함. 추가후 렌더링해보면 크기가 매우 작게 표시되는데, 해당 카메라의 경우 xLeft, xRight, yTop, tBottom 를 자동으로 계산하기 때문에 값에 직접 접근하기보다는 zoom
속성을 사용하여 렌더링 크기를 변경하는 것이 좋음. 위 이미지처럼 원근감 없이 렌더링 되는 것을 확인할 수 있음.
<Canvas
orthographic
camera={{
near: 0.1,
far: 20,
zoom: 100, // 배율
position: [7, 7, 0],
}}
>
<Box />
</Canvas>