다음을 통해 공유


프로젝션 변환(Direct3D 9)

프로젝션 변환은 카메라의 내부를 제어하는 것으로 생각할 수 있습니다. 카메라용 렌즈를 선택하는 것과 유사합니다. 이는 세 가지 변환 형식 중 가장 복잡합니다. 프로젝션 변환에 대한 이 설명은 다음 항목으로 구성됩니다.

프로젝션 행렬은 일반적으로 배율 및 원근 투영입니다. 프로젝션 변환은 보기 frustum을 큐보이드 모양으로 변환합니다. 보기 frustum의 가까운 끝은 먼 끝보다 작기 때문에 카메라에 가까운 개체를 확장하는 효과가 있습니다. 이는 원근이 장면에 적용되는 방식입니다.

보기 frustum 카메라와 보기 변환 공간의 원점 사이의 거리는 임의로 D로 정의되므로 프로젝션 행렬은 다음 그림과 같습니다.

프로젝션 행렬그림

보기 매트릭스는 z 방향에서 D로 변환하여 카메라를 원점으로 변환합니다. 번역 행렬은 다음 그림과 같습니다.

번역 행렬그림

변환 행렬을 프로젝션 행렬(T*P)을 곱하면 다음 그림과 같이 복합 프로젝션 행렬이 제공됩니다.

복합 프로젝션 행렬그림

큐브 뷰 변환은 보기 frustum을 새 좌표 공간으로 변환합니다. 다음 다이어그램과 같이 프러스텀이 큐보이드가 되고 원점이 장면의 오른쪽 위 모서리에서 가운데로 이동합니다.

큐브 뷰 변환이 보기 frustum을 새 좌표 공간으로 변경하는 방법에 대한 다이어그램

큐브 뷰 변환에서 x 방향 및 y 방향의 제한은 -1 및 1입니다. z 방향의 제한은 앞면 평면의 경우 0, 후면 평면의 경우 1입니다.

이 행렬은 카메라에서 가까운 클리핑 평면까지의 지정된 거리를 기준으로 개체를 변환하고 크기를 조정하지만 보기 필드(fov)를 고려하지 않으며, 멀리 있는 개체에 대해 생성하는 z 값은 거의 동일할 수 있으므로 깊이 비교가 어렵습니다. 다음 행렬은 이러한 문제를 해결하고 뷰포트의 가로 세로 비율을 고려하여 꼭짓점을 조정하여 큐브 뷰 프로젝션에 적합한 선택입니다.

큐브 뷰 프로젝션그림

이 행렬에서 Zn은 가까운 클리핑 평면의 z-값입니다. 변수 w, h 및 Q에는 다음과 같은 의미가 있습니다. fovw 및 fovk는 뷰포트의 가로 및 세로 보기 필드를 라디안으로 나타냅니다.

변수의 수식은

애플리케이션의 경우 시야각을 사용하여 x 및 y 크기 조정 계수를 정의하는 것은 뷰포트의 가로 및 세로 차원(카메라 공간)을 사용하는 것만큼 편리하지 않을 수 있습니다. 수학이 작동할 때 w와 h에 대한 다음 두 수식은 뷰포트의 차원을 사용하며 이전 수식과 동일합니다.

w 및 h 변수의 수식은 의미합니다.

이러한 수식에서 Zn은 근거리 클리핑 평면의 위치를 나타내고 Vw 및 Vh 변수는 카메라 공간에서 뷰포트의 너비와 높이를 나타냅니다.

C++ 애플리케이션의 경우 이러한 두 차원은 D3DVIEWPORT9 구조체의 Width 및 Height 멤버에 직접 해당합니다.

어떤 수식을 사용하든 Zn을 가능한 한 큰 값으로 설정해야 합니다. 카메라에 매우 가까운 z 값은 크게 달라지지 않기 때문입니다. 이렇게 하면 16비트 z 버퍼를 사용하는 깊이 비교가 다소 복잡해집니다.

세계 및 뷰 변환과 마찬가지로 IDirect3DDevice9::SetTransform 메서드를 호출하여 프로젝션 변환을 설정합니다.

프로젝션 매트릭스 설정

다음 ProjectionMatrix 샘플 함수는 앞면 및 후면 클리핑 평면뿐만 아니라 보기 각도의 가로 및 세로 필드를 설정합니다. 보기 필드는 pi 라디안보다 작아야 합니다.

D3DXMATRIX 
ProjectionMatrix(const float near_plane, // Distance to near clipping 
                                         // plane
                 const float far_plane,  // Distance to far clipping 
                                         // plane
                 const float fov_horiz,  // Horizontal field of view 
                                         // angle, in radians
                 const float fov_vert)   // Vertical field of view 
                                         // angle, in radians
{
    float    h, w, Q;

    w = (float)1/tan(fov_horiz*0.5);  // 1/tan(x) == cot(x)
    h = (float)1/tan(fov_vert*0.5);   // 1/tan(x) == cot(x)
    Q = far_plane/(far_plane - near_plane);

    D3DXMATRIX ret;
    ZeroMemory(&ret, sizeof(ret));

    ret(0, 0) = w;
    ret(1, 1) = h;
    ret(2, 2) = Q;
    ret(3, 2) = -Q*near_plane;
    ret(2, 3) = 1;
    return ret;
}   // End of ProjectionMatrix

행렬을 만든 후 D3DTS_PROJECTION 지정하는 IDirect3DDevice9::SetTransform 사용하여 설정합니다.

D3DX 유틸리티 라이브러리는 프로젝션 매트릭스를 설정하는 데 도움이 되는 다음 함수를 제공합니다.

W 친화적인 프로젝션 매트릭스

Direct3D는 세계, 뷰 및 프로젝션 행렬에 의해 변환된 꼭짓점의 w 구성 요소를 사용하여 깊이 버퍼 또는 안개 효과에서 깊이 기반 계산을 수행할 수 있습니다. 이와 같은 계산을 수행하려면 프로젝션 매트릭스가 w를 세계 공간 z와 동일하도록 정규화해야 합니다. 즉, 프로젝션 행렬에 1이 아닌 (3,4) 계수가 포함된 경우 적절한 행렬을 만들려면 모든 계수를 (3,4) 계수의 역으로 확장해야 합니다. 규격 매트릭스를 제공하지 않으면 안개 효과 및 깊이 버퍼링이 올바르게 적용되지 않습니다.

다음 그림에서는 비규격 프로젝션 매트릭스와 눈 상대 안개가 사용하도록 조정된 동일한 행렬을 보여 줍니다.

비규격 프로젝션 매트릭스 및 눈 상대 안개가 있는 행렬의 그림

앞의 행렬에서 모든 변수는 0이 아닌 것으로 간주됩니다. 시선 상대 안개에 대한 자세한 내용은 Eye-Relative 및 Z 기반 깊이참조하세요. w 기반 깊이 버퍼링에 대한 자세한 내용은 깊이 버퍼(Direct3D 9)참조하세요.

Direct3D는 w 기반 깊이 계산에서 현재 설정된 프로젝션 매트릭스를 사용합니다. 따라서 애플리케이션은 변환에 Direct3D를 사용하지 않더라도 원하는 w 기반 기능을 수신하도록 규격 프로젝션 매트릭스를 설정해야 합니다.

변환