Artoke

리깅: FK 심화 — 본 계층을 따라가는 행렬 곱의 사슬

리깅: FK 심화 — 본 계층을 따라가는 행렬 곱의 사슬 대표 이미지
출처: FK 심화 — 본 계층을 따라가는 행렬 곱의 사슬

로봇 팔의 관절값을 알고 있을 때 손끝이 공간 어디에 있는지 계산하는 일, 그것이 순기구학(forward kinematics, FK)이다. 캐릭터 리깅으로 옮기면 어깨·팔꿈치·손목의 회전값이 주어졌을 때 손이 월드 공간 어디에 놓이는지를 구하는 계산이 된다. 표현은 우아하지 않다. 그냥 행렬을 순서대로 곱하는 것뿐이다. 다만 그 "순서대로"라는 말 안에 리깅의 거의 모든 골칫거리가 숨어 있다.

본 하나가 들고 있는 것은 위치가 아니라 변환이다

본(bone)을 "위치와 회전을 가진 점"으로 상상하기 쉽지만, 계산의 관점에서 본이 실제로 들고 있는 것은 부모 좌표계에서 자기 좌표계로 가는 변환 하나다. 이 변환을 로컬 변환이라 부르고 보통 로 쓴다. 4×4 동차좌표 행렬로 적으면 이렇게 생겼다.

여기서 는 3×3 회전 행렬로, 이 본이 부모에 대해 얼마나 돌아가 있는지를 담는다. 는 3차원 열벡터로, 부모의 원점에서 이 본의 원점까지의 이동(오프셋)이다. 맨 아랫줄 은 계산을 위한 채움이다. 3차원 점 로 한 칸 늘려 놓으면, 회전과 이동을 한 번의 행렬 곱으로 처리할 수 있다. 이 한 칸이 없으면 이동은 곱셈이 아니라 덧셈이 되어 사슬로 엮을 수가 없다. 동차좌표가 존재하는 이유가 사실상 이것이다.

를 어느 방향으로 읽어야 하는지가 헷갈리는 지점인데, 규약은 이렇다. 본 의 로컬 좌표계에서 표현된 점 에 대해 부모 좌표계에서 본 같은 점이다. 즉 는 자식 공간 → 부모 공간 변환이다. 이름은 "본의 변환"인데 하는 일은 "자식에서 부모로 올려보내기"라는 점을 붙잡아 두면 뒤가 편하다.

사슬: 곱셈 순서가 곧 골격 구조다

이제 어깨(0) → 팔꿈치(1) → 손목(2) → 손끝(3)으로 이어지는 사슬을 생각하자. 손끝의 로컬 좌표계에 찍힌 점 를 월드 공간으로 데려가려면 어떻게 해야 하나. 한 계단씩 올라가면 된다.

손끝 공간의 를 곱하면 손목 공간의 점이 되고, 거기에 를 곱하면 팔꿈치 공간이 되고, 을 곱하면 어깨 공간, 마지막으로 를 곱하면 월드 공간이다. 이어 붙이면:

그래서 본 월드 변환(global transform) 는 루트부터 자기 자신까지의 로컬 변환을 순서대로 곱한 것이다.

실전에서는 이걸 곱셈 사슬로 매번 새로 계산하지 않고, 부모의 결과를 재활용하는 재귀식으로 쓴다.

이 한 줄이 FK 구현의 전부다. 계층을 루트에서부터 깊이 우선으로 훑으면서 부모의 에 자기 을 오른쪽에서 곱해 나간다. 본이 개면 곱셈도 번, 선형 시간이다. 순기구학이 항상 싸고 항상 답이 하나인 이유가 여기 있다. 역기구학(IK)이 비싸고 답이 여러 개인 것과 정확히 대비된다.

도식으로 보는 곱셈의 흐름

리깅: FK 심화 — 본 계층을 따라가는 행렬 곱의 사슬 도식

