Kris

3D 모델은 왜 이렇게 클까?

3D 압축glTFWebGL성능

당신의 모델이 몰래 살이 찌고 있다

GLB 파일을 하나 내보냈다. 10MB, 괜찮아 보인다. 그런데 휴대폰으로 옮겨 열어보니 — 하얀 화면, 버벅임, 심지어 바로 꺼져버렸다.

PC에서는 문제없는데, 휴대폰에서 터진다. 코드 탓이 아니다. 3D 모델에는 직관적이지 않은 특성이 있다: 디스크에 저장된 크기와 VRAM에서의 크기는 완전히 다르다.

JPG 이미지는 디스크에서 200KB에 불과할 수 있다. 하지만 GPU는 JPG를 모른다. GPU는 오직 원시 픽셀만 이해한다. 따라서 VRAM에 업로드되기 전에 이 이미지는 완전히 압축 해제된다. 2048x2048 텍스처 하나는 압축 해제 후 약 22MB의 VRAM을 잡아먹는다. 6개의 텍스처(albedo, normal, roughness, metallic, AO, emissive)를 사용했다면, 단일 재질 하나만으로 132MB를 소모한다.

휴대폰의 VRAM은 총 24GB 정도인데, 모델 하나의 텍스처가 36%를 차지한다. 씬에 10개의 모델이 있다면?

뜯어보자, 용량이 어디에 쓰이는지

전형적인 GLB 모델은 크게 세 부분으로 구성된다: 버텍스 데이터, 텍스처 맵, 그리고 메타데이터와 애니메이션.

실제 PBR 모델 하나를 살펴보자:

구성 요소구체적인 내용일반적인 비중설명
텍스처 맵albedo, normal, roughness, metallic, AO 등70-85%거의 항상 용량의 대부분
버텍스 데이터position, normal, UV, tangent, 색상10-20%모델 복잡도에 따라 다름
애니메이션 데이터본, 스킨, 키프레임0-15%애니메이션이 있을 때만
기타재질 정의, 씬 구조, 카메라< 2%무시 가능

텍스처 맵이 약 80%를 차지한다. 많은 경우 최적화해야 할 것이 버텍스라고 생각하지만, 실제로 공간을 많이 차지하는 것은 텍스처다.

3D 모델 PBR 텍스처 맵 분해

"디스크에서 작다" ≠ "VRAM에서 작다"

3D 성능을 이해하는 데 가장 중요한 포인트일 것이다.

PNG와 JPG는 네트워크 전송을 위해 설계되었다 — 디스크에서 작고, 다운로드가 빠르다. 하지만 GPU는 이들을 직접 사용할 수 없으며, 반드시 먼저 원시 픽셀로 완전히 압축 해제해야 한다. 계산 방법은 다음과 같다:

VRAM 점유 = 너비 * 높이 * 4바이트(RGBA) * 1.333(밉맵 포함)

4096x4096 RGBA 텍스처 하나:

지표
PNG 파일 크기~8MB
JPG 파일 크기~1.5MB
VRAM 점유 (밉맵 포함)~87MB

1.5MB의 JPG가 VRAM에서 87MB가 된다.

밉맵이란? GPU는 텍스처의 점진적으로 축소된 버전(원본 크기부터 1x1 픽셀까지, 각 단계는 이전 단계의 절반)을 생성한다. 이를 통해 먼 물체를 더 빠르고 선명하게 렌더링할 수 있지만, VRAM을 약 33% 더 사용한다. 거의 모든 3D 애플리케이션이 밉맵을 사용하므로, 이 오버헤드는 기본이라고 볼 수 있다.

따라서 PNG/JPG는 여행용 압축 팩과 같다 — 압축하면 작아서 휴대하기 편하지만, 도착지에서 모두 펼쳐야 한다. 다운로드는 빨라졌지만 VRAM은 전혀 절약되지 않았다.

디스크 저장 용량과 GPU VRAM 점유의 차이

VRAM이 부족하면 어떻게 될까

"VRAM 부족"이라는 안내창이 뜨지 않는다. 실제 상황은 더 나쁘다:

  • 모바일: 페이지가 하얗게 되거나, 시스템이 탭을 강제 종료한다.
  • VR 헤드셋: 프레임 드롭. VR에서 프레임 드롭은 "약간 버벅임"이 아니라 어지러움을 유발한다.
  • 데스크톱: 텍스처 깜빡임, 품질 저하, 렌더링 속도 저하.

네이버 카페에서 한 개발자가 WebXR 갤러리를 만들며 Quest에 60장의 스테레오 이미지를 넣었다. 처음에는 정상이었지만, 점점 불안정해지다가 결국 충돌했다. 그는 며칠 동안 코드를 디버깅했지만, VRAM을 전혀 고려하지 않았다는 것을 깨달았다 — 계속 GPU에 JPG를 밀어넣고 있었던 것이다.

압축의 두 가지 길

3D 모델 압축은 크게 두 방향으로 나뉜다:

버텍스 압축 — 버텍스 좌표, 법선, UV 등 기하 데이터를 더 콤팩트하게 저장한다. 예를 들어 32비트 부동소수점을 16비트 정수로 바꾸는 것(이를 양자화(quantization)라고 한다). 대표적인 방식: Draco, MeshOpt, KHR_mesh_quantization.

텍스처 압축 — 텍스처가 VRAM에서도 압축된 상태를 유지하도록 한다. GPU는 샘플링 시 실시간으로 단일 픽셀을 디코딩하며, 성능 오버헤드가 거의 없다. 대표적인 방식: KTX2 + Basis Universal.

버텍스 압축텍스처 압축
줄이는 것기하 데이터텍스처
일반적인 효과50-90% 축소디스크 50-70% 축소, VRAM 75% 축소
손실 있음?예, 정밀도 저하예, 화질 저하
적용 대상버텍스가 많은 모델거의 모든 PBR 모델
자세한 내용2편 참고3, 4편 참고

흔한 오해: Draco로 버텍스를 압축하면 모든 문제가 해결된다고 생각하는 것이다. 하지만 텍스처가 모델 용량의 80%를 차지하는데, 버텍스를 절반으로 줄여도 전체는 10% 정도밖에 줄지 않는다. 양쪽 모두 관리해야 한다.

모든 상황에 통하는 단 하나의 방법은 없다

이것이 이 시리즈의 핵심 주장이다:

플랫폼, 기기, 사용 방식에 따라 다른 압축 전략이 필요하다.

시나리오주요 병목집중해야 할 부분
데스크톱 웹 전시다운로드 속도파일 크기
모바일 브라우저VRAM텍스처 압축
VR 헤드셋VRAM + 프레임률텍스처 압축 + 버텍스 단순화
카카오톡 미니앱패키지 크기 + 호환성가벼운 방식 (MeshOpt)
대규모 씬VRAM + 드로우 콜전방위 압축 + LOD

앞으로의 각 편은 "X를 쓰면 된다"고만 말하지 않는다. 대신, X가 어떤 상황에 적합한지, 언제 오히려 역효과를 내는지, 어떤 경우에 Y를 써야 하는지 명확히 설명할 것이다.

다음 단계

이번 편에서 문제를 파악했다. 다음 편에서는 직접 실습한다 — 버텍스 압축의 세 가지 도구(양자화, MeshOpt, Draco)를 알아보자.

후원하기