Unreal Engine 프로파일링 1 : 프레임 레이트(Frame Rate)
프로파일링(Profiling) 이란?
프로파일링은 간단하게 정의하면 프로그램 최적화를 위해 성능 분석을 하는 것을 말합니다. 프레임레이트, 로딩속도, 버그 등 문제가 되는 요소들을 최적화하고 프로젝트의 목표 성능을 달성하기 위해 프로파일링은 프로젝트에서 꼭 필요한 과정입니다. 언리얼 엔진은 기본적으로 여러 프로파일링 툴을 제공하기 때문에, 디자이너도 쉽게 프로파일링을 할 수 있습니다. 수많은 프로파일링 방법이 있지만, 그동안 프로젝트를 진행하며 주요 문제들을 해결할 수 있었던 방법을 추려서 소개하겠습니다.
언리얼 엔진 4.26 버전을 기반으로 작성했습니다.
1. 프레임 레이트(Frame Rate)
프레임 레이트(Frame Rate)란 디스플레이 장치가 화면의 데이터를 표시하는 속도를 말하며 단위로 FPS를 사용합니다. 보통 GPU 처리 속도에 프레임 레이트가 영향을 많이 받게 되며, 전체 씬에서 혹은 플레이어가 특정 위치에 있을 때 주변 요소의 영향으로 프레임 레이트가 떨어지기도 합니다.
- 프레임 레이트가 저하되는 주요 요인
- 드로우 콜(Draw Calls)
- 실시간 라이트의 그림자
- 셰이더 복잡도
- 투명/반투명 머티리얼
- 기타 요인
- 플레이너 리플렉션
- 과도하게 높은 출력 해상도 (+ Screen Percentage, Anti-Aliasing)
보통 이 정도만 숙지하고 있어도 프로젝트 최적화에 많은 도움이 되지만, 성능이 낮은 기기를 타겟으로 하는 프로젝트일수록 정확한 프로파일링을 통한 최적화 작업이 필요합니다.
2. 프레임 레이트 진단 방법
FPS 확인
- 출력로그 창 혹은 키보드 ~키를 누르면 열리는 cmd 창에 'Stat FPS' 를 입력하면 현재 프레임 속도를 확인할 수 있습니다. (★★단축키 Ctrl + Shift + H)
- 뷰포트 우측에 FPS 수치가 오버레이 되기 때문에 작업하는 동안에 계속 켜 놓고 확인하며 작업하기 편리한 방법입니다.
- cmd 창에 'Stat Unit'을 치면 어디에서 지연이 걸리고 있는지 더 세세하게 확인할 수 있습니다.
- 보통 프로젝트를 시작하면 최대 FPS 제한이 걸려있습니다. 콘솔창에 't.maxfps 1000'를 입력하면 최대 FPS가 1000으로 설정되어, 프레임 속도 저하를 더 정확히 확인가능합니다. (혹은 프로젝트 세팅 -> 일반 -> 프레임 속도 -> '고정된 프레임 속도' 체크 해제)
GPU 작업 확인
- cmd 창에 'Stat Scenerendering'을 입력하면 현재 렌더링 작업과 드로우 콜(Draw Calls)을 확인할 수 있습니다.
- cmd 창에 'Profile GPU'를 입력하면 GPU 작업량을 표로 시각화해 줍니다. 이 표는 명령을 입력한 순간의 값이며 화면을 이동해도 변하지 않습니다.
셰이더 복잡도 확인
- 뷰포트 상단의 뷰 모드에 최적화 뷰모드 - 셰이더 복잡도를 선택하면 현재 화면에서 셰이더의 복잡도를 컬러로 확인할 수 있습니다. (단축키 Alt + 8)
- 일반적인 프로젝트에서 큰 문제가 될 만큼 복잡한 셰이더는 사용하지 않지만, 마찬가지로 사양이 낮은 기기에서 구동을 목표로 한다면 셰이더 복잡도를 확인할 필요가 있습니다.
- 머티리얼 에디터 창 상단에 '통계'를 클릭하면 Base pass shader에 필요한 Instruction(명령) 개수를 확인할 수 있습니다. 셰이더 복잡도는 이 Instructions 개수에 비례해 올라가며, 머티리얼 노드 개수와는 상관이 없습니다.
라이트 복잡도 확인
- 뷰 모드 - 최적화 뷰모드 - 라이트 복잡도 (단축키 Alt + 7) 로 라이트 복잡도를 확인할 수 있습니다. 한 메쉬에 여러 개의 '무버블 라이트'가 영향을 미칠 경우 라이트 복잡도가 올라가게 됩니다. 그렇기 때문에 라이트 세팅을 할 때 라이트 간의 거리와 반경을 조정해 라이트 복잡도를 낮춰줄 필요가 있습니다. (스태틱 라이트는 프레임 레이트와 무관하며, 라이팅 빌드 속도만 연관이 있습니다.)
- 마찬가지로 스테이셔너리 라이트가 서로 겹치는 경우에도 라이트 복잡도가 높아지며, '스테이셔너리 라이트 겹침' 모드에서 확인할 수 있습니다.
3. 프레임 레이트 문제 해결
- 이전에 프로젝트들을 프로파일링 하고 최적화하며, 주로 문제가 되었던 요소들을 해결한 방법을 소개해 보겠습니다.
그림자 (Shadow) 최적화
- 대부분의 프로젝트에서 무버블 라이트와 무버블 오브젝트가 프레임 레이트에 큰 영향을 미칩니다. 엄밀히 말하면 이 두 가지가 드리우는 그림자를 실시간으로 계산하는 과정이 퍼포먼스와 직결됩니다.
- 이전에 최적화를 진행했던 프로젝트의 GPU 시각화 툴 창입니다. ShadowDepths 항목의 'DirectionalLight_1'이 성능에 가장 큰 영향을 미치고 있습니다.
최적화 방법
Shadow Depths 처리비용에 영향을 미치는 요소와 개선방법은 다음과 같습니다.
- 실시간 그림자를 드리우는 무버블 라이트의 개수와 반경(Static Lights는 영향 제외)
- 앞서 언급했듯 정적 오브젝트들은 Static으로 세팅해 라이팅 빌드를 통해 그림자를 그려주고, 움직임이 필요한 오브젝트 들만 무버블로 세팅해 줍니다.
- 한 메시에 여러개의 무버블 라이트가 영향을 미치지 않도록 범위를 조절해 줍니다.
- 자세하게 표현하지 않아도 되는 프랍 같은 경우 무버블 라이트에 대해 컬링을 시키거나 Cast Shadow를 꺼서 그림자 연산을 줄여줍니다.
- 중요하지 않지만 음영이 필요한 움직이는 오브젝트의 경우 '라이트 프로브' 사용을 고려해 볼 수 있습니다.
- 실시간 그림자를 드리우는 무버블 오브젝트의 트라이앵글 개수
- 무버블 라이트에 영향을 받는 메쉬의 트라이앵글 수를 최소화하면 그림자 연산 성능을 향상할 수 있습니다.
- 메시 LOD를 적용하는 것도 방법이 될 수 있습니다.
UE5 버전이 출시되며 '나나이트'와 '버츄얼 섀도 맵'이라는 기술을 공개했습니다. 나나이트는 카메라의 위치, 거리에 따라 자동적으로 트라이앵글들을 가상의 나나이트 지오메트리로 묶어 렌더링 하는 기술입니다. 이 기술들로 무버블 라이트로 세팅된 대규모 씬도 품질 손실 적게 실시간 렌더링할 수 있으며, 5.1 버전부터는 폴리지에도 나나이트가 적용 가능해지는 등 계속해서 개선된 서비스를 내놓을 예정이라고 합니다.
- 그림자의 퀄리티 세팅
- 프로파일링을 통해 찾아낸 문제 되는 무버블 라이트의 디테일 창에서 그림자 설정을 조절해 줍니다.
- Directional Light의 경우 Dynamic Shadow Distance Mavable Light 설정을 조절해, 카메라 위치 기준으로 그림자를 드리우는 거리를 조절해 주는 것도 좋은 방법입니다.
드로우 콜 최적화
- 드로우 콜(Draw Calls)은 GPU에게 어떤 것을 렌더링 하라는 명령을 호출하는 것을 말합니다. 이 또한 프로젝트 최적화에 중요한 요소이며, 드로우 콜 최적화를 위한 다양한 기술들이 존재합니다.
- 드로우 콜 발생
- 메시 1, 머티리얼 1 일 때 드로우 콜은 1개 발생합니다.
- (Batching 하지 않을 때) 같은 머티리얼을 공유하는 메시가 10개면 드로우 콜은 10개 발생합니다.
- 메시 한 개에 여러 개의 머티리얼을 사용한 경우, 머티리얼 개수만큼 드로우 콜이 발생합니다.
최적화 방법
- 배칭(Batching)
- 배칭은 동일한 머티리얼 인스턴스를 사용하는 메시들을 묶어서 한 번에 렌더링 하는 기술입니다.
- 모양이 다른 메시라도 같은 텍스처와 머티리얼을 공유한다면 드로우 콜을 통합할 수 있습니다.
- 그렇기 때문에 4개의 메시에 256x256 사이즈의 텍스처 4개를 사용하는 것보다, 512x512 사이즈 텍스처 하나로 머티리얼을 공유하는 것이 더 최적화에 유리합니다.
- 배칭이 가능하게 하기 위해 보통 Texture Atlas를 사용합니다.
- 인스턴싱(Instancing)
- 인스턴싱은 형태가 같은 다수의 오브젝트를 렌더할 때, 병목현상을 최소화해 속도를 향상시키는 최적화 기술입니다.
- 수많은 식생이나 바위들 처럼 같은 오브젝트를 대규모로 렌더링 할 때 인스턴싱은 큰 성능 개선을 가져다줍니다.
- 언리얼 엔진은 4.22 버전부터 자동으로 인스턴싱을 실행합니다.
플레이너 리플렉션
- 엔진을 이용한 프로젝트에서 거울 반사는 항상 문제가 됩니다. 실시간으로 거울 반사 렌더링을 하는 것은 두 개의 카메라를 동시에 렌더링 하는 것과 비슷하므로 성능을 저하시킵니다. 그래서 Box/Sphere Reflection Capture를 통해 반사효과를 표현합니다. 프로젝트 용량에 영향을 주기 때문에 어쩔 수 없이 Planar Reflection을 이용하는 경우, Planar Reflection의 반사 범위를 줄이거나, Screen Percentage를 줄여 성능과 반사 퀄리티의 타협점을 찾아야 합니다.
UE5가 출시되면서 언리얼 엔진은 성능 저하가 적은 실시간 반사를 지원하고 있으며, 이후 버전에서 더욱 퀄리티 개선을 할 예정이라고 합니다.