절두체 컬링 순서가 중요한 이유
원래 코사인세타가 작은 각도를 기준으로 판정돼서 나와서 둔각으로 하면 반대편?으로 돌아가버린다.
1. FrustumCheckByPoint
class CFrustum :
public CEntity
{
public:
bool FrustumCheckByPoint(Vec3 _vWorldPos);
bool FrustumCheckBySphere(Vec3 _vWorldPos, float _fRadius);
public:
CLONE(CFrustum);
CFrustum(CCamera* _pOwner);
~CFrustum();
};
bool FrustumCheckByPoint(Vec3 _vWorldPos); => 점을 이용해서 절두체 내에 존재하는지 확인
bool CFrustum::FrustumCheckByPoint(Vec3 _vWorldPos)
{
for (int i = 0; i < FT_END; ++i)
{
// 임의의 점과 해당 평면의 법선벡터와 내적
Vec3 vNormal = m_arrFace[i];
vNormal.Normalize();
float fDot = vNormal.Dot(_vWorldPos);
// 내적한 값과 원점에서 해당 평면까지의 최단거리(D) 와 비교
if (fDot + m_arrFace[i].w > 0)
return false;
}
return true;
}
내적을 하는 이유?
평면에 있는 노말벡터랑 내적을 했을 때, 길이값이 나오는데 평면에 있는 w값이 들어있다.
vec4로 만든 이유가 w자리에 d값 (평면까지의 최단거리 값)
d값이랑 같으면 평면 위에 있는거고 d값보다 크면 절두체에 나갔다는 의미
6번의 평면 중에 하나라도 d값보다 크다(바깥쪽에 있다)라고 뜨면 안된다
받아서 노말라이즈 한 이유
이번 finaltick에서 구해놓은 평면의 방정식 값이 변경될 수 있어서 지역변수로 받아서 nomalize 해준다.
float fDot = vNormal.Dot(_vWorldPos); => woldpos는 내가 테스트 하려는 임의의 점이다.
이걸 평면과 수직한 노말벡터와 내적한 값을 fDot 이라 한 것이다.
fDot > m_arrFace[i].w => 6개의 평면방정식 중 하나라도 밖에 있다고 판정이 되면 실패여서 false가 된다.
* 그런데 코드상에서 왜 이렇게 작성한 했을까 ?
if (fDot + m_arrFace[i].w > 0)
return false;
근평면과 원평면은 카메라가 바라보는 벡터로부터 직교하는 성질이 있다.
따라서 노멀벡터는 이 됩니다.
우리는 바깥쪽을 바라보게 했기 때문에, 노말벡터가 (0,0,−1) 이다.
그래서 d값이 음수(-)의 값을 가지기 때문에 위와 같이 코드를 작성해야한다.
* Frustumcheck 를 했을 때. 스카이박스가 날아간 이유?
스카이박스는 무조건 원점에 있어서 사실상 위치가 의미가 없다.
어디를 쳐다봐도 나를 중심으로 스카이박스가 있는 느낌을 주려고 쉐이더에서 강제로 최대거리로 셋팅해놓았다.
실제오브젝트는 다른 곳에 있다 보니까 카메라 시야에 잡히지 않아 실패가 뜨는 것이다..
원점을 쳐다봐야 스카이박스가 그려질 것이다.
Frustumcheck 를 스카이박스처럼 꼭 하지 않아도 되는 애들을 위해 bool m_bFrustumcheck 를 둘 것이다.
2. FrustumCheckBySphere
bool CFrustum::FrustumCheckBySphere(Vec3 _vWorldPos, float _fRadius)
{
for (int i = 0; i < FT_END; ++i)
{
// 임의의 점과 해당 평면의 법선벡터와 내적
Vec3 vNormal = m_arrFace[i];
vNormal.Normalize();
float fDot = vNormal.Dot(_vWorldPos);
// 내적한 값과 원점에서 해당 평면까지의 최단거리(D) 와 비교
if (fDot + m_arrFace[i].w > _fRadius)
return false;
}
return true;
}
if (fDot + m_arrFace[i].w > _fRadius)
return false;
실패하려면 반지름이상으로 더 벗어나야 실패이다.
반지름의 기준?
내가 직접 imgui상에서 bounding 을 봐가면서 영역을 지정해나가야한다.
'DirectX 11 3d' 카테고리의 다른 글
230607 LandScape 포워드 -> 디퍼드 전환 (0) | 2023.06.14 |
---|---|
230602 지형 만들기, Height Map (다시) (0) | 2023.06.04 |
230531 Frustum Culling, 평면의 방정식 (1) | 2023.06.04 |
230530 tess.fx 이어서 작업 (0) | 2023.05.30 |
230526 Tesselation - Patch Constant Function (0) | 2023.05.26 |