뷰 행렬

카메라의 뷰 행렬( View Matrix )을 구하는 과정을 알아보자.
뷰 행렬은 공간변환 뿐만 아니라 셰이더에서 그림자 맵등을 구할 때도 사용된다.

카메라 뷰 행렬을 구할려면 다음 세 개의 값이 필요하다.

카메라 축 벡터를 구한 후에 X축, Y축, Z축에 해당 하는 값을  구한다.

카메라 위치 : eye

카메라 타겟 : at

카메라 Up 벡터 : up

//카메라 축 벡터들을 먼저 구한다.

zaxis = at - eye;
zaxis = normalize( zaxis);

xaxis = cross( up, zaxis);
xaxis = normalize( xaxis);

yaxis = cross( zaxis, xaxis);

//각 축에 대한 값

X축 값 = -dot( xaxis, eye);

Y축 값 = -dot( yaxis, eye);

Z축 값 = -dot( zaxis, eye);

mat._11 = xaxis.x

mat._12 = yaxis.x

mat._13 = zaxis.x

mat._21 = xaxis.y

at._22 = yaxis.y

mat._23 = zaxis.y

mat._31 = xaxis.z

mat._32 = yaxis.z

mat._33 = zaxis.z

mat._41 = -dot(&xaxis, &eye)

mat._42 = -dot(&yaxis, &eye)

mat._43 = -dot(&zaxis, &eye)

위의 설명은 왼손 좌표계에 대한 설명이었다. 오른손 좌표계는 zaxis 축을 구할 때 다음과 같이 한다.

zaxis = eye - at

다이렉트X를 이용하여 표현하면 다음과 같다.
MatrixLookAtLH 함수는 D3DXMatrixLookAtLH와 동일한 결과이다.

//왼손 좌표계
void MatrixLookAtLH(D3DXMATRIX* pOut, D3DXVECTOR3 *pEye, D3DXVECTOR3* pAt, D3DXVECTOR3* pUp)
{
    D3DXMATRIX& mat = *pOut; D3DXVECTOR3& eye = *pEye;
    D3DXVECTOR3& at = *pAt;  D3DXVECTOR3& up = *pUp;
    D3DXVECTOR3 xaxis, yaxis, zaxis;
        
    zaxis = at - eye;
    D3DXVec3Normalize(&zaxis, &zaxis);

    D3DXVec3Cross(&xaxis, &up, &zaxis);
    D3DXVec3Normalize(&xaxis, &xaxis);

    D3DXVec3Cross(&yaxis, &zaxis, &xaxis);

    D3DXMatrixIdentity(&mat);
    mat._11 = xaxis.x;               mat._12 = yaxis.x;            mat._13 = zaxis.x;
    mat._21 = xaxis.y;               mat._22 = yaxis.y;            mat._23 = zaxis.y;
    mat._31 = xaxis.z;               mat._32 = yaxis.z;            mat._33 = zaxis.z;
    mat._41 = -dot(&xaxis, &eye); mat._42 = -dot(&yaxis, &eye); mat._43 = -dot(&zaxis, &eye);  
}

 

//오른손 좌표계
void MatrixLookAtRH(D3DXMATRIX* pOut, D3DXVECTOR3 *pEye, D3DXVECTOR3* pAt, D3DXVECTOR3* pUp)
{
    D3DXMATRIX& mat = *pOut; D3DXVECTOR3& eye = *pEye;
    D3DXVECTOR3& at = *pAt;  D3DXVECTOR3& up = *pUp;
    D3DXVECTOR3 xaxis, yaxis, zaxis;
    
    zaxis = eye - at;
    D3DXVec3Normalize(&zaxis, &zaxis);

    D3DXVec3Cross(&xaxis, &up, &zaxis);
    D3DXVec3Normalize(&xaxis, &xaxis);

    D3DXVec3Cross(&yaxis, &zaxis, &xaxis);

    D3DXMatrixIdentity(&mat);
    mat._11 = xaxis.x;               mat._12 = yaxis.x;            mat._13 = zaxis.x;
    mat._21 = xaxis.y;               mat._22 = yaxis.y;            mat._23 = zaxis.y;
    mat._31 = xaxis.z;               mat._32 = yaxis.z;            mat._33 = zaxis.z;
    mat._41 = -dot(&xaxis, &eye); mat._42 = -dot(&yaxis, &eye); mat._43 = -dot(&zaxis, &eye);
}