스키닝(skinning)-1

스키닝이란?
스키닝(skinning)이란 피부를 붙이는 작업이라고 말할 수 있다.
3차원 메쉬는 관절과 관절 사이가 사람과 달리 끊김 현상이 발생할 수 있는데 , 이를 막는 기법을 스키닝이라고 한다.
마치 사람의 뼈 위에 피부가 있어서 관절부위가 보이지 않는 것처럼 말이다. 과거에는 고급 기법이었으나, 요즘에는 스키닝이 되지 않는 경우가 더 어색해 보일정도로 일반화 되었다. 





V(스킨 world) = V(스킨 local) * M0(뼈대 애니) * W0(가중치)

                      +  V(스킨 local) * M1(뼈대 애니) * W1(가중치) ....

 

이따구 식이 책에 나와있었다. 찢어버릴까보다.

책을 봐도 이해가 안갔다 뼈대 애니를 그대로 곱한다니... 스킨의 로컬 정점에 다가...

결국 알아낸 진짜 계산식...

 

V(최종 world) = V(스킨 world) * M0(월드 상에서 뼈가 움직인 만큼의 애니) * W0(가중치) ....

 

그럼 저 M0는 어떻게 구하느냐...

 

일단 뼈의 움직임을 월드 상의 움직임으로 바꾸어야 한다.

뼈 AniTm을 그대로 적용하면 뼈가 A만큼 움직였다고 해서 스킨도 A만큼 움직이지지 않는다.

왜냐? 

뼈 AniTm은 뼈의 로컬 정점이 월드에 적용되는 AniTm 값이기 때문에 이를 그대로 스킨의 로컬 정점에 적용하면 각 메시들의 변환 행렬의 차이로 다른 움직임을 보인다.그렇기 때문에 월드 상에서 뼈가 움직인 AniTm만큼 월드 상에 스킨 정점을 이동하는 방법을 찾아야 한다.

 

월드 상에서 시작 기준이 될 행렬 OffsetTm을 구한다

OffsetTm = 뼈의 초기 월드 행렬(움직임이 없는 고정된 상태에서 계산된 뼈 월드 행렬)의 역행렬

 

월드 상에서 뼈의 움직임 값을 구한다

(월드 상의 뼈 움직임) = OffsetTm * Bone AniTm

 

이를 월드 상의 정점에 적용

V(최종 world) = V(스킨 world) * (월드 상의 뼈 움직임)

 

스킨 로컬 상에서 뼈의 로컬 상의 움직임만큼 스킨 정점을 이동 후 월드화 해주는 방법도 있다.

아마 책에서 말했던 위의 식에서 말하는 뼈대 애니란 로컬 상에서의 뼈의 움직임을 말하는 것일 듯...

그럼 그렇게 적어놔야지 뼈대 애니 행렬이라고만 적으면 어떻하냐~


출저:My Memo :: 네이버 블로그




스키닝 정리


 스키닝공식을 살펴보면

V_world = V_local * M[INDEX0] * W_0 + V_local * M[INDEX1] * W_1 + .... V_local * M[INDEXn] * W_n

이렇게 되어있다.

이게 무슨 개소리인가라고 싶은 사람이 있을 것이다.

식을 쫘악 풀어보면 머리속에 가득찬 스모그가 사라질것이다.

 

V_world 

V_local(메시의 로컬좌표) * M_world(메시의 월드행렬) 

* M_world의 역행렬(본의 월드의 역행렬) * M_Animation(본의 애니메이션 월드행렬) * W_0( 0번째 가중치값 )


을 구할 수 있다.

이건 0번째에 해당하는 스키닝공식을 적용한 것이다.

 

V_local * M_world(메시의 월드행렬)을 통해 우선 메시의 월드공간으로 정점을 옮긴다.

그리고나서, M_world의 역행렬(본의 월드의 역행렬)을 통해 본의 좌표공간으로 옮길 수 있다.

왜 이렇게 옮겨야 되냐면 메시는 자신의 로컬좌표계기준을 가지고 있고 본 또한 자신의 로컬좌표계기준을 가지고 있기 때문이다.

로컬 좌표계는 각 자 하나씩 가지고 있는 좌표계가 아니던가.

이렇게 본의 로컬좌표계기준으로 옮겼기때문에 본의 애니메이션 월드행렬을 곱해주면 애니메이션 행렬연산을 적용받을 수 있게 된것이다.

그리고나서  W_0(0번째 가중치)만큼 곱해주면 우리는 0번째 스키닝행렬을 구한 것이다.

이런식으로 가중치 수가 4개라면 4개를 구한다음 더해주면 되는것이다.

 

이해하기가 힘들다면 로컬 좌표계는 노드마다 무조건 하나씩 가지고있는 공간으로서

어떤 V_world의 월드공간의 정점을 a라는 노드가 자신의 로컬좌표공간에서 참고하고 싶다면,

V_local = V_world * (a라는 노드의 월드공간의 역행렬)

으로 이해하면 되겠다.

(아하!!!!!!!!!!!!!!!!!!!!!!!!!!!)

 

그래도 모르겠다면 해골책의 소프트웨어 스키닝을 보면서 한번 따라가보길 바란다.

이래서 소프트웨어가 좋다구나.

  

<<tip!!!>>

잠깐! 방금 생각이 났는데 혹시 스티칭공부중인 사람이라면 왜 스티칭을 할때에는 M_world의 역행렬(본의 월드의 역행렬)을 안해주지라는 의문을 가진 사람이 있을수도 있다.

그건 최적화의 개념으로 보면 된다.


뭐냐하면...

V_world = V_local * M_World(메시의 월드행렬) * M_world의 역행렬(본의 월드의 역행렬) *  M_Animation(본의 애니메이션 월드행렬) 가된다.


풀어보면 이렇다.

스키닝의경우 하나의 정점에 영향을 주는 본이 여러개인데 반해서  

즉, V_local * M_World(메시의 월드행렬) * M_world의 역행렬(본의 월드의 역행렬) 이 식을 미리 계산해서 가져놓은 상태에서 바로 애니메이션 행렬을 곱할 수가 없다.

물론 어떻게든 할수 있겠지만 그만큼 메모리도 늘어날지도 모르겠다.

하지만 스티칭의 경우는 영향을 주는 본이 하나로 제한되어있기때문에 미리 정점을

 V_local * M_World(메시의 월드행렬) * M_world의 역행렬(본의 월드의 역행렬)을 한 상태로 저장해놓고

애니메이션행렬을 계산해주면 될것이다.

SMD를 공부할 때 정점을 이런식으로 해준다면 성능에 많은 도움을 줄 것이므로 참고하시라.


출저:




스키닝 이해가 안되서,
해골책 분석하고 블로그 2개 정도 참고하니 이해할수있었다.ㅠㅠㅠ
이글을 보고도 잘 이해가 안되는사람은 3D그래픽스 로컬좌표계 - 월드좌표계를 다시 한번 이해해서 보자!!
핵심은 이것이다!!.
TM(변환행렬)을 로컬좌표계에 적용하면 로컬->월드가 되지만
TM의 역행렬을 월드좌표계에 적용하면 월드->(어떤오브젝트의)로컬좌표계 가 된다.

Do you understand? OK?

애니메이션이란 참 힘든거구먼~

이 글을 공유하기

댓글

Designed by JB FACTORY