Autor Wątek: Skinning (poprawna metoda) ?  (Przeczytany 1329 razy)

Offline komorra

  • Użytkownik
    • Blog naszego teamu (o grze Voxelfield)

# Kwiecień 11, 2016, 15:22:18
Hej, tak się zastanawiam, ponieważ w niektórych silnikach (np. UE4) skinning jest zaimplementowany w sposób taki, że każdy vertex jest transformowany z jakąś wagą przez transformacje kości uwzględniając pełną macierz (obrót, skalę i pozycję). O ile jest to poprawne dla pozycji w vertexie, to transformacja normalnych (ew. tangentów) vertexu powinna uwzględniać tylko obrót danej macierzy transformacji - czyż nie?

Niby składowe takie jak normalne, czy tangenty powinny być normalizowane po wszystkim, ale to będzie chyba różnica w finalnym shadingu między metodą:
a) mnożymy przez całą macierz i normalizujemy, a
b) mnożymy przez obrót tylko

Więc, która metoda jest lepsza i czy UE4 aby na pewno robi to poprawnie? Z góry dziękuję za odpowiedzi.

Offline Mr. Spam

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

Offline Krzysiek K.

  • Moderator
    • DevKK.net

  • +2
# Kwiecień 12, 2016, 11:33:02
Cytuj
O ile jest to poprawne dla pozycji w vertexie, to transformacja normalnych (ew. tangentów) vertexu powinna uwzględniać tylko obrót danej macierzy transformacji - czyż nie?
Tak.

Cytuj
Niby składowe takie jak normalne, czy tangenty powinny być normalizowane po wszystkim, ale to będzie chyba różnica w finalnym shadingu między metodą:
a) mnożymy przez całą macierz i normalizujemy, a
b) mnożymy przez obrót tylko
Przede wszystkim musisz zignorować przesunięcie, czyli mnożyć tylko przed podmacierz 3x3, co można osiągnąć chociażby doklejając W=0 do normalnej przed mnożeniem przez macierz 4x4 (w odróżnieniu od pozycji, gdzie W=1). Współrzędna W wektora w mnożeniu przez macierz 4x4 decyduje właśnie, czy zostanie wykonana translacja, czy nie.

Po drugie, pytanie czy masz w tej macierzy skalowanie niejednorodne (rozciąganie, itp). Jeśli tak, to żeby przekształcić normalną musisz przemnożyć ją przez transpozycję odwrotności podmacierzy 3x3. Jeśli macierz jest macierzą wyłącznie obrotu, to transpozycja odwrotności == ta sama macierz, a ewentualne skalowanie jednorodne zmieni jedynie długość, którą i tak normalizujesz, ale przy skalowaniu niejednorodnym już tak nie jest (dla zobrazowania: narysuj długą sobie elipsę i jej normalne - normalne rozciągane są w przeciwną stronę niż elipsa).

Po trzecie: styczne transformuje się przez zwykłą podmacierz 3x3 (inaczej niż normalne, czyli bez odwracania i traspozycji). Jeżeli masz styczne, to możesz całkowicie olać normalną per-vertex i zapisać wyłącznie jej znak. Transformujesz wtedy wyłącznie styczne, a normalną wyznaczasz z iloczynu wektorowego i mnożysz przez znak. Znak normalnej jest konieczny, bo będzie się on zmieniał w zależności czy tekstura na modelu jest nałożona normalnie, czy jako lustrzane odbicie (np. gdy wykorzystuje się ten sam fragment tekstury na obie strony postaci).

Podsumowując: przekształcaj styczne przez podmacierz 3x3 (np. doklejając do nich W=0 i mnożąc przez tą samą macierz co pozycję), a normalną wylicz z iloczynu wektorowego i zmień jej znak jeśli trzeba.