이론/그래픽스

텍스처

tsyang 2022. 1. 22. 02:10

텍스처?


텍스처 매핑이란 물체의 표면에 컬러를 입히는 기법이다. 픽셀 쉐이더에서 텍스처의 값을 참조해 물체 표면을 표현하는 픽셀의 최종 컬러에 영향을 준다.

 


 

대역폭(병목)


텍스처가 병목인 경우는 주로 메모리 대역폭이 모자란 경우이다. 대역폭이란 프로세서가 메모리에 있는 데이터를 가져올 때 최대로 가져올 수 있는 크기를 말한다. PC의 경우에 메모리 대역폭이 문제가 되는 경우는 적지만 모바일 환경의 경우는 다르다.

 

모바일의 경우에는 성능보다 전력 효율이나 발열등을 신경써야 한다. 메모리도 나름 발열과 전력소비를 많이 하는데 따라서 모바일 하드웨어의 메모리 대역폭은 상당히 작게 설계되는 편이다. 이런 메모리 이슈에는 GPU가 CPU 메모리에서 데이터를 가져오는 경우도 해당한다. 

 

텍스처는 메모리를 많이 사용하는데, 따라서 텍스처의 크기(=해상도)가 성능에 큰 영향을 미치게 된다. 

 

 


 

텍스처 압축


성능을 잡겠다고 텍스처의 해상도를 무작정 줄이면 그래픽 퀄리티가 떨어지게 된다. 따라서 텍스처 압축이 필수적인 고려 대상이다. 

 

텍스처는 이미지와 같지만 일반적인 이미지 압축을 사용할 수는 없다. 그 이유는 랜덤 엑세스와 관련이 있다.

 

"AAAAABBBBCCC" 라는 문자열이 있다. 이 문자열은 12글자이지만 "5A4B3C"와 같이 표현한다면 6글자로 표현할 수 있다. 이런 압축 방식은 같은 길이라도 어떤 문자열이냐에 따라 압축된 결과물의 길이가 달라질 수 있다. 이런 방식을 가변 비율 인코딩이라고 한다. 

 

가변 비율 인코딩의 경우 랜덤 엑세스가 불가하다. 예를 들어 "5A4B3C"라는 인코딩된 문자열의 원본에서 9번째 문자가 뭔지 알고 싶다면? 프로세서는 문자열의 맨 앞부터 디코딩 해 나가야 한다. 

 

이런 방식은 GPU가 사용하기에 무리가 있는데 한 픽셀이 무슨 색인지 알기 위해서는 빠른 속도로 텍스처의 데이터를 읽어올 수 있어야 하기 때문이다. 

 

따라서 텍스처는 고정 비율 인코딩을 사용한다. 이런 경우 원본 텍스처의 픽셀을 n개씩 묶어 블록 단위로 다룰 수 있다.

 

디코딩 속도 역시 성능에 영향을 미치므로 적당한 압축 효율에 적당한 퀄리티로 타협을 봐야 한다. 그렇기 때문에 손실 압축을 사용한다.

 

 

텍스처 압축 기법들

메모리에 올라간 압축된 텍스처를 다시 고속으로 압축 해제 하려면 디코딩이 하드웨어에 구현되어 있어야 한다. 따라서 압축의 방식은 하드웨어에 의존적이다. 따라서 하드웨어 별로 몇 가지 텍스처 압축 기법이 있다.

 

모바일 환경에서는 PVRTC,ETC,ASTC를 대표적으로 쓴다.

 

PVRTC : iOS기기에서 주로 쓰이는 놈. 블록화 현상에 유리하지만 반대로 번짐 현상이 발생한다. 따라서 일반적인 텍스쳐에는 좋지만 도트나 아이콘에는 좋지 않다. 그런데 도트같은 경우에는 애초에 해상도가 작아서 그냥 텍스처 압축을 포기하면 된다.

 

ETC : 안드로이드 기기에서 많이 쓰는 포맷이다. 색의 차이보다는 밝기에 사람의 눈이 더 민감하다는 사실에 기인하여 만들었다. 따라서 일반적으로 좋은 퀄리티를 보여주지만 색상 차이가 큰 이미지에서는 화질 저하가 두드러지게 나타날 수 있다. ETC2에서는 이러한 단점을 보완하여 상위 호환이나, Open GL ES 3.0 이상에서만 사용 가능하다. 

 

