UDN
Search public documentation:

TextureOptimizationTechniquesKR
English Translation
日本語訳
中国翻译

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 홈 > 머티리얼과 텍스처 > 텍스처 최적화 기법
UE3 홈 > 퍼포먼스, 프로파일링과 최적화 > 콘텐츠 프로파일링과 최적화 > 텍스처 최적화 기법

텍스처 최적화 기법


문서 변경내역: Jeff Wilson 작성. 홍성진 번역.

개요


메모리와 디스크 공간 사용량은 어느 게임 개발에 있어서든 항상 문제입니다. 콘텐츠가 메모리와 디스크 공간을 많이 차지하게 되는 때가 오면 가장 큰 문제아는 거의 텍스처입니다. 종종 세심한 계획 없이, 채널 패킹을 효율적으로 사용하지 않고 풀에 텍스처를 추가했기 때문에 발생하는 문제입니다.

여기서는 비효율적으로 사용된 텍스처를 정리하는 꼼수와, 프로젝트 마감에 임박해서가 아닌 일찍서부터 효율 좋은 똑똑한 콘텐츠를 만드는 법에 대해 설명하겠습니다.

콘텐츠 평가


개발 도중 디스크 공간이 문제가 된다면, 디스크 상에 올리는 콘텐츠의 평가를 통해 어디에서 공간을 절약할 수 있을지 통찰해 볼 수 있습니다. 이 작업의 대부분은 눈으로 훑어 보는 것이라 금방 끝납니다. 콘텐츠 브라우저에서 패키지 안의 텍스처를 살펴보면 어디에서 공간이 낭비되는지 빠르게 알아볼 수 있습니다.

예:

assessment.jpg

마스터 머티리얼 디폴트


가끔 불필요하게 큰 텍스처가 게임 콘텐츠에 포함될 수 있는 부분은 마스터 머티리얼을 사용할 때입니다. 마스터 머티리얼에서 텍스처 샘플 파라미터를 사용할 때, 그 파라미터에 텍스처를 적용해야 하는데, 종종 전혀 보이지가 않는 경우가 있습니다. 각각의 자식 머티리얼이 각자의 목적에 맞게 덮어써 버렸기 때문이죠.

보시는 패키지의 T_Test_Mask 텍스처가 좋은 예입니다. 마스터 머티리얼을 살펴보면 이 머티리얼이 텍스처 샘플 파라미터에 적용되어 있는 것을 확인할 수 있습니다.

master_default.jpg

이 512x512 텍스처는 마스터 머티리얼에 디폴트로 적용된 것 이외에 실제 게임에서 사용되거나 나타나지 않고 있습니다. 문제는 마스터에 있는 텍스처는 쓰이든 안쓰이든 자식에게 무조건 물려준다는 점입니다. 이 문제점은 단순한 8x8 픽셀 검정 텍스처로 대체하면, 범용 패키지에 저장되어 비슷하게 셋업된 마스터 머티리얼에 재사용될 테니, 쉽게 해결할 수 있습니다. 또 한가지 주의할 점은, 노멀맵 용으로 사용된 텍스처 샘플 파라미터를 가진 마스터 머티리얼이 있는 경우, 별도의 플레이스홀더 텍스처를 사용해야 노멀 맵에 대한 플레이스홀더로 항상 노멀맵을 사용할 수 있을 것입니다.

머티리얼 참조 검사하기


머티리얼을 프로파일링할 때, 채널 팩의 일부가 아닌 (즉 RGB 이미지의 한 채널이 아닌) 이펙트에 대한 텍스처를 눈여겨 보십시오. 툭하면 낭비가 될 유력 후보입니다. 아래 예를 봅시다:

effect_no_pack.jpg

이 이펙트는 그레이스케일 텍스처로 보이는 RGB 출력을 사용하고 있으니, 텍스처는 확실히 채널 패킹된 텍스처의 일부가 아닙니다. 더욱 자세히 조사해 보기 위해, 텍스처 샘플의 Texture 프로퍼티에 대한 find_in_browser.jpg 버튼을 눌러 브라우저로 동기화시킵니다. 여기서는 텍스처가 512x512 노이즈 타일임을 확인할 수 있습니다.

