UDN
Search public documentation:

ContentProfilingHomeKR
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 홈 > 퍼포먼스, 프로파일링, 최적화 > 콘텐츠 프로파일링 및 최적화

콘텐츠 프로파일링 및 최적화


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

개요


새 콘텐츠를 추가할 때, 종종 잘못된 세팅으로 추가되거나 기존 콘텐츠에 비할 때 더 비싸지기도 합니다. 보통은 단순한 실수로 기인한 것입니다. 그러나 요즘 게임에서 활용하는 콘텐츠의 양으로 보면 추적하기 어렵습니다. 그래서 콘텐츠 및/또는 코드 최적화를 통해 게임 속도를 올려볼 수 있습니다. 경험에 의하면 가격대 퍼포먼스비가 가장 좋은 것은 거의 항상 콘텐츠 최적화였습니다. 이때문에 콘텐츠 제작자가 느린 부분을 찾아내고 수정하는 작업을 빠르게 할 수 있도록 해 주는 툴을 만드는 데 꽤 많은 시간을 들입니다.

프로파일링 / 최적화 프로세스 예제


기어즈 3 의 콘텐츠 최적화 가이드

기어즈 오브 워 3 에 도입된 콘텐츠 최적화 프로세스 관련 프리젠테이션이 East Coast Game Conference 에서 있었습니다. 관련 프리젠테이션 다운로드: Gears3ContentOptimizations_ECGC11_Final.pptx

기어즈 2 콘텐츠 최적화 작업방식

  1. QA 가 게임 전체 플레이, GPU 시간이 33ms 이상일 때마다 PIX GPU 캡처, 가급적 고유 시나리오 캡처 (동일 지역 캡처 10회 이하)
  2. 프로그래머가 GPU 캡처 분석
    • 느리면서 시각적 임팩트도 약한 것들 집어냅니다.
    • 최적화 꺼리를 이상적으로 잘 찾아내고 전부 구현된 경우, 씬은 33ms 미만이 될 것입니다.
    • 세부적인 드로 이벤트 정보를 사용하여 에디터의 각 드로 콜이 뭔지 빠르게 알아냅니다.
    • 녹화된 액터 이름, 리소스 이름 (스태틱 메시, 파티클 이미터 등), 머티리얼 이름
    • 렙디에게 명확한 방침과 스크린샷으로 변경할 부분을 제안합니다.
  3. 렙디와 아티스트가 바람직한 최적화 부분을 결정하고, 콘텐츠를 변경합니다.
    • 아트가 품질 결정을 확실히 담당하도록 합니다.
  4. 필요에 따라 1-3 단계를 반복합니다.

GOW2 의 경우, 전체 SP 맵의 90% 이상이 30fps 이상을 내는 데까지 2 패스만 수행되었습니다. 프로그래머 시간으로 6주가 걸렸습니다.

일반 커맨드렛


언리얼 엔진에는 많은 커맨드렛이나 작은 임베디드 프로그램이 제공되며, 이들 중 다수는 개발 주기를 순탄히 하기 위해 정기적으로 사용하기에 꽤나 좋습니다.

참조된 콘텐츠 분석

맵 참조가 무엇인지 아는 것부터가 최대 효율을 이끌어내기 위한 시작이요, 게임 전체에다 소비한 최적화 시간 측면에서의 "최대 효율"이 무엇인지 아는 것이 마무리겠습니다.

시간에 따른 변화를 감지할 수 있다는 건 역시 좋은 것입니다. 엑셀을 사용해서 2차 스프레드시트를 만들어 데이터를 이리저리 굴려보는 것도 필요합니다. AnalyzeReferencedContentCommandlet 출력물이 만병통치약!

사용법

커맨드렛을 사용하려면 그냥 다음 명령을 내리면 됩니다:

GAMENAME AnalyzeReferencedContent MAPNAMES

해당 맵의 콘텐츠로 .csv 파일이 여럿 만들어집니다. 맵 단위, 전역 단위 둘 다에 대해서입니다.

