3D 애니메이션 기초

3D 애니메이션 기초정리편.

 

애니메이션의 계층구조에 대하여.

노드의 월드행렬 = 노드의 지역행렬(Local Matrix) * 부모의 월드행렬( Parent World Matrix)

로 구할 수 있다.

 

애니메이션이 없는 static mesh일 경우에는 익스포팅할 때 미리 노드의 월드행렬을 계산하여 그대로 구성해주는 게 좋다.

하지만 애니메이션이 존재할 경우에는 크기변환, 회전변환, 이동변환을 가지고 지역 행렬을 구성해야 한다.

, S*R*T원칙( OpenGL에서는 그 반대인 T * R * S )에 따라!!!!!!!!!!!!!!

노드의 월드행렬 = 노드의 지역행렬(S*R*T) * 부모의 월드행렬( Parent World Matrix )

로 구성해준다.

 

그리고 노드의 지역행렬을 구하고자 한다면 행렬의 수학적인 원리에 따라,

노드의 월드행렬 * 부모의 월드행렬의 역행렬 = 노드의 지역행렬

을 구할 수 있다.


증명하자면!!!

노드의 월드행렬 * 부모의 월드행렬의 역행렬 =  노드의 지역행렬 * 부모의 월드행렬 * 부모의 역행렬 

노드의 월드행렬 * 부모의 월드행렬의 역행렬 = 노드의 지역행렬 * I

최종적으로

위와 같은 식인

노드의 지역행렬 = 노드의 월드행렬 * 부모의 월드행렬의 역행렬

을 구할 수 있는 것이다.

 

애니메이션의 종류

애니메이션은 크게 나누면 두 가지 방식으로 나누어질 수 있다.


1번째는 버텍스 애니메이션으로서 정점간의 선형보간을 통해 부드럽게 움직이는 것을 말한다.

이 방식은 속도가 빠르고 다양한 표현이 가능하나, 프로그래밍상에서 조작할 수 없으며, 애니메이터에게도 2번째 방식에 비해 일을 과중시킬 수 있다.


2번째는 본 애니메이션으로서 본을 움직임에 따라 메시가 따라 붙여서 움직이는 방식이다.

위 방식에 비해 계산도 복잡하고 속도도 느리다.

하지만 대부분 게임에서 사용되어지는 방식으로서 프로그래밍상에서 실시간으로 조작이 가능하며, 애니메이터는 잘 만든 본을 다른 캐릭터에도 공유할 수 있으므로 일적인 면에서도 효율적이다.

본애니메이션은 스티칭과 스키닝이라든 두 방식으로 구현방식이 나누어진다.

스티칭은 정점 하나에 무조건 본이 하나가 영향을 미치는 것으로 대표적인 포맷은 SMD가 있으며, 스키닝에 비해 계산이 단순하다는 게 장점이지만 너무 본을 구부릴 경우 메시가 파인게 보이는게 미관상 좋지 못하다.

그리고, 요즘같이 하드웨어가 발전한 시대에는 맞지 않다.

그래서 이러한 방식을 보완한 게 스키닝인데, 스키닝은 정점하나 당 여러 개의 본이 영향을 미치는 것으로 그만큼 계산면에서 복잡해지고 부하가 크다.

하지만 스티칭의 단점을 완전히 보완해주며, 현재 가장 많이 쓰인다.

또한 속도상의 문제도 세이더를 통한 GPU쪽에 스키닝 계산을 맡기면 줄어들기 때문에 사용할만한다.

 

피직과 스킨의 의미.

3D MAX를 보면 바이패드 혹은 본을 통해 계층구조를 구성하고 애니메이션을 시킨다.

그리고 우리는 피직과 스킨이라는 용어를 듣게 된다.

과연 피직과 스킨은 무엇이라는 말인가?

간단히 말하자면 피직과 스킨은 3D 맥스에서 그래픽 작업자가 하는 바이패드 혹은 본에 연결하는 리깅(Rigging)작업을 말한다.

즉 리깅 작업을 하는 방법의 차이라는 것이지. 이 두개의 작업 모두 목적은 정점에 영향을 주는 본을 설정하는 일이라는 것이다.

