모바일 VR은 몇 가지 제약을 벗어나지 않는 범위 내에서 작동해야 합니다. 모든 것을 두 번 렌더링하고 아주 높은 프레임 속도를 목표로 해야 합니다. 게임 루프에서부터 렌더 루프에 이르기까지 게임에서 프로세싱 시간이 필요한 모든 요소를 포괄하는 일곱 단계와 각 단계에서 최적화하는 방법은 다음과 같습니다.
모바일 VR의 빠른 최적화
초기에 수행해야 하는 작업:
- 정적 및 동적 배칭 활성화
- 섀도우 매핑 비활성화
- 절차적 스카이박스와 모든 스카이박스 조명 비활성화
- 런타임 전역 조명 비활성화
- 모든 광원을 베이크된 광원으로 변경
- 모든 이미시브 셰이더 프로퍼티를 베이크됨으로 변경
- 라이트맵 크기를 4096으로 확대
...나중에 수행해야 하는 작업:
- 프로파일러 사용!
- CPU 또는 GPU 스키닝 사용
- 오버드로우 검사(씬 뷰 오버드로우 모드 또는 교체 셰이더)
- 프레임 디버거를 사용하여 렌더링 순서 보기
- 렌더링 대기열 적절히 변경
CPU 포스트 프로세싱
성능을 고려할 때 살펴봐야 하는 사항:
- 게임플레이/물리/AI
- 트랜스폼 처리
- LOD와 게임 내 여러 오브젝트에 각기 다른 메시 해상도 할당
- 오클루전 컬링: 어떤 오브젝트가 다른 오브젝트 앞에 렌더링되어 오브젝트를 가리는지 살펴보고, 렌더링할 필요가 없는 오브젝트 살펴보기
~오클루전 컬링 문서: 오버드로우 씬 뷰에서는 벽 뒤에 가려진 방의 개수만큼 오버드로우가 높은 밀도로 렌더링됩니다. 게임 뷰에 표시되지는 않지만 렌더링하는 데 시간이 소요됩니다.
오클루전 컬링을 적용하면 멀리 있는 방은 렌더링되지 않아 오버드로우 밀도가 훨씬 낮아지고 렌더링되는 삼각형과 배치의 수가 크게 줄어들지만 게임 뷰에는 똑같이 표시됩니다.
- 동적 배칭: 배칭이 필요하다면 동적 배칭을 사용합니다. 씬에서 유사한 동적 오브젝트를 찾아 배치로 묶어서 사용되는 리소스를 줄일 수 있습니다.
- CPU 스키닝
- 절두체 컬링: 특정 순간에 절두체에서 무엇이 렌더링되는지 확인
- 정렬, 즉 렌더링 순서 설정
최적화 방법:
- 먼저CullingGroup API컬링할 오브젝트를 결정
- 캐릭터 계층 구조 최적화: 트랜스폼, 스크립트 등을 추가할 수 있게 전체 골격 메시를 해당 지점에 표시되는 필수 노드만으로 줄여서 최적화하는 체크박스가 실제로 있습니다.
- LOD 그룹 구현: 해상도가 각기 다르고 텍스처 세트와 머티리얼이 각기 다른 메시에 로드하고, 메시가 씬에 로드되는 거리를 조절합니다.
- 이 단계에서 정렬이 유용하지 않다고 생각한다면 정렬을 비활성화합니다.
- 마지막으로 드로우 콜에 얽매여 있는 것이 아니라면 배치(batch)를 사용하지 마세요.
렌더 루프
성능을 고려할 때 살펴봐야 하는 사항:
- 오브젝트를 모두 두 번씩(각 눈마다 한 번씩) 렌더링해야 합니다.
- 섀도우 맵 계산에 소요되는 리소스
최적화 방법:
- 활성화"싱글 패스 스테레오"렌더링 활성화. 각 눈을 따로 렌더링하는 대신 더 넓은 렌더 타겟과 교차 드로우콜을 사용하여 두 눈으로 보는 단일 씬을 한 번에 렌더링합니다.
싱글 패스 스테레오 렌더링을 활성화하는 방법: 플레이어 설정(Player Settings)을 엽니다. (메뉴: 편집(Edit) > 프로젝트 설정(Project Settings) > 플레이어(Player)). 플레이어 설정(Player Settings)에서 기타 설정(Other Settings)으로 이동하여 가상 현실 지원(Virtual Reality Supported) 체크박스가 선택되었는지 확인한 다음 그 밑에 있는 싱글 패스 스테레오 렌더링(Single-Pass Stereo Rendering) 체크박스를 선택합니다.
- 그림자에 소요되는 리소스 줄이기: 그림자를 드리우는 오브젝트와 그림자를 받는 오브젝트를 줄이고, 그림자 거리와 캐스케이드를 제한하고, 가능하다면 그림자를 끕니다.
- 섀도우 매핑 지양:Blob Shadow또는베이크된 그림자사용. 각 오브젝트의 부모가 될 수 있는데칼사용.
CPU에서 GPU로
성능을 고려할 때 살펴봐야 하는 사항:
- GPU 안에서 상태 변경을 지양하여 루프에서 벗어나도록 합니다.
- 머티리얼과 라이트맵 변경을 줄이는 방안에 대해 생각해 봅니다.
- 씬에서 오브젝트가 어떻게 그룹화되었는지 개요를 파악합니다.
최적화 방법:
- 배칭 사용: 예를 들어 여러 작은 메시 대신 큰 메시 하나가 렌더링되도록 정적 오브젝트를 배칭합니다.
- 텍스처 아틀라싱: 최대한 많은 텍스처와 머티리얼을 텍스처 아틀라스로 합쳐 렌더링 드로우 콜의 수를 줄입니다.
- 여러 작은 라이트맵 대신 더 적은 수(예: 룸 또는 위치별로 하나씩)의 큰 라이트맵을 구현합니다.
- 머티리얼 프로퍼티 블록 사용: 머티리얼을 완전히 교체하는 대신 머터리얼의 특정 요소만 변경하여인스턴스화의 장점을 활용합니다..
머티리얼에 GPU 인스턴스화를 사용하려면 프로젝트 창에서 머티리얼을 선택하고 인스펙터(Inspector)에서 인스턴스화 활성화(Enable Instancing) 체크박스를 선택합니다.
- 다중 스레드 렌더링 사용.
- 작업에Mesh API를 직접 사용하여 화면에 바로 그립니다. 방법은 조금 복잡하지만 화면에 표시할 오브젝트를 프로그래밍할 줄 안다면 이 저수준 API를 사용하여 그렇게 할 수 있습니다.
버텍스 프로세싱
성능을 고려할 때 살펴봐야 하는 사항:
- 래스터화
- 스피리컬 하모닉 광원
- 버텍스당 광원
- GPU 스키닝
최적화 방법:
- 더 적은 수의 삼각형을 사용.
- GPU 의존 게임이라면 CPU 스키닝을 사용합니다. 즉 GPU를 많이 사용하는 게임이라면 GPU 병목 현상을 일으키는 작업 중 이동 가능한 작업을 CPU에서 처리하도록 합니다.
프래그먼트 프로세싱
성능을 고려할 때 살펴봐야 하는 사항:
- 섀도우 맵 연산
- 디퍼드 라이팅 프리패스
- 라이트매핑
- 물리 기반 렌더링
최적화 방법:
- 오버드로우를 제한하여 성능 저하를 방지합니다. 그러려면 콘텐츠에서 오버레이되는 모든 요소(반투명한 연기 텍스처, 기타 파티클 효과, 겹쳐진 나뭇잎 등)에 대해 생각해야 합니다. 오버레이를 많이 사용할수록 더 많은 리소스가 사용됩니다.
- 무엇이 어떤 순서로 그려지는지 알 수 있도록Material.renderQueue를 사용하여 렌더링 순서를 제어합니다.
- 프레임 디버거를 사용하여 렌더링 순서를 차례대로 확인하고 씬의 각 부분이 어느 단계에서 렌더링되는지 정확하게 파악합니다. 그런 다음, 렌더링 순서를 어떻게 변경할지 생각해보고 렌더링할 필요가 없는 요소를 찾을 수 있습니다.
유니티의 프레임 디버거
- 겹쳐진 나뭇잎 등에서는 가능하면 오브젝트가 투명하게 표시되지 않게 하고 지오메트리를 간소화합니다.
- 모바일에서 리소스를 꽤 많이 소모할 수 있는 스탠다드 셰이더를 꼭 사용해야 하는지 생각해 봅니다. 모바일 스페큘러 셰이더나 기타 최적화된 모바일 셰이더를 대신 사용할 수도 있습니다.
멀티패스
성능을 고려할 때 살펴봐야 하는 사항:
- 섀도우 매핑
- 디퍼드 라이팅
- 버텍스당 광원
- 포워드 라이팅 광원 패스
최적화 방법:
- 씬에 빛이 어떻게 비춰지고 빛이 씬의 여러 오브젝트에 어떻게 오버랩되는지 살펴봅니다. 광원을 일정한 간격으로 배치하고 되도록 오버래핑을 방지하면 필요한 리소스가 절약됩니다.
- 감소픽셀당 광원 범위 줄이기.
- 픽셀당 최대 광원 수를 설정합니다.
화면 공간 프로세싱
성능을 고려할 때 살펴봐야 하는 사항:
-
이 단계에서는 멋진 영상을 연출하기 위해 효과를 적용하므로 많은 리소스가 필요할 수 있습니다. 가장 많이 사용되는 포스트 프로세싱 효과를 리소스를 적게 사용하는 것에서 많이 사용하는 순서로 아래에 정리하였습니다.
- 색 보정
- 톤 매핑
- 블룸
- AA
- SSRR: 화면 공간 반사
- SSAO: 화면 공간 앰비언트 오클루전
최적화 방법:
- 유니티의 최적화된 포스트 프로세싱 스택(무료 제공)을 사용하여 사용되는 리소스를 적게 유지합니다.여기스택과 관련한 빠른 시작 가이드를 참조할 수 있습니다. 워크플로에 대해 자세히 설명하는코리 존슨(Corey Johnson)의 강연도 참조할 수도 있습니다.
유니티의 새로운 포스트 프로세싱 스택의 실제 사용 사례
- 효과를 레이어로 처리하는 방법에 대해 깊이 생각해 보십시오. 타입마다 필요한 리소스의 양이 다릅니다. 픽셀당 프로세싱이 적을수록 좋지만, 균형을 찾는 것이 중요합니다.
'Unity' 카테고리의 다른 글
[Unity]Rigidbody가 붙어 있는 오브젝트를 움직이는 오브젝트에 고정시키는 방법(회전, 위치 등)(Rigidbody Fixed Method) (0) | 2019.03.29 |
---|---|
[Unity]draw call optimizer asset (0) | 2019.03.28 |
[Unity]VR카메라가 의도치 않은 방향 위치에 있을 때 (0) | 2019.03.28 |
[Unity]Galuxy S8/8+ 카드보드, 데이드림 및 하이브리드 2D 앱 다운 현상 해결방법 (0) | 2019.03.28 |
[Unity]초당 Frame 값 만들기 (0) | 2019.03.28 |