이 데이터를 살펴보고 집밖에 난 녀석(outlier), 가장 비싼 오브젝트, 가장 자주 사용되는 오브젝트 등을 찾아다가 최적화시켜주면 되겠습니다.

예제

  • StaticMesh .csv 에서 딱 한 두 번 정도만 사용되는 스태틱 메시를 찾아봅니다. 왕 중요한 부분이 아니면 보통 영향이 없는 선에서 삭제해 주고 좀 더 공통으로 사용되는 오브젝트로 대체해 줍니다. 즉 뭔가 시각적으로 독특한 효과를 주기 위해 레벨에 놓긴 했으나, 전체적으로 봤을 때 (특히나 비용면에서) 별로 필요치 않을 경우를 말합니다.
  • StaticMesh .csv 에서 메모리를 가장 많이 잡아먹는 오브젝트를 찾아봅니다. 얼마나 많은지, 최적화 시킬 수는 있는지?
  • .csv 의 요약 부분에서, 게임 전체에서 사용된 "인스턴스화된 트라이앵글" 총 수를 계산해 낼 수 있습니다. 특정 스태틱메시에 대해 "InstancedTriangles" 라는 새로운 열에다 NumInstances랑 NumTriangles를 곱해 넣는거죠. "InstancedTriangles" 열을 정렬해 보면 전체 게임의 삼각형을 많이 차지하는 메시를 알아볼 수 있습니다. 이런 것들을 최적화해 주면 보통 최적화 효율을 따져볼 때 밑지는 장사는 아닐 것입니다. (예로 거의 모든 레벨에 작은 관목숲이 쫙 깔렸다 칩시다. 레벨 몇몇에만 있는 엄청 비싼 펜스 메시보단 차라리 이런 것들 최적화해 주는 게 나을 것입니다.)

    (Click for full size)

    InstancedTriangles_small.jpg

  • # SoundNodeWaves .csv 에서 SoundNoveWaves의 크기로 정렬해 보니 다른 것보다 4배 비싼 환경음이 있는게 보입니다. 왜 그렇게 비싼지 알아봐야겠죠?
  • # SoundNodeWaves .csv 에서 BirdCall SoundNodeWaves 참조가 10개 확인됐습니다. 차이가 느껴지지 않는 선에서 종류를 좀 줄여볼 필요가 있겠죠? ^_^

이 커맨드렛 사용법에 대한 추가 정보는 Commandlet List KR 페이지의 Analyze Referenced Content 부분을 참고하시기 바랍니다.

Content Audit

Content Audio 커맨드렛은 현재 게임에서 사용중인 콘텐츠를 분석한 다음, 미리지정된 룰 세트에 따라 "문제있는" 것으로 간주될 수 있는 애셋을 찾아봅니다. 콘텐츠가 효율적으로 사용되고 있는지, 콘텐츠 아이템 속성 중 반드시 설정해야 하는 것이 설정되었는지 등을 확인하도록 룰을 디자인할 수 있습니다.

Content Audit Commandlet KR 페이지에 이 커맨드렛의 사용법에 대한 것이 더욱 자세히 수록되어 있습니다.

Content Comparison

Content Comparison 은 게임에서 활발히 사용되고 있는 콘텐츠를 분석한 다음 비슷한 타입이나 클래스의 애셋끼리 비교해 주는 커맨드렛입니다. 이를 통해 훨씬 비싼 종류의 애셋이 사용되고 있지는 않은지 확인할 수 있습니다.

PerfDebug_ Content Comparison Commandlet KR 페이지에 이 커맨드렛 사용법이 더욱 자세히 설명되어 있습니다.

Fixup Redirects

Fixup Redirects Commandlet 은 모든 패키지를 반복처리하며 모든 참조가 실제 애셋을 직접 가리키는지, 다른 패키지의 redirector 를 가리키지는 않는지 확인합니다. 이로써 콘텐츠가 사용되지 않을 때나 로드되지 말아야 할 때 로드되지 않도록 할 수 있습니다.

