Skinning by 김윤정

첨 해보는 하드웨어 스키닝이라.. 개념정리가 좀 필요하네..

- Requirements  에서 BonesPerPartition   = 20  으로 최대 Bone 개수를 제한한다. 현재 기본은 20개의 bone 처리

- Stream은 역시 Vertex shader와 순서를 맞춰주자.
 PDP_BlendWeights 1 PDT_Float4 // 본의 웨이트값 
 PDP_BlendIndices 2 PDT_UByteColorw //256. 본의 인덱싱 넘버.

를 추가해 주자.

-vertex shader에서 skinning을 사용하기 위해 nsf에다가,
Define 되어 있는 Bone의 Matrix를 정의해주자
CM_Defined      SkinBoneMatrix3     g_Bones     0    20

이렇게 설정이 끝났다면, 이번엔 hlsl로 넘어오자.

hlsl 에서 선언해줄 부분은 SKINBONEMATRIX3 이다.
float4x3 g_Bones[MAX_BONES]  : SKINBONEMATRIX3; 
으로 선언해준다. MAX_BONES은 상수로, 일단 20일 집어 넣는다.

vertex shader의 입력에서
 float4 vBlendWeights : BLENDWEIGHT;
 float4 vBlendIndices : BLENDINDICES;
두 개를 집어 넣는 것을 잊지 말자. 이전에 stream과 순서가 맞아야 한다는 것도 중요하다.
출력은... 별거 없다.
계산은 전부 vertex shader에서만 이루어지니까.


우선
int4 indices = D3DCOLORtoUBYTE4(In.vBlendIndices);// same as In.BlendIndices.bgra * 255.5;
로 indices를 만든다. 이것은 아까 받아온 bone의 index이다.

그다음 4개의 본을 각각 계산하기 시작하자.
첫 번째로는 weight값을 계산한다.
weight값은 다 합쳐서 1이 되어야 하기 때문에, 만약의 실수에 대비하는 것이 좋다.

  float weight4 = 1.0f - In.vBlendWeights[0] - In.vBlendWeights[1] - In.vBlendWeights[2];
들어온 3개의 weight값을 모두 1에서 빼주면, 남는 값이 weight4 라는 것이다. 굳이 4를 계산할 것 없이, 남은 것을 자동으로 입력해주어서 오차가 있더라도 대응할 수 있도록 해 준다.

그다음 float4로 재정렬 시킨다. 방금 구한 공식을 이용하여 4개로 연결하면 float4에 들어갈 것이기 때문이다.
 float4 weights = float4( In.vBlendWeights[0], In.vBlendWeights[1], In.vBlendWeights[2], weight4);

이렇게 weight 값을 구했으면, 이번엔 계산을 하자.
float4x3 mBoneTransform; 라는 행렬을 하나 가상으로 만들어 놓고,

각 본의 indices와 weight값을 곱한 것을 차례로 더하여 행렬을 만든다. 이 부분에 대해서는 설명을 좀 들어야 할듯.
mBoneTransform  = weights[0] * g_Bones[indices[0]];
    mBoneTransform += weights[1] * g_Bones[indices[1]];
    mBoneTransform += weights[2] * g_Bones[indices[2]];
    mBoneTransform += weights[3] * g_Bones[indices[3]];

이렇게 제작된 mBoneTransform 좌표계를
position 과 곱해주면 bone position이 나온다는 원리.
float3 vBoneSpacePos = mul(float4(In.vPosition, 1.0f), mBoneTransform);

normal도 당연히 이 좌표계에 곱해주면 끝난다.
꽤나 간단하지만 잘 안된다.

... 궁리중...


덧글

  • 블루밍 2010/02/16 19:27 #

    아....봐도 모르겠습니다. ㅠㅠ 뭔소리인지 =ㅁ=;;
  • 김윤정 2010/02/16 19:31 #

    저도 그림쟁이가 뭐하는건지 모르겠습니다 ㅠㅠ 그림좀 그려야 할텐데요
  • 원심무형류 2010/02/16 22:49 #

    저 20개의 기본값이 맥스에서 20개이긴 한데 4개 이상 사용 안하지 않나요 ㅎㅎ 일상적으로 보던 개념들을 문자열로 풀어서 보니 흥미롭네요 ^^
  • 김윤정 2010/02/16 22:52 #

    저 20개는 한 번에 처리하는 본의 갯수고 (어디서 20개밖에 지원 안했다고 들었는데 잊었음)
    4개는 한 vertex에 걸리는 본의 weight 값입니다 :)
    그래서 bone이 20개가 넘으면 2pass로 처리해야 했었다죠 ^^
  • 김윤정 2010/02/16 22:52 #

    말씀하신대로 그래픽하면서 그냥 외우던걸 직접 풀어서 제어해 보니 이해도 쉽고 재미있습니다 :)
  • 원심무형류 2010/02/17 13:05 #

    한번에 20개 밖에 처리 할수 없다니;; 뭘 만들어야 하는걸까요 ㅎㅎ
  • 김윤정 2010/02/17 15:41 #

    그래서 보통 2pass 이상으로 처리했었슴다.
  • 김윤정 2010/02/17 17:09 #

    이건 DX9의 제한이 30개라서 그렇다는군요. 메뉴얼에 나와 있네요
  • 김윤정 2010/02/17 11:42 #

    빼먹은것이 있었다 OTL 과연.
    마지막에 view projection 곱해주는걸 잊다니.
  • 앤써니 2010/02/19 00:30 #

    전 어떻게 공부해야 이해를 할까요-ㅅ-;;
  • 김윤정 2010/02/19 08:59 #

    ... 이거 하실라구요?
    그래픽만 하시려면 굳이 이해 안하셔도 무리 없습니당
※ 로그인 사용자만 덧글을 남길 수 있습니다.


MyADD

<script> (adsbygoogle = window.adsbygoogle || []).push({}); </script>