Il sistema di coordinate OpenGL è mancino o destrorso?

Sto cercando di capire il sistema di coordinate OpenGL. Tuttavia, alcuni tutorial dicono che il sistema di coordinate di default è mancino (vedi http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx ) e altri dicono che è destrorso (vedi http: // www .falloutsoftware.com / tutorial / gl / gl0.htm ). Che è corretto? Capisco che siamo in grado di trasformare l’uno con l’altro mediante il mirroring, ma mi piacerebbe conoscere le coordinate di default.

Il sistema di coordinate è destrorso. Il primo articolo sembra essere sbagliato.

C’è una certa confusione qui.

inserisci la descrizione dell'immagine qui

OpenGL è destrorso nello spazio oggetti e nello spazio mondiale.

Ma nello spazio della finestra (ovvero lo spazio dello schermo) siamo improvvisamente mancini .

Come è successo ?

Il modo in cui arriviamo da destrimano a mancino è un ingresso z scalare negativo nelle matrici di proiezione glOrtho o glFrustum . Il ridimensionamento di z di -1 (lasciando xey come erano) ha l’effetto di cambiare la manualità del sistema di coordinate.

Per glFrustum,

inserisci la descrizione dell'immagine quiinserisci la descrizione dell'immagine qui

lontano e vicino dovrebbero essere positivi, con lontano > vicino . Dire lontano = 1000 e vicino = 1. Quindi C = – (1001) / (999) = -1,002.

Vedi qui per maggiori dettagli e diagrammi.

Da una prospettiva ortografica , glOrtho genera una matrice come questa:

inserisci la descrizione dell'immagine qui

Qui, a sinistra , a destra , in basso e in alto ci sono solo le coordinate per i piani di ritaglio verticale verticale , verticale destro , orizzontale inferiore , orizzontale superiore (resp) .

I piani vicini e lontani , tuttavia, sono specificati in modo diverso . Il parametro near è definito come

  • Vicino: la distanza dal piano di ritaglio più vicino. Questa distanza è negativa se l’aereo deve essere dietro l’osservatore.

e lontano:

  • zFar La distanza dal piano di ritaglio più profondo della profondità. Questa distanza è negativa se l’aereo deve essere dietro l’osservatore.

Qui abbiamo un tipico volume di visualizzazione canonica

canonico

Poiché il moltiplicatore z è (-2 / (lontano)), il segno meno ridimensiona efficacemente z di -1 . Ciò significa che “z” viene trasformato a sinistra durante la trasformazione della visualizzazione, all’insaputa della maggior parte delle persone poiché funzionano semplicemente in OpenGL come sistema di coordinate “destrorse”.

Quindi, se chiami

 glOrthof(-1, 1, -1, 1, 10, -10) ; // near=10, FAR=-10, 

Quindi il NEAR PLANE è di 10 unità più avanti di te . Dove sei? Perché, all’origine, con l’asse x alla tua destra, l’asse y sulla sommità della testa e il tuo naso che punta verso il basso sull’asse z negativo (è l’impostazione predefinita “Per impostazione predefinita, la telecamera è situata all’origine , punta verso il basso l’asse Z negativo e ha un vettore verso l’alto di (0, 1, 0). ” ). Quindi il piano vicino è a z = -10. Il piano lontano è 10 unità dietro di te, a z = + 10 .

Per impostazione predefinita, la coordinata periferica normalizzata è mancino.

Il glDepthRange è di default [0, 1] (vicino, lontano) che rende il punto dell’asse + z nello schermo e con + x a destra e + y su è un sistema mancino.

La modifica dell’intervallo di profondità su [1, 0] renderà il sistema destrorso.

Citando una risposta precedente di Nicol : (lo stri-through è il mio lavoro, spiegato di seguito)

Sono sorpreso che nessuno abbia menzionato qualcosa: OpenGL funziona anche con un sistema di coordinate mancino. Almeno, lo fa quando lavori con gli shader e usi l’intervallo di profondità predefinito.

Una volta eliminata la pipeline a funzione fissa, gestisci direttamente lo “spazio-clip”. La specifica OpenGL definisce lo spazio clip come un sistema di coordinate omogeneo 4D. Quando segui le trasformazioni attraverso le coordinate del dispositivo normalizzate e in basso nello spazio della finestra, trovi questo.

Lo spazio finestra è nello spazio dei pixel di una finestra. L’origine è nell’angolo in basso a sinistra, con + Y in aumento e + X in corso a destra. Sembra molto simile a un sistema di coordinate destrorse. Ma che mi dici di Z?

L’intervallo di profondità predefinito (glDepthRange) imposta il valore Z vicino a 0 e il valore Z lontano su uno . Quindi il + Z sta andando via dallo spettatore.

Questo è un sistema di coordinate mancino. Si, puoi cambia il test di profondità da GL_LESS a GL_GREATER e cambia glDepthRange da [0, 1] a [1, 0]. Ma lo stato predefinito di OpenGL è quello di lavorare in un sistema di coordinate mancino . E nessuna delle trasformazioni necessarie per raggiungere lo spazio della finestra dallo spazio clip nega la Z. Quindi lo spazio delle clip, l’output dello shader del vertice (o della geometria) è uno spazio per mancini (kinda.) È uno spazio omogeneo 4D, quindi è difficile definire le maniere).