다음 단계는 이 텍스처를 사용하는 것이 있는지, 있다면 무엇인지 찾아보는 것입니다. 텍스처에 우클릭하고 맥락 메뉴에서 이 텍스처를 사용하는 머티리얼 전부 찾기 를 선택합니다. 문제 텍스처를 사용하는 머티리얼로 구성된 콜렉션을 만들어 주는 매우 편리한 명령입니다. 처음 실행하면 느립니다. 게임 콘텐츠의 크기에 따라 5 분 이상 걸릴 수도 있습니다.) 그러나 보통 처음 실행한 이후로는 매우 빠르게 실행됩니다.

콜렉션이 생성되면 선택해서 텍스처를 참조하는 것이 더 있는지 확인합니다.

이 경우 머티리얼 수가 꽤 되는데, 게임 전반적으로 많이 공유된 모양입니다. 제거한다고 득이 될 지 알 수 있는 것은 아니지만, 전폭적인 최적화가 더 필요한 경우도 있다는 점 유념하시기 바랍니다.

채널 패킹과 통합(consolidation)


앞의 패키지를 살펴보니, 공간 낭비의 주범으로 텍스처가 셋 지목되었습니다:

assessment_waste.jpg

이들 각각은 컬러 채널 셋이 전부 사용되고 있는 1024x1024 이미시브 텍스처입니다. 게다가 각 텍스처의 극히 일부분만 실제로 사용되고 있다는 것도 주목해 보십시오. 검적 픽셀 전부가 불필요하게 메모리를 차지하는 것입니다. 여기 문제는 이중이지만 해결책은 꽤나 간단합니다: 한 채널당 텍스처 하나씩, 하나의 텍스처로 패킹한 다음 가급적 픽셀을 조금 사용하도록 잘라냅(crop)니다.

이미시브 텍스처는 특히나 부드럽고, 잘라내기도 쉽고, 디테일도 엄청나지 않아서 이런 최적화에 이상적입니다. 게다가 일반적으로는 머티리얼의 전체적인 모양에 엄청난 공헌을 하는 것도 아닙니다. 물론 그런 경우가 아니고서야, 이 최적화도 그 특정 텍스처와 상황에 이상적이지 않을 수 있습니다.

emissive_mesh.jpg

이미시브 텍스처를 잘라낸 다음 '채널 패킹'을 하면 엄청난 메모리와 디스크 공간을 절약할 수 있습니다. 먼저 모든 이미시브를 256x256 영역에 맞도록 잘라냅니다. 가끔은 단순한 잘라내기 이상의 작업이 필요할 수도 있습니다. 예를 들어 가로나 세로로 잘라낸 다음 다른 축을 따라 스케일하여 텍스처를 찌그러뜨릴(squish) 수도 있습니다. 그런 다음 머티리얼에서 도로 펴서 괜찮아 보이나 확인하면 됩니다. 선이 부드러운 이미시브 텍스처에는 괜찮을 것입니다. 그러나 선이 강한 이미시브에는 괜찮지 않을 것입니다.

emissive_crop.jpg

이제 포토샵에서 요 이미시브들을 채널 패킹하겠습니다. 즉 컴파일된 3 채널 텍스처의 컬러 채널에 하나하나를 저장한다는 뜻입니다.

emissive_pack.jpg

채널 패킹 텍스처에 관해 알아두면 좋을 점이 한 가지 있습니다. 사용하는 압축 포맷이 DXT1 이라는 점인데, 압축 스키마에 기지를 발휘하여 데이터의 나머지 한 비트를 텍스처의 녹색 채널에 저장한다는 것입니다. 그리하여 디테일 빈도를 좀 높여줄 가치가 있거나 미묘한 이미시브가 있을 경우, 녹색 채널에 넣으면 가장 높은 품질을 낼 수 있습니다.

256 으로 잘라내고 나서도 보니, 텍스처에 여전히 낭비 공간이 많이 남아있을 수가 있습니다. 공간도 있고, 텍스처는 이미 잘라냈고, 머티리얼에 어떤 식으로든 오프셋시켰다면, 퀄리티를 높여 보는 것이 어떻겠습니까? 텍스처의 고해상도 소스 아트를 집어와서 그 이미시브에 더 고해상도 버전을 떨궈 주면, 같은 공간을 사용하면서도 그 채널의 퀄리티를 높일 수 있습니다.

emissive_highres.jpg

