"내일이 있다는 발상에 오늘이 희미해진다. 오늘 일은 오늘에 끝내라." – 김성근

2024/06/21

그래픽 성능 기본 원칙

원문

https://docs.unity3d.com/Manual/OptimizingGraphicsPerformance.html

이전 버전 문서

https://blog.fetchinist.com/?p=712

원문 내용이 완전히 바뀌어서 새로 올립니다.


이 페이지는 여러분이 만들고 있는 애플리케이션의 렌더링 성능 최적화에 대한 몇몇 간단한 지침을 포함하고 있습니다.

시작하기 전에: 문제를 찾고 이해하기

무언가 고치기 전에 문제의 원인을 찾으려면 애플리케이션을 분석해야 합니다. 원인을 알기 전에 성능 문제를 해결하려 시도하면 분명 시간을 허비하거나 문제를 악화시킬 수 있습니다. 덧붙여 렌더링과 관련된 성능 문제는 CPU나 GPU 모두에서 발생할 수 있습니다. 이런 문제를 고치는 방식은 매우 다양합니다. 그러므로 무언가 하기 전에 문제가 어디 있는지 아는 것이 중요합니다.

유니티 학습 사이트의 성능 문제 해결하기 글에서는 그래픽 성능에 대한 포괄적인 설명과 문제를 인지하고 해결하는 정보를 포함하고 있습니다. 이런 내용에 아직 익숙하지 않다면 이 페이지의 조언들을 따르기 전에 먼저 저 글을 읽어보세요.

렌러딩에 드는 CPU 비용 줄이기

일반적으로 CPU 렌더링 시간에 가장 큰 영향을 주는 것은 GPU에 렌더링 명령을 보내는 비용입니다. 렌더링 명령에는 그리기 호출(Draw call, 기하를 그리라는 명령)과 기하를 그리기 전에 GPU 설정을 변경하는 명령을 포함합니다. 이러한 경우에는 다음의 내용을 고려해보세요.

  • 유니티가 렌더링할 물체의 수를 줄일 수 있습니다.
    • 장면(Scene)장면은 환경과 게임의 메뉴를 포함합니다. 각각의 고유한 장면은 고유한 레벨이라고 생각하면 됩니다. 각각의 장면에 환경과 장애물, 장식물을 배치해서 조각조각 되어 있던 게임의 기본적인 모습으로 디자인하고 구축할 수 있습니다. 더보기에 있는 전체 물체의 수를 줄여보세요. 예를 들어 하늘 상자(Skybox)하늘을 표현하는 데 사용하는 특수한 유형의 재질. 보통은 여섯 면 사용. 더보기를 이용해 원거리에 있는 물체를 표현할 수 있습니다.
    • 선별(Culling)을 더욱 엄격하게 해서 유니티가 더 적은 물체를 그리게 합니다. 다른 물체에 가려져 보이지 않는 물체를 유니티가 그리는 것을 방지하기 위해 차폐 선별(Occlusion culling)카메라의 시야에서 숨겨진(가려진) GameObject의 렌더링을 비활성 하는 작업. 더보기 사용을 고려해 보고, 카메라장면 특정 시점의 영상을 만드는 요소. 결과물은 화면에 그려지거나 텍스처로 촬영될 수 있습니다. 더보기의 원거리 잘라내기 평면(Far clip plane)을 줄여서 먼 거리에 있는 물체들을 절두체 밖으로 빼거나 좀 더 세밀한 접근방법으로는 물체를 분리된 레이어에 넣고 Camera.layerCullDistance를 사용해 레이어별 선별 거리를 설정하는 방법이 있습니다.
  • 유니티가 각각의 물체를 그리는 횟수를 줄일 수 있습니다.
    • 조명과 그림자를 “굽는(사전 계산하는)” 조명 지도 작성(lightmapping)을 적절한 곳에 사용해보세요. 빌드 시간, 런타임의 메모리와 저장 공간 사용량이 늘어나지만 런타임 성능을 향상할 수 있습니다.
    • 애플리케이션이 전방 렌더링(Forward rendering)각각의 물체를 영향을 주는 조명에 따라 한 번 이상의 패스로 그리는 렌더링 경로(rendering path)입니다. 조명 자체도 또한 전방 렌더링에 의해 설정과 세기(intensity)에 따라 다르게 처리됩니다. 더보기을 사용한다면, 물체에 영향을 주는 픽셀당 실시간 조명의 수를 줄여보세요. 더 자세한 내용은 전방 렌더링 경로(Forward rendering path)를 참조하세요.
    • 실시간 그림자는 자원을 매우 많이 사용할 수 있으므로 효율적으로 드물게 사용해야 합니다. 더 자세한 내용은 그림자 문제 해결: 그림자 성능을 보세요.
    • 애플리케이션이 반사 감지기(Reflection Probes)자신을 둘러싼 모든 방향의 모습을 구형(球形)으로 촬영하는 카메라와 비슷한 렌더링 요소입니다. 촬영된 영상은 입방체 지도(cubemap)로 저장되어 반사 재질이 있는 물체에 사용할 수 있습니다. 더보기를 사용한다면, 반드시 최적하게 사용해야 합니다. 더 자세한 내용은 반사 감지기 성능을 보세요.
  • GPU에 더 효율적으로 “묶음(batches)”을 보내서 유니티가 준비하고 보내야 하는 그리기 명령의 양을 줄일 수 있습니다. 이를 달성하는 방법은 여러 방식이 있습니다. 더 자세한 내용은 그리기 호출 최적화를 보세요.