맥스에서 정점 대해서 하나의 본만 영향을 받게 처리한다면 강체 애니메이션을 위한 것이고, 정점에 대해서 여러 개의 본이 영향을 받게 처리한다면 스키닝 애니메이션을 위한 처리를 하는 것이다.

그리고 맥스 익스포팅할때는 피직과 스킨을 구별해주어 뽑아주어야 한다.

이 점을 유의해야 한다.

 

애니메이션 행렬을 구해보자! 강체애니메이션편

애니메이션에 대한 지역행렬은 위의 계층 구조편에서 본 것와 같은 공식을 사용하면 된다.

,

애니메이션의 지역행렬 = 노드의 애니메이션 월드 행렬 * 부모의 애니메이션 월드행렬의 역행렬이다.

간단하지 아니한가?

그렇다면 애니메이션의 월드 행렬을 구할려면 어떻게 해야 할 것인가?

역시 위에서 본 바와 같이 구하면 된다.


(양쪽에 부모의 애니메이션의 월드행렬을 곱해주면)

애니메이션의 지역행렬 * 부모의 애니메이션의 월드행렬 

노드의 애니메이션의 월드행렬 * 부모의 애니메이션의 월드행렬의 역행렬 * 부모의 애니메이션의 월드행렬


애니메이션의 지역행렬 * 부모의 애니메이션의 월드행렬 = 노드의 애니메이션의 월드행렬 * I

즉 정리하자면,

노드의 애니메이션의 월드행렬  =  애니메이션의 지역행렬 * 부모의 애니메이션의 월드행렬

이다.

 

애니메이션 행렬을 구해보자! 스키닝애니메이션편

피직,스킨에 대한 애니메이션 행렬을 방법은 강체 애니메이션과 차이가 있는데,

D3D기준으로 한다면,

애니메이션의 월드행렬 = Pivot행렬의 역행렬 * 시간에 대한 노드의 월드행렬

이다.

스키닝애니메이션은 하나의 정점P에 영향을 주는 행렬을 M1, 비중을 W1이라 한다면 변환후의 정점 위치 [P]는 다음과 같이 구할 수 있다.

[P] = (P * M1) * W1

이런식으로 여러 개라면,

[P] = ( (P*M1)*W1 ) + ( (P*M2)*W2 ) + ( (P*M3)*W3 ) …. + ( (P*Mn)*Wn )

으로 표현할 수 있다.

더 간단히 표현하면

[P] = P ( ( M1 * W1 ) + ( M2 * W2 ) + (M3 * W3 ) …… + (Mn * Wn)

여기서 유의해야 할 점은 w들의 모든 합한 값은 1.0이 되어야 한다.

모자라거나, 넘친다면 어떤 결과값이 나올지 예상하기 힘들다.

 

보간에 대해서

애니메이션 프레임 사이에는 보간을 해주어 좀 더 부드러운 모션을 줄 수 있다.

애니메이션을 할 때에는 두 가지의 보간 방식이 사용된다.

첫번째는 선형보간으로서 위치와 크기를 보간할 때 사용한다.

두번째는 구면선형보간으로서 회전을 보간할 때 사용한다.

왜 회전의 경우만 구면선형보간을 하는 것일까?

우선 회전을 왜 사원수를 이용하는지부터 알아보자.

회전의 경우는 pitch, yaw, roll과 같은 오일러회전을 사용할 경우 그 유명한 짐벌락현상(좌표축을

잃어버리는 현상)을 겪을 수 있다. 그렇기 때문에 이러한 짐벌락현상을 막기위해 사원수를 사용하

게 된것이다.

그렇다면 간단한것이다.

선형보간으로는 사원수를 보간할 수 없기 때문에 사원수를 위한 구면선형보간을 사용하는 것이다.

선형보간은 직선 보간에 유리하고 구면선형보간은 곡선 보간에 유리하기 때문에 회전 같은 경우

는 곡선이 많으므로 당연히 구면선형보간을 또 사용할 수 밖에 없다.

 

출저:01. 3D 애니메이션 기초 - 신들린프로그래머님의 노트

이 글을 공유하기

댓글

Designed by JB FACTORY