절두체 컬링

절두체 컬링.



그래픽스 시간에 절두체 컬링을 배웠었다. 그때는 '아 파이프라인에서 자체적으로 해주는구나'했는데, d3d를 보니 그게 아닌가보다...

프로그래머가 절두체를 정의하고 컬링을 해야한다는 것에 처음에 '이걸 왜 코딩으로 하지?'라는 물음이 생겼었다.

d3d 불편해...


1. 평면의 방정식


절두체 컬링이란, 월드에는 수없이 많은 폴리곤, 메쉬, 오브젝트가 존재한다. 하지만, 그중에서 실제로 카메라의 시야에 포함되는 것만을 렌더링하고, 그 외의 폴리곤은 렌더링하지 않는 기법을 말한다.

간단하게 말하면 카메라의 시야범위에 들어오는 폴리곤만을 렌더링한다는 뜻이다.


절두체는 총 6개 평면으로 직육면체로 이루어져있다.

( 앞면(near), 뒷면(far), 좌면(left), 우면(right), 상면(top), 하면(bottom) )


이제 실제로 폴리곤이 평면의 내부에 존재하는지, 외부에 존재하는지를 판단해야한다. 여기서는 평면의 방정식을 사용하여 판단한다.

평면의 방정식이란, 무한 평면을 정의하는 수학적 도구로서, 간단한 수식으로 평면을 표현한다.


ax + by + cz +d = 0


여기서 a,b,c는 평면의 방향을 나타내는 법선 벡터 (a,b,c)이고 d는 평면과 원점간의 거리를 나타내고 x,y,z는 평면위의 있는 임의의 한 점이다.

내 식대로 설명하자면 평면의 방정식을 구하는 D3DXPlaneFromPoints 함수를 통해서 보겠다


D3DXPLANE* D3DXPlaneFromPoints (D3DXPLANE* pout, const D3DXVECTOR3* pv1, const D3DXVECTOR3* pv2, const D3DXVECTOR3* pv3)


이 함수의 내부에서는 (아마도) 두 개의 벡터와 하나의 법선 벡터를 만들 것이다.


v1 = pv2 - pv1

v2 = pv3 - pv1

n = v1 x v2


이때, pv1,pv2,pv3가 평면위의 점이라고 보면 v1,v2로 벡터를 만들어서 외적하여 법선벡터n을 만들었다.

(쓰고보니 그냥 단순히 법선벡터를 만드는 과정아냐?)


이제 위의 방정식에 n(a,b,c)와 pv1,pv2,pv3중에 하나의 점을 x,y,z로 대입하면 d를 구할수 있다.

솔직히 필자는 평면을 무수한 점이 아닌 수학적으로 표현한다는게 처음에 잘 와닿지는 않았다. 그러나 이 편이 메모리적으로 수학적으로 훨씬 더 효율적이니 이 방법에 익숙해져야한다.



2. 평면의 방정식을 이용한 내외부 판단


우리는 평면의 방정식의 법선 벡터를 이용해서 평면의 방향을 알게 되었다.

그럼 이제 이 성질을 이용해서 평면에 대한 한 점의 내외부 판정을 할수 있다.


임의의 한 점(x,y,z)를 평면의 방정식에 대입한다. a,b,c는 당연히 법선 벡터이다.


 ax + by + cz + d = 0

 점이 평면 위에 있다.

 ax + by + cz + d < 0

점이 평면 앞(내)에 있다. 

 ax + by + cz + d > 0

점이 평면 밖(외)에 있다.


 이제 이 작업을 6개의 평면에 대해 모두 대입하면 된다.

그 6개의 결과가 양수라면 절두체 안에 포함되게 된다.



3. 그외의 컬링 방법


평면의 방정식을 사용한 것까지는 좋으나 모든 버텍스를 일일히 검사한다는 것은 상당히 비효율적으로 느껴진다.

그외의 컬링 방법으로는 경계구 판정과 쿼드 트리, 옥트리, bsp트리등이 있다.

(http://showmiso.tistory.com/131)



더보기

댓글,

Lowpoly

게임 서버 프로그래머 지망생