Z tego pytania wynika, że potrzebujesz czteroelementowego wektora pozycji, ponieważ łatwiej jest zmodyfikować jego pozycję za pomocą mnożenia macierzy.
Samo w sobie oznaczałoby to, że czwarty element powinien być po prostu zignorowany, gdy rozważa się go jako reprezentację punktu 3D (zakładając brak transformacji), ale wiem, że to nie jest prawda, jak gdy dostarczam wektor4 do GPU, jeśli czwarty element nie jest jeden, nie jest renderowany - dlaczego?
Jakie znaczenie ma czwarty element, gdy jest już w rasterizerze?
EDYCJA : Podczas przeglądu to pytanie było nieco źle sformułowane; dokładniej byłoby powiedzieć w drugim akapicie: „jeśli wartość czwartego elementu nie mieści się w określonym zakresie, nie jest renderowana„ poprawnie ”/„ zgodnie z oczekiwaniami ””.
Odpowiedzi:
Czwarty element to sztuczka pozwalająca śledzić rzut perspektywiczny. Kiedy wykonujesz rzut perspektywiczny, chcesz podzielić przez z: x '= x / z, y' = y / z, ale nie jest to operacja, którą można wykonać za pomocą macierzy 3x3 działającej na wektorze x, y, z. Sztuczka, która stała się standardem w tym zakresie, polega na dodaniu czwartej współrzędnej, w, i zadeklarowaniu, że x, y, z będzie zawsze dzielone przez w po zastosowaniu wszystkich transformacji i przed rasteryzacją.
Rzut perspektywiczny jest następnie realizowany przez macierz, która przesuwa z do w, tak że dzielimy przez z. Ale daje także elastyczność, aby pozostawić w = 1,0, jeśli nie chcesz dokonywać podziału; na przykład, jeśli chcesz tylko projekcji równoległej, obrotu lub cokolwiek innego.
Możliwość kodowania pozycji jako w = 1, kierunków jako w = 0 i użycia czwartego wiersza / kolumny macierzy do tłumaczenia jest dobrą zaletą uboczną, ale nie jest głównym powodem dodawania w. Można zastosować transformacje afiniczne (macierz 3x3 plus 3-komponentowy wektor translacji), aby uzyskać translację bez widoczności. (Trzeba będzie śledzić, jaka jest pozycja i jaki kierunek, i zastosować różne funkcje transformacji do każdej z nich; to trochę niewygodne, ale nie jest to naprawdę wielka sprawa).
(BTW, matematycznie, wektory rozszerzone o w są znane jako jednorodne współrzędne i żyją w miejscu zwanym przestrzenią rzutową . Jednak nie trzeba rozumieć wyższej matematyki, aby wykonać grafikę 3D.)
źródło
Próbując odpowiedzieć na odpowiedni komentarz Natana, zastanowiłem się, co może być przydatne, aby zrozumieć, co naprawdę dzieje się, gdy używasz wektorów w Przestrzeni Affine do reprezentowania wektorów 3D w standardowej Przestrzeni Euklidesowej.
Najpierw nazywam wektor tym, co ma współrzędne, więc punkt i wektor są tym samym bytem; wektor widzisz jako różnicę dwóch punktów: V = B - A ; V porusza A w B Ze względu A + V = A + B - A = B . Umieść A = 0 (początek), a otrzymasz V = B - 0 = B : punkt B i wektor, który porusza się 0do B są tym samym.
Nazwę „wektor” - w sensie używanym w większości bibliotek 3D - gdy wektor przestrzeni afinicznej ma w = 0.
Macierz jest używana, ponieważ pozwala przedstawić funkcję liniową w formie zwartej / eleganckiej / wydajnej, ale funkcje liniowe mają główną wadę, która nie może przekształcić początku: F ( 0 ) = 0, jeśli F chce być liniowy ( między innymi F (λ X ) = λF ( X ) i F ( A + B ) = F ( A ) + F ( B ))
Oznacza to, że nie możesz zbudować macierzy wykonującej tłumaczenie, ponieważ nigdy nie przeniesiesz wektora 0 . W grę wchodzi Affine Space . Przestrzeń afiniczna nadaje wymiar przestrzeni euklidesowej, więc przeszczepy można wykonywać za pomocą skalowania i rotacji.
Przestrzeń afiniczna jest przestrzenią rzutową w tym sensie, że można zbudować relację równoważności między wektorami afinicznymi i euklidesowymi, aby można było je pomylić (tak jak to zrobiliśmy z wierszami i wektorami). Wszystkie wektory afiniczne, które rzutują na początek w tym samym kierunku, mogą być postrzegane jako ten sam wektor euklidesowy.
Oznacza to, że wszystkie wektory o takich samych proporcjach we współrzędnych można uznać za równoważne:
Matematycznie:
tzn. każdy wektor afiniczny można zredukować do wersji kanonicznej, w której w = 1 (wybieramy spośród każdego równoważnego wektora ten, który najbardziej lubimy).
Wizualnie (euklidesowy 2D - afiniczny 3D):
stąd środek „rzutowej” przestrzeni; Należy zauważyć, że tutaj przestrzeń euklidesowa to 2D (region cyjan)
Istnieje szczególny zestaw wektorów afinicznych, których nie można łatwo umieścić w ich wersji kanonicznej, która leży na (hiper) płaszczyźnie w = 0.
Możemy to pokazać wizualnie:
(powinieneś) zobaczyć, że podczas gdy w -> 0, rzutowany wektor do przestrzeni euklidesowej przechodzi do nieskończoności, ale do nieskończoności w określonym Kierunku .
Teraz jest jasne, że dodanie dwóch wektorów w przestrzeni rzutowej może prowadzić do problemów, jeśli weźmiesz pod uwagę wektor sumy jako rzutowany wektor w przestrzeni euklidesowej, to się dodaje, ponieważ zsumujesz składniki W w przestrzeni afinicznej, a następnie rzutujesz je na płaszczyzna euklidesowa (hiper).
Dlatego można sumować tylko „punkty” do „wektorów”, ponieważ „wektor” nie zmieni współrzędnej w „punktu”, jest to prawdą tylko dla „punktów”, gdzie w = 1:
Jak widzisz, zielony punkt jest tym uzyskanym przez dodanie dwóch wektorów afinicznych, które reprezentują cyjan „punkt” i wektor „V” , ale jeśli zastosujesz V do każdego wektora afinicznego w innej formie niż kanoniczny, otrzymasz złe wyniki (czerwony „punkt”).
Widzisz, że Przestrzeń Affine nie można użyć w sposób przejrzysty do opisania operacji na przestrzeniach euklidesowych, a niewłaściwe użycie terminu „wektor” ma sens pod (ścisłym) ograniczeniem sum obliczeniowych tylko dla kanonicznych wektorów rzutowych .
Mówiąc to, całkiem rozsądnie jest myśleć, że GPU zakłada, że Vector4 musi mieć w = 0 lub w = 1, chyba że naprawdę wiesz, co robisz.
źródło
Załóżmy wektor taki jak (x, y, z, w). Ten wektor ma 4 składowe x (współrzędna x w przestrzeni), y (współrzędna y w przestrzeni), z (współrzędna z w przestrzeni) oraz interesujący i tajemniczy składnik w. W rzeczywistości większość gier 3D działa w przestrzeni 4d, zwanej także przestrzenią jednorodną 4d. Jest kilka oczywistych korzyści z tego ->
1> Pomaga nam łączyć macierze translacji i rotacji w jedną, ale możesz zastanawiać się, jaki jest pożytek, możemy po prostu pomnożyć macierz translacji i rotacji i to wszystko, ale nic więcej. Jeśli nie mamy w składniku we wszystkich naszych wektorach, a następnie, gdy pomnożymy wektor 3d (xyz) do połączonej macierzy translacji i obrotu w dowolny sposób, nieświadomie skalujemy wartości za pomocą x, y lub z (tak działa mnożenie macierzy) i to będzie prawdopodobnie uszkodził macierz pozycji (część translacji połączonej macierzy) z powodu skalowania. Aby rozwiązać ten problem, wprowadzono wektor składowy 4 i ten składnik wektora (w) będzie miał wartość 1,0 w 99% przypadków. Ten składnik 4 pozwala nam mieć nieskalowane wartości pozycji (tłumaczenie). Macierz jest reprezentowana jako->
a następnie mamy prostą, ale potężną macierz. :)
2> Kopiujemy wartość z do komponentu w na etapie projekcji perspektywicznej i dzielimy z nią x, y. W ten sposób obiekty stają się krótsze, gdy oddalają się od ekranu.
źródło