또 한 가지, "음, 텍스처에 채널이 하나 더 남아 있으니, 제 4 의 이미시브를 또 하나 끌어와도 되지 않을랑가?" 하는 생각이 들 수도 있습니다. 여기에서 문제는 4 채널 텍스처의 압축 방식은 DXT1 이 아닌 DXT5 라는 점인데, DXT5 에서 명심할 점 한가지는 알파 채널이 압축률 면에서 전체 해상도를 사용한다는 점입니다. 무슨 소리냐면, RGB 세 채널을 모두 합한 것 만큼의 메모리를 차지한다는 소립니다! 그래서 DXT5 가 비싼 것이지요.

이쯤에서 저장하고 채널-패킹된 텍스처를 임포트해도 됩니다.

이제 이미시브 텍스처를 잘라내고 오프셋시킬 수 있도록 지원하는 기능을 마스터 머티리얼에 셋업해 줘야 합니다. 셰이더가 약간 (6 인스트럭션) 복잡해 지기는 하지만, 텍스처 풀은 이미 넉넉해 졌을 것이기에 약간의 인스트럭션 가치는 할 것입니다.

마스터 셰이더가 텍스처 스톨(stalled, 지연) 상태, 즉 픽셀 셰이더 인스트럭션 처리보다 텍스처 샘플 처리에 더 많은 시간이 걸리고 있는 상태라면, 인스트럭션이 약간 추가된다고 해서 퍼포먼스에 영향을 끼칠 일은 없습니다. 그 상태를 알아보는 방법은 머티리얼을 PIX 캡처한 다음 마이크로소프트 퍼포먼스 분석 툴을 사용하여 분석해 보면 됩니다.

초기에 셰이더는 요 이미시브 텍스처를 "정말" 있는 그대로 받고 있습니다.

emissive_no_offset.jpg

머티리얼 위에 텍스처를 오프셋시켜 움직일 수 있도록 해 줘야 겠으니, 머티리얼 인스턴스 별로 파라미터를 더해 간단한 셰이더 계산을 약간 추가하여 처리해 주겠습니다.

(Click for full size)

emissive_offset_small.jpg

Static Switch Parameter (스태틱 스위치 파라미터)로 인스턴스마다 잘라낸 이미시브를 사용할 것인지 정해줄 수 있습니다. 스태틱 스위치는 바이너리 스위치처럼, 다른 말로 켜면 "A" 입력으로 들어가는 셰이더 인스트럭션 사용하고, 끄면 "B" 만 사용하는 식으로 작동합니다. 즉 "Opt In" 을 사용하기 전에는, 퍼포먼스 부하가 전혀 추가되지 않는다는 뜻입니다.

스위치 관련해서도 한 가지, 스위치 이름을 동사로 지어주면 좋다는 점입니다. 스위치를 토글하는 액션을 만드는 식으로 말이죠. 그러면 머티리얼을 처음 보는 사람도 두 옵션의 의미를 쉽게 알 수 있을 것입니다. 예를 들어 스위치 이름을 "CroppedEmissive", 잘라낸 이미시브라고만 해 놓고 셰이더를 보면, 어느 옵션이 어떤 상태를 말하는지 어찌 알겠습니까? 반면 "UseCroppedEmissive", 잘라낸 이미시브 사용 같은 식으로 해 두면 값의 체크 여부와 이름만으로도 스위치의 동작과 그 상태를 한 눈에 알 수 있을 것입니다. 그러니 항상 스위치 이름은 동사로 해 주시기 바랍니다.

여기의 파라미터는 간단한 Char_Emissive_CropOffset 라는 것으로, 이미시브 글로우의 X Y 좌표를 조작할 수도 있고, 그런 다음 X Y 스케일 파라미터로 텍스처를 한 축 개별적으로 스케일할 수도 있습니다. 어느 이미시브 텍스처든 "도로 펼 수"(unsquish) 있는 것입니다!

이 계산을 한 두 인스트럭션 정도 절약해서 할 수 있는 방법도 있지만, 다양한 옵션을 전부 소화하기에는 이 방법이 좋습니다.

다음, RGB 채널 패킹된 텍스처의 어느 채널을 사용할 것인지 선택할 수 있어야 하겠습니다. 머티리얼에 StaticComponentMaskParameter (스태틱 컴포넌트 마스크 파라미터) 표현식을 추가하면 새로이 패킹된 텍스처 속 어느 컬러 채널이든, 3 채널 중 딱 하나만 셰이더 체인에 통과시켜 선택적으로 사용할 수 있습니다:

emissive_channel_mask.jpg

