본문 바로가기
Three.js/Intro

[threejs-journey 1-6] Control

by SL123 2025. 6. 10.

 

개요

Three.js에서는 다양한 카메라 및 오브젝트 제어 컨트롤(Controls)이 제공되어, 3D 장면을 보다 자유롭고 직관적으로 탐색하거나 조작할 수 있도록 도와줍니다.

 

각 컨트롤은 사용 목적과 조작 방식이 다르므로, 모든 기능을 암기할 필요는 없습니다. 대신, 사용하려는 상황에 따라 적절한 컨트롤을 선택하여 문서를 참고하면서 적용하면 됩니다.

- 각 컨트롤은 Three.js 공식 문서에서 예제와 함께 확인할 수 있습니다.
- 대표적인 컨트롤로는 OrbitControls, FlyControls, FirstPersonControls, PointerLockControls, TrackballControls, TransformControls, DragControls 등이 있으며, 각각의 특성과 입력 방식이 다릅니다.

 

 

- FlyControls

https://threejs.org/docs/#examples/en/controls/FlyControls

 

three.js docs

 

threejs.org

자유롭게 공중을 부유하면서 상하좌우 이동할 수 있는 카메라 컨트롤입니다. 중력이나 지면 충돌 개념이 없기 때문에, 우주 공간이나 비행 시뮬레이션 같은 장면에서 사용하기 적합합니다

키보드로 이동, 마우스로 방향 전환
중력 없음 / 바닥 없음
속도 조절 가능(movementSpeed, rollSpeed 등)

 

 

- FirstPersonControls

https://threejs.org/docs/#examples/en/controls/FirstPersonControls

 

three.js docs

 

threejs.org

 

사용자가 마우스를 움직이면 카메라가 회전하고, 키보드(WASD)로 이동할 수 있는 1인칭 시점 컨트롤입니다. 중력 없이 자유롭게 이동하는 환경에서 사용되며, 일반적인 1인칭 어드벤처나 탐험 게임에 적합합니다.

마우스 이동 = 카메라 회전
WASD 이동
중력 없음
lookSpeed, movementSpeed 등 조절 가능

 

 

- PointerLockControls

https://threejs.org/docs/#examples/en/controls/PointerLockControls

 

three.js docs

 

threejs.org

 

마우스를 클릭하면 커서가 사라지고, 마우스 움직임으로 시점을 회전시키는 FPS 스타일 컨트롤입니다. 일반적인 FPS 게임과 같은 움직임을 제공합니다.

클릭 시 커서 잠금 (Pointer Lock)
마우스 = 시점 회전 / WASD = 이동
FPS 게임 스타일
중력/지면 충돌 기능 직접 구현 필요

 

 

- Pointer Lock API

https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API

 

Pointer Lock API - Web APIs | MDN

The Pointer Lock API (formerly called Mouse Lock API) provides input methods based on the movement of the mouse over time (i.e., deltas), not just the absolute position of the mouse cursor in the viewport. It gives you access to raw mouse movement, locks t

developer.mozilla.org

PointerLockControls의 기반이 되는 Web API입니다. 이 API를 사용하면 마우스의 이동량(delta)을 추적하여 보다 정밀한 입력 처리가 가능합니다. 커서를 감추고, raw mouse movement에 접근할 수 있기 때문에 게임 또는 3D 툴에서 자주 사용됩니다.

document.body.requestPointerLock()
mousemove 이벤트로 delta 추적
자유도 높은 커스터마이징 가능

 

 

- OrbitControls

https://threejs.org/docs/#examples/en/controls/OrbitControls

 

three.js docs

 

threejs.org

 

마우스를 이용해 카메라가 대상(타겟)을 중심으로 공전(orbit) 하도록 제어합니다. 가장 기본적이면서도 직관적인 3D Scene 탐색 컨트롤입니다. 제품 뷰어, 3D 뷰어, 전시 콘텐츠, 인터렉티브 씬 탐색 등에 사용됩니다.

마우스 드래그 = 회전 (공전)
마우스 휠 = 줌 (거리 조절)
마우스 우클릭/Shift 드래그 = 패닝
target 속성 기준으로 움직임 (예: 중심점)
enableDamping(관성), autoRotate, minDistance/maxDistance 등 설정 가능

 

 

