Game Develop

[DirectX11] 절두체 크기(Frustum Size) 구하기 본문

ComputerGraphics/DirectX

[DirectX11] 절두체 크기(Frustum Size) 구하기

MaxLevel 2021. 6. 15. 03:10

정확히는 현재 카메라의 절두체의 근평면(Near)과 원평면(Far)의 너비(Width), 높이(Height)를 구하는 과정이다. 

포폴제작중에 프러스텀컬링이 어느영역만큼 컬링하고있는지 컬라이더를 이용해서 시각적으로 표현하고싶어서 관련 내용에 대해 공부를 했다. 편한이해를 위해 최종적으로 구하려는 결과물이 어떤것인지 먼저 보여주고 시작하겠다.

 

 

- 구하려는 결과물

                                                                                                                                                      

FrustumCollider

 

위와같은 절두체컬라이더를 만드려면 어떻게해야할까?

버텍스 찍어주는거자체는 그냥 근평면 찍어주고 원평면 찍어주고 이어주면 된다.

꼭짓점과 근평면 찍어주는거는 선택사항이니 알아서 하면된다. 

 

버텍스는 아래와 같이 찍어야 할 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void FrustumCollider::CreateMesh()
{
    vertices.emplace_back(0.0f, 0.0f, 0.0f); // 꼭짓점
 
    // NearRect
    vertices.emplace_back(-mNearRectWidth / 2.0f, -mNearRectHeight / 2.0f, mDistanceToNearRect);
    vertices.emplace_back(-mNearRectWidth / 2.0f, mNearRectHeight / 2.0f, mDistanceToNearRect);
    vertices.emplace_back(mNearRectWidth / 2.0f, mNearRectHeight / 2.0f, mDistanceToNearRect);
    vertices.emplace_back(mNearRectWidth / 2.0f, -mNearRectHeight / 2.0f, mDistanceToNearRect);
    
    // FarRect
    vertices.emplace_back(-mFarRectWidth / 2.0f, -mFarRectHeight / 2.0f, mDistanceToFarRect);
    vertices.emplace_back(-mFarRectWidth / 2.0f, mFarRectHeight / 2.0f, mDistanceToFarRect);
    vertices.emplace_back(mFarRectWidth / 2.0f, mFarRectHeight / 2.0f, mDistanceToFarRect);
    vertices.emplace_back(mFarRectWidth / 2.0f, -mFarRectHeight / 2.0f, mDistanceToFarRect);
 
    indices = {
        1,2,2,3,3,4,4,1// NearRect 이어주기
        5,6,6,7,7,8,8,5// FarRect 이어주기
        1,5,2,6,3,7,4,8// NearRect와 FarRect 이어주기
    };
}
cs

 

큐브나 다른 도형 버텍스를 찍어본사람이면 위와같이 생각하는건 어렵지 않을것이다.

결국 우리가 구해야할것은 근평면과 원평면의 크기를 결정하는 너비와 높이를 구하는것이다.

두 평면다 공식은 똑같고 거리값만 바꿔주면 되기 때문에 원평면을 기준으로만 설명하겠다.

먼저 높이를 구해보겠다.

 

먼저 절두체를 측면에서 바라봤을때의 이미지다.

사실 저 이미지 본순간 알아버리는 사람도 있을것이다.

그냥 위의 삼각형을 반으로 쪼갠다음 위에있는 직각삼각형의 높이를 구하고 *2를 하면 된다.

직각삼각형의 세타는 2/FOV가 될 것이고 밑변의 길이는 개발자가 임의로 셋팅한 원평면까지의 거리(d)일 것이다.

그러면 아래와같이 구하면 된다.

 

tan(2/FOV) = 직각삼각형의 높이 / d 

직각삼각형의 높이 = tan(2/FOV) * d;

절두체의 높이 = 2 * tan(2/FOV) * d

 

그냥 기본적인 삼각함수공식 하나 알고있으면 구할 수 있는 값이다.

너비(Width)값은 높이값에다가 종횡비(AspectRatio)값을 곱해주기만 하면된다.

근평면도 똑같이 구하면된다. d값만 근평면까지의 거리로 바꿔주면 된다.

그러면 끝..