OpenGL koordinat sistemi solak mı yoksa sağlak mı?


88

OpenGL koordinat sistemini anlamaya çalışıyorum. Bununla birlikte, bazı eğitimler varsayılan koordinat sisteminin solak olduğunu söyler (bkz. Http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx ) ve diğerleri bunun sağ elini kullandığını söyler (bkz. Http: // www .falloutsoftware.com / tutorials / gl / gl0.htm ). Hangisi doğru? Yansıtarak birini diğerine dönüştürebileceğimizi anlıyorum, ancak varsayılan koordinatları bilmek istiyorum.



3
Bu tamamen gölgelendiricilerde dönüşümlerinizi nasıl yazdığınıza bağlı değil mi ve bu nedenle tamamen size bağlı mı?
jcoder

Sadece benim iki sentim evl.uic.edu/ralph/508S98/coordinates.html , kendi kendini açıklayan birkaç resmi var.
rraallvv

Kabul edilen cevabınızı güncellemeyi düşüneceğinizi sanmıyorum?
Jonathan Mee

Yanıtlar:


133

Burada bazı karışıklıklar var.

görüntü açıklamasını buraya girin

OpenGL, nesne alanında ve dünya alanında sağ elini kullanır .

Ancak pencere alanında (diğer adıyla ekran alanı) aniden solak oluruz .

Bu nasıl oldu ?

Sağlaktan solak olana geçme şeklimiz, glOrthoveya glFrustumprojeksiyon matrislerinde negatif bir z ölçeklendirme girdisidir. Z'yi -1 ile ölçeklendirmek (x ve y'yi olduğu gibi bırakarak), koordinat sisteminin el kullanımını değiştirme etkisine sahiptir.

GlFrustum için,

görüntü açıklamasını buraya girin görüntü açıklamasını buraya girin

uzak ve yakın pozitif, uzak > yakın . Uzak = 1000 ve yakın = 1 deyin . O zaman C = - (1001) / (999) = -1.002.

Daha fazla ayrıntı ve diyagram için buraya bakın .

Bir kaynaktan ortografik açısından , glOrtho böyle bir matris oluşturur:

görüntü açıklamasını buraya girin

Burada sol , sağ , alt ve üst , sol dikey , sağ dikey , alt yatay , üst yatay kırpma düzlemleri (resp) için yalnızca koordinatlardır .

Ancak yakın ve uzak düzlemler farklı şekilde belirtilmiştir . Civarındaki bir parametre olarak tanımlanır

  • Yakın: Daha yakın derinlik kırpma düzlemine olan mesafe . Uçak izleyicinin arkasında olacaksa bu mesafe negatiftir.

ve uzak:

  • zFar Daha uzak derinlik kırpma düzlemine olan mesafe . Uçak izleyicinin arkasında olacaksa bu mesafe negatiftir.

Burada tipik bir kanonik görünüm hacmine sahibiz

kanonik

Z çarpanı (-2 / (çok yakın)) olduğundan , eksi işareti z'yi -1 ile etkili bir şekilde ölçeklendirir . Bu, "z" 'nin görüntüleme dönüşümü sırasında sol elle çevrildiği anlamına gelir, çoğu insan sadece OpenGL'de "sağ elini kullanan" bir koordinat sistemi olarak çalıştıklarından habersizdir.

Yani ararsan

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

O zaman YAKIN UÇAK sizden 10 birim önde . Neredesin? Neden, başlangıç ​​noktasında, x ekseni sağınızda, y ekseni başınızın üstünde ve burnunuz negatif z eksenini gösteriyor (varsayılan olarak bu "Varsayılan olarak, kamera başlangıç ​​noktasındadır. , negatif z eksenini işaret eder ve yukarı vektörü (0, 1, 0). " ). Yani yakın düzlem z = -10'da. Uzaktaki düzlem, z = + 10'da 10 birim arkanızda .


1
"gluLookAt'da ileri vektör olumsuzlanır" - durumun böyle olduğunu onaylayabilir misiniz? GluPerspective veya glFrustum veya glOrtho değil mi?
Kos

