본문 바로가기

자바스크립트

threejs) 프레임마다 업데이트되는 TextGeometry

안녕하세요. 무려 한달 반만에 작성하는 게시글입니다.

프로젝트를 진행하며 무척 애를 먹었던 부분이 생겨 글을 작성해봅니다.

 

우선 제목에서 알다시피 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