더핑크퐁컴퍼니 서비스개발팀이 Unity 게임의 메모리를 줄이려고 텍스처 압축 포맷을 정리하고 실제로 적용한 기록이다. 아기상어 키즈 월드에 추가할 게임이 이전보다 많은 리소스를 쓰게 되면서 저사양 기기에서도 돌아가도록 최적화가 필요해졌다. 배경 이미지 하나를 14.2MB에서 4.7MB로 줄이고 게임 전체로는 약 100MB를 절감했다.
핵심 포인트- jpg나 png 같은 포맷은 디스크 용량을 위한 것이라 GPU가 바로 읽지 못하고 Unity가 GPU 전용 포맷으로 변환한다. 따라서 원본 이미지 포맷은 성능과 무관하다.
- ASTC를 적용하자 배경 이미지 하나의 메모리 사용량이 14.2MB에서 4.7MB로 약 3분의 1이 됐다.
- 게임 전체 텍스처를 용도에 맞게 압축해 약 100MB를 줄였다.
- ASTC는 POT가 아닌 텍스처도 압축할 수 있지만 PVRTC나 ETC는 NPOT 텍스처에서 오히려 메모리가 늘 수 있다.
- ASTC가 Unity 기본값이 아닌 이유는 구형 기기가 지원하지 않기 때문이라 대상 기기 분포를 봐야 한다.
- 압축률만 좇으면 화질이 떨어지므로 기획자·디자이너와 품질 기준을 함께 정해야 한다는 것이 결론이다.
상세 정리- 배경: 지금까지는 간단한 2D 게임이라 최적화를 깊게 보지 않았지만 앞으로 파티클과 모션과 고화질 이미지를 더 쓰게 된다.
- 대상 사용자: 주 이용자가 아이들이라 저사양 기기 비중이 높을 것으로 예상해 메모리 최적화를 우선했다.
- 텍스처의 정의: 이미지를 GPU에서 쓰기 위해 렌더링한 것으로 GPU 메모리에 직접 로드되므로 렌더링 중 접근이 빠르다.
- bpp의 의미: 픽셀당 비트가 낮으면 디스크와 메모리를 덜 쓰고 GPU가 픽셀을 읽는 데 필요한 메모리 대역폭도 줄어든다. 이 대역폭이 프레임 속도 병목이 되기도 한다.
- 무압축 RGBA: 채널당 8비트로 픽셀당 32비트를 쓰며 알파를 안 쓰면 24비트다. 품질은 최고지만 bpp도 가장 높다.
- DXT1: 16픽셀을 64비트 블록으로 바꾸며 블록마다 두 개의 RGB 극단값과 픽셀당 2비트 인덱스로 네 가지 색을 쓴다. 압축 효율은 높지만 알파를 제대로 지원하지 않아 알파 없는 이미지에 주로 쓴다.
- PVRTC: 주로 iOS에서 쓰며 DXT1과 비슷하되 블록 경계를 뭉개 블러링한다. 그 과정에서 색이 번지는 block artifact가 생길 수 있고 알파 포함 4비트로 원본 대비 8분의 1이다.
- ETC1: OpenGL ES 2.0을 지원하는 모든 안드로이드 기기에서 쓸 수 있고 픽셀당 4비트로 6분의 1이지만 알파 채널을 지원하지 않는다.
- ETC2: ETC1을 확장해 알파를 포함하지만 OpenGL ES 3.0 이상에서만 지원되며, 2.0 기기에서는 동작은 해도 효율이 떨어진다.
- ASTC: 블록 기반 압축과 엔트로피 인코딩, 가변 블록 크기를 섞어 품질과 압축률의 균형을 맞춘다.
- ASTC의 강점: 용도별로 블록 크기를 다르게 줄 수 있다. 잠깐 나왔다 사라지는 파티클은 12x12로 크게 잡아 용량을 줄이고, 플레이어 캐릭터나 주요 배경은 4x4로 작게 잡아 품질을 지킨다.
- 적용 방법: 텍스처 에셋을 고르고 Inspector에서 플랫폼별 Override를 켠 뒤 텍스처 크기와 압축 포맷을 지정한다.
- 실측 1: 압축 전 14.2MB이던 배경 이미지가 ASTC 4x4 적용 후 4.7MB가 됐고 Max Size까지 줄이면 더 내려간다.
- 실측 2: NPOT 배경 이미지에 PVRTC 4비트를 적용하면 오히려 메모리가 늘어나는 것을 확인했다.
- 실측 3: 게임 전체 텍스처에 용도별 포맷을 적용한 뒤 약 100MB가 줄었다.
- 남는 판단: 대상 연령층과 지역, 기기 분포를 확인해 포맷을 정해야 하며 대상 기기가 모두 ASTC를 지원한다면 ASTC만 써도 절감 효과가 크다.
왜 읽나Unity 모바일 게임의 메모리가 빠듯하다면 포맷별 특성과 POT 여부에 따른 역효과까지 한 번에 확인하고 바로 적용해볼 수 있다.