Jak uzyskać tłumaczenie z matrycy widoków


11

Jak mogę pobrać pozycję kamery w przestrzeni świata z jej matrycy widoku? Jedyne odpowiedzi, jakie widziałem na to pytanie, sugerują, że tłumaczenie znajduje się w ostatnim wierszu / kolumnie, ale to nie zadziała, ponieważ macierz zawiera [x (kropka) w prawo, y (kropka) w górę, z (kropka) wygląda]

Odpowiedzi:


10

Krótka odpowiedź

Najpierw odwróć macierz widoku. Następnie pobierz tłumaczenie z ostatniego wiersza / kolumny.

Długa odpowiedź

Jednym ze sposobów na wydedukowanie zawartości macierzy widoku jest rozpoczęcie od rozważenia kamery jako dowolnego innego obiektu na świecie i obliczenia dla niej macierzy świata:

RightX  RightY  RightZ  0
UpX     UpY     UpZ     0
LookX   LookY   LookZ   0
PosX    PosY    PosZ    1

Macierz światowa przekształca współrzędne z przestrzeni lokalnej na przestrzeń świata. Ale w tym przypadku lokalna przestrzeń kamery i przestrzeń widzenia są takie same, więc możemy również powiedzieć, że ta macierz przekształca współrzędne z przestrzeni widzenia na przestrzeń świata.

Ponieważ potrzebujemy konwersji w przeciwnym kierunku, musimy odwrócić macierz. Rezultatem jest to, co nazywamy macierzą widoku, która przekształca współrzędne z przestrzeni świata na przestrzeń widzenia:

   RightX        UpX        LookX      0
   RightY        UpY        LookY      0
   RightZ        UpZ        LookZ      0
-(Pos*Right)  -(Pos*Up)  -(Pos*Look)  1      // * = dot product

I taki macie macie macie. Aby więc odzyskać pozycję kamery, najpierw musisz ją odwrócić, a następnie możesz pobrać tłumaczenie z ostatniego wiersza (lub kolumny, w zależności od systemu).


1
Po co najpierw odwracać matrycę? Jeśli (miejmy nadzieję) wiesz, czy jesteś w wierszu głównym lub głównym, lokalizacja wektora translacji powinna być oczywista.
3Dave

7

Po pierwsze, wysoce poleciłbym po prostu osobne przechowywanie pozycji jako wektora, to znacznie ułatwi obliczenia. W każdym razie ...

[x (dot) right, y (dot) up, z (dot) look]nie jest rzeczywistą matrycą widoku. Sama matryca ma postać:

1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1

gdzie górna lewa matryca 3x3 reprezentuje obroty, skalę itp. Tam odbywa się cała orientacja kamery. Pozostały wiersz i kolumna są używane do tłumaczenia i innych skomplikowanych rzeczy z perspektywy, do których nie zamierzam teraz wchodzić.

Po otrzymaniu macierzy (zakładając, że jest to macierz 4x4), tłumaczenie zawsze będzie przechowywane w ostatnim wierszu lub ostatniej kolumnie, w zależności od tego, czy klasa macierzy jest uporządkowana według rzędów, czy kolumn.

To, co prawdopodobnie wprawia Cię w zakłopotanie, to fakt, że potrzebujesz produktów kropkowych. To, co się dzieje, to uproszczenie matematyki macierzy. Odpowiedzi na to pytanie dotyczące przepełnienia stosu zawierają bardziej szczegółowe odpowiedzi: /programming/349050/calculating-a-lookat-matrix

Rozwiązanie można znaleźć tutaj , musisz wziąć odwrotność macierzy i uzyskać tłumaczenie tego:

Vector3 ViewTrans = Matrix.Invert(ViewMatrix).Translation;
Position = ViewTrans;

5

Inne odpowiedzi tutaj wyjaśniają, jak uzyskać odwrotną pozycję kamery z matrycy kamery.

Jeśli część matrycy kamery 3x3 ma tylko obrót (bez skalowania lub ścinania), jak zwykle, obliczenia można zoptymalizować, mnożąc translację matrycy kamery z transpozycją obrotu kamery. Pozycja kamery jest następnie transformowanym wektorem translacji pomnożonym przez -1. W GLSL jest to:

vec3 cameraPosition = -transpose(mat3(worldToCameraMatrix)) * worldToCameraMatrix[3].xyz;

lub

vec3 cameraPosition = -worldToCameraMatrix[3].xyz * mat3(worldToCameraMatrix);

Tego właśnie używałem w moich shaderach wierzchołków, jeśli nie chcę obliczać i przekazywać pozycji kamery jako munduru.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.