[UE4 최적화] Material

Unreal/TA 2019. 7. 13. 02:13

이번 포스팅은 언리얼4에서 Material을 다루면서 최적화하는 방법에 대해 다루겠습니다.

 

언리얼4의 특징 중 하나는 쉐이더를 따로 작성하지 않고 Material 에디터에서 노드 조작으로 간단하게 쉐이더를 작성 할 수 있습니다, 이는 사실 Material 파일 안에 수 많은 쉐이더들이 생성되서 뒤에서 멀티 플랫폼, Material 설정에 맞춰 자동으로 동작하고 있는 형태입니다. 

(엔진을 뜯어서 HLSL 쉐이더를 직접 작성하는 방법도 있습니다.)

 

이번 최적화 포스팅의 핵심은 자동으로 생성되고 동작되는 쉐이더를 Material 설정, 프로젝트 설정을 통해 제어하는 법에 대해 다루겠습니다.

 

 

 

Material 퍼포먼스 모니터링

우측 상단 메뉴에서 통계를 키시면 하단에 통계탭을 확인 할 수 있습니다.

통계탭에서 instructions 값을 통해 픽셀, 버텍스 쉐이더 수치를 확인 할 수 있고 픽셀 쉐이더 수치가 높아지면 무거운 쉐이더이므로 여러가지 방법을 통해 수치가 높지 않게 해줘야 합니다, 방법에 대해서는 뒤에서 설명하겠습니다.

 

키보드 Alt+8을 누르거나 위 사진의 메뉴를 누르면 쉐이더 복잡도 화면을 볼 수 있습니다.

이는 쉐이더 Instruction 수치가 어느 정도인지 확인 할 수 있는 화면입니다, 아래 그래프에 보이는 데로 좌측 초록색에 가까우면 가벼운 상태이고 우측 빨강~흰색으로 보이면 무거운 상태를 의미합니다.

 

주로 쉐이더 자체가 무겁거나 이펙트같은 반투명 쉐이더가 겹쳐서 오버드로우 현상이 날때 무겁습니다, 이점을 모니터링하면서 마테리얼 최적화를 하며 되겠습니다.

 

 

 

프로젝트 쉐이더 기본 세팅

프로젝트세팅의 엔진 - 렌더링에 보시면 위 옵션들이 있습니다, 위 옵션은 Material 생성시 자동으로 지원하는 기능을 끄고 킬 수 있는 옵션들입니다. 

목표로하는 플랫폼, 성능에 맞춰 위 옵션들을 끄면 Material 생성시 자동으로 생성되는 쉐이더의 갯수를 줄여 Material 에셋 크기를 줄일고 쉐이더 컴파일 속도를 높일 수 있습니다.

 

기본으로 쉐이더는 Material 하나하나에 안에 저장되어 있지만 위 옵션을 활성화 시키면 별도의 하나의 라이브러리에 쉐이더가 모두 저장되어 각 Material들은 라이브러리안에 쉐이더를 참조하는 형태로 사용하게 됩니다.

결과적으로 쉐이더 컴파일 속도는 좀 느려지지만 에셋 용량은 매우 줄어들게 됩니다.

(파라곤게임에서 1.8GB쉐이더 용량은 400MB수준으로 줄였다고 함)

 

 

Material 기본 설정

Material 생성 후 목표로하는 용도에 맞게 디테일 패널의 기본 옵션을 조정하면 쉐이더 비용을 아낄 수 있습니다.

 

각 옵션을 조정할때마다 instruction값을 확인하여 얼마나 최적화되는지 확인 할 수 있습니다.

 

 

1. Fully Rough

이 옵션 해제하면 Roughness(거칠기) 값을 연산하지 않게 되고 강제로 값이 1으로 맞춰집니다.

쉐이더 계산량을 줄이고 텍스처 샘플 1개를 더 사용 할 수 있게 됩니다.

 

여기서 텍스처 샘플 1개를 더 사용 할 수 있다는 말은 

한 개의 마테리얼에서 사용 할 수 있는 텍스처 최대 갯수가 존재 합니다, PC나 최신형 플랫폼에서는 여유가 있으나 OpenGLES2.0 하드웨어에서는 5개까지 사용 할 수 있습니다, 이런 상황에서 텍스처를 1개 더 사용 할 수 있다는 뜻입니다.

 

 

2. Use Lightmap Directionality

라이트맵 방향성 사용옵션입니다. 이 옵션을 끄면 라이트맵을 구울 때 방향성 정보 없이 구워집니다.

instruction값이 변동도 없고 겉보기에는 달라보이지 않지만 도큐먼트의 자료에 의하면 비용이 줄어든다고 설명 되어있습니다.

 

3. Decal Response(DBuffer)

