[Graphics] Mathematical Concepts

[Non-Uniform Scale] Scale변환 시 normal벡터 변환 방법 유도

doyyy_0 2024. 11. 21. 13:25

Rasterization에서 vertex쉐이더 단계에서 삼각형을 변환할 때 Rotation, Translation Scale 행렬 등을 통해 변환합니다.  하지만 반드시 같이 변환해줘야 하는 벡터가 있는데 삼각형의 normal벡터(법선벡터)입니다. Rotation이나 Translation은 변환시 상관이 없는데 Scale변환 시 normal벡터가 변환된 삼각형과 수직이 안 될 수 있기 때문에 따로 다른 행렬을 통해 변환 시켜줘야합니다. 

 

예를들어 다음 그림과 같이 non-uniform형식의 변환이 있다고 생각해봅시다. non-uniform형식은 x, y, z 각각이 같은 비율이 아니라 다른 비율로 변환 된다는 뜻입니다.  (a)에서 (b)로 변환되었고, (c)는 b의 normal벡터를 수직화 한 것입니다.

 

공식 유도는 다음과 같습니다

 

이 때, 단지 normal벡터를 수직화를 유지한 것이지 크기가 어떻게 변할지 모릅니다. 따라서 A의 역행렬을 Transpose하고 normalize로 반드시 길이를 1로 만들어줘야합니다.

 

 

여기서 추가적으로 A행렬을 역행렬화 하고 Transpose하기 전에 반드시 Translation값을 0으로 해줘야합니다. 벡터는 크기변환과 회전은 할 수 있어도, 이동하지는 않기 때문입니다. 그렇게 하지 않으면 추후에 값들이 섞여서 normal 벡터의 다른 부분에 영향을 줄 수 있습니다.

기본적으로 알아야할 내용은 벡터는 위치가 아니라 크기와 방향만 나타내기 때문에 (a,b,c,0)으로 나타내고 point는 (a,b,c,1)로 나타냅니다

 

코드는 다음과 같습니다.

this->m_worldRow = worldRow; //모델 변환
this->m_worldITRow = worldRow; //모델 변환 행렬 복사
m_worldITRow.Translation(Vector3(0.0f)); //이동 값 0으로 만들기
m_worldITRow = m_worldITRow.Invert().Transpose(); //역변환 후 Transpose