DirectX/개념

[DX] ##8. FRUSTUM CULLING ( 절두체 선별 )

코딩하는상후니 2022. 8. 25. 16:16

 


 

*FRUSTUM CULLING ( 절두체 선별 )

 
=> 월드상의 모든 물체를 다 그리기엔 비용이 너무나도 크다.

 

https://en.wikipedia.org/wiki/Viewing_frustum

 

 

=> 해당 영역 안에 있는 물체들만 랜더링한다.
 

 

 
저 사다리꼴 모형의 영역을 지정하기 위해서
총 6개의 평면을 정의하고 어떤 하나의 점이 모든 평면의 안쪽에 존재하는지 판별해야한다.
 
우선 우리는 평면방정식을 알아야한다.
 
 
 
 
 
 
 
 
 

* 평면 방정식

 
 
* 평면 방정식에서 필요한 요소들은 무엇일까 ??
 
1. 평면의 노말벡터
2. 원점과 평면과의 거리
 
 
 
 
'평면에 원점이 포함될 때' 평면 위의 두 벡터를 안다면
해당 두 벡터를 외적함으로써 우리는 노멀벡터를 구할 수 있다.
 

 

 

 
이 때, 우리는 한 가지 사실을 알 수 있다.
 
"  N • (dot) P1 = 0  "
 
=> 노말벡터와 평면 위의 벡터의 내적이 '0' 이라는 것은
서로 '직교' 한다는 것임.
 
 
 
 
 
만약,
평면이 원점을 벗어나 있다면 어떤 상황이 될까 ??

 

 

 

이 때는 A, B 두 점 만으로는 두 개의 벡터가 나올 수 없으므로,
평면 위의 최소 A, B, C  3개의 정점을 알아야지만 N 을 구할 수 있다.
 
 
 
 
'D' 는 원점에서부터 거리를 나타낸다.
평면 위의 점과 N 을 내적하면 평면의 N 에 투영된 길이가 곧 'D' 가 된다.
 
 
따라서,
이전의 원점 위에서의 평면과 원점을 벗어난 평면의 차이점은 'D' 의 값이다.
원점에 존재하면 D = 0 아니면 D > 0 , D < 0
 
 
 
평면 위의 벡터를 구하기 위해선 평면 위의 세 정점이 필수적이고
이 정점들을 이용해 노말벡터를 구하고
이 노멀벡터와 평면 위의 한 정점을 내적하면 평면과 원점 사이의 거리가 나온다.
 
 
결과적으로,
위 내용을 토대로 식을 세우면 우리가 익히 보았던
' ax + by + cz + d ' 의 평면방정식이 세워진다.
 
 
a, b, c : 노말벡터의 좌표
x, y, z : 미지수
d : 원점과 평면의 거리
 
 
 
 
 
 

* 임의의 정점, 평면 방정식을 이용해 판별하기

 
 
임의의 정점이 평면에 위치할 곳은 총 '3가지' 이다.
 

 

 

N • S = SD
 
1. 평면 밖 ( SD > D )
2. 평면 위 ( SD = D )
3. 평면 안 ( SD < D )
 
 
 
즉,
ax + by + cz + d 방정식에 정점을 대입했을 때 값으로 판별할 수 있다.
 
 
 
 
 
 
 
 
 
 
 

* 구현 라이브러리

 
 
 
* XMPlaneFromPoints

 

 
=> 세 정점으로 평면 방정식을 구할 수 있다.

 

inline XMVECTOR XM_CALLCONV XMPlaneFromPoints
(
    FXMVECTOR Point1,
    FXMVECTOR Point2,
    FXMVECTOR Point3
) noexcept
{
    XMVECTOR V21 = XMVectorSubtract(Point1, Point2);
    XMVECTOR V31 = XMVectorSubtract(Point1, Point3);

    XMVECTOR N = XMVector3Cross(V21, V31);
    N = XMVector3Normalize(N);

    XMVECTOR D = XMPlaneDotNormal(N, Point1);
    D = XMVectorNegate(D);

    XMVECTOR Result = XMVectorSelect(D, N, g_XMSelect1110.v);

    return Result;
}