도식의 마지막 두 줄이 계층 애니메이션의 직관 전부다. 상속은 아래로만 흐른다. 수식에서 를 바꾸면 가 바뀌지만, 를 바꿔도 에는 아무 영향이 없다. 이건 취향이 아니라 곱셈 사슬의 구조가 강제하는 결과다.

행렬 곱은 교환법칙이 없다 — 그래서 짐벌락이 있다

실수하기 가장 좋은 지점이 여기다. 일반적으로

이다. 곱하는 순서를 바꾸면 다른 변환이 된다. 사슬을 로 뒤집어 쓰면 팔이 엉뚱한 곳으로 날아간다. 어떤 엔진은 행벡터 규약(점을 처럼 왼쪽에 두는 방식)을 쓰기 때문에 곱셈 순서가 문서마다 뒤집혀 보이는데, 그건 다른 수학이 아니라 같은 식의 전치(transpose)일 뿐이다. 이므로 열벡터 규약의 는 행벡터 규약에서 로 적힌다. 두 규약을 섞어 쓰지만 않으면 된다.

비가환성은 본 하나 안에서도 문제를 만든다. 오일러 각으로 회전을 줄 때, 로컬 회전 은 축별 회전의 곱이다.

는 각각 X, Y, Z축 둘레의 회전각이다. 이 곱의 순서가 바로 리깅 툴의 "회전 순서(rotation order)" 설정이다. XYZ, ZYX, YZX… 전부 다른 행렬을 낳는다. 그리고 여기서 짐벌락이 나온다. 예컨대 에서 가 되면 X축 회전과 Z축 회전이 같은 축을 공유하게 되어, 세 개였던 자유도가 둘로 무너진다. 수식으로 보면 에만 의존하는 형태로 축약된다. 두 다이얼을 돌려도 한 축만 움직이는 상태. 어깨나 목처럼 큰 각도로 도는 본에서 회전 순서를 신경 써야 하는 이유이고, 쿼터니언을 꺼내게 되는 이유이기도 하다.

바인드 포즈와 스키닝 행렬

본의 월드 변환 를 구했다고 해서 곧바로 메시를 움직일 수 있는 건 아니다. 메시의 정점은 본의 로컬 좌표계가 아니라 바인드 포즈(T-포즈 등 스킨을 붙인 시점의 자세) 기준 월드 좌표에 놓여 있기 때문이다. 그 시점의 본 월드 변환을 라 하자. 정점 를 본 의 로컬 공간으로 되돌리려면 를 곱해야 한다. 되돌린 뒤 현재 자세의 로 다시 내보낸다.

를 흔히 역바인드 행렬(inverse bind matrix)이라 부르고, 바인드 포즈가 바뀌지 않는 한 상수이므로 미리 계산해 캐싱한다. 실무에서 를 통째로 "스키닝 행렬"이라 부르며, 이게 GPU로 넘어가는 팔레트의 정체다.

정점 하나가 여러 본에 걸쳐 있으면 가중치 를 얹어 선형 결합한다. 선형 블렌드 스키닝(LBS)이다.

는 정점 번호, 는 그 정점에 영향을 주는 본, 는 본 가 정점 를 끌고 가는 정도다. 가중치 합이 1이어야 한다는 조건은 정점이 본들 사이 어딘가에 "머물러" 있게 해준다. 다만 여기서 중요한 함정이 있다. 행렬을 먼저 섞고 그 다음에 점을 곱하는 이 방식은 회전을 섞을 때 회전이 아닌 행렬을 만든다. 두 회전 행렬의 중간값은 일반적으로 회전 행렬이 아니라 살짝 찌그러진 변환이다. 팔꿈치를 크게 굽혔을 때 부피가 빨려 들어가는 "캔디 랩(candy wrapper)" 현상이 바로 이 대수적 사실의 결과다. 듀얼 쿼터니언 스키닝은 섞는 대상을 행렬이 아닌 다른 대수 구조로 바꿔 이 문제를 완화한다.