이러한 많은 접근방식은 GPU에 필요한 작업 또한 줄여줄 겁니다. 예를 들어 한 프레임에 유니티가 그리는 물체의 전체 수를 줄이면 결과적으로 CPU와 GPU 양쪽의 작업량을 줄이게 됩니다.

렌더링에 드는 GPU 비용 줄이기

한 프레임을 그리는 시간 내에 GPU가 작업을 완료하지 못하는 이유는 크게 세 가지가 있습니다.

애플리케이션이 채우기 속도(fillrate)에 제한을 받고 있다면 GPU는 자신이 처리 할 수 있는 프레임당 픽셀컴퓨터 영상의 가장 작은 단위. 픽셀 크기는 화면 해상도에 따라 달라집니다. 픽셀 조명은 화면의 모든 픽셀에 계산이 들어갑니다. 더보기 수보다 더 많이 그리려 한다는 뜻입니다. 이런 경우라면 다음의 방법을 고려해 보세요.

  • 애플리케이션에서 겹쳐 그리는(overdraw)곳을 찾고 줄이세요. 겹쳐 그리기가 가장 빈번하게 일어나게 하는 것은 UI(User Interface, 사용자 접속기) 사용자가 애플리케이션과 상호작용을 할 수 있게 합니다. 유니티는 현재 세 가지의 UI 체계를 지원합니다. 더보기, 입자(particles)와 스프라이트이차원 그래픽 물체. 삼차원에서 작업하는데 익숙하다면 스프라이트는 기본적으로 기본 텍스처와 같지만, 개발을 하는데있어 효율적이고 편리하게 스프라이트 텍스처를 합치고 관리하는 기술이 있습니다. 더보기 같은 투명 요소가 겹쳐지는 것입니다. 유니티 편집기의 겹쳐 그리기 출력 모드(Overdraw Draw Mode)를 사용해서 문제가 되는 지점을 찾아보세요.
  • 파편 셰이더(fragment shaders) 실행에 드는 비용을 줄이세요. 셰이더GPU에서 실행되는 프로그램. 더보기 성능에 대한 정보는 셰이더 성능 페이지를 보세요.
  • 유니티의 내장 셰이더를 사용한다면 Mobile이라 Unlit 카테고리에 있는 것 중의 하나를 고르세요. 비 휴대 플랫폼에서도 잘 동작하지만, 더 복잡한 셰이더를 간소화하고 비슷하게 근사화한 버전입니다.
  • 동적 해상도GPU에 드는 작업량을 줄이기 위해 개별 렌더 목표를 동적으로 크기 조절할 수 있는 카메라 설정. 더보기는 개별 렌더 목표(render targets)를 동적으로 크기 조절할 수 있는 유니티 기능입니다.