이 커맨드렛을 사용하여 콘텐츠 참조를 깔끔한 상태로 유지하는 법에 대한 정보는 FixUp Redirects Commandlet KR 페이지에서 찾아보실 수 있습니다.

일반 브라우저 및 툴


프리미티브 통계 브라우저

프리미티브 통계 브라우저는 레벨에 사용된 지오메트리 애셋에 대한 세부적인 분석을 제공하여, 디자이너가 어떤 애셋을 제거할지 아니면 아트 팀에 변경하도록 할 지 결정하는 작업의 효율을 높여 줍니다.

다음은 프리미티브 통계 브라우저(예전 스태틱 메시 통계 브라우저)의 열에 대한 설명입니다:

  • Type 종류 - 스켈레탈 메시인지, 스태틱 메시인지, 터레인인지, BSP (모델)인지 등 리소스의 종류입니다.
  • Count 수 - 레벨에 그 메시 인스턴스의 수 입니다.
  • Triangles 트라이앵글 - 인스턴스별 트라이앵글 수 입니다.
  • Resource Size 리소스 크기 - "view resource usage" 로 보고된 리소스의 KByte 크기이며, 스태틱 메시와 스켈레탈 메시에면 관계있습니다.
  • Lights (avg LM/ other/ total) 라이트 - 각 인스턴스에 영향을 끼치는 라이트매핑된 (LM), 라이트매핑되지 않은 (other), 총 라이트 수입니다.
  • Obj/ Light cost 오브젝트/라이트 비용 - 오브젝트 / 라이트 상호작용 비용입니다. 이 수치는 이 스태틱 메시가 라이팅 목적으로 몇 번이나 다시 렌더링되야 하는가를 나타냅니다. 이는 라이트매핑되지 않은 라이트의 수에 모든 인스턴스의 총 섹션 수를 곱한 것입니다. 라이트맵은 이 수치에 포함되지 않았는데, 이미시브 패스의 일부로 렌더링되는지라 "free"로 간주될 수 있기 때문입니다.
  • Triangle cost 트라이앵글 비용 - 라이팅 목적으로 렌더링되어야 하는 트라이앵글 수입니다. 이 수치에는 z-prepass, 이미시브, 라이트맵이 제외되는데, 이들은 라이트의 수와는 무관하게 고정적인 부하가 걸리기 때문입니다.
  • Lightmap 라이트맵 - 라이트맵 데이터가 사용하는 메모리 양입니다.
  • Shadowmap 섀도우맵 - 섀도우맵 데이터가 사용하는 메모리 양입니다.
  • LM Res 라이트맵 해상도 - 인스턴스별 평균 라이트맵 해상도입니다.
  • Sections 섹션 - 이 메시가 갖는 섹션 수입니다.
  • Radius (min/max/avg) 반경 - 메스의 각 인스턴스에 대한 경계 박스의 최소/최대/평균 반경입니다.

(Click for full size)

primitivestats_small.jpg

스태틱 메시


퍼포먼스 문제의 흔한 진원지는 스태틱 메시입니다. 일반적으로 한두번만 사용되는 스태틱 메시는 무엇이든 대체할 수 있으며, 이미 많이 사용되는 비슷한 것으로 대체할 수도 있습니다. 가급적이면 스카이박스에는 고유 메시 사용을 피하십시오. 가능하면 버텍스 라이팅 대 라이트맵 라이팅 사이에 적절한 균형을 맞추시기 바랍니다.

메시 단순화 툴

메시 단순화 툴로 레벨-단위로 스태틱 메시 애셋의 지오메트리 복잡도를 줄일 수 있습니다. 트라이앵글 수를 파라미터적으로 감소시켜 메시의 단순화된 사본을 만들 수 있으며, 그런 다음 레벨 패키지 안에 메시를 저장합니다. 레벨의 모든 액터에 대한 고해상도 메시로의 참조를 대체할 수도 있으며, 시간의 흐름에 따라 단순화된 메시를 유지하는 데 도움이 됩니다.

