Camera 클래스는 추상 클래스 👉 상속받아 프로퍼티와 함수를 활용한다
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 1, 100)
첫 번째 파라미터 : FOV
알맞은 fov를 찾으려면 테스트가 필요하다
👉 주로 45
나 75
를 사용
두 번째 파라미터 : Aspect ratio
// e.g.) Aespect Ratio
const sizes = {width: 800, height: 600}
near
값 보다 카메라에 가깝거나 far
값 보다 카메라에서 먼 오브젝트는 렌더링 시 보이지 않는다0.0001
이나 99999
처럼 극단적으로 큰 값들을 넣는다면 z-fighting 오류를 일으킨다0.1
과 100
사용카메라부터의 거리에 상관없이 오브젝트는 동일한 사이즈로 보여진다
const aspectRatio = sizes.width / sizes.height
const camera = new THREE.OrthographicCamera(-1 * aspectRatio, 1 * aspectRatio, 1, -1, 0.1, 100)
<canvas>
의 width
와 height
가 1:1 이 아니므로 aspectRatio
를 설정해준다 ➡️ 큐브가 늘어나거나 찌그러지지 않는다
첫 번째 - 네 번째 파라미터: left
, right
, top
and bottom
각 방향으로부터 카메라가 얼마나 멀리 볼 수 있는지 지정해주어야 한다
다섯 번째 & 여섯 번째 파라미터: Near & Far
PerspectiveCamera와 동일
// Camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 1, 1000)
camera.position.z = 3
camera.lookAt(mesh.position)
scene.add(camera)
다시 PerspectiveCamera로 돌아가 큐브를 바라보도록 카메라를 옮겨주었다
// Cursor
window.addEventListener('mousemove', (event) =>
{
console.log(event.clientX, event.clientY)
})
마우스로 카메라를 컨트롤 하기 위해서 자바스크립트의 mousemove
이벤트를 addEvenetListener
를 사용해서 구현한다
// Cursor
const cursor = {
x: 0,
y: 0
}
const tick = () =>
{
// ...
// Update camera
camera.position.x = cursor.x
camera.position.y = cursor.y
// ...
}
cursor
오브젝트 변수에 마우스 위치를 저장했으니 tick
함수를 이용해서 카메라의 위치를 업데이트 할 수 있다
window.addEventListener('mousemove', (event) =>
{
cursor.x = event.clientX / sizes.width - 0.5
cursor.y = event.clientY / sizes.height - 0.5
console.log(cursor.x, cursor.y)
})
event.clientX
를 sizes.width
로 나누는 것은 0
과 1
의 값을 리턴한다
➡️ 그 결과에 -0.5를 뺀다는 것은 -0.5
과 0.5
사이의 값을 리턴하게 될 거라는 것
const tick = () => {
// ...
// Update camera
camera.position.x = Math.sin(cursor.x * Math.PI * 2) * 2
camera.position.z = Math.cos(cursor.x * Math.PI * 2) * 2
camera.position.y = cursor.y * 3
camera.lookAt(mesh.position)
// ...
}
tick()
sin
과 cos
을 사용해서 오브젝트가 원을 그리며 움직이도록 할 수 있다
한 바퀴를 돌려면 앵글에게 𝜋 * 2 만큼의 진폭을 준다
➡️ 이런 한 바퀴를 tau라고 부르는데 자바스크립트에서는 이 값에 접근할 수 없으므로 𝜋를 이용한다
const tick = () =>
{
// ...
// Update Camera
camera.position.x = Math.sin(cursor.x * Math.PI * 2) * 2
camera.position.z = Math.cos(cursor.x * Math.PI * 2) * 2
camera.position.y = cursor.y * 3
camera.lookAt(mesh.position)
}
tick()
원의 반지름을 늘리려면 Math.sin(...)
과 Math.cos()
의 값에 곱하기를 해주면 된다
디바이스, OS, 브라우저의 방향 정보를 자동으로 얻어낸다
VR을 떠올리면 쉬울 것 같다
3가지 축 기준으로 회전시킬 수 있고 앞뒤로 움직일 수도 있다
카메라를 우주선에 탄 것 처럼 움직인다
자바스크립트의 pointer lock API를 사용한다
이 API는 커서를 숨기고 가운데에 위치시킨 후에 mousemove
이벤트 콜백에서 움직임을 보내준다
브라우저 내에서 FPS 게임 등을 만들 때 사용하며 포인터는 잠김 처리된다
마우스 좌클릭으로 오브젝트를 회전시키거나 우클릭으로 좌우로 옮길 수 있고 마우스 휠로 줌 인 / 줌 아웃이 가능하다
OrbitControls와 유사하나 버티컬 앵글에 제한이 없다
카메라와는 상관이 없고, 오브젝트를 옮기기 위해 gizmo를 오브젝트에 더해준다
TransformControls 처럼 카메라와는 상관이 없고 드래그 & 드랍을 이용해서 오브젝트를 움직일 때 사용한다
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
// Controls
const controls = new OrbitControls(camera, canvas)
OrbitControls 클래스를 사용하기 위해 임포트를 먼저 해주고 변수를 초기화한다
controls.target.y = 2
카메라는 scene의 가운데를 보여주는 것이 디폴트이지만 target
프로퍼티를 사용해서 변경할 수 있다
damping은 좀 더 부드러운 애니메이션을 구현해준다
// Controls
const controls = new OrbitControls(camera, canvas)
controls.enableDamping = true
// ...
const tick = () =>
{
// ...
// Update controls
controls.update()
// ...
}
damping을 사용하기 위해서 controls
의 enableDamping
프로퍼티를 true
로 변경한다
controls도 controls.update()
를 사용해서 각 프레임 마다 업데이트 되어야 한다
역시나 tick
함수를 이용해서 업데이트 해준다