ASTC : ARM에서 개발한 텍스처 압축 알고리즘. 이 방법의 가장 큰 특징은 가변 블록 크기를 사용하여 품질을 맘대로 조절할 수 있다는 점이다. 이런 방식은 파티클처럼 이미지가 뭉개져도 상관 없는 경우는 12x12를 사용하여 용량을 절약하는 등 사용자가 적절하게 품질을 조절하면 더 효율적으로 텍스처를 압축할 수 있다는 장점이 있다. 그리고 일반적으로 ETC보다 품질이 좋다. 또한 안드로이드와 iOS 모두 지원하기 때문에 유지보수가 수월하다. 그러나 지원하는 기기의 성능 컷이 좀 높은 편이므로 타겟 디바이스에 제약이 좀 있다.

 

https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/Unity/Korean%20Unity%20Guide%20Translations/Real%20time%203D%20Texturing_KO.pdf

 

그외

16비트 디더링 : 위의 텍스처 압축 기법들은 어쩔 수 없이 화질 열화가 생긴다. 따라서 이미지의 정밀도를 반 정도로만 줄이고 디더링을 사용하기도 한다. (정밀도를 반으로 줄이면 마하 밴드가 생기는데 이걸 디더링으로 손보는 방식)

 

크로마 서브샘플링 : 이 기법은 거의 원본 대비 품질 저하가 없다. 다만 반투명한 색상은 표현하지 못한다. (알파 채널이 1bit) 크로마 서브샘플링은 BPP(Bits Per Pixel)가 32인 이미지를 BPP12로 표현해준다. 이는 ETC나 PVRTC보다 효율이 떨어지지만 품질 저하가 거의 없다는 점에서 유리하다. 이 방식은 쉐이더로 구현되어 있어서 디코딩이 GPU에서 일어난다. 즉, CPU가 디코딩을 해서 생기는 부하는 없다. 이 방식은 1비트의 알파 채널, 추가적인 쉐이더 사용등의 부담이 있지만 카드게임의 일러스트와 같이 화질 저하에 민감한 부분에 사용하기 좋다. 

 


밉맵(Mipmap)


이건 텍스처의 LOD라고 생각하면 된다. 화면에서 작게 그려지는 애들을 위해 작은 해상도의 텍스처를 따로 마련하는 것이다. 

 

https://en.wikipedia.org/wiki/Mipmap

이런식으로 하면 런타임 성능은 좋아지지만 메모리 사용은 늘어난다. 

 

만약 3D 게임에서 밉맵을 끄면 성능도 떨어지지만 지글거림과 같은 문제가 발생할 수 있다. 그러나, 화면에 그려지는 오브젝트의 크기가 줄어들 일이 없다면 (ex. 횡스크롤 게임의 캐릭터) 밉맵이 필요 없을 수 있다. 

 


 

기타

POT

Power Of Two. 즉 2의 n승을 말한다. POT 해상도의 텍스처라 하면 1024, 2048 등의 해상도를 의미한다. ETC나 PVRTC 방식은 POT 텍스처를 사용해야 하므로 텍스처들을 POT 해상도로 제작할 필요가 있다. POT 해상도가 아닌 것을 NPOT라고 한다. 단, 2D 스프라이트나 GUI 이미지 같은건 NPOT여도 아틀라스로 묶어서 POT 문제를 쉽게 해결할 수 있다.

 

Read/Write Enable

유니티에 보면 Read/Write Enable 체크박스가 있다. 이건 CPU가 해당 텍스처에 접근할 수 있냐 없냐를 나타내는데, 텍스처는 GPU 메모리에 상주하므로 CPU가 런타임에 텍스처에 접근하려면 텍스처를 CPU메모리에 올려야 하기 때문이다. 

 


참고 : 오지현, 유니티 그래픽스 최적화 스타트업, 비엘북스, [336~377p]

 

 

'이론 > 그래픽스' 카테고리의 다른 글

(기초) 포워드 VS 디퍼드 렌더링  (1) 2022.07.13
컬링(Culling)  (0) 2021.12.14
배칭(Batching)  (2) 2021.11.15
드로우콜(Draw Call)  (3) 2021.11.13
병목(Bottleneck)  (0) 2021.11.03