이제 마스터 셰이더에 적용시킨 다음, 그 마스터를 부모로 사용하는 인스턴스를 하나 열어 변경한 것이 제대로 작동하는지 테스트해 봅시다.

먼저 잘라낸 이미시브를 사용하기 위해 스태틱 스위치를 켭니다.

emissive_usecropped.jpg

그런 다음 새로이 패킹된 텍스처를 이미시브 슬롯에 적용합니다:

emissive_texture.jpg

사용할 컬러 채널을 선택합니다 (이 경우엔 빨강이죠):

emissive_componentmask.jpg

스케일 파라미터를 2 로 설정하여 머티리얼에 적당한 이미시브 크기를 구해냅니다.

emissive_scale.jpg

emissive_wrap.jpg

음 그런데 별로 괜찮아 보이지가 않네요. 왜 그럴까요? 텍스처가 CLAMP(제한)로 설정되지 않았기 때문입니다. 디폴트로 UE3 에 새로이 임포트된 텍스처는 텍스처 프로퍼티에 WRAP 설정됩니다. 다른 말로 타일링하게 되는 경우 반복된다는 뜻입니다. 브라우저에서 텍스처에 더블클릭하고 CLAMP 로 설정해 줍니다.

emissive_texclamp.jpg

거기서 이 옵션도 설정해 줍니다:

emissive_preserveborder.jpg

텍스처의 가장자리 픽셀은 전부 검기에, 이렇게 하면 어떤 밉 레벨을 뿌리든 항상 검정 상태로 있게 된다는 뜻입니다. 정말정말 멀리 떨어져 있을 때 텍스처가 발리지(못알아보도록 뭉개지지) 않도록 합니다.

emissive_clamp.jpg

낫죠! 이제 파라미터를 사용하여 텍스처를 오프셋시킵니다. 눈대중으로도 충분합니다만, 잘라낸 값을 정확히 포토샵에서 계산하여 박스에 입력하는 식도 가능합니다. 여기서는 우연히도, 오프셋 없이 완벽히 들어맞아 있습니다.

emissive_cropoffset.jpg

머티리얼 인스턴스의 이미시브 컬러를 바꿔주고 체크합니다:

emissive_color.jpg

같은 과정을 다른 머티리얼 인스턴스에도 새로이 패킹된 이미시브 텍스처를 사용하여 해 줍니다. 최종 결과는 이렇습니다:

emissive_mesh_final.jpg

이제 미사용 텍스처를 없앱니다. 여기서는 consolidate (통합) 명령을 사용하겠습니다.

구식 텍스처 셋을 선택한 다음 새로 만든 것도 선택해 줍니다.

emissive_select.jpg

우클릭하고 Consolidate (통합)을 선택합니다. 이 작업은 선택한 것 중 셋을 삭제한 다음, 그 셋을 넷째로 영구히 redirect 해 줍니다. 이 작업은 패키지가 달라도 할 수 있는 작업이지만, 안전을 위해 모두 미리 체크아웃해 두십시오. 이 작업은 되돌릴 수 없으니, 조심하시기 바랍니다!

이런 대화창이 뜹니다:

emissive_consolodate.jpg

새로이 패킹된 이미시브 텍스처를 선택하고, consolidate_button.jpg 버튼을 누릅니다. 세 노병은 영영 사라지고, 신참만 남습니다. 다시 강조하건데, 조심! 심각한 문제가 생길 수 있습니다! 패키지 저장 잊지 마시고요.

끝맺음


  • UV 를 패킹할 때, 이미시브를 서로 가까이 붙여 패킹해 보세요! 잘라내기도 쉽고 메모리도 절약됩니다.
  • 애초에 이런 식으로 셋업을 해 두면, 나중에 고생이 훨씬 덜합니다.
  • 가끔 셰이더 복잡도를 투자 대비 메모리 절약효과가 신통치 않을 수 있습니다. 매우 희귀한 경우이며 건별로 다르긴 합니다만, 거의 항상 밥값은 합니다.
  • 이미시브를 잘라내지 않고 채널 패킹만 해도 좋습니다. 셰이더 계산 부가 비용이 전혀 들지 않으니, 품질만 받쳐준다면 손해볼 것 없는 장사입니다.
  • Consolidate... (통합), Find All Materials Using This Texture (이 텍스처를 사용하는 머티리얼 전부 찾기) 는 강력한 툴입니다.