Quick Comparison
Occlusion culling은 카메라 시야 안에서도 벽·지형·건물 뒤에 가려진 객체의 draw와 fragment 작업을 건너뛰는 최적화입니다. frustum culling이 카메라 밖을 버리는 것과 달리 occluder 뒤의 가시성을 판정하며, 확실하지 않은 객체는 버리지 않는 것이 원칙입니다.
| 단계 또는 기법 | 무엇을 제외하는가 | 실행 시점 | 잘못 쓰면 | | --- | --- | --- | | Frustum culling | 카메라 절두체 밖의 객체 | CPU 또는 GPU draw 전 | world bounds가 갱신되지 않으면 보이는 객체가 사라짐 | | Portal / PVS | 현재 구역에서 도달할 수 없는 구역 | 로드 시 계산 또는 CPU | 문이 열리거나 동적 구조가 바뀐 장면에는 그대로 적용할 수 없음 | | Occlusion query | 다른 물체 뒤에 완전히 가려진 객체 | GPU 결과를 다음 프레임에 소비하는 경우가 많음 | 같은 프레임에 CPU가 결과를 기다리면 GPU-CPU 동기화가 생김 | | Hi-Z culling | depth pyramid보다 뒤에 있는 bounds | GPU-driven draw 전 | 깊이 방향, mip 선택, bounds가 틀리면 popping이 생김 |
판정 흐름
world bounds
-> frustum 통과?
-> 화면 사각형과 깊이 범위로 투영
-> Hi-Z 또는 visibility data와 비교
-> visible list 또는 indirect draw 목록에 기록occlusion culling은 시야 안에 있어도 벽, 지형, 큰 건물 뒤에 있는 객체를 줄입니다. backface culling처럼 삼각형 하나의 앞뒤를 검사하는 기능도 아니고, frustum culling처럼 카메라 밖만 버리는 기능도 아닙니다. 큰 occluder가 많고 같은 영역을 반복해서 그리는 도시나 실내 장면에서 draw와 fragment 작업을 함께 줄일 수 있습니다.
Hi-Z는 depth buffer를 작은 해상도로 계속 축소한 depth pyramid입니다. 객체의 bounding box를 화면 사각형과 깊이 범위로 투영한 뒤, 그 사각형을 덮는 적절한 mip의 깊이와 비교합니다. 객체가 그 깊이보다 확실히 뒤에 있을 때만 가려졌다고 판정합니다. normal Z와 reversed Z는 가까운 값의 방향과 clear/depth compare 규칙이 반대이므로, pyramid 생성과 비교식도 같은 규약으로 맞춰야 합니다.
Bounds와 결과 소비
| 확인할 값 | 바꾸는 때 | 틀렸을 때 보이는 증상 |
|---|---|---|
| Bounds 공간 | local bounds를 쓸지 world bounds를 쓸지 정할 때 | transform을 적용하지 않으면 카메라 이동에 따라 물체가 튐 |
| Bounds 여유 | 스키닝, 파티클, vertex displacement가 있을 때 | 변형된 끝부분이 먼저 가려져 popping이 생김 |
| Hi-Z mip | 화면 투영 사각형의 크기에 맞출 때 | 너무 세밀한 mip은 비용이 커지고, 너무 거친 mip은 가려짐을 놓침 |
| Depth bias / 여유 | z precision, camera jitter가 있을 때 | 경계에서 한 프레임씩 보였다 사라짐 |
| 결과 지연 | 이전 프레임 결과를 쓸지 정할 때 | 빠른 카메라 회전 뒤에 잠깐 비어 보이거나 과하게 그림 |
GPU query 결과를 CPU가 즉시 읽으면 GPU가 끝날 때까지 CPU가 기다릴 수 있습니다. 그래서 query 결과는 다음 프레임에 쓰거나, compute shader가 visibility 목록과 indirect draw 명령을 GPU 안에서 바로 만드는 구조가 흔합니다. camera cut, FOV 변경, 해상도 변경, depth buffer 재생성 뒤에는 이전 Hi-Z나 temporal visibility를 신뢰하지 말고 한 프레임은 넉넉히 그리는 편이 안전합니다.
선택과 실패 신호
| 장면 조건 | 먼저 선택할 방법 | 측정할 값 |
|---|---|---|
| 방과 복도가 명확한 실내 | Portal 또는 PVS | visible set 크기와 로딩 메모리 |
| 큰 벽과 건물이 많은 도시 | Hi-Z 또는 hardware query | draw 수, hidden object의 fragment 시간 |
| 작은 인스턴스가 매우 많음 | GPU culling + indirect draw | culling compute 시간과 draw submission 시간 |
| 열린 지형 | frustum, LOD를 우선 | culling 비용 대비 줄어든 draw 수 |
카메라 가까이의 작은 객체, 투명 객체, 이동하는 occluder는 Hi-Z 결과가 불안정해지기 쉽습니다. 투명 물체는 보통 불투명 depth에 기록하지 않으므로 가림막으로 취급하지 않습니다. 또한 오브젝트를 버린 뒤 그 오브젝트가 만드는 그림자, 반사 probe, 후처리 마스크까지 함께 없어져도 되는지 pass별로 따로 정해야 합니다.