일반적으로 VR 프레임 속도 유지는 추천 사양에서도 극도로 힘든 일입니다. 일반적인 실시간 렌더링에 비하면 프레임 속도 일관성이 더욱 중요한데, 프레임이 갑자기 떨어지면 사용자에게 편안한 느낌을 줄 수 없기 때문입니다.
그 점을 염두에 두고, 그래서 평균보다 길게 늘어지는 프레임을 흡수할 수 있도록 여지를 남겨둬야 합니다. 파이프라인을 여러 프레임에 걸치도록 하지는 않고 있는데, 그로 인해 입력/트래킹 지연시간이 생길 수 있기 때문입니다. 즉 게임 스레드는 항상 렌더 스레드보다 딱 한 프레임 앞서 있으며, GPU 및 렌더 스레드는 같은 프레임에 유지됩니다. 즉 GPU 시간 11ms 보다 살짝 적게 나오는데, 리프로젝션 부하 때문입니다. 게임 플레이 코드 부하로 인해 게임 스레드에서, 또는 드로 콜 부하로 인해 렌더 스레드에서, 또는 트랜스폼이나 셰이더의 부하로 인해 GPU 에서 프레임 시간이 길어지면, 프레임 시간을 놓칠 수 있습니다. 세 가지 요소 모두 고려해서 균형을 맞춰야 합니다.
가상 현실 실전 사례 문서의 콘솔 변수 세팅을 따르면, 렌더 스레드 퍼포먼스는 충분한 수준이 나올 것입니다. 거기서부터, 그 프레임 속도를 낼 수 있도록 콘텐츠와 게임플레이 코드를 최적화시키는 것이 중요합니다. 콘텐츠 측면에서는, 가급적 모든 것을 단순하게 유지하도록 하세요.
콘텐츠를 단순화시키는 일반적인 방법은 다음과 같습니다.
- 다이내믹 라이트와 섀도를 사용하지 않습니다.
- 반투명을 과도히 사용하지 않습니다.
- 보이는 일괄 부분에는 인스턴스를 활용합니다. 인스턴스 그룹의 엘리먼트가 하나 보이는 경우, 전체 그룹이 그려집니다.
- 모든 것에 LOD 를 만듭니다.
- 오브젝트의 머티리얼 복잡도와 머티리얼 수를 적게 유지합니다.
- 가능한 한 모든 것은 굽도록 합니다.
- 플레이어를 아우르는 커다란 지오메트리는 피합니다.
- 가급적 프리컴퓨티드 비저빌리티 볼륨을 사용합니다.
Bullet Train 및 Showdown 슬라이드에서 실제보다 복잡해 보이는 가상현실용 콘텐츠를 에픽에서 어떻게 제작했는지 그 예제를 확인할 수 있습니다. 또, 대부분의 스크린 스페이스 팁은 입체 상태에서는 기대했던 효과를 얻지 못합니다. 그저 평평하거나 이상해 보입니다.
프로젝트 전반에 걸쳐 프로파일링을 하면서, 프레임 속도가 유지되고 있는지 확인하도록 하십시오. 한계점에 달할 때까지 서서히 복잡도를 늘려가는 편이, 발매를 며칠 앞두고 목표 퍼포먼스를 맞추느라 가지를 마구 쳐내는 것보다 관리하기가 좋습니다.
드로콜 감소 기법은 딱 두 가지로 요약할 수 있습니다. 머티리얼은 가급적 많이 합치도록 하고, 인스턴스드 스태틱 메시 컴포넌트를 적극 활용하도록 합니다. 강조하지만 인스턴싱의 경우, 인스턴싱된 것이 무엇이든 한 부분이라도 보이면 항상 전체가 그려진다는 점을 기억하세요. 인스턴싱의 이점이 크게 감소되는 경우가 생길 수 있으므로, 일괄 오브젝트 대부분이 같은 지점에서 보이거나 보이지 않을 수도 있는 경우에는 일괄 인스턴싱을 하도록 하세요.
또 한 가지 고려할 수 있는 방법이라면, 컬 볼륨을 사용해서 어떤 방을 벗어났을 때 보이지 않는 방을 완전히 걸러내도록 하는 것입니다. 오클루전 시스템은 그릴 것을 선택하는 데 약간 더 자유로운 편이라, 컬 볼륨이 있으면 그 선택을 약간 보수적으로 만들 수 있습니다. 추가적으로, 액터(나 전체 서브레벨)의 비저빌리티 설정을 토글해도 똑같은 효과를 얻을 수 있습니다. 단 콘텐츠를 그런 식으로 제작을 해 두었어야 하겠습니다.
또 한가지 중요한 점은, 알파가 0 인 것이 있어도 여전히 그려는 집니다. 즉 아예 그려지지 않게 하려면, 실제로 숨겨서 렌더링되지 않도록 하시기 바랍니다.
일반 통계 구하기
Oculus 와 SteamVR 모두 퍼포먼스 감시를 위한 외부 툴을 제공합니다. 컴포지터 부하를 포함한 실제 프레임 타이밍을 확인하기 위해서는 이러한 툴을 사용할 것을 추천합니다.
UE4 측면에서, 게임에 있을 때 일반적인 통계를 구하는 방법은 몇 가지 있습니다:
콘솔 명령 | 설명 |
---|---|
stat unit | 게임 스레드, 드로 스레드, GPU 시간은 물론 전반적인 프레임 시간 정보가 나옵니다. 총 프레임 시간이 제대로 나오고 있는지, 게임 스레드 시간은 어떤지에 대한 정보를 수집하기에는 가장 좋습니다만, 드로 스레드나 GPU 시간에는 쓸 수 없습니다. |
startfpschart / stopfpschart | 90Hz 이상으로 소모되는 시간 비율을 파악하려면, 이 명령을 실행하면 됩니다. 시작부터 중지할 때까지 일정 구간의 통계 데이터를 캡처하여 종합한 다음, 프레임 속도 정보가 포함된 파일을 덤프합니다. 참고로 가끔 게임에서는 실제로 90Hz 여도 그 미만으로 보고하는 경우가 있는데, 80 이상 버킷을 검사해서 실제 프레임 속도에 소모된 시간을 결정하는 것이 좋습니다. |
stat gpu | 4.14 에 추가된 이 명령은, GPU 프로파일러와 비슷하지만, 게임에서 감시하고 모니터링할 수 있는 형태의 통계가 나옵니다. GPU 작업 비용을 간단히 검사할 때 좋습니다. |
실시간 GPU 프로파일러
새로운 실시간 GPU 프로파일러를 사용하려면, 게임 또는 에디터에서 stat gpu
라 입력합니다. 통계는 누적되며 계층구조가 없어서, 트리 구조의 이벤트를 통해 파내려가지 않고도 주요 카테고리를 확인할 수 있습니다. 예를 들어, 섀도 프로젝션은 (모든 뷰에 걸친) 모든 라이트의 섀도 프로젝션 전체의 총합입니다.

