안녕하세요 :)
개인 프로젝트로 블랙홀을 만들고 있는데요, 재미있는 gltf 오브젝트가 있어서 추가해 보았습니다.
저는 보통 작업할 때 크롬을 사용하기 때문에, 크롬 환경에서 시간에 따른 액션 변화를 설정했는데요,
이게 웬걸 사파리나 파이어폭스에서는 액션이 엉뚱한 타이밍에 트리거 되는 것이었습니다.
왜 이런 문제가 발생하는지 찾아보니 브라우저별 성능차이로 인한 문제였습니다.
Three.js에서 움직임을 표현할 때 자바스크립트 내장 함수인 requestanimationFrame을 많이 이용합니다.
이 함수는 한 차례 랜더링이 끝나면 이어서 다음 랜더링이 시작되기 때문에 기기와 브라우저의 프레임 차이에도 최적화된 움직임을 표현할 수 있습니다.
문제는 저는 requestanimationFrame안에서 인스턴스의 상태를 업데이트하며 Three.Clock 클래스의 delta 타임을 인자로 넣어주었습니다. 그리고 초반 불필요한 애니메이션을 스킵하기 위해 delta 타임에 고정된 값을 곱하거나 나누어 애니메이션 속도를 조절했습니다. delta 타임은 이전 프레임 렌더링 이후 얼마만큼의 시간이 흘렀는지를 계산합니다. 따라서 기능이 좋아 프레임 렌더링이 잦은 기기나 브라우저에서는 여러 번 인스턴스의 상태가 업데이트되며 곱해지거나 나누어진 delta 시간이 들어가며 애니메이션의 액션이 브라우저마다 달라지는 현상이 발생했던 것으로 추측됩니다.
아래와 같이 deltaTime을 직접 구해서 인스턴스에 전달해 주는 방식으로 해결했습니다.
class World {
constructor(canvasEl) {
....
this.lastTimestamp = Date.now()
window.addEventListener('resize', () => this.resize())
}
resize() {
this.renderer.resize()
this.camera.resize()
}
update() {
const deltaTime = (Date.now() - this.lastTimestamp) / 1000
this.lastTimestamp = Date.now()
this.renderer.update()
this.postprocessor.update()
this.spaceDust.update(deltaTime)
this.ton618_gltf.update()
this.stars.update()
this.gate.update(deltaTime)
this.controller.update()
requestAnimationFrame(() => {
this.update()
})
}
}
사실 개념상 Three.Clock deltaTime과 다를바가 없습니다만 왜 이렇게 하니까 문제가 해결되는지 잘은 모르겠습니다 :(
문서에 따르면 Three.Clock deltaTime은 getDelta 함수가 호출되고 다음 호출 때까지의 시간을 값으로 가진다고 합니다. 그렇다면 제가 직접 구한 deltaTime과는 값이 같아야 하지만 아래와 같이 값이 다름을 확인할 수 있었습니다. 그리고 직접 구한 deltaTime의 경우 값이 비슷비슷하였지만 Three.Clock의 deltaTime은 값의 편차가 컸습니다. 심지어 어떤 값은 0이었습니다.
직접 구한 deltaTime : 0.023
Three.Clock deltaTime: 0.0010000000000072759
공부가 아직 많이 필요해 보이긴 합니다.
혹시나 원인을 아시는 분은 공유해 주시면 정말 감사하겠습니다.

'Canvas > Three.js' 카테고리의 다른 글
[Three] Curious about the mind of AI (0) | 2024.01.19 |
---|---|
[Three] AI의 머릿속이 궁금하다 (0) | 2024.01.19 |
[Three.js] 텍스처가 깜빡이는 문제 (0) | 2023.08.18 |
[Three.js] renderer와 scene 백그라운드 차이 (0) | 2023.06.07 |