Autor Wątek: Animacja Postaci (skinning)  (Przeczytany 2776 razy)

Offline Piot

  • Użytkownik

# Kwiecień 05, 2008, 14:44:24
Mam pytanie Jak powinna wyglądać struktura wirzcholka dla animacji postaci metoda (skinningu) jeśli chce
wszystko robic w verte shader. W tej chwili mam cos takiego:

struct Vertex {
   D3DXVECTOR4 vWeight_1;  // vektor opisujacy pozycje dla pierwszej wagi (vWeight_1.w = waga danej kosci)
   D3DXVECTOR4 vWeight_2;
   D3DXVECTOR4 vWeight_3;
   D3DXVECTOR4 vWeight_4;

   D3DXVECTOR4 vIndexBone; //indexy kosci wplywajacych na ten wierzcholek(max = 4);
   .....
};


W stalych shadera ustawiam caly szkielet i z danych wag obliczam odpowiednie pozycje wierzcholkow.
Wszysko dziala tak jak powinno. Animacja odgrywana jest poprawnie.

Ptyanie: Czy da sie zapisac to inaczej (rozmiar wirzcholka jest dosc dozy)?

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline gwhrkk

  • Użytkownik

# Kwiecień 06, 2008, 12:34:39
Jeden wektor 4D wystarczy do zapisu 4 wag przecież? Używam animacji przez VS i w wierzchołku mam z tego względu 4 floaty i 4 ubyte - razem 20 bajtów dodatkowych danych. Da się przeżyć.

Offline Piot

  • Użytkownik

# Kwiecień 06, 2008, 12:48:55
W takim razie jak obliczasz finalny vertex?

Ten wektor 4D zawiera pozycje pomocnicza (xyz) oraz wage (w).
kazda z tych pozycji mnoze przez odpowiednie przeksztalcenie danej kosci oraz wage
a suma tych wszystkich przeksztalcen daje finalny vertex.


Mam vertex opisany w ten sposób  :  pozycja w przestrzeni swiata (x,y,z) orza wagi (w1,w2,w3,w4) index kosci (i1,i2,i3,i4)
Mam kosc opisana w ten sposób : rotacja (x,y,z) przesuniecie (x,y,z)

teraz zeby wszystko dzialalo musze przeksztalcic pozycje vertexa z przestrzeni swiata do przestrzeni kosci stad :

poz1 = vertex.xyz * bone[vertex.i1];
poz2 = vertex.xyz * bone[vertex.i2];
poz3 = vertex.xyz * bone[vertex.i3];
poz4 = vertex.xyz * bone[vertex.i4];

stad mam te cztery pozycje ktore opisuja vertex w przestrzeni kosci.

a jak wy to robicie?

 
 
« Ostatnia zmiana: Kwiecień 06, 2008, 13:36:21 wysłana przez Piot »

Offline Zielony

  • Użytkownik
    • Ghurund Engine

# Kwiecień 06, 2008, 16:16:51
to co opisałeś przypomina raczej tweening, Ty liczysz średnią ważoną z czterech wierzchołków, a powinieneś zsumować przekształcenia jednego wierzchołka, czyli:

float3  p    :POSITION;
float3  n    :NORMAL;
float2  t    :TEXCOORD0;
float4  bw  :BLENDWEIGHT;
float4  bi   :BLENDINDICES;

i do tego tablica macierzy wspólna dla wszystkich wierzchołków

Offline Piot

  • Użytkownik

# Kwiecień 06, 2008, 16:42:31
Ale wtedy to chyba zwiekszy sie ilosc macierzy?

Offline gwhrkk

  • Użytkownik

# Kwiecień 06, 2008, 23:28:25
BLENDINDICES to chyba int4.

macierz jest jedna dla każdej kości szkieletu. taki wycinek z shadera z naszego silnika:

 
  float4 base_position = input.position;
  float3 base_normal = input.normal;
  int   bone_indices[4] = (int[4])input.bone_indices;
  float bone_weights[4] = (float[4])input.bone_weights;
  input.position = 0.0f;
  for (int i = 0; i < 4; ++i)
  {
    input.position += mul(base_position, g_bone_matrices[bone_indices[i]]) * bone_weights[i];
    input.normal += mul(base_normal, g_bone_matrices[bone_indices[i]]) * bone_weights[i];
  }

Offline Zielony

  • Użytkownik
    • Ghurund Engine

# Kwiecień 07, 2008, 02:13:26
BLENDINDICES to chyba int4.

to sie gdzieś w trakcie konwertuje i na pewno miałem tego powód  :P, nvm

Offline Piot

  • Użytkownik

# Kwiecień 07, 2008, 02:24:58


Cytuj
Mam vertex opisany w ten sposób  :  pozycja w przestrzeni swiata (x,y,z) orza wagi (w1,w2,w3,w4) index kosci (i1,i2,i3,i4)
Mam kosc opisana w ten sposób : rotacja (x,y,z) przesuniecie (x,y,z)

To majac tak opisany model jak mam przgotowac vertexy by móc zapisać w shaderku (chodzi o przeksztalcenie)

Cytuj
  float4 base_position = input.position;
  float3 base_normal = input.normal;
  int   bone_indices[4] = (int[4])input.bone_indices;
  float bone_weights[4] = (float[4])input.bone_weights;
  input.position = 0.0f;
  for (int i = 0; i < 4; ++i)
  {
    input.position += mul(base_position, g_bone_matrices[bone_indices[i]]) * bone_weights[i];
    input.normal += mul(base_normal, g_bone_matrices[bone_indices[i]]) * bone_weights[i];
  }