Warsztat » Forum

[Matematyka i fizyka] Własna macierz projekcji - co robię nie tak?

Apr 25, 2009 | Demon |
14 wypowiedzi na 1 stronach:
1
Demon
Apr 25, 2009

Własna macierz projekcji - co robię nie tak?

Witam, piszę program który ma software'owo renderować grafikę 3d, stanąłem na perspektywicznej projekcji i nie mam  pojęcia dlaczego to nie działa. A mianowicie tworzę macierz projekcji  w sposób opisany tutaj : http://publib.boulder.ibm.com/infocenter/pseries/v5r3/topic/com.ibm.aix.opengl/doc/openglrf/gluPerspective.htm

Rezultat tego jest taki że nieważne jaką wartość współrzędnej Z wektora ustawiam to w rezultacie ciągle dostaję te same współrzędne [X, Y] punktu po przekształceniu przez tą macierz.
orzech
Apr 25, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Witam!

Myślę, że lepiej byłoby gdybyś pokazał nam swój kod źródłowy, ponieważ tam znajduje się błąd (a nie w specyfikacji OpenGLa). ;)

Po wykonaniu transformacji przez podaną przez Ciebie macierz punkt zostaje zrzutowany na płaszczyznę rzutowania i przeniesiony do ''unormowanej przestrzeni' nazywanej NDC (normalized device coordinates). NDC ma zakres na ogół (zawsze?) rozmiar [-1; 1]x[-1; 1]x[-1; 1], zatem jak sam widzisz, nie są to jeszcze współrzędne punktu, które chciałbyś użyć do wyświetlania na ekranie.

Aby zobaczyć poprawny wynik dodatkowo musisz przemnożyć rzutowane punkty przez 'macierz okienkowania' (teraz tak sobie nazwałem :P). Macierz okienkowania ustawia środek układu współrzędnych w punkcie (0, 0), odwraca oś y i przede wszystkim skaluje układ do rozmiarów okna.

Zauważ, że możesz połączyć macierz projekcji i macierz okienkowania w jedną transformację.

Podejrzewam, że to jest przyczyna Twojego problemu, ale jak powiedziałem - pokaż swój kod, abym mógł się upewnić.

Pozdrawiam! :)

@edit : literowki
Demon
Apr 26, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Chyba już wiem o co chodzi, samo przemnożenie przez tą macierz nie daje efektu perspektywy, trzeba współrzędne [X, Y] podzielić przez magiczną współrzędną w, no tak ale skąd się bierze tą współrzędną?
orzech
Apr 23, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Cytat:

Chyba już wiem o co chodzi, samo przemnożenie przez tą macierz nie daje efektu perspektywy, trzeba współrzędne [X, Y] podzielić przez magiczną współrzędną w, no tak ale skąd się bierze tą współrzędną?

A właśnie. :D Też nie zwróciłem uwagi. W wyniku mnożenia macierzy zmienna 'w' (tak zwana współrzędna jednorodna) pojawia się pod 4 składową wektora.  Przez nią musisz podzielić każdą ze składowych x, y, z przetransformowanego wektora... Mam nadzieję, że używasz wektorów 4d (inaczej nie dałoby się pomnożyć wektora przez macierz 4x4)?

Pozdrawiam
Demon
Apr 24, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Nie używam wektorów 4d, ale i nie widzę sensu tego robić, skoro ta współrzędna jest używana tylko przy perspektywie i jest tworzona na podstawie każdego wektora, to po prostu funkcja która się zajmuje transformacja perspektywiczną będzie tą współrzędną obliczać. Nie wiem tylko czy początkowa jej wartość wynosi 1, czy 0.
Krzysiek K.
Apr 26, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Cytat:
Nie wiem tylko czy początkowa jej wartość wynosi 1, czy 0.

1 dla wektorów określających pozycję, a 0 dla wektorów określających kierunki.


Jeżeli piszesz własny renderer, to możesz "olać" macierz projekcji, a zamiast tego podzielić X i Y przez Z (po wcześniejszym rpzyciąciu przez near clipping plane) i wynik rpzeskalować tak, żeby pasował do okna i zachowany był aspect ratio. :)
orzech
Apr 26, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Cytat:

Nie używam wektorów 4d, ale i nie widzę sensu tego robić, skoro ta współrzędna jest używana tylko przy perspektywie i jest tworzona na podstawie każdego wektora, to po prostu funkcja która się zajmuje transformacja perspektywiczną będzie tą współrzędną obliczać.

Używanie wektorów 4D będzie bardzo przydatne, jeśli chcesz zachować zgodność z przekształceniami z OpenGLa. Rozszerzenie wektorów 3D na współrzędne jednorodne pozwala Ci reprezentować przy pomocy macierzy 4x4 wszelkie transformacje afiniczne (w tym translację).

Wiadomo, że nie musisz używać macierzy rzutowania, aby rzutować cokolwiek, ale jest to bardzo wygodne, bo możesz sobie parę transformacji połączyć w jedną macierz (nawet przekształcenie z przestrzeni modelu aż po sam ekran).
Krzysiek K.
Apr 27, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Cytat:
Rozszerzenie wektorów 3D na współrzędne jednorodne pozwala Ci reprezentować przy pomocy macierzy 4x4 wszelkie transformacje afiniczne (w tym translację).

Do tego wystarczą wektory 3D i macierz 3x4 (lub 4x3 w zależności od notacji). Pozostały wiersz/kolumna macierzy wynosi zawsze [ 0 0 0 1 ], za wyjątkiem przekształceń perspektywicznych, więc nie musisz tego trzymać. :)
Demon
Apr 24, 2009

Odp: Własna macierz projekcji - co robię nie tak?

