Three.js PointerLockControls, mergeGeomatery

강정우·2025년 1월 14일
0

three.js

목록 보기
20/24
post-thumbnail

PointerLockControls

Three.js 의 PointerLockControls 은 브라우저에 내장된 Pointer Lock API 를 구현한다.

PointerLockControls 은 시간 경과에 따른 마우스 움직임(즉, 델타)에 기반한 입력 방법을 제공한다.

이 PointerLockControls 를 사용하면 마우스는 가운데에 고정으로 숨김처리되어 보이지 않는다.
따라서 보통 1인칭 시점 3D 게임에 사용된다.

PointerLockControls(THREE.Camera, domElement?: HTMLElement | null)

자, 그럼 간단한 사용 예를 들어보자.
다음과 같은 div 요소가 있다고 가정하고,

.lock(), .unlock()

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() 함수는 바로 사용하면 안 되고 반드시 어떤 함수의 콜백으로써 사용되어야한다. 그렇지 않으면 다음과 같은 에러를 만나게 된다.

mergeGeomatery

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개가 되었을 것이다.

what is render.calls?

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글