데칼 반응여부를 선택하는 옵션입니다, 기본으로 켜져 있지만 해당 Material을 가진 오브젝트가 데칼 영향이 가지 않는 다고 판단하면 None으로 끄면 됩니다.

instruction값이 매우 크게 낮아집니다.

 

4. Tangent Space Normal

탄젠트 노멀 좌표계 연산을 끄는 옵션입니다. 이 옵션만 끄면 instructions도 변화가 없고 표면상 차이가 없습니다.

Material Attributes 노드를 사용해야 연산이 안되는 것 같습니다.

이 작업으로 인해 instructions가 크게 감소합니다, 하지만 노멀맵을 사용할 수 없게 됩니다.

 

간단하게 구체 모델에다가 예시를 만들고 쉐이더 복잡도를 확인해봤습니다, Opaque쉐이더로 적은 차이지만 만약 반투명 쉐이더로 오버드로우가 발생할시에는 매우 큰 최적화 효과가 날것입니다.

 

 

 

계산식 노드

가벼운 계산식

가장 기본적이면서 많이 사용하는 노드들 입니다.

 

 

무거운 계산식

기본적으로 삼각함수계열은 모두 무겁습니다, 그리고 if, Divide도 매우 무겁습니다.

 

Fast노드

삼각함수 노드중에 Fast가 붙은 노드가 있습니다, 좀더 효율이 좋습니다.

 

쉐이더를 작성하면서 사용하는 계산식 중 무거운 노드가 있고 가벼운 노드가 있습니다, 이점을 인지하고 같은 결과물을 내더라도 가벼운 노드를 활용해서 쉐이더를 작성하면 가볍게 만들 수 있습니다.

예를 들어 A / 2를 계산하는 노드가 있다면 A * 0.5로 수정하면 가벼운 계산으로 바뀌게 됩니다.

 

 

 

Customized UV

Customized UV를 사용하면 Pixel Shader가 아닌 Vertex Shader에서 연산하게 됩니다, 그래서 매우 퍼포먼스를 올릴 수 있습니다, 픽셀이 아닌 버텍스로 그리는 만큼 퀄리티가 떨어 질 수 있는데 Mesh의 버텍스 수를 늘리거나 퀄리티가 낮아도 상관없는 요소에 사용하면 좋겠습니다.

 

Customized UV 사용법

간단하게 텍스처 한장을 확대 축소하는 노드를 작성 했습니다, 일반적으로 Texture Sample 노드에 UV값을 넣어 만듭니다.

이 노드를 Customized UV로 바꿔보겠습니다.

 

디테일 패널에서 Num Customized UVs가 기본으로 0으로 되어있는데 숫자를 늘려주면 숫자만큼 우측 사진처럼 노드가 생성됩니다.

 

이전에 Texture Sample UV노드에 넣엇던 값을 Customized UV0에 넣으면 똑같이 동작하게 됩니다.

 

 

만약 Customize UVs를 2개 생성하면

 

Texture Sample 노드를 클릭하고 디테일 패널에서 Const Coordinate 값에 맞춰 Customized UV0~1 노드를 맞추면 어떤Textrue Sample 노드의 UV를 조작할지 선택할 수 있습니다.

 

어떤 자료에 의하면 Texcoord노드의 Index도 맞춰줘야 한다고 써있는데 차이점은 잘 모르겠습니다.

 

 

 

쉐이더 최적화 예시 : 텍스처 맵 합쳐서 사용하기

외부 에셋에서 PBR 캐릭터 1개를 구했습니다.

 

이 모델에 들어가는 텍스처는 38장으로 매우 많습니다, 또한 텍스처 1장당 2048x2048입니다, 메모리를 매우 점유 할 것이며 Mipmap등 필터링 하거나 마테리얼 내부에서 많은 비용이 들것으로 예상됩니다.

 

 

그래서 BaseColor맵을 제외한 데이터형식 맵들(Metalic, Emissive, Normal, AO)을 1개의 텍스처로 합치고

 

위와 같이 UV를 조작해서 1개의 텍스처에서 맵을 추출하여 마테리얼을 구현했습니다.

 

간단하게 노드 구현으로 텍스처 최적화를 완료했습니다.

 

상세 구현 내용으로

노멀맵은 기본으로 노멀맵세팅이 아닌 일반 텍스처 이미지라서 0~1범위의 값을 -1~1로 만들기 위해 위와 같은 노드를 구현하여 노멀맵 만드는 작업을 했습니다.

 

sRGB옵션이 원래 켜져있어야 하는 AO같은 텍스처는 다시 색을 눌러주기 위해 pow(2.2)연산을 했습니다.

 

나머지 일반 맵들은 UV로 추출한 텍스처를 적용해주면 됩니다.


WRITTEN BY
CatDarkGame
Technical Artist dhwlgn12@gmail.com

,