안녕하세요. 무려 한달 반만에 작성하는 게시글입니다.
프로젝트를 진행하며 무척 애를 먹었던 부분이 생겨 글을 작성해봅니다.
우선 제목에서 알다시피 threejs의 TextGeometry부분입니다.
다른 지오메트리와 달리 textGeomtry는 매 프레임마다 업데이트 되면 성능문제를 피할 수 없습니다.
여기서 말하는 업데이트란, 텍스트의 변화입니다.
사진으로 보기엔 정상적으로 나오는 텍스트입니다. 하지만 이것을 매 프레임마다 업데이트한다면 어떻게 될까요?
제 경우에서는 "onmousemove"이벤트에서 실행될 것입니다.
좌표 (0,0,0)에서 현재 마우스 위치까지의 거리를 "distanceTo"메서드로 구한 후 이를 텍스트로 나타내는 기능입니다.
영상에서 보시다시피 마우스를 움직이면 즉각적으로 텍스트에 변화가 생기는 것이 아니라 몇 초의 짧은 텀을 두고 텍스트가 업데이트 됩니다.
마치 디바운스를 사용한 것 같습니다.
해당 성능문제는 저를 사흘을 넘게 괴롭혔습니다. 하나하나 체크하며 성능 문제를 발생시키는 부분을 확인하기도 했고, 모든 코드를 갈아엎기도 했습니다.
예시로 보여드린 코드는 매우 간단합니다.
function onMouseMove(e){
// ...do something
if (scene.getObjectByName("text")) {
scene.remove("text");
}
const t = new Text({ text: `${distance}` });
t.name = "text";
t.rotation.x = -Math.PI / 2;
scene.add(t);
}
다른 지오메트리는 괜찮지만 유독 텍스트 지오메트리에서 성능이슈가 발생하는 이유는 TextGeometry의 생성 과정이 매우 비싼 연산이기 때문입니다.
TextGeomtry는 텍스트를 폰트 매트릭스에 따라 3D 지오메트리로 변환하는 복잡한 과정을 거칩니다. 이 과정에는 세그먼트, 폰트 데이터 등의 복잡한 계산이 필요합니다.
그럼 어떻게해야 성능이슈 없이 프레임마다 폰트를 생성할 수 있을까요?
답은 threejs discourse에서 찾을 수 있었습니다.
매 프레임마다 TextGeometry를 업데이트하는 것을 피하고, "Troika-three-text"와 같은 threejs와 연계될 수 있는 외부 라이브러리를 사용하는 것을 권장한다 합니다.
해당 공식문서를 읽어보는 것을 추천합니다만, 사용법은 threejs보다 훨씬 쉽습니다.
const t = new Text();
scene.add(t);
t.color = "red";
t.fontSize = 5;
t.name = "text";
t.text = `${distance}`;
t.rotation.x = -Math.PI / 2;
t.sync();
영상이 저품질이라 끊기는 느낌이 들지만, 실제로는 매우 부드럽게 동작하고 있습니다.
'자바스크립트' 카테고리의 다른 글
THREEJS로 인테리어 기능 (1) | 2024.09.23 |
---|---|
JS) 무한 캔버스(Infinity Canvas)의 원리와 구현 (1) | 2024.06.30 |
React) mediasoup을 이용한 SFU (1) | 2024.05.03 |
JS) 논리적 AND OR (0) | 2024.04.16 |
JS) remove() 와 removeChild() (0) | 2024.04.12 |