1. 문제 소개

최근 3D 렌더링을 위한 Three.js를 사용한 프로젝트에서, 복잡한 3D 모델과 애니메이션을 처리하면서 성능 저하 문제가 발생했습니다.

특히, 다수의 3D 오브젝트를 렌더링하는 데 있어서 프레임 드랍(fps 저하) 현상과 웹 브라우저에서의 렌더링 속도 저하 문제가 두드러졌습니다.

이는 실제 사용자 경험에 큰 영향을 미쳤고, 개발 과정에서 병목 지점을 찾아 성능 최적화가 필요하다는 점이 명확히 드러났습니다.

2. 직면한 문제 설명

Three.js를 사용하여 3D 모델을 렌더링하는 과정에서, 다음과 같은 문제가 발생했습니다

  • 프레임 드랍: 복잡한 3D 모델이 많은 경우(예: 100개 이상의 오브젝트) 렌더링 성능이 급격히 저하되었습니다.

  • 느린 반응 속도: 마우스 인터랙션이나 카메라 이동 시 렌더링 속도가 느려지거나 지연되는 현상이 발생했습니다.

  • 자원 소모 증가: GPU와 CPU 자원 소모가 급증하여 브라우저에서 다른 탭을 전환하거나 다른 작업을 진행할 때 웹 성능이 현저히 저하되었습니다.

3. 문제 분석

문제의 핵심은 렌더링 최적화와 효율적인 리소스 관리가 부족했다는 점입니다.

개발자 도구에서 확인한 결과, 렌더링 성능을 저하시킨 주된 원인은 불필요한 렌더링 호출과 비효율적인 3D 오브젝트 관리였습니다.

특히 다음과 같은 병목 지점들이 있었습니다

  • 렌더링 호출 횟수 과다: 매 프레임마다 불필요한 렌더링을 호출하고 있었습니다.

  • 과도한 3D 모델 업데이트: 3D 모델의 위치나 상태를 자주 변경하는 과정에서 성능이 떨어졌습니다.

  • 애니메이션 처리: 큐브 애니메이션을 처리할 때, 복잡한 계산과 연산이 매 프레임마다 발생하여 성능에 영향을 미쳤습니다.

4. 해결책

성능 문제를 해결하기 위해 다음과 같은 접근 방식을 사용했습니다:

4.1 렌더링 최적화

렌더링을 불필요하게 호출하지 않도록, 렌더링 조건을 최적화했습니다.
예를 들어, 3D 씬을 한 번만 렌더링하고 이후에는 렌더링을 필요할 때만 호출하도록 구현했습니다.

let needsRendering = true;

function animate() {
    if (needsRendering) {
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
        needsRendering = false;  // 렌더링 후 호출 안 함
    }

    // 애니메이션 업데이트
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    // 조건에 따라 렌더링을 다시 요청
    if (cube.rotation.x % Math.PI === 0) {
        needsRendering = true;
    }
}

4.2 오브젝트 및 애니메이션 최적화

모든 오브젝트의 애니메이션을 처리할 때, 프레임 단위로 렌더링을 최소화하고, 경량화된 애니메이션을 적용하여 성능을 개선했습니다.

예를 들어, 3D 오브젝트의 회전 속도를 일정 간격으로 업데이트하고, 너무 복잡한 애니메이션은 제거했습니다.

// 애니메이션 업데이트 속도 줄이기
let lastTime = 0;
function animate() {
    const now = Date.now();
    if (now - lastTime > 30) {  // 30ms마다 업데이트
        cube.rotation.x += 0.01;
        cube.rotation.y += 0.01;
        lastTime = now;
        renderer.render(scene, camera);
    }
    requestAnimationFrame(animate);
}

4.3 기타 최적화 방법

  • WebGLRenderer의 antialiasing을 비활성화하고, 복잡한 씬의 경우 레벨 오브 디테일(LOD)을 적용하여 성능을 개선했습니다.

  • OrbitControls에서 발생하는 렌더링 부하를 줄이기 위해, 카메라 제어 시 렌더링을 최소화하도록 했습니다.

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;  // 부드러운 카메라 이동
controls.dampingFactor = 0.25;
controls.screenSpacePanning = false;  // 화면을 넘는 카메라 이동 비활성화

5. 성능 측정 및 개선 전후 비교

개선 전

  • 프레임율: 약 25fps
  • CPU 및 GPU 자원 소모: 70% 이상
  • 렌더링 지연: 약 200ms

개선 후

  • 프레임율: 약 60fps 이상
  • CPU 및 GPU 자원 소모: 40% 이하
  • 렌더링 지연: 약 50ms 이하

성능 측정 도구를 사용하여 프레임별 자원 소모와 프레임 속도를 분석했습니다.
개선 후, 렌더링 시간과 CPU/GPU 자원 소모가 확연히 줄어들었으며, 사용자 경험 또한 개선되었습니다.

결과 및 결론

위의 성능 최적화 작업을 통해, 렌더링 속도와 자원 소모를 크게 개선할 수 있었습니다.
특히, 프레임 드랍 문제가 해결되어 사용자 경험이 향상되었으며, 성능 테스트 결과도 매우 긍정적이었습니다.

이 최적화 작업은 다양한 3D 모델을 다룰 때 필요한 기본적인 최적화 방법을 제공하며, 실무에서 3D 렌더링 프로젝트를 진행할 때 매우 유용한 기술로 활용될 수 있습니다.

출처: Three.js Demo

profile
꾸준히, 의미있는 사이드 프로젝트 경험과 문제해결 과정을 기록하기 위한 공간입니다.

0개의 댓글