Próbuję zrozumieć układ współrzędnych OpenGL. Jednak niektóre samouczki mówią, że domyślny układ współrzędnych jest leworęczny (patrz http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx ), a inne mówią, że jest praworęczny (patrz http: // www .falloutsoftware.com / tutorials / gl / gl0.htm ). Który jest poprawny? Rozumiem, że możemy przekształcić jedno w drugie przez odbicie lustrzane, ale chciałbym poznać domyślne współrzędne.
opengl
coordinates
341008
źródło
źródło
Odpowiedzi:
Jest tu trochę zamieszania.
OpenGL jest praworęczny w przestrzeni obiektów i przestrzeni świata.
Ale w przestrzeni okna (aka przestrzeni ekranu) nagle stajemy się leworęczni .
Jak to się stało ?
Sposób, w jaki przechodzimy od praworęcznych do leworęcznych, to ujemny wpis skalowania z w macierzy
glOrtho
lubglFrustum
macierzy projekcji. Skalowanie z o -1 (pozostawiając niezmienione x i y) ma wpływ na zmianę ręczności układu współrzędnych.Dla glFrustum,
dalekie i bliskie mają być pozytywne, z daleka > blisko . Powiedz daleko = 1000 i blisko = 1. Wtedy C = - (1001) / (999) = -1,002.
Zobacz tutaj, aby uzyskać więcej szczegółów i schematów.
Z perspektywy ortograficznej glOrtho generuje taką macierz:
Tutaj lewa , prawa , dół i góra to tylko współrzędne dla lewej pionowej , prawej pionowej , dolnej poziomej , górnej poziomej płaszczyzny przycinającej (odpowiednio) .
Jednak bliskie i dalekie płaszczyzny są określane inaczej . Pobliżu parametr określa się jako
i daleko:
Tutaj mamy typową kanoniczną objętość widoku
Ponieważ mnożnik z wynosi (-2 / (daleko-blisko)), znak minus skutecznie skaluje z o -1 . Oznacza to, że „z” jest obracane w lewo podczas transformacji widoku, o czym większość ludzi nie wie, ponieważ po prostu pracują w OpenGL jako „praworęczny” układ współrzędnych.
Więc jeśli zadzwonisz
Wtedy BLISKI SAMOLOT jest 10 jednostek przed tobą . Gdzie jesteś? Na początku, z osią X po prawej stronie, osią Y na czubku głowy i nosem skierowanym w dół na ujemną oś Z (to jest domyślne ustawienie „Domyślnie kamera jest umieszczona na początku , wskazuje ujemną oś z i ma wektor w górę (0, 1, 0). ” ). Więc najbliższa płaszczyzna ma z = -10. Daleka płaszczyzna znajduje się 10 jednostek za tobą, w punkcie z = + 10 .
źródło
gluLookAt
obliczeniach nie ma nic wspólnego ze zmianą ręczności przestrzeni współrzędnych, tak właśnie jest obliczana ta macierz (w rzeczywistości + z jest rzeczywiście „wstecz” w przestrzeni prawoskrętnej).gluLookAt
nie robi nic poza obliczeniem zwykłej transformacji ciała sztywnego (obrót + przesunięcie) w przestrzeni prawoskrętnej. To macierze projekcji używane przez potok funkcji stałych (i zazwyczaj również przez shadery), które dokonują rzeczywistej zmiany ręczności w ich negacji składowej z, jak już zauważyłeś w swojej odpowiedzi.gluLookAt
nie byłoby zmiany podstawy, skoro takgluLookAt
? Zdecydowanie nie (ponieważ prawdopodobnie wiesz, że nie "wszyscy" używajągluLookAt
do obliczania macierzy widoku), ponieważ jak powinieneś wiedzieć,gluLookAt
nie robi nic innego niż zbiór wywołań rotacji i tłumaczenia (czy nawet ukrywają się jako zmiana " terminu " wysokiego poziomu " base ” ) bez żadnych odbić.Domyślnie znormalizowane współrzędne urządzenia są leworęczne.
Zakres glDepthRange to domyślnie [0, 1] (blisko, daleko), dzięki czemu oś + z wskazuje na ekran, a przy + x w prawo i + y w górę jest to system leworęczny.
Zmiana zakresu głębokości na [1, 0] spowoduje, że system będzie praworęczny.
Cytując poprzednią odpowiedź Nicola : (przekreślenie to moja praca, wyjaśnione poniżej)
Uderzyłem jedną część, ponieważ odbiegała od moich ustaleń.
Zmiana DepthRange lub DepthFunc i użycie ClearDepth (0) działa, ale podczas używania obu anulowały się nawzajem z powrotem do systemu leworęcznego.
źródło
TYLKO NDC
Należy tylko zauważyć, że OpenGL zna tylko NDC! a to jest lewoskrętny układ współrzędnych.
Niezależnie od używanego układu współrzędnych - lewoskrętny lub prawoskrętny układ współrzędnych oś - wszystkie muszą być odzwierciedlone w NDC. Jeśli chcesz, możesz całkowicie obsłużyć przestrzeń świata jako lewoskrętny układ współrzędnych.
Dlaczego zwykle używamy prawoskrętnego układu współrzędnych w przestrzeni świata?
Myślę, że to konwencjonalne. Po prostu działa. Może po prostu chce odróżnić się od DirectX.
źródło
Książka „WebGl Programming Guide” autorstwa Kouichi Matsudy zajmuje prawie dziesięć stron na temat „WebGl / OpenGl: Left or Right Handed?”
Według książki:
W praktyce większość ludzi używa systemu praworęcznego
OpenGl jest wewnętrznie systemem leworęcznym
Wewnętrznie, głębiej, tak naprawdę nie jest. Na samym dole OpenGl nie dba o wartość z. Kolejność rysowania określa, co jest rysowane na górze (najpierw narysuj trójkąt, a następnie kwadrat, kwadrat przesłania trójkąt).
Nie do końca zgadzam się z twierdzeniem „to też nie”, ale i tak jest to prawdopodobnie kwestia filozoficzna.
źródło
The order in which you draw things determines what is drawn on top (draw a triangle first, then a quad, the quad overrides the triangle).
To prawda, jeśli nie ma testów głębokości. W przypadku testowania głębokości wartość z fragmentu jest porównywana z wartością w buforze głębokości, a fragment odrzucany, jeśli nie przejdzie testu głębokości, więc quad może, ale nie musi, nadpisać trójkąt w zależności od ich głębokości i używana funkcja głębokości.Opengl jest zdecydowanie leworęczny. Widzisz wiele samouczków stwierdzających coś przeciwnego, ponieważ negują one wartość z w macierzy projekcji. Kiedy końcowe wierzchołki są obliczane w Vertex Shader, konwertuje to wierzchołki, które przekazujesz ze strony klienta (koordynatory po prawej stronie) do leworęcznych, a wierzchołki zostaną następnie przesłane do Geometry Shader i Fragment Shader. Jeśli używasz prawego układu współrzędnych po stronie klienta, Opengl nie obchodzi. Zna tylko znormalizowany układ współrzędnych, który jest leworęczny.
Edycja: Jeśli mi nie ufasz, po prostu eksperymentuj w swoim Vertex Shader, dodając macierz translacji i możesz łatwo sprawdzić, czy Opengl jest leworęczny, czy nie.
źródło
Korzystając z wbudowanych w OpenGL funkcji projekcji i transformacji, obserwowanie ruchów na ekranie odbywa się zgodnie z regułami praworęcznego układu współrzędnych. Na przykład, jeśli obiekt znajdujący się przed Twoim widokiem zostanie przesunięty w dodatnim kierunku z, obiekt ten przesunie się w Twoją stronę.
Bufor głębokości jest zupełnie odwrotny i tutaj do gry wchodzą NDC (znormalizowane współrzędne urządzenia). Jeśli przekazanie GL_LESS do funkcji glDepthFunc oznacza, że piksele będą rysować, gdy będą bliżej Ciebie niż to, co jest już w buforze głębi, wówczas uważa się, że piksele żyją w lewoskrętnym układzie współrzędnych.
Jest jeszcze jeden układ współrzędnych i to jest rzutnia! Układ współrzędnych rzutni jest taki, że + x wskazuje w prawo, a + y w dół. Myślę, że w tym momencie ręczność jest dyskusyjna, ponieważ w tym momencie mamy do czynienia tylko z x, y.
Wreszcie, gluLookAt pod maską musi zanegować wektor patrzenia. Ponieważ matematyka zakłada, że wektor jest skierowany w dodatnim kierunku w kierunku obiektu, na który patrzy, a kamera patrzy w dół -z, wektor patrzenia musi zostać zanegowany, aby był wyrównany z kamerą.
Coś do gryzienia. Nie ma sensu nazywać kierunku z prawoskrętnego układu współrzędnych wektorem do przodu :). Myślę, że Microsoft zdał sobie z tego sprawę, kiedy zaprojektował Direct3D.
źródło