배움 저장소

[UE4] Profiling and Optimization 본문

Dev/Unreal Engine4

[UE4] Profiling and Optimization

시옷지읏 2021. 10. 31. 02:40
더보기

공부하며 작성한 글입니다.

틀린 부분이 있다면 알려주세요!

 

 

1. GPU 문제인가 CPU 문제인가?

최적화 문제를 다룰 때 GPU와 CPU 어디에서 더 많은 작업을 해야할까?

Unreal Engine 내부에서 ` (혹은 ~)키를 눌러 콘솔 창을 띄운 후 stat unit, stat unit grap를 입력해보자. 다음과 같은 창이 나타난다.

- Frame : 프레임이 끝나기 위해 소모되는 시간

- Game : C++ 또는 BP 작업에 소모되는 시간.

- Draw : CPU Redering 시간

- GPU : GPU Rendering 시간

Frame 시간이 CPU와 GPU 작업시간의 합이 아니다. CPU와 GPU은 각자의 일을 하고 있기 때문이다.

 

2. 특정 하드웨어에서 최적화 테스트

- 특정 하드웨어에서 바로 테스트하는 것이 좋다. Profiling을 할 때 주의할 점은 Editor에서 실행하

- 만약 Unreal Editor에서 테스트한다면 Edtior의 각 기능을 최소화 하고 Play Standalone모드로 실행하자

  이 때 Project Settings -> Frame Rate Smoothing Off 해주자.

  이 때 VSync도 Off 해주자. ( r.vsyn0 )

 

3. Frame 분석

1) Game

렌더링 전 CPU는 게임에 있는 모든 논리적 요소를 처리한다. 게임 안에 있는 객체의 Location, Physics, AI 등이 있다. 게임안에 구현되어 모든 요소의 계산 결과를 1Frame에 처리한다.

2) Draw

카메라 안에 있는 모든 지각 가능한 객체를 리스트로 만들어 GPU에게 전달한다. Shaders, Texture, Mesh 등이 있다.

3) GPU

화면에 출력하기 위하여 Rendering 한다.

 

FPS Chart 활용하기

Console 명령어 StartFPSChartStopFPSChart로 CSV파일을 확인할 수 있다.

- 예를 들어, 특정 게임 레벨에서 해당 기능을 활용하여 모든 맵을 돌아다닌 후 저장한다면 어느 부분에서 문제가 있는지 최적화 검사가 가능하다. 자동화 하자. 

 

Profiling CPU

stat Startfile,  stat Stopfile을 활용하여 로그를 기록한 뒤에 Window->Developer Tools-> Session Front End에서 해당 로그를 확인해볼 수 있다.

 

Unreal Insight

 

Unreal Insights

Profile application performance with Unreal Insights

docs.unrealengine.com

원격작업을 지원한다.

 

 

4. 문제찾기

1) Game

- CPU는 게임 내에 모든 로직을 계산한다. 이때 불 필요한 Tick이 성능 저하의 원인이 된다. 대부분의 게임 요소는 매 프래임마다 업데이트를 필요하기 보다, 특정 상황이 발생했을 때에만 동작한다. 공격, 포션사용, 퀘스트처럼.

- Tick 함수를 자주 사용하는 객체는 게임 화면에서 Mesh를 가지고 있는 Actor 객체들이다.

- 게임내에 얼마나 많은 Tick 함수가 있는지 확인하려면 stat game 과 dumpticks 활용하자

Tick 함수의 대안

- Timelines

- Timers

- Manual toggling of Actor Tick

   a. Player와 멀리 있을 때 Tick Off Player와 가까워졌을 때 Tick On

- Event driven Systems( Use Dispatchers )

- Reducing the Tick Interval

BluePrint Class에서 Tick이 업데이터 되는 시간 간격 조절이 가능하다

Decoration's Movement

바람에 풀이 흔들리거나, 바람개비가 돌아가는 효과는 게임을 더 사실적으로 만들지만 매 시간 Tick함수를 통하여 계산해줘야하며 FPS가 늘어난다. 어떻게 하면 효과적으로 간단한 움직임을 구현할까?

1. Vertext Shader

이 작업은 CPU가 Transformation을 계산하지 않고 GPU로 작업을 바로 넘긴다. 바람개비를 예로 들면, GPU가 곧바로 움직이는 바람개비를 매 프레임 렌더링해준다. 이 경우 Transformation이나 Collision에 아무 변화가 없음을 고려하고 있어야한다. 이 때 RotateAboutWorldAxis()을 사용하자

 

Vertex Shader 사용방법 예시

https://www.tomlooman.com/rotate-mesh-vertex-shaders-ue4/

https://medium.com/@lordned/unreal-engine-4-rendering-part-2-shaders-and-vertex-data-80317e1ae5f3

 

 

2. C++에서 RotatingMovemnetComponent를 사용할 수 있다.

 

 

비용이 큰 함수들

Gat All Actors of Class : 만약 모든 액터를 가져와야 한다면 게임 시작 때 하는 것이 좋다.

 

Spawn Actor None -> Object Pooling을 이용하여 기존의 Object를 재사용하자. 

 

 

Nativizing BluePrints 사용해보기
 

Nativizing Blueprints

Technical guide for programmers exposing gameplay elements to Blueprints.

docs.unrealengine.com

Unreal Editor는 BluePrint를 코드로 바꾸어주는 작업을 할 수 있다. BluePrint 작업의 FPS가 너무 길다면 Nativizing 기능을 활용해보고 시간이 얼마나 단축되는지 확인해보자.

BluePrint vs Nativizing

- 복잡한 작업은 C++로!

 

Animation Fast Path

Animation 작업을 할 때 Blueprint를 많이 사용한다. 가능한 Fast Path 표시인 번개 모양이 표시되도록 하자. 성능이 더 좋다.

https://docs.unrealengine.com/4.27/en-US/AnimatingObjects/SkeletalMeshAnimation/Optimization/#animationfastpath

 

Particle System 

파티클 시스템을 사용해보지 않아서 뭔지 잘 모르겠다. 나중에 찾아보기

 

2. DRAW

Draw에서는 CPU의 계산 결과를 토대로 Rendering이 필요한 대상을 찾는다. 이때 각 객체를 화면 위에 Rendering 하도록 요청하는 작업을 Draw Call이라고 한다. 객체가 많고 복잡할 수록 더 많은 Draw Call이 필요하다. 

Draw Call이 너무 많아도 FPS가 길어진다.

Draw Call을 확인하고 싶다면?

- Console 창에서 stat scenerendering

- OpenSource RenderDoc 사용하기

 

Draw Call 줄이기

- 사용 되는 Object의 개수를 줄인다.

- 낱개의 Object를 사용하지 않고 합친다.

 

합쳤을 때 발생할 수 있는 문제점

예 1) 커다란 빌딩에서 문 하나만 움직여도 새로 불러와야함

예 2) Light Mapping이 섬세하게 표현되지 못함. 커다란 빌딩을 기준으로 빛과 상호작용함

예 3) 한 번에 Object를 불러올 때 Memory 사용이 급격히 늘어남. 최적화 하기 어려움

 

- LOD( Level of Detail ) 사용

멀리 있을때 더 간단한 Mesh를 사용할 수 있다.

 

- HLOD 사용

멀리 있는 여러 Mesh를 하나로 합쳐서 Draw Call을 한 번만 호출한다. 합치고 싶은 Mesh가 모여있는 곳에 HLOD 박스를 놓아주면 된다.

 

Hierarchical Level of Detail Overview

Overview of the Hierarchical Level of Detail system in Unreal Engine 4

docs.unrealengine.com

 

-Merge Actors 사용

Level Design을 할 때 Module을 많이 사용한다. Module로 만들어진 객체를 모두 합쳐버리자. 언리얼 내부에 MergeActors를 지원한다.

 

level Design을 할 때 같은 Mesh를 여러군데 사용할 떄가 많다. 이때 Instanced Mesh를 사용하자. 같은 Instanced Mesh는 모아서 한 번에 Draw Call을 실행한다.

 

3. GPU

문제 확인하기

화면에서 표시하고 있는 여러 요소를 Off 하면서 확인해볼 수 있다.

ShowFlag.<assetType> 0 // to hide
ShowFlag.<assetType> 1 // to show

// Common Ones:
ShowFlag.StaticMeshes
ShowFlag.SkeletalMeshes
ShowFlag.Particles
ShowFlag.Lighting
ShowFlag.Translucency
ShowFlag.ReflectionEnviroment
ShowFlag.InstancedStaticMeshes

관련 명령어 https://docs.unrealengine.com/4.27/en-US/TestingAndOptimization/PerformanceAndProfiling/Overview/ 

 

 

LOD, HLOD가 어떻게 적용되었는지 확인할 수 있다.

https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/LevelEditor/Viewports/ViewModes/#lodcoloration

 

 

GPU Visualizer

Console  >>ProfileGPU 를 검색하거나 Ctrl + Shift + , 로 실행할 수 있다.

r.rhicmdbypass 1
r.rhithread.enable 0
r.showmaterialdrawevents -1

위의 명령어를 입력하면 각 Material 당 Draw 비용이 어느정도인지 나타내준다. Desktop에서만 동작한다.

 

Draw Cost 줄이기

OverShading

아주 멀리 있는 물체는 디스플레이에 몇 픽셀만 차지해도 수 많은 폴리곤은 모두 계산되고 있다. 따라서 위에서 나온 LOD를 사용해서 계산할 폴리곤을 줄이자.

 

Quad OverDraw

물체의 꼭지점이 많이 모여 있으면 화면에 모두 표시되지 않는데도 모두 계산하고 있다. 이러한 일이 일어나는지 확인하려면

좁은 구역에 수많은 꼭지점이 합쳐져있다면 LOD를 더 적극적으로 사용하거나, Object를 정리해보자.

 

이 외에도

 

Shader Complexity

- 화면에 나오는 물체를 더 사실적으로 묘사하기 위하여 Grayscale Map을 사용한다. GrayScale맵을 하나로 압축하여 사용하자

- 복잡한 Shader 기능을 구현하기보다 Switching 기능을 활용하여 Baking( Instanced? ) 완료된 Texture로 전환해주자 

- If 조건문은 비용이 크다.

- Feature Level Switches ( 각 실행 환경마다 다른 설정을 가능하게 해주는 옵션 )을 사용하자

https://www.youtube.com/watch?v=wo6fSPJVp2I 

 

Vertex Based >  Pixel Based

Vertex Based 작업이 Pixel Base보다 보간법(Interpolation) 작업을 더 잘해서 자원을 아낄 수 있다.

https://youtu.be/EbXakIuZPFo?t=2387 

 

Light Complexity

- Dynamic Lights를 최소화 하기

- Lighting Channel 사용하기

 Transform에서 Movable로 설정하면 물체는 그림자를 계속해서 업데이트 한다. 이때 Light Channel을 이용하면 특정 Light에 한정해서 상호작용하고 나머지는 무시한다.

https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/LightingAndShadows/LightingChannels/ 

 

-  Shadow Casting은 비효율적이다 필요에 따라 On/Off를 조절하자

- 플레이어 거리에 따라 Shadow, Dynamic light가 필요없어지면 Off 설정하자

- Static ligtht는 그림자를 Disk에 저장하므로 속도 / 저장공간을 고려해서 사용해야한다.

'Dev > Unreal Engine4' 카테고리의 다른 글

[UE4] Introduction to C++ Programming in UE4  (0) 2021.11.08
[UE4] Asset Manger and Soft Reference  (0) 2021.11.07
[UE4] Unreal Property System (Reflection)  (0) 2021.11.02
[UE4] UI 최적화  (0) 2021.10.30
[UE4] Programming KickStart  (0) 2021.10.28
Comments