1
Klip alanından itibaren birdenbire solak olduk, sadece pencere alanı değil.
efsaneler2k

3
Tüm cevap için +1, "Sağ elden solaklığa geçme şeklimizin yolu, ileri vektörün, gluLookAt () fonksiyonunun standart uygulamasında olumsuzlanmasıdır. herkes görünüm matrisini oluşturmak için kullanır. İleri vektörü geçersiz kılarsanız, bu koordinat sisteminin el tercihini değiştirme etkisine sahiptir. " , bu sadece çöp ...
Christian Rau

2
... gluLookAtHesaplamadaki ileri vektörü olumsuzlamanın, koordinat uzayının elini değiştirmeyle hiçbir ilgisi yoktur, bu sadece bu matrisin hesaplanma şeklidir (ve gerçekte + z, sağlak uzayda gerçekten "geri" dir ). gluLookAtsağ elini kullanan uzayda sıradan bir katı cisim dönüşümünü (döndürme + öteleme) hesaplamaktan başka bir şey yapmaz. Cevabınızda daha önce belirttiğiniz gibi, z bileşeninin olumsuzlamasında gerçek ellilik değişikliğini gerçekleştiren sabit işlevli ardışık düzen tarafından (ve genellikle gölgelendiriciler tarafından da) kullanılan projeksiyon matrisleridir.
Christian Rau

2
@bobobobo Görüş matrisinizi yalnızca döndürme ve çevirme işlevlerini kullanarak hesaplarsanız (ki el tercihini değiştirmekle suçlamazsınız sanırım), bunun yerine gluLookAt, temelde bir değişiklik gluLookAtolmaz mıydı? Kesinlikle hayır (muhtemelen "herkesin"gluLookAt matris hesaplaması için kullanmadığını biliyorsunuzdur ), çünkü bilmeniz gereken gluLookAtbir grup rotasyon ve çeviri çağrısından başka bir şey yapmaz (bunlar "üst düzey" terim "değişikliği olarak gizlenmiş olsa bile) temel " ) kesinlikle hiçbir yansıma olmadan.
Christian Rau

26

Varsayılan olarak Normalleştirilmiş Aygıt Koordinatı solaktır.

GlDepthRange varsayılan olarak [0, 1] (yakın, uzak) olup + z eksenini ekrana işaret eder ve + x sağa ve + y yukarı ile solak bir sistemdir.

Derinlik aralığını [1, 0] olarak değiştirmek sistemi sağ elini kullanacaktır.

Nicol'den önceki bir cevabı alıntılamak : ( Üstünü çizmek benim işim, aşağıda açıklanmıştır)

Kimsenin bir şey söylemesine şaşırdım: OpenGL de solak bir koordinat sisteminde çalışıyor. En azından, gölgelendiricilerle çalışırken ve varsayılan derinlik aralığını kullandığınızda işe yarar.

Sabit işlevli ardışık düzeni bir kez attığınızda, doğrudan "clip-space" ile ilgilenirsiniz. OpenGL Spesifikasyonu, klip uzayını 4D homojen koordinat sistemi olarak tanımlar. Dönüşümleri normalleştirilmiş cihaz koordinatlarından ve pencere alanına kadar takip ettiğinizde, bunu bulursunuz.

Pencere alanı, bir pencerenin piksellerinin alanıdır. Başlangıç, sol alt köşede, + Y yukarı ve + X sağa gidiyor. Bu çok sağ elini kullanan bir koordinat sistemine benziyor. Peki ya Z?

Varsayılan derinlik aralığı (glDepthRange), yakın Z değerini 0'a ve uzak Z değerini bire ayarlar . Yani + Z izleyiciden uzaklaşıyor .

Bu solak bir koordinat sistemi. Evet yapabilirsinderinlik testini GL_LESS'ten GL_GREATER'a değiştirin veglDepthRange'i [0, 1] 'den [1, 0]' a değiştirin. Ancak OpenGL'nin varsayılan durumu, solak bir koordinat sisteminde çalışmaktır. Ve klip uzayından pencere uzayına ulaşmak için gerekli olan dönüştürmelerin hiçbiri Z'yi olumsuzlamaz. Dolayısıyla, tepe (veya geometri) gölgelendiricisinin çıktısı solak bir uzaydır (bir tür 4D homojen bir uzaydır, yani teslim olmak zordur).

