[OpenGL ES를 이용한 3차원 컴퓨터 그래픽스 입문] 13. 캐릭터 애니메이션
캐릭터 골격의 뼈 공간과 부모 변환부터 애니메이션 포즈를 만드는 정기구학, 피부를 부드럽게 하는 스키닝, 역기구학까지 정리했습니다.
개요
그래픽스에서 애니메이션을 적용할 가장 중요한 대상은 캐릭터이다. 이 중 특히 사람 캐릭터가 중요하다. 사실적이고 자연스러운 캐릭터 움직임을 만들어내는 것은 컴퓨터 애니메이션의 영원한 과제이다. 이를 위해 수많은 기술이 개발되었는데, 이 장은 실시간 캐릭터 애니메이션의 기초적인 기법을 소개한다.
13.1 캐릭터 골격과 공간 이전
실시간 캐릭터 애니메이션을 위해서는 대체로 캐릭터의 골격(skeleton)을 이용한다. 캐릭터의 골격은 다수의 뼈(bone)로 구성된 관절체 (articulated body)이다.
13.1.1. 골격
1장에서 설명한 것처럼 그래픽 디자이너는 3차원 모델링 패키지를 사용하여 캐릭터를 제작하는데, 그림 13.1.a와 같은 폴리곤 메시가 제작되었다고 하자. 이와 같은 캐릭터의 기본 자세를 드레스 포즈(dress pose)라 한다.
대부분의 3차원 모델링 패키지는 사람 캐릭터에 적합한 기본적인 골격을 제공한다. 그림 13.1.b는 3ds Max에서 제공하는 바이페드(biped)라는 기본 골격이다. 이는 편집 가능하다. 그림 13.1.c의 골격은 바이페드의 척추 뼈 네 개를 합치는 등의 편집 과정을 거쳐 만들어졌다.
이러한 골격은 그림 13.1.d처럼 폴리곤 메시로 옮겨진 후, 캐릭터의 드레스 포즈에 수작업으로 맞춰진다. 그림 13.1.e에서는 드레스 포즈에 맞도록 골격의 왼팔을 들어 올렸다. 그림 13.1.f는 모든 뼈에 대해 이런 작업을 수행한 결과를 보여 준다.
그림 13.1에서는 뼈를 마치 부피를 가진 물체처럼 그렸는데, 이는 골격을 드레스 포즈에 맞추는 과정에서만 쓰인다. 일단 골격이 드레스 포즈에 맞춰지면, 각 뼈마다 하나의 변환 행렬이 자동으로 계산된다. 나중에 골격의 애니메이션을 표현하는 데 이 행렬들을 이용한다. 이 절의 나머지는 드레스 포즈에서 계산된 행렬에 대해 다룬다.
13.1.2. 뼈와 공간 이전
골격을 구성하는 뼈들은 계층적으로 부모-자식 관계를 형성한다. 그림 13.2는 이 장에서 사용할 골격을 구성하는 뼈의 이름과 그 계층적 구조를 보여준다. 캐릭터 애니메이션에서는 관례적으로 골반을 루트 노드로 정한다.
그림 13.2. 이 장에서 사용할 캐릭터의 골격은 계층 구조를 가지는 20개의 뼈들로 이루어졌다.
뼈는 관절(joint)로 연결되어 있다. 그림 13.3은 캐릭터 골격 중에서 세 개의 뼈(위팔, 아래팔, 손)와 세 개의 관절(어깨, 팔꿈치, 손목)을 보여주는데, 쉬운 이해를 위하여 앞으로는 하단의 2차원 그림을 사용할 것이다. 이 그림에서 정점 $v_u$, $v_f$, $v_h$는 각각 위팔, 아래팔, 손에 속한다. 아래첨자 u, f, h는 각각 upper arm, forearm, hand의 첫 글자이다. 한 뼈가 움직이면 그 뼈에 속한 정점도 움직인다. 예를 들어 아래팔이 움직인다면 $v_f$도 따라 움직여야 하는데 이를 위해서는 $v_f$를 아래팔의 오브젝트 공간에 정의해야 한다. 4.5절 및 그 이후에 누차 논의한 것처럼, 한 물체는 자신의 오브젝트 공간과 결합되어 있다. 아래팔과 그 오브젝트 공간은 항상 같이 움직이므로, 오브젝트 공간에 정의된 $v_f$는 항상 아래팔과 같이 움직이게 된다.
캐릭터 메시의 모든 정점이 정의되어 있는 공간을 캐릭터 공간이라 부르자. 드레스 포즈에 골격이 맞춰지면, 캐릭터 공간의 각 정점은 자신이 속한 뼈의 오브젝트 공간으로 변환되어야 하는데, 이를 간단히 뼈 공간이라 부르자. 그림 13.3의 예에서 $v_f$는 원래 캐릭터 공간에서 정의되었지만 아래팔의 뼈 공간으로 변환되어 (2,0)의 좌표를 가지게 된다. 그런데 우리는 거꾸로 뼈 공간에서 캐릭터 공간으로의 변환을 계산할 것이다. 즉, 아래팔 공간에서 (2,0)의 좌표를 가지는 $v_f$를 캐릭터 공간으로 변환할 것인데, 이를 역을 취하면 바로 우리가 원하는 변환을 얻게 된다.
그림 13.3. 세 개의 뼈와 세 개의 관절. 오른쪽 2차원 그림의 배경으로 주어진 격자를 사용하면 $v_u$, $v_f$, $v_h$의 뼈 공간 좌표를 쉽게 이해할 수 있다.
그림 13.1.f에서와 같이 드레스 포즈에 골격이 맞춰지면, 부모와 자식 뼈 사이의 상대적인 위치와 방향이 결정된다. 한 뼈에 속한 정점을 그 부모의 뼈 공간으로 변환해 보자. 우리는 이를 부모 변환(to-parent-transform)이라 부른다. 아래팔의 부모 변환 행렬을 $M_{f,p}$로 표기하자. 여기에서 f는 forearm을 p는 parent를 의미한다. 아래팔에서 위팔로의 공간 이전(space change)을 의미하는 $M_{f,p}$는 위팔 좌표계를 아래팔 좌표계에 포개는 행렬과 같다. 이해되지 않는다면, 5.2.2절의 뷰 변환을 복습하자.
골격을 구성하는 각 뼈는 고유의 길이를 갖고 있으며, 자신의 뼈 공간의 x축을 따라 놓이는 것이 관례이다. 그림 13.3에서 위팔의 길이는 4이고, 팔꿈치는 위팔 공간에서 (4,0)에 위치한다. 따라서, $M_{f,p}$는 x축을 따라 4만큼 이동하는 행렬로 표현된다.
\[M_{f,p} = \begin{pmatrix} 1 & 0 & 4 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \tag{13.1}\]이는 아래팔 공간에서 (2,0)의 좌표를 가지는 $v_f$를 위팔 공간으로 변환한다.
\[M_{f,p} v_f = \begin{pmatrix} 1 & 0 & 4 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 2 \\ 0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 6 \\ 0 \\ 1 \\ \end{pmatrix} \tag{13.2}\]그림 13.3을 보면 위팔 공간에서 $v_f$가 (6,0)의 좌표를 가진다는 사실을 쉽게 이해할 수 있을 것이다.
이제 손의 부모 변환을 생각해 보자. 그 행렬은 다음과 같다.
\[M_{h,p} = \begin{pmatrix} 1 & 0 & 3 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \tag{13.3}\]손 공간에서 좌표가 (1,0)인 $v_h$는 위 행렬에 의해 아래팔 공간으로 변환된다.
\[v_h' = M_{h,p} v_h = \begin{pmatrix} 1 & 0 & 3 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 1 \\ 0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 4 \\ 0 \\ 1 \\ \end{pmatrix} \tag{13.4}\]한편 식 (13.4)의 $v_h’$는 식 (13.1)의 $M_{f,p}$에 의해 위팔 공간으로 변환될 수 있다.
\[M_{f,p} v_h' = \begin{pmatrix} 1 & 0 & 4 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 4 \\ 0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 8 \\ 0 \\ 1 \\ \end{pmatrix} \tag{13.5}\]식 (13.5)는 다음과 같이 고쳐쓸 수 있다.
\[M_{f,p} v_h' = M_{f,p} M_{h,p} v_h = \begin{pmatrix} 1 & 0 & 4 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 1 & 0 & 3 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 1 \\ 0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 8 \\ 0 \\ 1 \\ \end{pmatrix} \tag{13.6}\]즉 $M_{h,p}$가 $M_{f,p}$와 결합되어 손에 속하는 정점을 조부모인 위팔 공간으로 변환한 것이다.
이 사실을 일반화하면, 한 뼈의 정점이 주어졌을 때 부모 변환 행렬을 계속 결합하면 골격 계층 구조의 어떤 조상이든지 그것의 뼈 공간으로 정점을 변환할 수 있음을 알 수 있다. 물론 이 조상은 계층 구조의 루트 노드일 수 있다.
13.1.3. 캐릭터 공간에서 뼈 공간으로의 변환
그림 13.4는 골반, 척추, 쇄골, 위팔, 아래팔, 손의 부모-자식 관계에 집중해서 그림 13.2의 골격을 다시 그린 것이다. 논의를 간결하게 진행하기 위해, 골반은 1, 척추는 2와 같은 일련 번호로 부르도록 하자. 따라서 그림 13.4에서 부모 변환 행렬은 $M_{2,p}$, $M_{3,p}$, $M_{4,p}$, $M_{5,p}$, $M_{6,p}$로 표기된다. 예를 들어, $M_{3,p}$는 쇄골(3번) 공간에서 척추 공간으로 이전하는 부모 변환 행렬이다.
드레스 포즈의 골격이 주어지면, 각 뼈 공간에서 캐릭터 공간으로의 변환을 결정할 수 있다. 이 행렬을 $M_{i,d}$로 표기하자. 여기에서 i는 뼈의 일련번호를, d는 드레스 포즈를 의미한다. 골반은 루트 노드이므로, 골반 공간은 캐릭터 공간과 동일하다고 간주하자. 따라서 $M_{1,d}$는 단위 행렬(I) 이다.
이제 척추 공간에서 캐릭터 공간으로 변환하는 행렬 $M_{2,d}$를 구해 보자. 이는 다음과 같이 두 개 행렬의 결합으로 정의된다.
\[M_{2,d} = M_{1,d} M_{2,p} \tag{13.7}\]즉 척추의 정점은 $M_{2,p}$에 의해 척추의 부모인 골반의 뼈 공간으로 우선 변환되고, 그 다음 $M_{1,d}$에 의해 캐릭터 공간으로 변환된다. 그림 13.5.a의 점선 화살표 두 개가 이 경로를 보여준다.
나머지 뼈에 대해서도 같은 방식을 적용할 수 있다. 쇄골의 정점은 그림 13.5.b에 보인 것처럼 세 개의 행렬을 통해 캐릭터 공간으로 변환된다.
\[M_{3,d} = M_{1,d} M_{2,p} M_{3,p} \tag{13.8}\]
그림 13.5.b. 드레스 포즈 골격에서 캐릭터 공간과 뼈 공간 사이의 변환 - 쇄골 공간에서 캐릭터 공간으로
앞의 식에서 $M_{1,d} M_{2,p}$는 식 (13.7)의 $M_{2,d}$와 동일하다. 이는 그림 13.5.b에서 쇄골의 정점이 캐릭터 공간에 도달하기 위해 밟아가는 경로가 그림 13.5.a에서 척추의 정점이 밟아가는 경로를 포함한다는 사실을 반영한다. 식 (13.8)은 다음과 같이 간략화될 수 있다.
\[M_{3,d} = M_{1,d} M_{2,p} M_{3,p} = M_{2,d} M_{3,p} \tag{13.9}\]식 (13.7)과 (13.9)는 다음과 같이 일반화된다.
\[M_{i,d} = M_{i-1,d} M_{i,p} \tag{13.10}\]그림 13.5.c의 수평 화살표들은 이러한 변환을 모두 보여준다.
지금까지 우리는 뼈 공간에서 캐릭터 공간으로의 변환 $M_{i,d}$를 정의했다. 그러나 관절체 애니메이션에서 필요한 것은 그 역변환인 $M_{i,d}^{-1}$이다.
\[M_{i,d}^{-1} = M_{i,p}^{-1} M_{i-1,d}^{-1} \tag{13.11}\]그림 13.5.d의 수평 화살표들은 이러한 변환을 모두 보여준다.
요약해 보자. 드레스 포즈 골격이 주어지면, 각 뼈의 부모 변환 행렬 $M_{i,p}$가 즉시 결정된다. 이는 $M_{i,p}^{-1}$이 즉시 결정된다는 뜻이기도 하다. 따라서, 식 (13.11)의 $M_{i,d}^{-1}$ 계산을 위해서는 $M_{i-1,d}^{-1}$만 있으면 된다. 그런데 $M_{i-1,d}^{-1}$을 위해서는 $M_{i-2,d}^{-1}$이 필요할 것이다. 이런 식으로 골격 계층을 거슬러 올라가 보면 우리에게 궁극적으로 필요한 것은 루트 노드인 골반의 $M_{1,d}^{-1}$임을 알 수 있다. 다행히 $M_{1,d}^{-1}$은 단위 행렬이다. 따라서, $M_{1,d}^{-1}$부터 시작해서 골격 계층 구조를 따라 ‘위에서 아래로 내려가면서’ 모든 뼈의 $M_{i,d}^{-1}$을 구할 수 있다.
13.2 정기구학
앞 절에서 소개한 $M_{i,d}^{-1}$은 드레스 포즈 골격의 캐릭터 공간 정점을 i번째 뼈 공간으로 변환한다. 예를 들어 그림 13.6.a의 $v_5$는 원래 캐릭터 공간에 정의되었지만, $M_{5,d}^{-1}$에 의해 변환되어 아래팔 공간에서 (2,0)의 좌표를 가지게 되었다.
그림 13.6. 정기구학. (a) 드레스 포즈. (b) 애니메이션 포즈.
이제 관절체 애니메이션을 생각해 보자. 각 정점은 자신이 속한 뼈에 의해 움직이는데, 그림 13.6.b는 아래팔이 회전함에 따라 v5도 회전한 것을 보여준다. 그런데, 이렇게 애니메이션이 완료된 정점을 렌더링에 사용하기 위해서는 이를 다시 캐릭터 공간으로 변환해야 한다. 이렇게 해야 애니메이션 포즈의 캐릭터 전체가 GPU 파이프라인을 따라 월드 변환, 뷰 변환 등을 거쳐서 최종적으로 스크린에 렌더링될 것이다. 그림 13.6에서 우리는 “(1) v5에 애니메이션을 적용하고, (2) 그 결과를 캐릭터 공간으로 옮기는 변환”이 필요하다. 이를 $M_{5,a}$라 표기하자. 여기서 a는 애니메이션을 의미한다.
그림 13.6.b에서 아래팔은 90도 회전했다. 이는 아래팔의 뼈 공간의 원점인 팔꿈치를 중심으로 한 회전이다. 이러한 지역적인 특성을 반영하여 지역 변환이라 부르자. 아래팔의 지역 변환은 $M_{5,l}$로 표기할 것이다. 여기에서 5는 아래팔의 고유 번호이고, l은 local을 의미한다. 2차원 동차 좌표계에서의 회전 행렬은 다음과 같다.
\[\begin{pmatrix} cos \theta & -sin \theta & 0 \\ sin \theta & cos \theta & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \tag{13.12}\]따라서 90도 회전을 표현하는 $M_{5,l}$은 다음과 같다.
\[M_{5,l} = \begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \tag{13.13}\]이는 v5에 적용된다.
\[v_5' = M_{5,l} v_5 = \begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 2 \\ 0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 0 \\ 2 \\ 1 \\ \end{pmatrix} \tag{13.14}\]그림 13.6.b에서 v5와 v5’를 비교해 보자. 아래팔과 그 뼈 공간은 하나로 묶여 있으므로, 아래팔이 회전해도 v5는 아래팔 공간에서 (2,0)이라는 좌표를 그대로 유지한다. 반면 v5’는 ‘회전되기 전의’ 아래팔 공간을 기준으로 하는 좌표이다. 그런데 ‘회전되기 전의’ 아래팔과 위팔의 관계는 식 (13.1)의 $M_{5,p} (M_{f,p})$에 의해 정의되었다. 따라서, v5’는 $M_{5,p}$에 의해 위팔 공간으로 변환된다.
\[v_5'' = M_{5,p} v_5' = \begin{pmatrix} 1 & 0 & 4 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 0 \\ 2 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 4 \\ 2 \\ 1 \\ \end{pmatrix} \tag{13.15}\]그림 13.6.b의 점선 격자를 보면 위팔 공간에서 $v_5’‘$가 (4,2)의 좌표를 가지고 있음을 쉽게 확인할 수 있을 것이다. 식 (13.14)와 (13.15)는 아래와 같이 결합된다.
\[v_5'' = M_{5,p} M_{5,l} v_5 = \begin{pmatrix} 1 & 0 & 4 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} \begin{pmatrix} 2 \\ 0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 4 \\ 2 \\ 1 \\ \end{pmatrix} \tag{13.16}\]관절체 애니메이션에서 모든 뼈는 회전 가능하다. 즉, 아래팔뿐 아니라 위팔도 회전할 수 있다. “(1) 위팔에 속한 정점에 애니메이션을 적용하고, (2) 그 결과를 캐릭터 공간으로 옮기는 변환”을 $M_{4,a}$라 표기하자. 그러면 $M_{4,a}$와 식 (13.16)의 $M_{5,p} M_{5,l}$을 결합해서 $M_{5,a}$를 정의할 수 있다.
\[M_{5,a} = M_{4,a} M_{5,p} M_{5,l} \tag{13.17}\]즉 $M_{5,p} M_{5,l}$에 의해 아래팔 공간에서 위팔 공간으로 옮겨진 다음, $M_{4,a}$에 의해 캐릭터 공간으로 변환되는 것이다. 골격의 계층 구조를 생각해보면, 식 (13.17)은 다음과 같이 일반화될 수 있다.
\[M_{i,a} = M_{i-1,a} M_{i,p} M_{i,l} \tag{13.18}\]애니메이터가 캐릭터의 애니메이션 포즈를 만들면, 각 뼈의 $M_{i,l}$은 확정된다. 20개의 뼈를 가진 캐릭터라면, 20개의 $M_{i,l}$이 정해지는데, 식 (13.13)의 $M_{5,l}$이 하나의 예가 된다. 한편, 그림 13.4에 보인 것처럼, 드레스 포즈로부터 $M_{i,p}$도 확정된다. 따라서 식 (13.18)의 $M_{i,a}$ 계산을 위해서는 $M_{i-1,a}$만 있으면 된다. 그런데 $M_{i-1,a}$ 계산을 위해서는 $M_{i-2,a}$가 필요하다. 이런 식으로 골격 계층을 거슬러 올라가 보면 우리에게 궁극적으로 필요한 것은 루트 노드인 골반의 $M_{1,a}$임을 알 수 있다.
그림 13.7. 애니메이션 포즈에서 각 뼈 공간에서 캐릭터 공간으로의 변환
$M_{1,a}$는 “(1) 골반에 속한 정점에 애니메이션을 적용하고, (2) 그 결과를 캐릭터 공간으로 옮기는 변환”으로 정의된다. (1)항의 골반 애니메이션은 뭘까? 월드 공간에서 캐릭터의 위치와 방향을 정하기 위해 월드 변환이 필요할 텐데, 이 월드 변환은 골격의 루트 노드인 골반을 기준으로 정한다. 즉, 골반의 애니메이션은 나중에 캐릭터의 월드 변환으로 대체될 수 있으므로 지금은 불필요하다. (2)항의 변환도 불필요하다. 골반 공간은 캐릭터 공간과 같기 때문이다. 따라서, $M_{1,a}$는 단위 행렬이다. 이제 우리는 애니메이션 포즈에서 모든 뼈와 $M_{i,a}$를 계산할 수 있다. 그림 13.7을 보라. 단위 행렬인 $M_{1,a}$부터 시작해 골격 계층 구조를 따라 ‘위에서 아래로 내려가면서’ 각 뼈마다 식 (13.18)을 사용해 $M_{i,a}$를 계산하면 된다.
그림 13.8. v와 v’는 모두 캐릭터 공간에서 정의되었는데, 매 프레임 v’이 갱신된다.
전체를 요약해 보자. 드레스 포즈 골격이 결정되면, 그림 13.5.d에 보인 바와 같이, 골격 계층 구조를 따라 ‘위에서 아래로 내려가면서’ 각 뼈마다 $M_{i,d}^{-1}$을 계산한다. 이는 단 한 번 계산된다. 한편, 애니메이션 포즈가 결정되면, 그림 13.7에 보인 것처럼, 골격 계층 구조를 따라 역시 ‘위에서 아래로 내려가면서’ 각 뼈마다 $M_{i,a}$를 계산한다. 이는 모든 애니메이션 포즈에서, 즉 애니메이션의 각 프레임마다 반복된다. 드레스 포즈에서 정점의 캐릭터 공간 좌표를 v로 표기하자. 이는 우선 $M_{i,d}^{-1}$에 의해 해당 뼈 공간으로 변환된다. 그 이후 $M_{i,a}$에 의해 애니메이션 되고 캐릭터 공간으로 변환된다. 이 정점을 v’라 표기하자.
\[v' = M_{i,a} M_{i,d}^{-1} v \tag{13.19}\]이렇게 얻어진 v’들을 모아 렌더링하면 애니메이션 포즈의 캐릭터를 얻게 된다. 그림 13.8을 보자.
기구학(kinematics)은 질량이나 힘을 고려하지 않고 물체의 움직임을 기술하는 학문 분야이다. 모든 뼈의 변환을 계산하여 관절체 전체의 모습을 결정하는 것을 정기구학(forward kinematics 혹은 direct kinematics)이라고 부른다. 이 절에서 다룬 내용이 바로 정기구학이다. 우리는 13.4절에서 역기구학(inverse kinematics)에 대해 공부할 것인데, 이는 관절체의 말단 노드의 위치와 방향이 주어졌을 때 이를 위하여 관절체의 뼈에 어떠한 변환을 적용해야 하는 지 결정한다.
13.3 스키닝
캐릭터의 폴리곤 메시를 피부(skin)라고도 부르는데, 이 절은 골격 움직임에 따라 어떻게 피부를 부드럽게 변형하는지 다룬다.
13.3.1 정점 블렌딩
그림 13.9 a와 b. 스키닝 애니메이션. (a) 피부 위의 정점. (b) 블렌딩을 수행하지 않은 경우.
그림 13.9 c와 d. 스키닝 애니메이션. (c) 블렌딩 가중치. (d) 블렌딩을 수행한 경우.
이제까지 우리는 한 정점은 오직 하나의 뼈에 속한다고 가정했다. 그림 13.9.a는 팔꿈치에 연결된 위팔과 아래팔을 보여주는데, 팔꿈치 주위의 세 정점 a, b, c를 보자. 이 중 a는 위팔에 속하고 b와 c는 아래팔에 속한다고 가정하자. 그림 13.9.b는 이런 가정 하에 두 팔이 회전했을 때의 결과를 보여준다. 변형된 피부는 부드럽지 않다.
한 정점은 오직 하나의 뼈에 속한다는 제약 때문에 이러한 문제가 발생한 것인데, 여러 개의 뼈가 한 정점에 영향을 주도록 하고 그 결과를 블렌딩하면 이 문제는 상당히 완화될 수 있다. 이를 위해서는 각 뼈가 한 정점에 얼마나 영향을 주는지 미리 정해줘야 하는데, 이를 블렌딩 가중치 혹은 간단히 가중치라 부른다. 그림 13.9.c에서, a에 대해 위팔은 70%, 아래팔은 30%의 가중치를 가진다. a가 아래팔보다는 위팔에 더 가까이 있으므로 위팔에 더 많은 영향을 받게 설정하는 것은 타당하다. b와 c의 가중치도 비슷한 원칙에 따라 정해질 수 있다.
그림 13.9.a의 드레스 포즈에서, 정점 a는 캐릭터 공간에서 정의되었다. 이것이 위팔 공간으로 변환되어, 위팔의 움직임에 따라 애니메이션된 후, 다시 캐릭터 공간으로 변환된 것이 그림 13.9.d에 보인 $a_u’$이다. 그런데, 이제 a는 아래팔의 영향도 받는다. a가 아래팔 공간으로 변환되어, 아래팔의 움직임에 따라 애니메이션된 후, 다시 캐릭터 공간으로 변환된 것이 그림 13.9.d의 $a_f’$이다. $a_u’$와 $a_f’$에 각각 0.7과 0.3의 가중치를 곱해 더한 것이 a’이다. 즉, 0.7과 0.3의 가중치를 이용해 $a_u’$와 $a_f’$를 선형보간한 것이다. b’와 c’도 그림 13.9.c의 가중치를 사용해서 같은 방법으로 구해진다. 이제 a’, b’, c’를 연결하면 그림 13.9.b보다 훨씬 부드러운 피부를 얻게 된다. 이러한 기법을 스키닝(skinning) 혹은 정점 블렌딩(vertex blending)이라 부른다.
그림 13.10에서 v는 드레스 포즈의 캐릭터 공간에서 정의된 정점이다. 이것이 $M_{5,d}^{-1}$에 의해 아래팔 공간으로 변환된 것을 $v_5$로 표기하였다.
\[v_5 = M_{5,d}^{-1} v \tag{13.20}\]이제 아래팔뿐 아니라 손도 v에 영향을 준다고 가정하자. 그러면 v는 $M_{6,d}^{-1}$에 의해 손 공간으로도 변환되는데, 이를 $v_6$로 표기하자.
\[v_6 = M_{6,d}^{-1} v \tag{13.21}\]이제 아래팔이 90도 회전하고 손이 -90도, 즉 시계방향으로 90도 회전하여 그림 13.10.b와 같은 애니메이션 포즈를 얻었다고 가정하자. 그러면 $v_5$와 $v_6$는 각각 $M_{5,a}$와 $M_{6,a}$에 의해 애니메이션되고 캐릭터 공간으로 변환된 후, 미리 정의된 가중치 $w_5$와 $w_6$를 사용해 블렌딩된다.
그림 13.10. 정점 블렌딩. (a) 하나의 정점은 두 개의 뼈 공간에서 서로 다른 좌표($v_5$와 $v_6$)를 가진다. (b) 애니메이션 포즈에서 $v_5$와 $v_6$는 각기 다른 캐릭터 공간 좌표를 가지게 되는데, 이를 블렌딩하여 최종 위치를 결정한다.
식 (13.20)과 (13.21)을 식 (13.22)에 삽입한 결과는 다음과 같다.
\[v' = w_5 M_{5,a} M_{5,d}^{-1} v + w_6 M_{6,a} M_{6,d}^{-1} v \tag{13.23}\]일반적으로, 한 정점에 영향을 주는 뼈들과 그 가중치는 애니메이션 과정 전체에 걸쳐 일정하게 유지되는데, m개의 뼈가 한 정점에 영향을 준다고 가정하자 (게임과 같은 실시간 그래픽스에서는 대체로 m은 4로 고정된다. 물론 m개의 뼈의 가중치 합은 1이다). 그러면 식 (13.23)은 다음과 같이 일반화된다.
\[v' = \sum_{i=1}^{m} w_i M_{i,a} M_{i,d}^{-1} v \tag{13.24}\]$M_{i,a} M_{i,d}^{-1}$을 간단히 $M_i$로 표기하자.
\[v' = \sum_{i=1}^{m} w_i M_i v \tag{13.25}\]
그림 13.11. 스키닝 알고리즘의 입력 및 작동 원리. 팔레트 인덱스와 가중치는 정점별로 고정되어 있다. 스키닝 알고리즘은 드레스 포즈의 v를 애니메이션 포즈의 v’로 변환한다.
그림 13.11은 식 13.25가 어떻게 구현되는지 보여준다. 야구 선수 캐릭터의 골격은 20개의 뼈를 가진다. 따라서 애니메이션 과정의 매 프레임마다 20개의 $M_i$를 갱신해야 한다. 이는 행렬 팔레트(matrix palette)라 불리는 테이블에 저장된다. 드레스 포즈의 한 정점 v를 보자. 그림 13.11에서 v에 영향을 미치는 뼈의 인덱스는 0, 2, 7, 18이다. 따라서, v는 행렬-정점 곱셈을 의미하는 mul 함수를 이용하여 M0, M2, M7, M18 네 개의 행렬에 의해 변환되고, 그 결과는 각각 0.2, 0.3, 0.4, 0.1의 가중치를 이용해 결합된다. 그 결과가 바로 v’이다.
일반적으로 스키닝 알고리즘은 정점 쉐이더로 구현된다. 정점 쉐이더에게 행렬 팔레트는 유니폼으로 제공된다. 반면, 팔레트 인덱스와 블렌딩 가중치는 정점 위치, 노멀, 텍스처 좌표 등과 함께 정점에 저장된다. 그림 13.11에서 (0, 2, 7, 18)과 (0.2, 0.3, 0.4, 0.1)이 정점 배열 내 v의 칸에 저장되는 것이다. 이들은 모두 정점 쉐이더에게 애트리뷰트로 제공된다.
13.4 역기구학
로봇 팔의 끝에 부착되어 물체를 잡고 다루는 등의 용도로 쓰이는 기구를 말단 장치(end effector)라 한다. 정기구학(forward kinematics)은 로봇 팔의 관절 각도를 입력으로 받아 말단 장치의 위치 및 방향을 결정한다. 이러한 작업의 역순을 역기구학(inverse kinematics; 이하 IK로 약칭)이라 한다. 즉, 목표로 하는 말단 장치의 위치 및 방향이 입력으로 주어지면, 그 목표를 달성하기 위해 필요한 각 관절의 각도를 계산한다.
로봇 분야에서 개발된 IK는 캐릭터 애니메이션에도 유용하게 사용된다. 예를 들어 울퉁불퉁한 지형을 걷는 캐릭터의 발이 지형 표면에 정확히 놓일 수 있도록 다리의 관절 각도를 결정하는데 IK가 쓰인다. 이렇게 실시간으로 IK를 풀어서 캐릭터의 관절 운동을 결정하게 되면, 미리 예측할 수 없는 환경 혹은 동적으로 변화하는 환경에서도 자연스러운 캐릭터 애니메이션을 구현할 수 있다.
로봇 분야에서는 미분 방정식을 풀어서 IK 해를 구한다. 이는 대체로 복잡한 계산 과정을 거치고 연산 시간이 많이 든다는 단점이 있다. 실시간 응용 분야에서는 이를 대신하는 간단한 알고리즘이 널리 사용되는데, 이 절은 그 중 두 가지 기법을 소개한다.
13.4.1 해석적 기법
그림 13.13 관절과 자유도. (a) 1자유도의 팔꿈치. (b) 3자유도의 어깨.
물체의 상태를 정의하는 독립적인 변수의 개수를 자유도(degrees of freedom; DOF)라 부른다. 그림 13.13.a의 로봇 팔꿈치는 기구학적으로 경첩(hinge)과 같아서, 아래팔을 위아래로 움직이는 자유도만 가지고 있으므로, 1자유도 관절이라 한다. 반면, 그림 13.13.b의 어깨는 기구학적으로 볼 조인트(ball joint)와 같은데, 위팔이 특정한 방향을 가리키려면 좌우로 한 번 움직이고 위아래로 한 번 움직이면 된다. 여기까지는 자유도가 2이다. 그런데, 위팔은 스크루 드라이버처럼 회전될 수 있다. 결국 자유도는 하나 증가하여 3이 된다. 즉, 어깨가 3자유도 관절이다.
IK를 위해 해석적 기법(analytic)을 사용할 수 있는데, 그림 13.14.a와 같이 두 개의 관절을 가진 로봇 팔을 예로 들어보자. 문제를 단순화하기 위해 말단 장치의 방향은 무시하고 위치만 고려하자. 그림 13.14.a에서는 아래팔의 끝점 T가 G로 표기된 목표 위치에 닿을 수 있도록 위팔과 아래팔이 회전되어야 한다. IK는 이렇게 위팔과 아래팔을 회전시키는데 필요한 어깨와 팔꿈치의 관절각(joint angle)을 계산한다.
1자유도 관절인 팔꿈치의 관절각은 간단히 계산된다. 그림 13.14.b에 2차원으로 그려진 로봇 팔을 보자. 위팔과 아래팔의 길이는 각각 $l_u$와 $l_f$로 표기하였다. T가 G에 닿았을 때의 팔꿈치 관절각을 $\theta$로 표기하고, 위치가 고정되어 있는 어깨와 목표 지점 G 사이의 거리를 $l_g$로 표기하자. 여기에 코사인 법칙을 적용한 결과는 다음과 같다.
\[l_g^2 = l_u^2 + l_f^2 - 2 l_u l_f \cos \theta \tag{13.26}\]
그림 13.14.a. IK를 풀기 위한 해석적 기법. (a) 목표 위치 G와 초기 자세를 입력으로 받아 최종 자세가 출력된다.
그림 13.14.b와 c. (b) 1자유도 팔꿈치의 관절각 세타를 계산한다. (c) 3자유도 어깨에서는 회전축과 회전각 $\phi$를 계산한다.
위 식에서 세타는 다음과 같이 계산된다.
\[\theta = \arccos \left( \frac{l_u^2 + l_f^2 - l_g^2}{2 l_u l_f} \right) \tag{13.27}\]이렇게 계산된 팔꿈치 관절각 세타만큼 아래팔이 회전하면 그림 13.14.c와 같은 자세를 얻는다. 이제 위팔을 회전하면 아래팔이 따라서 움직여서 T가 G에 닿을 것이다. 어깨와 T를 연결하는 단위 벡터를 v1, 어깨와 G를 연결하는 단위 벡터를 v2라 하자. 만약 v1이 $\phi$만큼 회전해서 v2가 된다면 T는 G에 닿을 것이다. 회전각 $\phi$는 v1과 v2의 내적을 통해 계산된다. (v1 $\cdot$ v2 = ||v1|| ||v2|| cos $\phi$임을 기억하자). 3자유도를 가진 어깨의 경우 회전각 하나로는 충분하지 않다. 회전축이 필요하다. 이는 v1과 v2에 모두 수직이어야 하므로 이들의 벡터곱을 통해 결정된다. 이렇게 구해진 회전축을 중심으로 위팔이 $\phi$만큼 회전하면 T는 G에 닿게 된다.
13.4.2 CCD 알고리즘
간단한 관절체의 경우 해석적 기법을 사용하면 빠르고 정확하게 IK를 해결할 수 있다. 하지만 많은 관절을 가진 복잡한 관절체에는 이것을 사용하기 어렵다. 대안으로 종종 CCD(cyclic coordinate descent) 알고리즘이 채택된다. 이 기법은 말단 장치로부터 시작해 계층 구조를 거슬러 올라가면서, 말단 장치와 목표 지점 간 거리가 최소화되도록 관절각을 조정한다. 모든 관절각 조정을 마쳤는데도 말단 장치와 목표 지점 간 거리가 임계값 이상 벌어지면, 말단 장치로부터 시작해 관절각을 조정하는 작업을 반복한다.
그림 13.15.a는 위팔, 아래팔, 손으로 이루어진 골격을 이용해 CCD 작동 원리를 설명한다. 최종 목표는 T와 G를 같게 하는 것이다. CCD는 말단 장치인 손부터 움직이는데, T가 G를 가리키도록 회전시킨다. 손의 뼈 공간 원점 $O_h$를 생각해보자. $\overrightarrow{O_h T}$는 $O_h$와 손끝 T를 연결하는 벡터이다. $\overrightarrow{O_h G}$는 $O_h$와 G를 연결하는 벡터이다. $\overrightarrow{O_h T}$는 $\overrightarrow{O_h G}$ 와 겹쳐지기 위해서 세타만큼 회전할 것이다. 또한 회전축도 필요하다. 회전각과 회전축은 앞 절에서 기술한 것처럼 $\overrightarrow{O_h T}$와 $\overrightarrow{O_h G}$를 사용해 각각 내적과 벡터곱으로 구할 수 있다.
그림 13.15. CCD 알고리즘. (a) 초기 자세. (b) 손이 회전되었고, 다음은 아래팔이 회전할 차례이다. (c) 아래팔이 회전되었고, 다음은 위팔이 회전할 차례이다. (d) 위팔이 회전되었다. T와 G간 거리가 충분히 가깝지 않으면, 다시 손부터 시작하는 회전을 반복할 것이다.
그림 13.15.b는 손이 회전한 결과를 보여준다. 아직 T와 G가 일치하지 않는다. 따라서 손의 부모인 아래팔이 회전할 차례이다. $\overrightarrow{O_f T}$가 $\overrightarrow{O_f G}$가 겹쳐지도록 회전해야 하는데, 회전각과 회전축은 앞서 설명한 방법으로 계산된다. 그림 13.15.c는 아래팔이 회전된 결과를 보여준다. 아직 T와 G는 일치하지 않는다. 따라서, 이제 위팔이 회전할 차례인데, 회전각과 회전축은 앞서 설명한 방법으로 계산된다. 그림 13.15.d는 그 결과를 보여준다. T와 G간 거리를 계산해서 그 거리가 충분히 가까우면 CCD 알고리즘은 종료되지만, 아니라면 그림 13.15.d에 보인 것처럼 말단 장치인 손에서 시작해 동일한 작업을 반복한다. 이러한 반복은 T와 G간 거리가 미리 정한 임계값 이하가 되거나 혹은 미리 설정한 최대 반복 횟수에 도달했을 때 중단된다.
그림 13.16. 날아가는 공을 응시하고 공을 향해 손을 뻗는데 IK가 사용되었다.
게임에서는 자연스러운 캐릭터 애니메이션을 위해 IK를 자주 사용한다. 예를 들어, 축구 게임의 경우 선수의 발이 날아오는 공을 향하도록 만드는 데 IK를 사용한다. 그림 13.16에서는 날아가는 공을 향해 군인의 팔을 뻗는데 IK가 사용되었다. 이 말고도 IK의 사용 범위는 넓다. 캐릭터가 이리저리 움직이는 물체를 응시하도록 할 때에는 IK가 캐릭터의 머리 뼈에 적용된다. 그림 13.16에서는 팔뿐 아니라 머리에도 IK가 적용되었고, 이에 따라 군인이 날아가는 공을 응시하게 된 것이다. 슈팅게임에서 군인이 적에게 총을 겨누도록 하는 데도 역시 IK가 사용된다.
참고



