Three.js에서 애니메이션을 구현하다 보면 아래와 같은 코드를 자주 볼 수 있습니다.
const currentTime = Date.now()
const deltaTime = currentTime - time
time = currentTime
mesh.rotation.y += 0.001 * deltaTime
처음 보면 이런 생각이 들 수 있습니다.
currentTime도 현재 시간인데, time도 시간 아닌가?
왜 currentTime - time 을 하는 걸까?
이번 글에서는 Three.js에서 일정한 애니메이션 속도를 유지하기 위해 deltaTime을 사용하는 이유를 알아보겠습니다.
Date.now()는 현재 시간을 반환한다
Date.now()
는 현재 시간을 밀리초(ms) 단위로 반환합니다.
예를 들어:
console.log(Date.now()) // 1747551000000
처럼 아주 큰 숫자가 출력됩니다.
currentTime 과 time 의 차이
여기서 중요한 점은:
- currentTime → 현재 프레임 시간
- time → 이전 프레임 시간
이라는 점입니다.
즉:
const deltaTime = currentTime - time
은
이전 프레임 이후 얼마나 시간이 지났는지
를 계산하는 코드입니다.
동작 흐름 이해하기
예를 들어 첫 번째 프레임에서:
time = 1000
이라고 가정해보겠습니다.
다음 프레임에서 현재 시간이:
currentTime = 1016
이라면:
deltaTime = 1016 - 1000
결과는:
16
이 됩니다.
즉:
지난 프레임 이후 16ms가 지났다는 의미입니다.
그리고:
time = currentTime
를 실행하여 다음 프레임을 준비합니다.
왜 deltaTime 이 필요한가?
컴퓨터마다 FPS(Frame Per Second)가 다르기 때문입니다.
예를 들어:
- 어떤 컴퓨터는 60fps
- 어떤 컴퓨터는 144fps
- 어떤 컴퓨터는 30fps
로 실행될 수 있습니다.
잘못된 애니메이션 방식
mesh.rotation.y += 1
이렇게 작성하면 프레임마다 회전값이 증가합니다.
문제는 FPS가 높은 컴퓨터일수록 더 많은 프레임이 실행된다는 점입니다.
예를 들어:
- 60fps 컴퓨터 → 1초 동안 60번 실행
- 30fps 컴퓨터 → 1초 동안 30번 실행
즉:
- 60fps → 총 60만큼 회전
- 30fps → 총 30만큼 회전
하게 됩니다.
결과적으로 FPS가 높은 컴퓨터에서 애니메이션이 훨씬 빠르게 동작하게 됩니다.
deltaTime 을 사용하면 왜 일정해질까?
핵심은:
프레임 기준이 아니라 시간 기준으로 움직이기 때문입니다.
예를 들어:
speed = 100
이라면:
1초에 100만큼 이동
한다고 가정해 보겠습니다.
60fps 환경
60fps 환경에서는 보통:
deltaTime ≈ 16ms
정도가 나옵니다.
즉:
0.016초
가 지난 것입니다.
이번 프레임에서 이동해야 하는 양은:
100 * 0.016 = 1.6
이 됩니다.
그리고 1초 동안 약 60번 실행되므로:
1.6 * 60 = 96
정도로 거의 100에 가까운 이동량이 됩니다.
30fps 환경
30fps 환경에서는:
deltaTime ≈ 33ms
정도가 됩니다.
즉:
0.033초
가 지난 것입니다.
이번 프레임 이동량은:
100 * 0.033 = 3.3
이 됩니다.
1초 동안 약 30번 실행되므로:
3.3 * 30 = 99
가 됩니다.
핵심 원리
FPS가 낮으면:
- 프레임 실행 횟수는 적지만
- 한 번에 더 많이 이동
하게 됩니다.
반대로 FPS가 높으면:
- 프레임 실행 횟수는 많지만
- 한 번에 조금씩 이동
하게 됩니다.
결과적으로:
어떤 FPS 환경에서도 1초 기준 이동량이 비슷해지는 것
입니다.
쉽게 비유하면
deltaTime 없이 이동
"한 걸음씩 걸어"
- 빨리 걷는 사람 → 더 빨리 도착
- 천천히 걷는 사람 → 늦게 도착
deltaTime 사용
"1초 동안 1m 이동"
- 빨리 발을 움직이면 보폭이 작아짐
- 천천히 움직이면 보폭이 커짐
하지만 결과적으로는 같은 속도로 이동하게 됩니다.
실제 Three.js 코드
let time = Date.now()
const tick = () =>
{
const currentTime = Date.now()
const deltaTime = currentTime - time
time = currentTime
mesh.rotation.y += 0.001 * deltaTime
renderer.render(scene, camera)
window.requestAnimationFrame(tick)
}
tick()
THREE.Clock 사용하기
최근에는 직접 시간을 계산하기보다 Three.js의 Clock 클래스를 사용하는 경우도 많습니다.
Three.js 에서는 다음과 같이 사용할 수 있습니다.
const clock = new THREE.Clock()
const tick = () =>
{
const deltaTime = clock.getDelta()
mesh.rotation.y += deltaTime
renderer.render(scene, camera)
window.requestAnimationFrame(tick)
}
getDelta()가 자동으로 이전 프레임과 현재 프레임의 시간 차이를 계산해 주기 때문에 더 간단하게 사용할 수 있습니다.
정리
Three.js에서:
currentTime - time
을 계산하는 이유는:
이전 프레임과 현재 프레임 사이의 시간 차이(deltaTime)를 구하기 위해서입니다.
그리고:
movement = speed * deltaTime
처럼 사용하여:
- FPS가 높은 환경에서는 조금씩 자주 이동
- FPS가 낮은 환경에서는 크게 적게 이동
하도록 보정하여 결과적으로 일정한 애니메이션 속도를 유지할 수 있게 됩니다.
Three.js에서 부드럽고 안정적인 애니메이션을 구현하기 위해 꼭 이해해야 하는 중요한 개념 중 하나입니다.
'프론트엔드 > Three.js' 카테고리의 다른 글
| [ Three.js ] PerspectiveCamera는 어떤 역할을 할까요? (0) | 2026.05.21 |
|---|---|
| [ Three.js ] Date.now() 와 THREE.Clock 의 차이점 (0) | 2026.05.19 |
| [ Three.js ] React Three Fiber vs Three.js, 어떤 걸 배워야 할까요? (0) | 2026.05.15 |
| [ Three.js ] Three.js의 미래는 밝을까? (0) | 2026.05.07 |
| [ Three.js ] MeshLambertMaterial의 특징 (0) | 2025.02.02 |
댓글