게임의 리소스중 대부분은 텍스처이다. 따라서 텍스처 최적화는 게임 성능에 가장 큰 영향을 미친다.


아래는 텍스처 최적화에서 자주 논의되는 개념들을 나열한 것이다.


1. POT

POT 은 Power Of Two 의 약어로, 2의 거듭제곱을 말한다. 많은 하드웨어에서 2의 거듭제곱 크기인 텍스처만을 사용할 수 있다. 하지만 게임에서는 2의 거듭제곱이 아닌 텍스처들도 분명 존재하고, 유니티는 이를 사용할 수 있도록 하기 위해 내부적으로 작업을 수행한다. 이 작업은 원본 텍스처보다 큰 2의 거듭제곱 텍스처를 만들고 원본 크기만큼을 복사, uv 를 조절하는 작업이다. 따라서 메모리 비용이 증가한다. 원본 크기를 제외한 영역은 재활용할 수 없으므로 낭비이다. 따라서 가능한 2의 거듭제곱 텍스처를 사용해야만 한다.


2. Compression

1024 x 1024 크기의 32비트 텍스처는 4MB의 메모리를 차지한다. 안드로이드를 기준으로, 이 텍스처를 ETC1 포맷으로 압축하면 512KB 로 정확히 8배 감소한다. 메모리 최적화 면에서 압축이 가장 높은 효율을 보인다. 하지만 압축에는 다음과 같은 제약사항이 있다.

- 대부분 POT 크기의 텍스처만 지원한다

- iOS 에서 사용하는 압축 방식인 PVRTC 같이 정방 크기의 텍스처만 지원하는 경우도 있다

- 알파를 지원하지 않는 경우도 있다. ETC1 같은 포맷은 지원하지 않는다. 이는 아래의 Alpha Channel Split 을 참고한다

압축은 대부분의 하드웨어에서 지원하고 원본과 비교했을 때 품질 저하가 적기 때문에 적극 권장되는 방법이다.


3. Color Channel Bits 낮추기

압축 포맷을 사용하지 않을 경우 RGBA 32비트 혹은 RGB 24비트 포맷이 많이 사용된다. 둘의 차이는 알파 채널의 존재 여부이다. 각 채널당 8비트 를 할당한 포맷으로 품질면에서 제일 좋은 반면 메모리는 가장 많이 차지한다. 채널에 할당되는 비트수를 낮추는 것으로 품질은 떨어뜨리면서 차지하는 메모리를 낮출 수 있다. RGBA 32비트, RGB 24비트 모두 16비트로 낮출 수 있는데 RGBA 32비트의 경우 각 채널당 4비트, RGBA 24비트의 경우 R채널은 5비트, G채널은 6비트, B채널은 5비트가 된다. 그라데이션같이 색의 분포가 넓은 경우 비트를 낮췄을 때 디더링( Dithering ) 현상이 심하게 나타나는데 이를 줄이기 위해 포토샵 필터 등의 외부 툴이 필요한 경우도 있다.

비트를 낮추는 방법은 품질을 크게 떨어뜨리므로 주의해서 적용해야 한다.


4. Alpha Channel Split

알파 채널이 존재하는 텍스처를 알파를 지원하지 않는 방식으로 압축하고자 할 때 알파 채널을 분리하는 방법을 사용할 수 있다. UI 같이 대부분 알파 채널을 포함하는 곳에 자주 적용되는 방법이다. 개념은 간단한데 원본 텍스처에서 알파 채널을 분리하여 별도의 텍스처로 만들고 각각을 압축, 렌더링할 때 두 장의 텍스처를 읽어서 연산해주는 것이다. 텍스처가 두 장으로 늘어나서 비효율적일 것 같으나 RGBA 32비트 텍스처 기준으로 여전히 4배 적은 크기를 차지한다. 유니티4 까지는 직접 쉐이더를 구현해야 하고 유니티5 부터는 텍스처 타입이 Legacy GUI 혹은 Sprite 인 경우에 아래처럼 지원해준다.



5. Max Size

2048 크기를 1024로, 1024크기를 512로 낮추는 것처럼 텍스처 크기를 한 단계 내리는 것으로 메모리 크기를 4배 줄일 수 있다.


6. Mipmap

밉맵은 더 적은 bandwidth 로 텍스처를 렌더링할 수 있도록 해서 렌더링 성능과 품질을 높여주는 반면 원본 텍스처가 차지하는 메모리보다 약 33% 증가한 메모리를 차지한다. 따라서 필요치 않은 경우 밉맵을 꺼서 메모리를 아낄 수 있다. 또한 밉맵 텍스처들은 빌드에 포함되므로 비활성화시 파일 크기가 줄어드는 것도 확인할 수 있다.


7. Load From File

빌드 크기를 최소화하는 방법 중 jpg 혹은 png 같은 원본 이미지 파일을 실행 중에 동적으로 로드하는 방법이 있다. 압축 포맷이 지정된 텍스처라 하더라도 jpg 보다는 훨씬 큰 경우가 많다. 따라서 원본 이미지 파일을 bytes 형태로 Resources 하위 폴더에 넣어두고 실행 중에 Resources.Load 로 읽어서 텍스처로 만들게 되면 메모리는 증가하겠지만 빌드 크기를 줄일 수 있다.

Posted by 카코데몬
,