Sabit işlevli boru hattında, standart projeksiyon matrislerinin (glOrtho, glFrustum ve benzerleri tarafından üretilen) tümü, sağ elini kullanan bir alandan sol elini kullanan bir alana dönüşür . Z'nin anlamını tersine çevirirler; sadece ürettikleri matrisleri kontrol edin. Göz alanında + Z izleyiciye doğru hareket eder; projeksiyon sonrası alanda uzaklaşır.

Microsoft'un (ve GLide'nin) kendi projeksiyon matrislerinde olumsuzlama yapma zahmetine girmediğinden şüpheleniyorum.

Bulgularımdan farklı olduğu için bir parçayı vurdum.

Ya DepthRange'i ya da DepthFunc'u değiştirmek ve ClearDepth (0) kullanmak işe yarıyor, ancak her ikisi de kullanıldığında, sol elli bir sisteme geri döndüler.


Derinlik aralığı [1, -1] olamaz. Sanırım [1, 0] demek istediniz. Ayrıca, bu daha önce de belirtilmişti .
Nicol Bolas

Cevabınız harika, DirectX sorusu için çok kötü, burada tekrar göndermelisiniz!
hultqvist

3
@SigTerm neden yanlış bir ifadeyi düzeltmenin buna değmediğini düşünüyorsunuz? Sırf varsayılan koordinat sisteminin aslında sağ elini kullanmadığını öğrenmek için birkaç saat köşe koordinatları ve matris dönüşü oluşturma sorunlarını gidermek için harcadım.
hultqvist

1
Soru, bunun sağ elini mi yoksa sağ elini kullanan bir sistem mi olduğuydu. Bu cevabın bundan daha fazla detayı var, onu sağ elle tutmanın diğer iki yolunu açıklamak, bir matris dönüşümüne -1 eklemek, bunu yapmanın başka bir yolu. Ancak bunların hiçbirinin önemi yok, sistemin varsayılan olarak sağ elini kullandığına inanıyorsanız, bir şeyi yalnızca neyden değiştiğinizi biliyorsanız değiştirebilirsiniz. Hala
hultqvist

1
Cevabı çok aydınlatıcı buldum ve aramalarda ortaya çıktı, bu yüzden benim için buna değerdi.
OpenGL ES

13

SADECE NDC

Yalnızca OpenGL'nin yalnızca NDC'yi bildiğini fark etmelisiniz ! ve bu solak bir koordinat sistemidir.

Hangi koordinat sistemini kullanırsanız kullanın - solak veya sağ el eksen koordinat sistemi - hepsinin NDC'ye yansıtılması gerekir. İsterseniz, dünya uzayını tamamen solak koordinat sistemi olarak kullanabilirsiniz.

Dünya uzayında neden genellikle sağ elini kullanan koordinat sistemini kullanıyoruz?

Bunun geleneksel olduğunu düşünüyorum. Sadece yapar. Belki sadece DirectX'ten ayırt etmek istiyordur.


3
Bunun yeterince tekrarlanmadığını düşünüyorum. "Modelleme dönüşümü", "görünüm dönüşümü", "perspektif dönüşümü" nü gösteren tüm bu diyagramlar, OpenGL'nin içsel bir parçası olmadıklarını göstermede başarısız oluyor. Tüm dönüştürmelerinizi manuel olarak, gölgelendiricili veya gölgesiz, matrisli veya matrissiz bile yapabilirsiniz.
Tom

3
Yine de "normalleştirilmiş cihaz koordinatları" kelimelerini içerecek şekilde tekrarlamak daha iyi olabilir.
Tommy

6
OpenGL, DirectX'ten birkaç yıl öncesine dayanıyor, bu nedenle OpenGL kesinlikle kendisini DirectX'ten ayırmaya çalışmıyordu. DirectX'in baş geliştiricisi Alex St. John, Microsoft'un solak bir koordinat sistemine gitme kararının "kısmen kişisel tercihin dışında" ve "keyfi bir seçim" olduğunu söyledi.
Chris Nolet

