Game Dev – SW Occlusion Culling 성능

내가 작성한 SW Occlusion Culling코드는 256×256 float 버퍼에서 1730개 정도의 삼각형을 Z-Raster / Z-Test 하는데 15만클럭 정도가 소요된다.
SSE 명령어셋을 사용하는데 FPU만 사용하는것보다 2배 정도는 빠르다. AVX로 8샘플씩 처리하는 코드도 만들어놨지만 SSE만 쓰는것보다 느리다.
처음엔 싱글스레드 코드였지만 현재는 멀티스레드 4스레드를 사용한다. 내 PC의 물리코어가 4개이고 이 머신에선 4스레드보다 많은 스레드를 투입해도 성능향상이 미비하다. 그래서 현재 물리코어 개수로 제한했다.

오브젝트가 2만개가 넘는 상황에서 현재 스샷과 같은 카메라 방향으로 탐색할 경우, 1회의 탐색에서 오브젝트를 이루는 삼각형들을 Z-Raster / Z-Test하는 작업을 1000번 이상, Node의 AABB를 Z-Test하는 작업을 1000번 이상 수행하게 된다.
이걸 최종 노드까지 다 탐색할때까지 제한없이 돌리니 캐릭터가 움직일때 15프레임 선까지 떨어졌다.
캐릭터가 움직이면 카메라 방향과 위치가 바뀌고 이때 보이는 오브젝트들의 목록을 갱신해야하는데 SW Occlusion Culling의 부하로 이만큼 떨어지는 것이다. GPU는 펑펑 놀고 순수 CPU 부하로 이만큼 떨어진다.
따라서 어느 선까지만 SW Occlusion Culling으로 걸러내고 나머진 GPU HW Occlusion Culling으로 처리해야한다.

이리저리 상수를 바꿔보며 나름 최적의 상수값을 찾았다. 현재로선 오브젝트의 Z-Raster / Z-Test를 최대 200회, Node의 Z-Test를 1000회로 제한하는게 가장 적절해보인다.

현재 스샷에선 HW Occlusion Culling을 완전히 끄고 SW Occlusion Culling에만 의존하고 있다. SW Occlusion Culling으로 얼마만큼의 자원을 소모하는지 비교하기 위해서 HW Occ를 껐다.
캐릭터가 뛰어다니며 카메라가 갱신되는 상황에서 70프레임 정도, 카메라 갱신 없이 86프레임 정도 나온다. 즉 SW Occlusion Culling하느라 소모한 시간으로 16프레임을 깍아먹고 있는 것이다.
21028개의 오브젝트중에 4245개를 렌더링하고 있다. 실제 보이는 오브젝트는 이보다 적다. 900개 정도일 것이다.
제한없이 SW Occlusion Culling을 돌리면 확실하게 보이지 않는 오브젝트를 거의 다 제거할 수 있지만 이 경우 culling으로 너무 많은 시간을 잡아먹게 된다.
HW Occlusion Culling을 켜면 카메라 갱신이 없을 경우 300프레임 이상으로 뛰게 된다.

SW Occ를 사용한 탐색 1회당 평균 17개의 node를 걸러냈다. 17개의 node중에는 굉장히 큰 덩어리(비교적 상위node)도 있고 작은 덩어리(비교적 하위node)도 있다.
큰 node를 걸러내면 하위 node들과 그에 속한 오브젝트들을 한방에 날릴 수 있으므로 매우 효율적이다.

그와는 별도로 자신이 속한 node의 culling에서는 살아남았지만 오브젝트 단위의 culling에서 제거된 오브젝트가 120개 정도 된다. 이쪽은 사실 개수가 많아도 큰 의미는 없다.
SW Occlusion Culling을 위해서는 어차피 각 오브젝트들을 Occluder로서 zbuffer에 그려야 하기 때문에(z값 비교를 하면서) 이 과정에서 오브젝트가 culling된다. 이건 그저 부수적인 효과이다.
SW Occ를 적용한 가장 큰 목적은 트리를 탐색해가는 과정에서 가려져서 보이지 않는 node를 제거하는 것이다. 오브젝트 단위의 culling은 HW Occlusion Culling이 무조건 빠르다. 정밀한 단위의 Culling은 HW Occlusion Culling에 맡기면 된다.

오브젝트 탐색코드에서 약간 더 최적화할 여지가 있긴 하지만 SW Occlusion Culling으로 기대할 수 있는 성능은 여기까지인것 같다.

SW_Occ_2017_0507


답글 남기기

댓글을 게시하려면 다음의 방법 중 하나를 사용하여 로그인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중