간단히 말해, 레벨 디자이너가 이 툴을 사용하여 약간의 시각적 품질을 대가로 빠르게 맵의 메모리 풋프린트를 줄이고 렌더 시간을 향상시킬 수 있습니다.

이 툴 사용법에 대한 세부적인 내용은 Mesh Simplification Tool KR 페이지를 참고해 주시기 바랍니다.

애니메이션


AnimSet 이 게임에 의해 참조되면, 그 AnimSet 내의 애니메이션이 전부 로드됩니다. 일부만 사용할 때는 낭비가 될 수 있습니다. AnimSet 내의 애니메이션이 전부 필요치 않을 경우, 보통은 작은 AnimSet 로 나누어 필요할 때만 로드하는 것을 추천합니다.

예를 들어 모든 무기의 애니메이션을 항상 필요치 않다면 다른 무기에 각자의 AnimSet 를 갖게 하면 됩니다.

마티네:

이 문제는 마티네로 오면 더 심해질 수 있습니다.

마티네 시퀸스나 레벨별로 다른 AnimSet 를 유지하는 것은 작업방식에 따라 (예로 각기 다른 사람이 각기 다른 마티네 시퀸스 작업을 하는 경우) 매우 귀찮을 수 있습니다. 이상적으로는 레벨 당 하나의 AnimSet 를 두는 것인데, 이를 다양한 (렙디, 애니메이터, 스크립터) 개발자 그룹간에 유지시키는 것은 매우 시간 소모가 심할 수 있습니다.

InterpData 내의 bShouldBakeAndPrune 플랙 (CL 259515) 으로 이 상황을 타개할 수 있습니다. 레벨에 대한 AnimSet 을 새로 만들어 사용된 애니메이션만 복제한 다음 참조를 다시 링크합니다. 어쨌든 AnimSet 이 쿠킹/로드되면 이 플랙을 꺼 줘야 같은 애니메이션이 복제되지 않습니다. bake and prune 하려는 AnimSet 가 레벨에 로드될 필요가 없는 경우 사용해 줘야 합니다. *Editor.ini 의 Cooker.MatineeOptions 부분에 bBakeAndPruneDuringCook 값을 FALSE 로 설정해 주면 전역적으로 끌 수 있습니다.

DefaultEditor.ini 안에:

[Cooker.MatineeOptions]
bBakeAndPruneDuringCook=false

애니메이션 압축

애니메이션 압축은 애니메이션 메모리 절약에 큰 비중을 차지합니다. 언리얼 엔진 3 는 압축된 애니메이션만 쓸 수 있으나, 공간 절약 대비 시각 충실도 손실율이 다양한 알고리즘이 있습니다. 각 애니메이션에 올바른 압축 기법을 선택해야 절약되는 메모리 양에 큰 영향을 끼칠 수 있습니다.

사용가능한 압축 알고리즘과 애니메이션 적용법에 대한 세부사항은 Animation Compression KR 페이지를 참고하십시오.

애님 사용량 추적

어떤 애니메이션은 AnimSet 에 저장됩니다. AnimSet 가 참조되면 그 AnimSet 안의 모든 애니메이션이 로드됩니다. 조직화 목적으로 AnimSet 에는 (걷기 등) 특정 동작에 대한 애니메이션이 여럿 있을 수 있습니다. 문제는 전혀 사용되지 않는 애니메이션도 있을 수 있다는 것입니다. 사용되지 않는데도 메모리에 무임승차하고 있는 것인데, 찾아내서 끌어내야 하겠습니다!

TRACEANIMUSAGE 콘솔 명령을 실행합니다.

다음 사항이 나타납니다:

  • 사용되지 않은 애니메이션
  • 게임플레이 도중 사용자에게 가장 많이 보인 애니메이션

더 나은 결과를 위해서는 같은 맵도 여러 사람에게 여러 샘플을 얻는 것이 좋습니다. (플레이 스타일이 다른 사람이 있습니다)

