렌더핑 파이프라인의 정점처리 단계에서 가장 먼저 수행되는 작업은 오브젝트 공간의 정점을 월드 공간으로 옮기는 작업입니다. 이 작업을 월드 변환이라고 부릅니다. 오브젝트 공간의 정점을 월드 공간의 정점으로 변환하기 위해 이용되는 연산들을 소개드리겠습니다.
Scaling
x, y, z 좌표에 대한 축소확대 배율을 각각 sx, sy, sz라고 할 때
아래와 같은 행렬곱 연산을 통해 축소확대 연산을 수행할 수 있습니다.
⎣⎢⎡sx000sy000sz⎦⎥⎤⎣⎢⎡xyz⎦⎥⎤=⎣⎢⎡sxxsyyszz⎦⎥⎤
Rotation
회전 연산은 기준이 되는 축에 따라서 회전 행렬도 달라집니다.
x축을 기준으로 하는 회전 연산은 아래와 같은 행렬곱 연산을 통해 수행할 수 있습니다.
⎣⎢⎡1000cosθsinθ0−sinθcosθ⎦⎥⎤⎣⎢⎡xyz⎦⎥⎤=⎣⎢⎡xycosθ−zsinθysinθ+zcosθ⎦⎥⎤
y축을 기준으로 하는 회전 연산은 아래와 같은 행렬곱 연산을 통해 수행할 수 있습니다.
⎣⎢⎡cosθ0−sinθ010sinθ0cosθ⎦⎥⎤⎣⎢⎡xyz⎦⎥⎤=⎣⎢⎡xcosθ+zsinθy−xsinθ+zcosθ⎦⎥⎤
z축을 기준으로 하는 회전 연산은 아래와 같은 행렬곱 연산을 통해 수행할 수 있습니다.
⎣⎢⎡cosθsinθ0−sinθcosθ0001⎦⎥⎤⎣⎢⎡xyz⎦⎥⎤=⎣⎢⎡xcosθ−ysinθxsinθ+ycosθz⎦⎥⎤
위 회전행렬들에서 θ는 두 축이 이루는 오일러각을 나타냅니다. 이렇듯 오일러각에 대한 회전 연산을 결합하여 오브젝트의 방향을 표시하는 것을 오일러 변환이라고 부릅니다.
이러한 오일러 변환에서는 짐벌락이라고 부르는 문제가 발생하기 때문에 오일러 변환을 대신하여 쿼터니온을 사용합니다. 이는 다음에 기회가 될 때 소개드릴 수 있도록 하겠습니다.
Translate
이동 연산은 다음과 같은 행렬합 연산을 통해 수행할 수 있습니다.
⎣⎢⎡txtytz⎦⎥⎤+⎣⎢⎡xyz⎦⎥⎤=⎣⎢⎡x+txy+tyz+tz⎦⎥⎤
축소확대 연산과 회전 연산은 행렬곱으로 표현할 수 있었지만 이동 연산은 행렬곱으로 표현할 수 없는 경우가 있습니다. 다시 말해 아래와 같은 식을 만족하는 행렬 Mt가 존재하지 않을 수 있습니다.
Mt⎣⎢⎡xyz⎦⎥⎤=⎣⎢⎡x+txy+tyz+tz⎦⎥⎤
이는 이동 연산이 선형성을 만족하지 않기 때문입니다.
하지만 기존의 좌표에 차원을 하나 더 추가하여 동차 좌표로 만든다면 이동 연산 또한 행렬곱으로 표현이 가능합니다. 따라서 지금부터는 기존에 사용하던 3차원 좌표를 다음과 같은 4차원 좌표로 표현하겠습니다.
⎣⎢⎢⎢⎡xyz1⎦⎥⎥⎥⎤
그리고 위와 같은 동차 좌표를 통해 이동 연산을 행렬곱으로 표현하면 다음과 같습니다.
⎣⎢⎢⎢⎡100001000010txtytz1⎦⎥⎥⎥⎤+⎣⎢⎢⎢⎡xyz1⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡x+txy+tyz+tz1⎦⎥⎥⎥⎤
당연히 앞서 언급한 축소확대 연산과 회전 연산 또한 동차 좌표를 통해 계산할 수 있습니다. 그리고 이러한 아이디어를 통해 아래에서 설명드릴 최종적인 변환 행렬을 구할 수 있습니다.
정점의 좌표를 월드 공간에 표현하기 위해서는 위와 같이 축소확대, 회전, 이동의 3가지 연산이 필요합니다. (회전은 3번의 연산이 필요하지만 여기서는 1번이라고 가정하겠습니다.)
만약 오브젝트를 구성하고 있는 정점의 개수가 n개라면 총 3n번의 행렬곱 연산을 수행해야합니다. 하지만 앞서 설명한 축소확대 행렬, 회전 행렬, 이동 행렬을 합성하여 오브젝트를 구성하고 있는 정점을 월드 좌표에 표현하기 위한 하나의 변환 행렬을 구한다면 행렬곱 연산의 횟수를 n+2번으로 줄일 수 있습니다.
축소확대 행렬 Ms, 회전 행렬 Mr, 이동 행렬 Mt이 있다고 가정하겠습니다. 그리고 어떠한 오브젝트를 구성하고 있는 정점 v1, v2, v3, v4, v5 을 가정하겠습니다. 만약 변환 행렬을 구하지 않고 각 정점에 대하여 Ms, Mr, Mt를 매번 곱한다면 다음과 같은 연산들을 수행해야 합니다.
MsMrMtv1=u1
MsMrMtv2=u2
MsMrMtv3=u3
MsMrMtv4=u4
MsMrMtv5=u5
하지만 MsMrMt를 먼저 계산하여 변환 행렬 T를 구한다면 다음과 같이 필요한 연산이 줄어들 것입니다.
MsMrMt=T
Tv1=u1
Tv2=u2
Tv3=u3
Tv4=u4
Tv5=u5
오브젝트 공간의 정점을 월드 공간으로 옮기면 정점의 좌표뿐만 아니라 노멀 또한 바뀝니다. 그렇다면 정점의 변환된 노멀은 어떻게 구할 수 있을까요?
앞서 소개드린 변환 행렬 M을 그대로 오브젝트 공간의 노멀에 곱한다고 월드 공간의 노멀로 변환되지는 않습니다. 결론부터 말씀드리면 (M−1)T를 곱해야 하는데 이에 대한 증명을 살펴보겠습니다.
3개의 벡터 p, q, r로 이루어진 평면과 이 평면의 노멀 n이 있다고 가정하겠습니다. 여기서 노멀 n은 p, q가 이루는 벡터와 수직입니다. 즉, 두 벡터의 내적 결과가 0입니다. 따라서 다음과 같이 쓸 수 있습니다.
nT(p−q)=0
그리고 변환행렬 M에 의해 변환된 p, q를 p′, q′라고할 때 다음이 성립합니다.
p′=Mp
q′=Mq
그리고 양변에 M−1를 곱하면 다음 식을 유도할 수 있습니다.
M−1p′=p
M−1q′=q
유도된 위 식을 처음 식에 대입하면 다음과 같습니다.
nT(M−1p′−M−1q′)=0
M−1으로 묶으면 다음과 같습니다.
nTM−1(p′−q′)=0
따라서 기존의 노멀에 M−1을 곱하면 월드 공간의 노멀을 구할 수 있음을 알 수 있습니다.