Nella pipeline a funzione fissa, le matrici di proiezione standard (prodotte da glOrtho, glFrustum e simili) si trasformano da uno spazio per destrorsi a uno per mancini . Capovolgono il significato di Z; basta controllare le matrici che generano. Nello spazio degli occhi, + Z si sposta verso lo spettatore; nello spazio di post-proiezione, si allontana.

Sospetto che Microsoft (e GLide) semplicemente non si siano preoccupati di eseguire la negazione nelle loro matrici di proiezione.

Ne ho colpito una parte poiché si discostava dai miei risultati.

O cambiando DepthRange o DepthFunc e usando ClearDepth (0) funziona, ma quando si usano entrambi si annullano a vicenda in un sistema mancino.

SOLO NDC

Dovresti solo notare che OpenGL only knows NDC!! ed è una coordinata a sinistra. non importa quale coordinata si usa, la coordinata dell’asse della mano sinistra, quella della mano destra, ecc. Tutti devono essere specchiati su NDC. Se ti piace, puoi scrivere totalmente lo spazio del mondo nella coordinata sinistra.

Perché usiamo la coordinata della mano destra nello spazio del mondo?

Penso che sia convenzionale. Semplicemente. Magari voglio solo distinguere da DirectX.

Il libro “WebGl Programming Guide” di Kouichi Matsuda spende quasi dieci pagine su “WebGl / OpenGl: Left o Right Handed?”

Secondo il libro:

  • In pratica, molte persone usano un sistema destrorso

  • OpenGl è in realtà un sistema per mancini internamente

  • Internamente, più profondamente non è in realtà nessuno dei due. In fondo OpenGl non si preoccupa del valore z. L’ordine in cui peschi le cose determina ciò che viene disegnato in alto (disegna prima un triangolo, poi un quadruplo, il quadratino sovrascrive il triangolo).

Non sono pienamente d’accordo con “non è né”, ma probabilmente è comunque una questione filosofica.

Opengl è decisamente mancino. Vedete un sacco di tutorial che affermano il contrario perché stanno annullando il valore z nella matrice di proiezione. Quando i vertici finali sono calcolati all’interno di vertex shader, converte i vertici passati dal lato client (coord destro) a mancini, ei vertici saranno passati a shader di geometria e shader di frammenti. Se si utilizza il sistema di coordinate a destra sul lato client, a Opengl non importa. Conosce solo il sistema di coordinate normalizzato, che è mancino.

Modifica: se non ti fidi di me, prova semplicemente il vertex shader aggiungendo una matrice di traduzione e puoi facilmente vedere se Opengl è mancino o no.