Three.js 의 PointerLockControls 은 브라우저에 내장된 Pointer Lock API 를 구현한다.
PointerLockControls 은 시간 경과에 따른 마우스 움직임(즉, 델타)에 기반한 입력 방법을 제공한다.
이 PointerLockControls 를 사용하면 마우스는 가운데에 고정으로 숨김처리되어 보이지 않는다.
따라서 보통 1인칭 시점 3D 게임에 사용된다.
자, 그럼 간단한 사용 예를 들어보자.
다음과 같은 div 요소가 있다고 가정하고,
const controls = new PointerLockControls(camera, renderer.domElement)
const menuPanel = document.getElementById('menuPanel') as HTMLDivElement
const startButton = document.getElementById('startButton') as HTMLButtonElement
startButton.addEventListener(
'click',
() => {
controls.lock()
},
false
)
controls.addEventListener('change', () => {
console.log('pointerlock change')
})
controls.addEventListener('lock', () => (menuPanel.style.display = 'none'))
controls.addEventListener('unlock', () => (menuPanel.style.display = 'block'))
lock()
: 앞서 언급한 마우스 포인터를 중앙에 고정 후 숨김
참고로 lock()
함수는 바로 사용하면 안 되고 반드시 어떤 함수의 콜백으로써 사용되어야한다. 그렇지 않으면 다음과 같은 에러를 만나게 된다.
let geometries: THREE.BufferGeometry[] = []
for (let i = 0; i < 1000; i++) {
const g = new THREE.BoxGeometry(Math.random() * 4 + 1, Math.random() * 29 + 1, Math.random() * 4 + 1)
g.computeBoundingBox()
g.translate(Math.random() * 500 - 250, ((g as any).boundingBox.max.y - (g as any).boundingBox.min.y) / 2, Math.random() * 500 - 250)
geometries.push(g)
}
// merge geometries
const mergedGeometries = BufferGeometryUtils.mergeGeometries(geometries)
const cubeMaterial = new THREE.MeshStandardMaterial({ roughness: 0.12, metalness: 0.9 })
const buildings = new THREE.Mesh(mergedGeometries, cubeMaterial)
buildings.castShadow = true
buildings.receiveShadow = true
scene.add(buildings)
수 천개의 Geometry 를 생성하고 이를 mergeGeometries()
함수로 하나로 묶으면 수 천개가 하나의 Geometry 로 묶여 Material 과 shadow 작업을 한 번만 수행하면 된다.
이는 또한 renderer.info.render.calls
를 로그를 찍어보면 알 수 있는데 1000개를 만들었는데 하나의 Geomatry 로 묶여서 렌더링을 1개만 해주면 된다는 것이다. 만약 하나로 묶지 않았다면 아마 1004개가 되었을 것이다.