✍️ 개요
[ Model이 렌더링(Rendering)되는 과정 (1편) ]
이전에 Model을 렌더링하기 위해 CPU는 Draw Call을 통해 GPU로 렌더링에 필요한 정보인 Mesh, Material, Texture, Shader, DP Call을 전송한다는 것을 확인했습니다.
여기서 GPU는 가장 먼저 Mesh을 구성하는 정점들의 좌표계를 로컬 -> 월드 -> 뷰 -> 투영 -> 클립 좌표계로 변환하는 것까지 살펴봤습니다.
이때 카메라 프러스텀에 대한 이야기를 잠시 했었는데, 오늘은 이부분과 관련하여 컬링 기법에 대해 살펴보도록 하겠습니다.
📌 Frustum Culling
Frustum Culling : 화면에 보이지 않는 객체를 렌더링 대상에서 제외하는 최적화 기법
위 사진에서 붉은 영역은 카메라 시야에서 벗어나기 때문에 굳이 렌더링할 필요가 없습니다.
그래서 카메라의 프러스텀과 충돌하지 않는 오브젝트는 렌더링에서 제거합니다.
위 사진을 보면 Frustum이 넓게 퍼지는 것을 확인할 수 있습니다.
그 이유는 3D 상의 원근법을 구현하기 위함으로, Unity 카메라는 두가지 모드를 제공합니다.
- Orthographic Camera : 직교 투영
- Perspective Camera : 원근 투영
이때, Near Clipping Planes와 Far Clipping Planes, FOV 값을 수정하여 Frustum Culling 범위를 설정합니다.
Frustom Culling 적용 전 (약 2,000개 렌더링) -> 적용 후 (약 1,300개 렌더링)
하지만 Frustom Culling을 적용하면 멀리 있는 모델이 갑자기 사라지는 현상이 나타낼 수 있습니다.
이때는 안개(Fog) 효과를 적용하여 출력을 보완하는 방법을 사용하면 좋습니다.
Frustom Culling을 사용하기 위해서 공간 분할 기법(Spatial Partition)을 사용합니다.
주로 2D는 Ouadtree를 사용하고, 3D는 Octree을 사용하여 재귀적으로 빠르게 탐색합니다.
탐색은 빠르지만 공간을 관리해야 하기 때문에 동적인 물체들이 많다면 오버헤드가 발생할 수 있습니다.
그래서 얼마나 잘게 쪼갤 것인지에 대해 매직 넘버를 찾는 것이 중요합니다.
Q. 혹시 Frustum 영역 내부로 특정 오브젝트가 그려지는 순간에 발동하는 이벤트가 있을까요?
A. 네! Unity 메시지 함수인 OnBecameVisible & OnBecameInvisible 이벤트 함수가 존재하니 참고하세요!
📌 Occlusion Culling
Occlusion Culling : 앞의 물체에 의해 가려진 물체를 렌더링 대상에서 제외하는 최적화 기법
주로 실내(Indoor)에서 많이 사용하며, 거의 50% 이상으로 성능 향상을 기대할 수 있습니다.
다만, 실외(Outdoor)에서는 오히려 느려질 수 있습니다. (추가 계산 비용이 존재하는데 효율을 보지 못하기 때문)
보통 Unity에서 정적인 물체는 Occluder만, 동적인 물체는 Occluder & Occludee 둘다 설정합니다.
Occlusion Culling의 효율을 극대화하기 위해선 매직 넘버를 찾아야 합니다. (머신러닝을 활용하여 찾기도 함)
청크가 너무 크면 효율이 떨어질 수 있고, 너무 작으면 추가 계산 오버헤드가 증가할 수 있다.
📌 Culling Mask
Culling Mask : Flag Layer을 활용하여 원하는 부분만 렌더링만 하는 기법
사실 Frustum 또는 Occulusion 컬링 이후에 Masking이 되기 때문에 효율이 증가하지는 않는다.
만약 여러 카메라를 사용하는 경우에는 Cinemachine 가상 카메라를 사용하면 좋습니다.
Cinemachine은 카메라들을 제어하는 역할을 하는 컴포넌트라서 여러 카메라를 사용하는 것보다 성능이 좋습니다.
📌 LOD
LOD : 일정 거리 이상을 넘어가면 렌더링을 최소화하는 기법
📝 정리
'유니티(Unity) > 이론 정리' 카테고리의 다른 글
[Unity] Model이 렌더링(Rendering)되는 과정 (1편) (0) | 2024.11.21 |
---|---|
[Unity] URP란 무엇인가? (0) | 2024.11.20 |
[Unity] 직렬화(Serialization)란 무엇인가? (1) | 2024.11.19 |
[Unity] Mono & IL2CPP 컴파일 방식의 차이 (0) | 2024.11.18 |
[Unity] .NET이란? (4) | 2024.11.17 |