행렬 규약을 섞으면 생기는 문제
행 벡터, 열 벡터, Row-Major와 좌표계
본 블로그 작성 글들은, 강의를 목표로 하고 제작되었습니다. 또한 작성된 글의 정보도 틀렸을 수 있으니, 주의해주세요.
행렬 코드를 옮겼는데 물체가 반대 방향으로 회전하거나 이동이 이상해지는 경우가 있다. 대부분 Row Vector와 Column Vector, 저장 순서, 좌표계 규약을 섞었을 때 발생한다.
행 벡터와 열 벡터
행 벡터 규약
v' = vM
열 벡터 규약
v' = Mv
같은 변환이라도 벡터를 어느 쪽에 곱하는지에 따라 행렬 모양과 결합 순서가 달라진다.
Row-Major는 곱셈 규칙과 다른 말이다
Row-Major와 Column-Major는 메모리에 행과 열 중 무엇을 연속으로 저장하는지에 관한 말이다. 행 벡터를 사용한다는 말과 Row-Major 저장을 사용한다는 말은 같은 뜻이 아니다.
행렬
[ a b ]
[ c d ]
Row-Major 메모리: a b c d
Column-Major 메모리: a c b d
전치 행렬
Transpose는 행과 열을 서로 바꾼다.
[ a b c ]T [ a d ]
[ d e f ] = [ b e ]
[ c f ]
CPU 라이브러리와 Shader가 기대하는 배치가 다르면 Upload 전에 전치하기도 한다. 하지만 이유를 모르고 무조건 Transpose를 넣으면 다른 코드와 결합할 때 다시 뒤집힌다.
좌표계도 확인한다
Left-Handed와 Right-Handed 좌표계는 Z축 방향과 회전 방향, Projection 행렬에 영향을 준다. DirectX 함수 이름의 LH, RH가 이 차이를 나타낸다.
행렬 버그를 만났을 때 숫자만 바라보지 말고 다음을 먼저 적는 것이 좋다.
벡터는 행인가 열인가?
곱셈은 어느 방향인가?
메모리 저장은 Row-Major인가?
좌표계는 LH인가 RH인가?
Shader에서 Transpose하는가?
규약 하나하나는 어렵지 않다. 문제는 서로 다른 규약의 코드를 설명 없이 섞는 것이다.