애플리케이션이 메모리 대역폭에 제한을 받고 있다면 GPU는 전용 메모리에서 한 프레임 내에 처리 할 수 있는 데이터보다 더 많은 데이터를 읽고 쓰려 한다는 뜻입니다. 이는 보통 텍스처가 너무 많거나 텍스처가 너무 커서 그렇습니다. 이런 경우라면 다음의 방법을 고려해 보세요.

  • 런타임에 카메라로 부터 거리가 달라지는 텍스처의 밉맵(mipmaps) 기능을 활성화합니다. (예로 삼차원 장면에서 쓰이는 대부분의 텍스처들.) 이는 메모리 사용량과 이들 텍스처의 저장 공간을 늘리지만 런타임 GPU 성능을 향상할 수 있습니다.
  • 메모리 들어갈 텍스처의 크기를 줄이기 위해 딱 맞는 압축 포맷을 사용하세요. 이로써 불러오기 시간을 더 빠르게 하고 메모리 사용 총량을 적게 하며 GPU 그리기 성능이 향상될 수 있습니다. 압축 텍스처는 비압축 텍스처에 필요한 메모리 대역폭의 일부만 사용합니다.

애플리케이션이 정점 처리에 제한을 받고 있다면 GPU는 한 프레임에 처리 할 수 있는 정점보다 더 많은 수를 처리하고 있다는 뜻입니다. 이런 경우라면 다음의 방법을 고려해 보세요.

  • 정점 셰이더그려지고 있는 삼차원 모델링의 각각의 정점에 실행되는 프로그램. 더보기 실행에 드는 비용을 줄이세요. 셰이더 성능에 대한 정보는 셰이더 성능 페이지를 보세요.
  • 모델링을 최적화하세요. 필요 이상으로 추가적인 삼각형(폴리곤)을 사용하지 말고, UV 매핑 이음새(seams)와 아주 뾰족한 모서리(정점이 겹쳐질 정도)를 가능한 한 적게 유지하세요. 더 자세한 내용은 최적 성능을 위한 모델 제작을 보세요.
  • 세부 단계(Level of Detail)세부 단계(Level of Detail, LOD) 기술은 카메라와의 거리가 늘어남에 따라 유니티가 그려야 하는 게임오브젝트의 삼각형 수를 줄이는 최적화입니다. 더보기 기능을 사용하세요.

렌더링 빈도 줄이기

애플리케이션의 렌더링 프레임율을 줄이면 때때로 이득이 되는 경우가 있습니다. 이렇게 해도 한 프레임을 그리는데 드는 CPU와 GPU 비용은 줄어들지 않지만, (스크립트 실행 같은) 다른 작업들의 빈도에 영향을 주지 않고 유니티가 렌더링하는 빈도를 줄일 수 있습니다.

애플리케이션의 일부나 전체 애플리케이션의 렌더링 프레임율을 줄일 수 있습니다. 프레임율을 줄이면 불필요한 전원 사용을 방지하고 배터리 수명을 연장하며 장치 온도가 CPU 주기(클록) 제한이 발생하는 지점에 도달하는 것을 방지할 수 있습니다. 이는 특히나 휴대용기기에서 유용합니다.

애플리케이션 자원에 상당한 부분을 렌더링이 소비하고 있다는 것을 프로파일링에서 알게 되었다면, 어느 부분에서 이것을 가져가고 있는지 확인해보세요. 일반적인 사용 예로 메뉴나 일시 정지 화면, 턴제 게임에서 게임이 입력을 기다리는 경우, 그리고 자동차의 UI 같은 아주 정적인 요소를 가진 애플리케이션이 있습니다.

입력 지연을 방지하기 위해 입력을 하는 동안 임시로 프레임율을 올려서 반응성 있게 느껴지도록 할 수 있습니다.

렌더링 프레임율을 조정하려면 주문형 렌더링(OnDemandRendering) API를 사용하세요. 이 API는 적응형 성능 패키지와 특히 잘 작동합니다.

알림: VR가상 현실(Virtual Reality) 더보기 애플리케이션은 주문형 렌더링을 지원하지 않습니다. 모든 프레임을 렌더링하지 않으면 머리 움직임과 영상이 맞지가 않아 멀미를 유발할 위험이 올라갑니다.

댓글 남기기 | cat > 타닥타닥 | tag > ,

댓글 남기기

* 표시된 곳은 반드시 입력해주세요