[three.js] 애니메이션 루프 함수

네모난네모·2024년 11월 28일
1
post-thumbnail

three.js 실습을 진행하면서 어디에는 requestAnimationFrame이 쓰이고, 어디에는 setAnimationLoop가 쓰이고 있다는 것을 발견했다.
지금의 실습 범위에서는 두 함수의 차이점을 느끼지 못하고 있지만 나중을 위하여 차이점을 확인해두어야 겠다는 생각이 들어 기록을 해두려고 한다.

애니메이션 루프란

3D 애니메이션을 계속 갱신하고 렌더링하는 과정을 말한다.

Three.js에서 애니메이션 루프를 구현하는 주요 방법에는 requestAnimationFrame()setAnimationLoop() 두 가지가 있다.

두 방법 모두 애니메이션을 매 프레임마다 실행하고, 화면을 갱신해준다.

requestAnimationFrame()

이 함수는 브라우저의 네이티브 함수로, 애니메이션을 한 프레임씩 실행하고, 다음 프레임을 요청한다.

브라우저의 네이티브 함수란 웹 브라우저에서 제공하는 기본적인 내장 함수를 말하며
자바스크립트 환경에서 추가적인 라이브러리나 프레임워크 없이 바로 사용할 수 있는 기능이다.

이 함수는 각 화면 갱신 주기마다 호출되며, 브라우저가 최적의 속도로 실행할 수 있도록 해준다.

특징

  • requestAnimationFrame()는 애니메이션 함수 내에서 수동으로 호출해야 하며, 콜백 함수 안에서 재귀적으로 호출해야만 애니메이션이 이어진다.
  • requestAnimationFrame(animate) : animate 함수가 호출될 때마다 새로운 프레임을 그리기 전에 animate()가 호출된다.
  • Three.js와 별개로, 다양한 애니메이션을 필요로 하는 프로젝트에서 많이 사용된다.

예문

function animate() {
  requestAnimationFrame(animate); // 애니메이션 루프를 계속해서 호출
  mesh.rotation.x += 0.01; 
  mesh.rotation.y += 0.01;
  renderer.render(scene, camera); // 장면 렌더링
}

animate();

setAnimationLoop()

이 함수는 Three.js의 고유한 함수로, three.js의 WebGLRenderer 객체에 내장되어 있다.
애니메이션 루프를 Three.js의 장면 렌더링과 함께 최적화하여 관리할 수 있다.

특징

  • 함수 내에서 호출하지 않아도 자동으로 애니메이션 루프를 계속 호출한다.

  • Three.js 렌더러와 통합되어 있어 렌더러의 프레임 타이밍과 최적화된 동작을 보장한다.

  • WebXR(가상/증강현실) 환경과 통합되어 있어, VR/AR 렌더링 루프에서 효율적으로 동작한다.

    WebXR은 웹 환경에서 가상현실(VR)과 증강현실(AR) 경험을 제공하기 위한 API다.
    브라우저가 VR/AR 장치를 지원하도록 설계되어, 사용자가 별도의 애플리케이션을 설치하지 않고도 웹에서 몰입형 경험을 즐길 수 있다.

예문

function animate() {
  mesh.rotation.x += 0.01; 
  mesh.rotation.y += 0.01;
  renderer.render(scene, camera); // 장면 렌더링
}

renderer.setAnimationLoop(animate); // setAnimationLoop로 애니메이션 루프 시작

[참고] 애니메이션 중단

requestAnimationFrame()

  • 애니메이션 중단을 위해 별도의 플래그를 사용해야 한다.
let isAnimating = true; // 애니메이션 상태 플래그

function animate() {
  if (!isAnimating) return; // 플래그가 false면 애니메이션 종료
  requestAnimationFrame(animate); // 반복 호출 예약
  mesh.rotation.x += 0.01; 
  mesh.rotation.y += 0.01;
  renderer.render(scene, camera);
}

animate();

setAnimationLoop()

  • 애니메이션 중단을 위해 별도의 플래그나 조건을 추가할 필요 없이 setAnimationLoop(null)을 호출하는 것으로 바로 중단된다.
renderer.setAnimationLoop((time) => {
  mesh.rotation.x += 0.01;
  renderer.render(scene, camera);

  if (mesh.rotation.x > Math.PI) {
    renderer.setAnimationLoop(null); // 루프 종료
  }
});

1개의 댓글

comment-user-thumbnail
2024년 11월 28일

잘 배우고 갑니다!!

답글 달기