GameDev – Object Culling #1

네트워크 플레이의 기본 구조는 제대로 구현했다.
이제 플레이 가능한 속도를 보장할수 있도록 오브젝트 컬링을 위한 작업에 들어갔다.

우선 월드를 KD-Tree로 분할해서 복셀 오브젝트들을 집어넣었다.
뷰프러스텀에 들어가는 오브젝트를 찾을때 상위노드부터 제거하므로 탐색 효율은 확실히 좋아졌다. 하지만 이것만으론 많이 부족하다.
역시 가려진 오브젝트를 그리지 않도록 하는것이 가장 중요하다.

예전에 사용했던 Room/Portal/BSP방식도 이번엔 사용할 수 없다. 지형이 실시간으로 변경되니까.
H/W Occlusion Culling은 무조건 사용한다.
다만 지금 보면 16x16x16정도의 복셀 오브젝트를 렌더링할때 Geometry Shader에 상당한 부하가 걸린다. 따라서 원래의 렌더링 체계로 Occluder를 그리면 오히려 더 느려질것이다. 원래의 복셀 오브젝트의 외형을 뚫고 나오지 않으면서 최대한 큰 사이즈의 단순화된 메시가 필요하다.

복셀 오브젝트마다 가공된(조각된) 복셀 오브젝트를 뚫고 나오지 않는 최대사이즈의 박스를 생성하도록 했다. 이것은 복셀 하나하나를 편집할때마다 갱신된다. 이걸 Occluder로 사용할거다.
복셀 오브젝트의 최대 사이즈 박스(1.6m x 1.6m x 1.6m)는 Occludee로 사용한다.
H/W Occlusion에서 써먹을건 확실하다. 그런데 그것만으론 부족하다. 최종적으로 H/W Occlusion까지 갈때까지 너무 많은 오브젝트를 수집하게 될 것이다.

KD-Tree를 순회하면서 뷰프러스텀에 들어가는 노드와 오브젝트를 찾을때 박스 Occluder에 가려지는 노드와 오브젝트는 바로 제외시키려고 한다. 그럼 노드 단계에서부터 왕창 거를 수 있다.
그렇다면 박스 Occluder에 가려지는 노드(AABB로 표현)와 오브젝트(AABB로 표현)는 어떻게 컬링할 것인가…

기하학적으로 컬링하는 방법을 생각해봤는데 복잡하다. 그리고 가장 큰 문제는 오브젝트 단위로 Occluer뷰프러스텀을 만들어서 제외시키기엔 오브젝트의 크기(최대 1.6m x 1.6m x 1.6m)가 너무 작아서 효율이 많이 떨어질걸로 예상한다.
예를 들어 두개의 단일 오브젝트에는 가려지지 않지만 붙어있는 두개의 오브젝트에는 가려질 수 있다.그런데 기하학적으로 처리하려면 오브젝트 단위의프러스텀을 만들어서 각각 컬링을 시도한다. 이 경우 어느쪽에도 완전히 가려지지 않아 컬링되지 않는다.

depth buffer를 하나 만들어서 픽셀 단위의 깊이값 비교를 할 생각이다. 이것도 GPU를 이용할순 있지만 KD-Tree탐색단계에서 사용하려면 CPUGPU간 통신이 너무 빈번하다. 아마 더 느려질 것이다. 이 부분은 S/W Rasterizer를 만들어서 처리할 예정이다.
512×512정도 사이즈라면 SSE 어셈코드와 멀티스레드 조합으로 어떻게든 말이 되는 속도를 만들어낼 수 있을것 같다.

512×512정도 사이즈라면 SSE 어셈코드와 멀티스레드 조합으로 어떻게든 말이 되는 속도를 만들어낼 수 있을것 같다.