momodudu.zip
#2 View Frustum culling에 관하여 본문
카테고리를 그래픽스로 할까 OpenGL로 할까 굉장히 고민을 많이했다(...) 일단 이론쪽에 가까워서, 그래픽스 카테고리로 결정했다.
그래픽스 파이프라인에서 culling이란, "어떤것을 그릴 지 말지 결정하는 과정"이라고 정의내릴 수 있다.
보통 파이프라인 내에서 culling은 두 단계로 이루어진다.
첫 번째로, back-face culling이라고 불리우는 object를 구성하는 mesh 삼각형을 그릴지 말지 결정하는 단계다. 즉, 한개의 object가 여러개의 삼각형(또는 사각형..) mesh로 구성이 되어있는데, 카메라가 보여주는 부분은 한정적이기 때문에 카메라에 등을 돌리고 있는 부분은 사실 그릴 필요가 없다.
이 back-face culling은 GPU pipeline내의 primitive assembly stage에서 이루어진다. 삼각형을 구성할때는 항상 정점의 순서가 있는데, 이 순서에 따라서 삼각형의 normal이 결정될것이다. openGL은 오른손좌표계를 취하고 있으므로, 삼각형의 정점 구성 순서를 보고 이 z방향과 반대의 normal을 갖는 삼각형들은 버린다.
이 과정은 GPU가 알아서 처리해주므로 우리가 신경 쓸 필요는 없다.
두 번째로는, View Frustum culling기법이 있다. 이는 GPU단계에서 이루어지는게 아니라, CPU에서 일어나는 전처리 과정이다. 간단하게 요약하자면, object를 감싸는 어떤 bounding box, 혹은 구를 만들어서 이 object자체가 frustum내에 들어가는지 아닌지 CPU Stage에서 검사를 해서 view frustum에서 걸러지는 object들은 애초에 GPU로 보내지 않는 것이다. 어차피 GPU로 들어가는 카메라와 카메라가 보여지는 영역에 대한 정보는 CPU에서 알고있기 때문이다.
사실 view frustum밖에 있는것을 CPU단에서 culling 전처리를 하지 않고 파이프라인으로 보낸다고 해서 그려지는건 아니다. 버텍스 쉐이더에서 투영 변환 수행 후에 clip space가 생기게 되는데, 이 clip space에서 뷰 프러스텀 밖에 있는것은 모두 클리핑해주긴 한다. 그러나 GPU성능을 극대화 하기 위해서는 CPU도 어느정도는 써줘야 한다.
본 포스팅에서는 View Frustum culling 기법에 대해 간단하게 설명하고자 한다.
View Frustum culling기법은 기본적으로 Object를 감싸는 bounding volume을 구성하여 View frustum 절두체가 해당 bounding volume과 교차하는지 매 프레임마다 검사하여 교차한다면 GPU로 보내고, 아니라면 CPU에서 GPU로 보내지 않는다.
본 포스팅에서는, bounding volume을 구성하는 방법들과 CPU전처리 작업에서 사용되는 view frustum culling 기법에 대해 간략하게 설명한다.
<Bounding Volume>
Bounding volume을 구성하는 방법에는 직육면체로 구성하는 방법과, 구로 구성하는 방법이 있다.
먼저 직육면체로 구성하는 방법은 직관적이다.
x-y 2차원에 대해서만 예를 들었는데, 점이 위와 같이 구성이 되어있다면 각 정점을 모두 방문해서 x,y의 max/min값을 갱신하면 된다. 3차원에서도 마찬가지다. 즉, 오브젝트를 구성하는 메쉬의 모든 정점을 방문하면서 max X,Y,Z 와 min X,Y,Z를 구하여 그걸로 직육면체를 만들면 된다. 이 기법을 바로 AABB(Axis-Aligned Bounding Box)라고 한다.
그리고 이렇게 AABB의 대각선 길이의 반을 반지름으로 취하는 구를 구성하면 bounding 구가 완성된다.
하지만 이 경우 실제 object보다 구가 더 크게 취해질 수 있어서, 실제로 object에 거의 접하다시피하는 구를 구하는 알고리즘을 쓰는것이 좋다고 한다. (이건 찾아봐야 할 듯...)
보통은 간단하게 AABB를 많이 쓰는듯 하다.
<View Frustum culling 기법>
1. AABB
View frustum의 6개의 plane의 노말에 AABB의 각 꼭지점을 (어디를 연결하는거지?)연결하는벡터를 내적해서, 내적한 값이 0보다 작으면 out을 counting하고 0보다 크거나 같으면 in을 카운팅한다. in의 개수가 하나라도 없으면 해당 오브젝트는 프러스텀 밖에 있다. 만약 in의 개수가 하나라도 있고, out도 있다면 intersect일것이다. 만약 out이 하나도 없으면 이 aabb는 frsutum내에 있다고 판단한다.
2. Sphere
뭔가 어떤점과 프러스텀 각 면의 노말을 내적한 값이 해당 바운딩sphrere의 -r보다 작은면이 하나라도 있으면 outside. r보다 크면 intersect. 그 외는 모두 inside.
'Graphics' 카테고리의 다른 글
#1 오일러각(Euler Angle)과 쿼터니언(Quaternions) 회전 (0) | 2019.10.05 |
---|