문제 소개: Three.js로 3D 씬 렌더링 시 성능 저하 문제

Three.js는 강력한 3D 렌더링 라이브러리지만, 복잡한 씬을 렌더링할 때 성능 저하 문제가 발생할 수 있습니다.

예를 들어, 큰 용량의 텍스처를 로드하거나, 복잡한 기하학적 형태를 그리거나, 잘못된 카메라 설정으로 인해 렌더링 속도가 느려질 수 있습니다.

이로 인해 페이지가 끊어지거나, 렌더링 품질이 떨어지는 등의 문제가 발생할 수 있습니다.

문제의 예시로는 3D 모델을 씬에 추가했을 때, 화면이 깨지거나 렌더링 속도가 현저히 느려지는 경우가 있을 수 있습니다.

이는 WebGLRenderer의 설정이 적절하지 않거나, 복잡한 씬이 렌더링되는 과정에서 성능 병목이 발생하는 경우입니다.

직면한 문제

1. 렌더링 속도 저하

너무 많은 3D 객체와 텍스처를 한 번에 로드할 때 발생하는 속도 저하 문제.

2. 메모리 사용량 급증

복잡한 모델이나 텍스처를 렌더링할 때 메모리 사용량이 급증하여, 특히 저사양 장치에서 렌더링이 불가능해지는 문제.

3. 화면 깜빡임

렌더링이 부드럽게 처리되지 않아 화면이 깜빡이거나, 끊어지는 현상.

해결책 1: 텍스처 최적화 및 LOD(Level of Detail) 사용

문제 분석

렌더링 성능 저하의 주요 원인 중 하나는 텍스처의 크기입니다.
고해상도 텍스처를 사용하면 메모리 사용량과 렌더링 시간이 급격히 늘어나게 됩니다.
또한, 너무 많은 텍스처를 한 번에 로드하면 GPU의 처리 능력을 초과할 수 있습니다.

해결책

1. 텍스처 크기 축소
가능한 텍스처의 해상도를 줄여서 메모리 사용을 최적화합니다.

2. LOD (Level of Detail) 사용
객체가 카메라로부터 멀어질수록 낮은 해상도의 텍스처를 사용하여 성능을 향상시킵니다.

// 텍스처 로딩 최적화 예시
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('path/to/texture.jpg');

// 텍스처 크기를 줄여 로드
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.generateMipmaps = false; // mipmap 생성하지 않음

3. 불필요한 객체 렌더링 방지
카메라에서 멀리 있는 객체는 렌더링하지 않도록 설정합니다.

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ map: texture });

const cube = new THREE.Mesh(geometry, material);
cube.frustumCulled = false; // 카메라 밖의 객체는 렌더링하지 않도록 설정
scene.add(cube);

해결책 2: 카메라와 렌더러 최적화

문제 분석

카메라의 설정이나 렌더러의 설정이 잘못되면 렌더링 성능에 큰 영향을 미칩니다.
예를 들어, 불필요하게 복잡한 카메라 설정이나 잘못된 프로젝션 매트릭스가 성능 저하를 일으킬 수 있습니다.

해결책

1.카메라의 near 및 far 속성 최적화
카메라의 near와 far 속성값이 너무 넓으면 깊이 버퍼의 정밀도가 낮아져 성능에 영향을 미칩니다.

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.near = 0.5; // 최소 거리
camera.far = 1000; // 최대 거리

2. 렌더러의 안티앨리어싱 설정 최적화
안티앨리어싱을 비활성화하거나, 성능에 맞는 설정으로 조정합니다.

const renderer = new THREE.WebGLRenderer({ antialias: false });

3. 창 크기 변경 시 카메라와 렌더러 크기 동기화

window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
});

해결책 3: 애니메이션 최적화

문제 분석

애니메이션을 구현할 때, requestAnimationFrame을 사용하여 렌더링을 최적화하는 것이 일반적입니다.
하지만 불필요한 계산이 많거나, 렌더링 주기가 너무 자주 발생하면 성능에 악영향을 미칩니다.

해결책

1. 애니메이션 루프에서 불필요한 렌더링 방지

let lastTime = 0;

function animate(time) {
    requestAnimationFrame(animate);
    const deltaTime = time - lastTime;

    if (deltaTime > 1000 / 60) { // 60fps로 제한
        renderer.render(scene, camera);
        lastTime = time;
    }
}

2. 애니메이션 속도 조절 및 오버헤드 제거

// 객체의 애니메이션 속도 조절
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;

성능 테스트 및 결과

성능 비교 전후

  • 성능 테스트: fps 측정을 통해 최적화 전후의 프레임 속도 변화를 측정했습니다.
  • 테스트 환경: 웹 브라우저 (Chrome), 1080p 해상도, 고사양 PC

결과 분석

1. 성능 향상

텍스처 최적화와 카메라 설정 최적화 후 평균 FPS가 45에서 60으로 향상되었습니다.
또한, 메모리 사용량이 300MB에서 200MB로 감소하였습니다.

2. 프레임 시간 분석

프레임 시간이 안정적으로 유지되었으며, 화면 깜빡임이나 지연 없이 부드럽게 렌더링되었습니다.

결론

이번 포스팅에서 다룬 성능 최적화 방법은 Three.js로 복잡한 3D 씬을 렌더링할 때 발생할 수 있는 여러 문제를 해결하는 데 효과적이었습니다.

텍스처 최적화, 카메라 설정 최적화, 애니메이션 루프 최적화를 통해 렌더링 성능을 크게 향상시킬 수 있었습니다.

실시간 성능 테스트 결과를 통해 최적화 전후의 성능을 비교할 수 있었고, 최적화 후 더욱 부드럽고 빠른 렌더링을 확인할 수 있었습니다.

이와 같은 성능 최적화 기법은 3D 웹 애플리케이션에서 매우 중요한 부분이므로, 실제 프로젝트에 적용하여 성능을 향상시키는 데 도움이 될 것입니다.

출처: Three.js Basic (Scene, Camera, Renderer)

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

0개의 댓글