사용되지 않는 애니메이션 세트를 찾았다면, 그를 AnimSet 밖 TYPE_NotUsed 로 옮기는 것이 보통 문제 해결에 최선의 방법입니다.

traceanimusage.png

머티리얼


씬 내 머티리얼의 복잡도는 씬의 GPU 부하에 크게 영향을 끼칠 수 있습니다. 동적 라이트 사용량이 많을 수록, 머티리얼 비용도 높아집니다.

  • Dependent Texture 읽는 양을 제한해 보십시오. 즉 BumpOffset 처럼 텍스처를 가진 UV 를 변경하는 것을 말합니다.
  • 머티리얼 인스턴싱을 사용하고, 퍼포먼스 교환을 쉽게 하기 위해 on/off 토글 가능하도록 비싼 효과에 대해서는 StaticSwitchParameters 를 사용하십시오.
  • 스페큘러가 너무 많지는 않은 머티리얼에서 스페큘러를 제거해 보십시오. 상당량의 픽셀 셰이더 인스트럭션을 제거해 주며, 대부분 티도 안납니다.
  • 각 머티리얼의 텍스처 룩업 수를 줄여 보십시오. 텍스처 룩업이 많을 수록 GPU 가 필요한 텍스처를 구해오는 시간도 길어집니다.

  • 인스트럭션 수
  • 사용량(usage) 플랙 주시 - 머티리얼당 셰이더 수 제어

텍스처


언리얼 엔진 3 는 텍스처 스트리밍 풀을 사용합니다. 모든 스트리밍 텍스처는 총 알려진 메모리 풋프린트를 갖고 있어, 엔진은 최선을 다해 크거나 플레이어 주변의 텍스처만 최대 해상도로 로드합니다. 그러나 여전히 텍스처가 너무 많이 추가되어 여기저기 뿌옇게 보일 소지가 있습니다. 이 경우 유일한 해결책은 텍스처 사용량을 현실적인 수준으로 끌어내리는 수 밖에 없습니다. 텍스처 최적화 팁이라면:

  • STAT STREAMING 및 스트리핑 오차(fudge factor) 검사를 합니다. 이 수치가 1.0 이면 걱정할 것이 없으나, 1.0 보다 크면 맞지 않는 텍스처가 있어 일부가 뿌옇게 보인다는 뜻입니다.
  • LISTTEXTURES 를 사용하여 무엇이 로드되는지 확인합니다. 로그에 로드되는 텍스처 목록을 뱉어낼 것입니다. 이 정보는 엑셀로 복사해 넣을 수 있으며, (Data 아래) "Text to Columns" 버튼을 누르고 Delimited->Comma-> 완료하면 줄/열로 자동 정렬됩니다. 그리고 정렬을 누르면 각 열을 오름차순 또는 내림차순으로 정렬할 수 있습니다.
  • listtextures 출력을 엑셀로 가져오고 나서, "Current Size" 열에 내림차순 정렬하면 가장 악성인 순으로 분석을 시작해 볼 수 있습니다. 가장 메모리를 많이 차지하는 텍스처인 거죠.

텍스처 최적화 기법

적절히 계획을 세우고 언리얼 엔진 3에 제공된 여러가지 툴을 사용하면 텍스처가 차지하는 디스크 공간과 메모리의 양을 최적화하는 데 도움이 됩니다. 그에 관련된 기법과 꼼수가 Texture Optimization Techniques KR 페이지에 수록되어 있습니다.

Set Texture LODGroup

Set Texture LODGroup 커맨드렛은 모든 텍스처를 분석하여 텍스처의 현재 LODGroup 이 해당 텍스처 유형에 적합한지 판단하고, 그렇지 않다면 LODGroup 을 올바른 그룹으로 설정해 줍니다. LODGroup 세팅이 잘못된 텍스처가 있으면 텍스처 풀 리소스가 제대로 할당되지 못하는 문제가 생길 수 있습니다.

