OpenGL座標系を理解しようとしています。ただし、一部のチュートリアルでは、デフォルトの座標系が左利きであると言います( http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx を参照)、および他の人は右利きだと言います( http://www.falloutsoftware.com/tutorials/gl/gl0.htm を参照)。どちらが正しい?ミラーリングによって一方を他方に変換できることは理解していますが、デフォルトの座標を知りたいです。
ここには混乱があります。
OpenGLは、オブジェクト空間とワールド空間でright handedです。
しかし、ウィンドウスペース(スクリーンスペース)では、突然左利きになります。
どうしてそうなった?
右手から左手に至る方法は、 glOrtho
または glFrustum
射影行列の負のzスケーリングエントリです。 zを-1でスケーリングすると(xとyはそのまま)、座標系の利き手を変更する効果があります。
GlFrustumの場合、
farおよびnearは正であると想定されており、far>nearである。far= 1000およびnear= 1と言います。次に、C =-(1001)/(999)= -1.002。
詳細と図については、 here を参照してください。
orthographicパースペクティブから、glOrthoは次のようなマトリックスを生成します。
ここで、left、right、bottomおよびtopはただ left vertical、right vertical、bottom horizontal、top horizontalの座標クリッピングプレーン(それぞれ) 。
nearおよびfar平面、ただし、は異なる方法で指定されます。nearパラメータは次のように定義されます
そして遠い:
ここに典型的な標準的なビューボリュームがあります
Z乗数は(-2 /(far-near))であるため、マイナス記号はzを-1で効果的にスケーリングします。これは、表示変換中に「z」が左回転であることを意味します。OpenGLで「右手」座標系として作業するだけなので、ほとんどの人には知られていません。
だから、あなたが電話した場合
glOrthof(-1, 1, -1, 1, 10, -10) ; // near=10, FAR=-10,
次に、NEAR PLANEは10ユニット先です。どこにいますか?原点で、右にx軸、頭の上のy軸、鼻が下を向いている理由負のz軸(デフォルトは "Byデフォルトでは、カメラは原点にあり、負のz軸を指しており、アップベクトルは(0、1、0)です。 " )。したがって、ニアプレーンはz = -10にあります。遠方面は後方10ユニット、z = + 1です。
デフォルトでは、正規化デバイス座標は左利きです。
GlDepthRangeはデフォルトで[0、1](近、遠)であり、+ z軸を画面に向け、+ xを右に、+ yを上にすると左利きのシステムになります。
深度範囲を[1、0]に変更すると、システムは右利きになります。
以前の Nicolからの回答 :を引用(取り消し線は私の仕事です。以下で説明します)
誰も言及していないことに驚いています。OpenGLは左手系でも動作します。少なくとも、シェーダーを使用しており、デフォルトの深度範囲を使用している場合はそうなります。
固定機能パイプラインを破棄すると、「クリップスペース」を直接処理します。 OpenGL仕様は、クリップ空間を4D同次座標系として定義しています。正規化されたデバイス座標を介してウィンドウ空間まで変換をたどると、これがわかります。
ウィンドウスペースは、ウィンドウのピクセルのスペースにあります。 Originは左下隅にあり、+ Yが上がり、+ Xが右になります。これは、右手座標系によく似ています。しかし、Zはどうですか?
デフォルトの深度範囲(glDepthRange)は、Zの近くの値を0に、Zの遠くの値をoneに設定します。したがって、+ Zはビューアーから離れて移動します。
それは左利きの座標系です。はい、できます
深度テストをGL_LESSからGL_GREATERに変更し、glDepthRangeを[0、1]から[1、0]に変更します。ただし、OpenGLのdefault状態は、左手座標系で動作します。そして、クリップスペースからウィンドウスペースに到達するために必要な変換はどれもZを無効にしません。したがって、クリップスペース、頂点(またはジオメトリ)シェーダーの出力は左手スペース(ちょっと。4D同次空間です。利き手を特定するのは難しいです)。固定機能パイプラインでは、標準投影行列(glOrtho、glFrustumなどによって生成)はすべて、右手空間から左手空間に変換します。 Zの意味を反転させます。生成する行列を確認するだけです。目の空間では、+ Zは視聴者に向かって移動します。投影後の空間では、移動します。
Microsoft(およびGLide)は、単純に投影行列で否定を実行することを気にしなかったのではないかと思います。
それが私の発見とは異なるため、私は一部を打った。
DepthRangeまたはDepthFuncを変更してClearDepth(0)を使用すると動作しますが、両方を使用すると、互いにキャンセルされて左利きのシステムに戻ります。
OpenGL only knows NDC!!
、そしてそれは左手座標です。使用する座標に関係なく、左、右の軸座標など。すべてNDCにミラーリングする必要があります。必要に応じて、左座標でワールド空間を完全に記述できます。
私はそれが従来のものだと思う、それはただそれだけで、たぶんDirectXと区別したいだけかもしれない。
松田幸一による本「WebGl Programming Guide」は、「WebGl/OpenGl:左利きか右利きか?」でほぼ10ページを費やしています。
本によると:
実際には、ほとんどの人は右利きのシステムを使用します
OpenGlは実際には内部的に左利きのシステムです
内部的には、実際にはどちらでもありません。一番下のOpenGlはz値を気にしません。描画する順序によって、上に描画されるものが決まります(最初に三角形を描画し、次に四角形を描画します。四角形が三角形を上書きします)。
「どちらでもない」ということには完全に同意しませんが、それはおそらく哲学的な質問でしょう。
Openglは間違いなく左利きです。射影行列のZ値を無効にしているため、反対のことを述べている多くのチュートリアルがあります。最終的な頂点が頂点シェーダー内で計算されると、クライアント側(右手座標)から左手に渡す頂点が変換され、頂点がジオメトリシェーダーとフラグメントシェーダーに渡されます。クライアント側で右手座標系を使用する場合、Openglは気にしません。それは左利きの正規化された座標系のみを知っています。
編集:私を信用していない場合は、変換マトリックスを追加して頂点シェーダーを試すだけで、Openglが左利きかどうかを簡単に確認できます。