- TrackballControls

https://threejs.org/docs/#examples/en/controls/TrackballControls

 

three.js docs

 

threejs.org

 

마우스를 중심으로 마치 트랙볼을 돌리듯이 카메라를 회전, 확대, 이동시킬 수 있는 컨트롤입니다. OrbitControls보다 더 자유롭고 부드러운 카메라 제어가 가능합니다. CAD 스타일 에디터, 3D 툴 뷰어, 자유 회전 인터페이스 등에 사용됩니다.

마우스 이동 = 회전
휠 = 줌
Shift + 드래그 = 패닝
회전 방향이 마우스 움직임과 더 직관적으로 매칭됨
관성 느낌을 줄 수 있어 편집 툴, 3D UI에서 자주 사용

 

 

- TransformControls

https://threejs.org/docs/#examples/en/controls/TransformControls

 

three.js docs

 

threejs.org

오브젝트를 이동(translate), 회전(rotate), 스케일(scale) 할 수 있는 위젯을 제공하는 컨트롤입니다. Unity/Blender처럼 축을 기준으로 직접 조작할 수 있습니다. 3D 에디터, AR/VR 콘텐츠 배치, 오브젝트 조작 툴 등에서 사용됩니다.

X, Y, Z 축에 대한 Gizmo 제공
모드 전환 : "translate", "rotate", "scale"
attach(object)로 적용
dragging 상태를 통해 다른 컨트롤과 충돌 방지 가능
마우스로 직접 핸들을 클릭하고 드래고

 

 

- DragControls

https://threejs.org/docs/#examples/en/controls/DragControls

 

three.js docs

 

threejs.org

오브젝트를 마우스로 직접 드래그하여 이동할 수 있게 해주는 컨트롤입니다. 평면(예: XY 평면) 상에서 간단한 드래그/드롭 기능을 구현할 수 있습니다. 퍼즐 게임, 드래그 기반 배치 시스템, UI 요소 이동에 적합합니다.

클릭한 오브젝트를 마우스로 끌기 가능
raycaster 기반, 직관적인 조작
이동 범위 제약, 충돌은 직접 구현 필요
setObjects()로 조작 가능한 객체 지정

 

 

- OrbitControls 사용법

OrbitControls는 Three.js에서 가장 널리 사용되며, 대상(타겟)을 중심으로 카메라를 회전시키는 대표적인 컨트롤입니다. 해당 카메라 컨트롤의 사용방법에 대해서 알아보죠.

 

 

 

- import 시 주의사항

// 아래처럼 접근하면 에러 발생
console.log(THREE.OrbitControls); // 오류 발생

// 아래처럼 명시적으로 가져와야 함
import { OrbitControls } from "three/examples/jsm/Addons.js";

console.log(OrbitControls); // 정상 출력

import * as THREE from "three" 는 핵심(Core) 기능만을 포함하며, OrbitControls 보조 유틸리티는 따로 불러와야 합니다. 또한, 모듈 구조가 분리되어있기 때문에 직접적으로 가져와서 import를 시켜줍니다. 

 

 

 

- target 위치 변경

카메라가 바라보는 지점을 바꾸고 싶을 때 controls.target을 수정합니다.

const controls = new OrbitControls(camera, canvas);
controls.target.y = 2;
controls.update();

이 때 update를 하지 않으면 동작하지 않기 때문에 반드시 update를 수행해줘야 합니다.

 

 

 

- 부드러운 카메라 이동(enableDamping)

enableDamping을 활성화하면 관성 효과처럼 부드럽게 움직입니다. 반드시 애니메이션 루프에서 controls.update()를 호출해야 적용됩니다.

 
controls.enableDamping = true;

const tick = () => {
  controls.update(); // 필수!
  renderer.render(scene, camera);
  window.requestAnimationFrame(tick);
};

 

 

결론

대부분의 경우 OrbitControls 하나로도 충분하지만, 장면의 성격에 따라 FlyControls, PointerLockControls 등 다양한 컨트롤을 활용하면 더욱 몰입감 있는 사용자 경험을 만들 수 있습니다. 목적에 맞는 컨트롤을 선택하고, 공식 문서를 참고해 유연하게 적용하는 습관이 중요합니다.