실시간 통계 기능은 게임플레이 도중 통계를 수집(해서 나중에 그래프로 만드는 등의 작업을 )하고자 할 때 특히나 유용합니다. 실시간 통계를 통해 콘솔 변수나 퀄리티 세팅으로 켜진 기능을 프로파일링하거나, 에디터 내 최적화 결과를 바로 확인할 수 있습니다.
통계는 코드에 플로트 카운터로 선언되어 있습니다:
DECLARE_FLOAT_COUNTER_STAT(TEXT("Postprocessing"), Stat_GPU_Postprocessing, STATGROUP_GPU);
렌더스레드 코드 블록은 SCOPED_GPU_STAT
매크로로 instrument 시킬 수 있는데, SCOPED_DRAW_EVENT
화 비슷하게 작동합니다:
SCOPED_GPU_STAT(RHICmdList, Stat_GPU_Postprocessing);
드로 이벤트와는 달리, GPU 통계는 누적됩니다. 같은 통계에 대한 여러 항목을 추가하면 합산됩니다.
명시적으로 마킹되지 않은 것은 전부 쓸어담는 [unaccounted]
통계에 포함됩니다. 그 시간이 높다면, 무언가 명시적 통계에 잡히고 있지 않으니 트래킹 매크로를 추가해줘야 한다는 것을 나타냅니다.