A w jaki sposób odbywają się operacje matematyczne na wektorach 4d? Jeśli na przykład chcę obliczyć długość wektora to mam brać pod uwagę składową w, lub przy dodawaniu, odejmowaniu, mnożeniu, dzieleniu, operacjach dot i cross product?
orzech
Apr 25, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Generalnie to jest tak, że jeśli chcesz być 'za pan brat' ze wszystkimi macierzami w OpenGL (czy tam DX), to powinieneś stosować wektory 4D. Ma to swoją wadę, a mianowicię taką, że przekształcenia afiniczne w 3D nie wykorzystują dolnego wiersza macierzy 4x4, przez co w czasie transformacji mnożysz troszkę więcej niz trzeba. Dobrą stroną jest to, że wszystkie przekształcenia (od modelowania po projekcje) są matematycznie spójne i mogą być ze sobą łączone. Całą transformację wierzchołka z przestrzeni modelu aż po właściwy punkt na ekranie możesz wykonać przy pomocy jednego mnożenia wektora 4D przez macierz 4x4 (w praktyce rzadko się to zdarza, gdyż po przeniesieniu do układu kamery wypada poprzycinać trójkąty przynajmniej do najbliższej płaszczyzny obcinania). Z matematycznego punktu widzenia nie można mnożyć macierzy 3x4 przez macierz 3x4. ;) Ale można to obejść.

Oczywiście nie musisz używać macierzy do rzutowania w ogóle. Wtedy faktycznie wektory 4D nie będą Ci potrzebne. :)

Cytat:

A w jaki sposób odbywają się operacje matematyczne na wektorach 4d? Jeśli na przykład chcę obliczyć długość wektora to mam brać pod uwagę składową w, lub przy dodawaniu, odejmowaniu, mnożeniu, dzieleniu, operacjach dot i cross product?

Tak, powinieneś uwzględnić współrzędną w. Warto zauważyć, że kiedy współrzędna w wynosi 1.0, mówimy o punktach (punktów się nie mnoży, nie liczy iloczynu wektorowego ...), a kiedy w równa jest 0.0 mówimy o wektorach (i tutaj uwzględnienie w nic nie zmienie w stosunku do zwykłych wektorów 3D).

Pozdrawiam! :)
Demon
Apr 26, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Ok dzięki wszystkim za odpowiedzi, pliki ze źródłami operacji na wektorach i macierzach mają już 6100 linijek kodu, a i tak pewnie jeszcze o czymś zapomniałem :D
Krzysiek K.
Apr 26, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Cytat:
Tak, powinieneś uwzględnić współrzędną w. Warto zauważyć, że kiedy współrzędna w wynosi 1.0, mówimy o punktach (punktów się nie mnoży, nie liczy iloczynu wektorowego ...), a kiedy w równa jest 0.0 mówimy o wektorach (i tutaj uwzględnienie w nic nie zmienie w stosunku do zwykłych wektorów 3D).

A jak zamierzasz policzyć cross product dwóch wektorów 4-wymiarowych, skoro 4-wymiarowy cross product jest operatorem o trzech argumentach, a wektory masz tylko dwa? ;)


Rada praktyczna: zawsze i wszędzie używałem wektorów 3D i nigdy jeszcze się na tym nie przejechałem i Tobie też tak radzę. Jedyny wyjątek to przekazywanie pozycji wierzchołka do vertex shadera, ale tam to W=1 było akurat potrzebna do wygodnego mnożenia macierzy zawierającej projekcję. :)
orzech
May 1, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Cytat:

A jak zamierzasz policzyć cross product dwóch wektorów 4-wymiarowych, skoro 4-wymiarowy cross product jest operatorem o trzech argumentach, a wektory masz tylko dwa? ;)

Znaczy się w tym przypadku nie ma to sensu, ale generalnie możesz policzyć sobie iloczyn wektorowy dwóch N-wymiarowych wektorów. Iloczyn wektorowy w N wymiarowej przestrzeni wymaga N-1 argumentów. ;)

Cytat:
Rada praktyczna: zawsze i wszędzie używałem wektorów 3D i nigdy jeszcze się na tym nie przejechałem i Tobie też tak radzę.

W moim rendererze wierzchołki modelu są przechowywane jako punkty 3D, dopiero podczas kopiowania ich do wewnętrzengo bufora pipeline'u uzupełniane są o współrzędną w. W czasie przekształceń model->kamera używam używam macierzy 4x3, a w czasie rzutowania i okienkowania macierzy 4x4. ;) Podejrzewam, że to po częsci kwestia gustu.
Krzysiek K.
May 5, 2009

Odp: Własna macierz projekcji - co robię nie tak?

Cytat:
Znaczy się w tym przypadku nie ma to sensu, ale generalnie możesz policzyć sobie iloczyn wektorowy dwóch N-wymiarowych wektorów. Iloczyn wektorowy w N wymiarowej przestrzeni wymaga N-1 argumentów. ;)

Wiem i właśnie o tym mówię. Jeżeli chodzi o sens, to sens jest i to spory. Iloczyn wektorowy 4D daje wektor 4D prostopadły do każdego z nich. W przypadku, gdy punkt jest punktem 3D, a W jest współrzędną normalizującą też jest sens - iloczyn wektorowy trzech takich punktów daje w wyniku współrzynniki równania płaszczyzny przechodzącego przez te punkty (Ax+By+Cz+Dw=0). Skolei jeżeli weźmiemy trzy płaszczyzny o współczynnikach ABCD i zastosujemy na nich iloczyn wektorowy 4D, to dostaniemy xyzw punktu, w którym przecinają się wszystkie te płaszczyzny. :)
Strony:
1