Bu tamamen doğru değil. OpenGL ayrıca kırpma koordinat sistemini de bilir, çünkü kırpma burada gerçekleşir. Klip koordinat sistemi, NDC koordinat sistemi tho ile aynı ele sahiptir.
plasmacel

7

Kouichi Matsuda'nın "WebGl Programlama Kılavuzu" adlı kitabı "WebGl / OpenGl: Sol mu Sağ El mi?"

Kitaba göre:

  • Pratikte çoğu insan sağ elini kullanan bir sistem kullanır

  • OpenGl aslında dahili olarak solak bir sistemdir

  • Dahili olarak, daha derinde aslında ikisi de değil. En altta OpenGl z-değerini umursamıyor. Nesneleri çizdiğiniz sıra, üstte neyin çizileceğini belirler (önce bir üçgen, sonra bir dörtlü çizin, dörtgen üçgeni geçersiz kılar).

"Hiçbiri" fikrine tam olarak katılmıyorum ama bu muhtemelen felsefi bir soru.


7
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). Derinlik testi olmadığında bu doğrudur. Derinlik testinin varlığında, bir parçanın z değeri, derinlik tamponundaki değerle karşılaştırılır ve derinlik testinde başarısız olursa parça atılır, böylece dörtlü, derinliklerine ve derinliklerine bağlı olarak üçgenin üzerine yazabilir veya yazmayabilir. derinlik işlevi kullanıldı.
chrisvarnz

3

Opengl kesinlikle solaktır. Projeksiyon matrisindeki z değerini olumsuzladıkları için bunun tersini belirten birçok öğretici görüyorsunuz. Nihai köşeler köşe gölgelendiricisi içinde hesaplandığında, istemci tarafından (sağ taraftaki) geçtiğiniz köşeleri sol tarafa dönüştürür ve köşeler daha sonra geometri gölgelendiricisine ve parça gölgelendiricisine aktarılır. İstemci tarafında sağ koordinat sistemini kullanırsanız, Opengl umursamıyor. Yalnızca solak olan normalleştirilmiş koordinat sistemini bilir.

Düzenleme: Bana güvenmiyorsanız, bir çeviri matrisi ekleyerek köşe gölgelendiricinizi deneyin ve Opengl'in solak olup olmadığını kolayca görebilirsiniz.


0

OpenGL'nin yerleşik projeksiyon ve dönüştürme işlevlerini kullanarak, ekrandaki hareketleri gözlemlemek, sağ elini kullanan koordinat sisteminin kurallarını takip eder . Örneğin, görünümünüzün önündeki bir nesne pozitif z yönünde çevrilmişse, nesne size doğru hareket edecektir.

Derinlik tamponu tam tersidir ve NDC'nin (Normalize Cihaz Koordinatları) devreye girdiği yer burasıdır. GL_LESS'in glDepthFunc'a aktarılması, piksellerin size zaten derinlik tamponunda bulunandan daha yakın olduklarında çizileceği anlamına geliyorsa, piksellerin solak bir koordinat sisteminde yaşadığı kabul edilir .

Bir koordinat sistemi daha var ve bu görüntü alanı! Görüntü alanının koordinat sistemi, + x sağa ve + y aşağıya bakacak şekildedir. Sanırım bu noktada el tercihi tartışmalı, çünkü bu noktada sadece x, y ile uğraşıyoruz.

Son olarak, kaputun altındaki gluLookAt, bakma vektörünü reddetmelidir. Matematik, bir vektörün baktığı nesneye doğru pozitif bir yöne işaret ettiğini varsaydığından ve bir kamera -z aşağı baktığından, bakma vektörü, kamera ile hizalanması için olumsuzlanmalıdır.

Çiğnenecek bir şey. Sağ el koordinat sisteminin z yönünü ileri vektör olarak adlandırmak pek mantıklı değil :). Sanırım Microsoft bunu Direct3D'yi tasarlarken fark etti.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.