Set Texture LODGroup Commandlet KR 페이지에 이 커맨드렛이 자세히 설명되어 있습니다.

Find Duplicate Textures

시간이 갈 수록 사람들은 약간 변경하려고, 다른 식으로 사용하려고, 또는 실수로 텍스처를 복제하곤 합니다. 보통 알아채기도 힘든 변경이거나 시도해본 후 취소한 경우가 많습니다. 그런데도 그런 텍스처가 남아 떠돌다 다른 사람이 머티리얼에 사용해 버립니다. 그래서 메모리 내 한 레벨에 완전 똑같은 텍스처가 여럿 있게 되는 것입니다. 분명 피해야 할 상황입니다. Find Duplicated Textures 커맨드렛으로 이 복제 텍스처를 찾아 위치를 알아낼 수 있습니다.

Find Duplicate Textures 커맨드렛을 실행하려면, 명령줄에 다음과 같이 입력합니다:

게임명 FindDuplicateTexturesCommandlet

게임 콘텐츠 내 복제 텍스처 전부가 나열됩니다.

주: 이 커맨드렛의 다양한 옵션을 알아보려면 프로그래머를 대동하는 것이 좋습니다. 특히 살펴볼 곳은: UnPackageUtilities.cpp UFindDuplicateTexturesCommandlet::Startup()

파티클 시스템


씬에는 보통 파티클이 여럿 있게 마련이고, 비용도 제각각입니다. 다른 것보다 두드러지게 비싼 파티클이 있는지 알아보면 좋겠죠. 추가적으로 필요없는 곳에 돌고 있는 파티클이 있는지도 알아보면 좋겠습니다.

#define TRACK_DETAILED_PARTICLE_TICK_STATS 1 설정하면 로그에 파티클 틱 통계가 많이 출력됩니다.

추가적으로 프레임마다 경계가 업데이트되는 파티클을 찾아보고 싶을 수도 있겠습니다. 그런 파티클시스템에는 ContentAudit 태그가 붙어있을 테지만, 혹시나 각 프레임마다 경계가 동적으로 업데이트되는 파티클을 발견했다! 딱 FixedRelativeBoundingBox 를 시험해 볼 좋은 마루타다 생각하시면 되겠습니다.

파티클 최적화용 팁이라면:

  • 콜리전이나 자잘한 것들 끄기 (UT 에서 Enforcer 무기 스파크는 콜리전을 사용합니다!)
  • 오버드로 피하기
  • PIX 및 VIEWMODE SHADERCOMPLEXITY 사용
  • STAT PARTICLES 로 수 확인
  • 공용 효과나 큰 것에 대한 경계 박스를 수동 설정
  • 에디터가 생성한 최대 활성 카운트가 맞는지 확인
  • 자세한 것은 Particle System Reference KR 페이지 확인
  • MEMORYSPLIT 사용. 현재 Active 로 로드된 파티클 데이터는 얼마나 되는지, Peak 로 로드 가능한 것은 얼마나 되는지. (한 번에 파티클에 할당 가능한 최대 메모리)

오디오와 사운드


오디오 최적화용 팁입니다:

  • 꼭 필요치 않으면 다중 음악 트랙이 사용되지 않도록 확인합니다. 뮤직 트랙을 자체 스트리밍 맵에다 놓아 필요할 때면 스트림 인/아웃 되도록 하는 것도 좋은 생각입니다. (퍼포먼스에 영향을 끼치지는 않지만, 전체 레벨 예산에는 영향을 끼칩니다.)
  • STAT AUDIO, STAT MEMORY 를 통해 예산 검사
  • LISTSOUNDS 를 사용하여 현재 로드된 사운드 확인 - 어떤 종류의 사운드가 메모리를 많이 차지하는지 확인차 그룹 단위로 저장된 웨이브를 표시합니다.
  • LISTWAVES 는 현재 재생중인 사운드를 나열합니다. (PC 전용)
  • LISTAUDIOCOMPONENTS 는 현재 고려중인 사운드를 나열합니다.