PUMA 로봇 팔이 부품을 집기 위해 뻗은 모습
The forward kinematics equations define the trajectory of the end-effector of a PUMA robot reaching for parts. · 출처: FK 심화 — 본 계층을 따라가는 행렬 곱의 사슬

로봇 쪽의 표기법: DH 파라미터

로봇 공학에서는 각 관절의 로컬 변환을 자유롭게 두지 않고, 네 개의 숫자로 규격화한다. Denavit–Hartenberg(DH) 규약이다.

는 관절 회전각, 는 관절 축 방향 오프셋, 는 링크 길이, 는 링크 비틀림각이다. 은 회전, 는 이동. 회전 관절이면 만 변수이고 나머지 셋은 하드웨어가 정한 상수다. 그래서 6축 팔의 자세는 여섯 개 숫자로 완전히 결정되고, 엔드 이펙터의 자세는 그냥

가 된다. 캐릭터 리깅에서는 이 규격화를 하지 않고 임의의 를 허용하는데, 아티스트가 오프셋과 스케일을 자유롭게 만지도록 하기 위해서다. 대신 그 대가로 "본에 스케일이 들어갔더니 자식이 기울어졌다" 같은 사고가 가능해진다. 비균등 스케일 가 회전과 섞이면 이므로, 부모의 스케일이 자식 회전축을 비틀어 버린다. 마야의 segment scale compensate 같은 옵션은 이 곱셈에서 부모 스케일 성분을 로 미리 상쇄해 주는 장치다.

야코비안: FK를 미분하면 IK가 보인다

FK는 관절각 벡터 를 받아 엔드 이펙터 위치 를 뱉는 함수다.

이 함수를 각 관절각으로 편미분해 모아 놓은 행렬이 야코비안 다.

는 "관절 를 아주 조금 돌렸을 때 손끝의 번째 좌표가 얼마나 움직이는가"를 뜻한다. 그러면 미소 변화끼리는 선형 관계가 된다.

IK는 이 식을 거꾸로 푸는 일이다. 원하는 손끝 이동 가 주어졌을 때 로 관절 변화를 추정하고 (는 유사역행렬), 그 결과를 다시 FK에 넣어 실제 위치를 확인하고, 오차가 줄 때까지 반복한다. 즉 IK 안에는 FK가 매 반복마다 들어 있다. 관절 수 이 목표 자유도(보통 3 또는 6)보다 크면 는 가로로 긴 행렬이 되고 해가 무수히 많아진다. 팔꿈치가 어디를 향할지 폴 벡터로 따로 지정해야 하는 이유가 이 여분 자유도다.

결국 FK 쪽은 방향이 하나뿐이라 항상 답이 나오고, IK 쪽은 방향이 여럿이라 선택과 반복이 필요하다. 두 세계를 잇는 게 야코비안이고, 야코비안의 원재료는 우리가 앞에서 세운 곱셈 사슬 다.

정리하면

FK는 한 줄이다. 부모의 월드 행렬에 자기 로컬 행렬을 오른쪽에서 곱한다. 그런데 그 한 줄에서 파생되는 것들이 리깅의 실무 대부분을 차지한다. 곱셈에 교환법칙이 없어서 회전 순서와 짐벌락이 생기고, 스케일이 회전과 교환되지 않아서 스케일 보정이 필요하고, 바인드 포즈를 되돌려야 해서 역바인드 행렬이 있고, 행렬을 선형 보간해서 캔디 랩이 나오고, 이 사슬을 미분해서 IK가 나온다. 리그가 이상하게 움직일 때, 대개 답은 "곱셈 어디에서 순서가 틀렸나"라는 질문 안에 있다.

함께 읽기 — 이 글이 쓰는 기초 수학

출처

광고

리깅 파이프라인 자동화 도구

반복 작업은 스크립트에게. 현업에서 쓰는 리깅 툴 모음.

리깅 도구 보기