비균등 비례변환(Non Uniform Scale Transform) 을 적용했을때 우리가 구한 법선은 더이상 수직이 아니게 된다.
법선 벡터를 만들때 사용했던, 접선 벡터(Tangent Vector)를 이용한다.
접선 벡터는 법선 벡터와 항상 수직이기 때문에.
$u=v_1-v_0$
즉, 변환행렬 A가 주어졌을 때, 변환 이후에도 법선 벡터가 수직이 되도록 만들어 주는 변환행렬 B를 구해야 한다.
B는 n이 접선 벡터인 u와 수직이라는 사실과 A행렬을 이용해서 구할 수 있다.
$u \cdot n = 0$
$un^T=0$
$u(AA^-1)n^T=0$
$(uA)(A^{-1}n^T)=0$
$(uA)((A^{-1}n^T)^T)^T=0$
$(uA)(n(A^{-1})^T)^T=0$
$uA \cdot n(A^{-1})^T=0$
$uA \cdot nB=0$
변환된 접선 벡터와 변환된 법선 벡터가 실제로 직교함을 알 수 있다.
즉, uA와 수직이 되게 하는 변환 행렬은 A의 역행렬의 전치행렬이다.
여기서 A가 만약 직교행렬이라면 역전치를 따로 구할 필요없이 그대로 사용하면 된다.
static XMMATRIX InverseTranspose(CXMMATRIX M)
{
XMMATRIX A = M;
A.r[3] = XMVectorSet(0.f, 0.f, 0.f, 1.f); // 이동 변환을 제외해준다.
XMVECTOR det = XMMatrixDeterminant(A);
return XMMatrixTranspose(XMMatrixInverse(&det, A));
}