私がOpenGLを学んでいるとき、私はしばしばいわゆる目の空間座標に出くわします。
私が正しければ、通常、3つの行列があります。モデル行列、ビュー行列、射影行列。その背後にある数学がどのように機能するかは完全にはわかりませんが、座標をワールドスペース、ビュースペース、スクリーンスペースに変換することは知っています。
しかし、目の空間はどこにあり、何かを目の空間に変換するためにどの行列が必要ですか?
私がOpenGLを学んでいるとき、私はしばしばいわゆる目の空間座標に出くわします。
私が正しければ、通常、3つの行列があります。モデル行列、ビュー行列、射影行列。その背後にある数学がどのように機能するかは完全にはわかりませんが、座標をワールドスペース、ビュースペース、スクリーンスペースに変換することは知っています。
しかし、目の空間はどこにあり、何かを目の空間に変換するためにどの行列が必要ですか?
おそらく、さまざまなスペース間の関係を示す次の図が役立つでしょう。
固定関数パイプラインを使用している場合(glMatrixMode()
たとえば、呼び出す場合)、またはシェーダーを使用している場合、操作は同じです-シェーダーで直接コーディングするか、OpenGLパイプラインが支援するかによって異なります。あなたの仕事で。
固定機能パイプラインの観点から物事を議論することに嫌悪感がありますが、それは会話をより簡単にするので、私はそこから始めます。
従来のOpenGL(つまり、OpenGL 3.1より前のバージョン、または互換性プロファイルを使用)では、モデルビューと射影の2つのマトリックススタックが定義され、アプリケーションが各スタックの最上位でマトリックスを開始すると、単位行列(1.0対角線、他のすべての要素の場合は0.0)。その空間に座標を描画すると、正規化されたデバイス座標(NDC)で効果的にレンダリングされ、X、Y、Zの両方で[-1,1]の範囲外の頂点が切り取られます。を呼び出すことによって設定されるglViewport()
のは、NDCをウィンドウ座標(実際にはビューポート座標ですが、ほとんどの場合、ビューポートとウィンドウは同じサイズと場所です)、および深度値を深度範囲にマップするものです。(デフォルトでは[0,1]です)。
現在、ほとんどのアプリケーションで、指定される最初の変換は射影変換です。これには、正投影と透視投影の2種類があります。正投影は角度を保持し、線分の相対的な長さを歪めないため、通常、科学および工学のアプリケーションで使用されます。従来のOpenGLでは、正投影はまたはのいずれかで指定されglOrtho
ますgluOrtho2D
。より一般的に使用されるのは遠近法変換です。これは、目がどのように機能するかを模倣し(つまり、目から遠いオブジェクトは近いオブジェクトよりも小さい)、またはのいずれかで指定されglFrustum
ますgluPerspective
。透視投影の場合、彼らは視錐台を定義しました、これは目の位置に固定された切り捨てられたピラミッドであり、目の座標で指定されます。目の座標では、「目」は原点にあり、-Z軸を見下ろしています。近距離および遠距離のクリッピング平面は、-Z軸に沿った距離として指定されます。目の座標でレンダリングする場合、ニアクリッピングプレーンとファークリッピングプレーンの間、および表示錐台の内側で指定されたジオメトリはカリングされず、ビューポートに表示されるように変換されます。これは、透視投影の図と、画像平面との関係です。
目は視錐台の頂点にあります。
議論する最後の変換は、モデルビュー変換です。これは、座標系(オブジェクトではなく、すぐに詳しく説明します)を移動して、目と視錐台に対して適切な位置に配置する役割を果たします。一般的なモデリング変換は、平行移動、スケール、回転、およびせん断です(OpenGLではネイティブサポートはありません)。
一般的に、3Dモデルは、ローカル座標系を中心にモデル化されます(たとえば、原点を中心とする球の座標を指定します)。モデリングトランスフォームは、「現在の」座標系を新しい場所に移動するために使用されます。これにより、ローカルでモデリングされたオブジェクトをレンダリングするときに、適切な場所に配置されます。
モデリング変換と表示変換の間に数学的な違いはありません。通常、モデリング変換は特定のモデルに使用されglPushMatrix()
、glPopMatrix()
操作によって制御されます。操作は通常、表示変換が最初に指定され、後続のすべてのモデリング操作に影響します。
現在、この最新のOpenGL(コアプロファイルバージョン3.1以降)を実行している場合は、これらすべての操作を論理的に自分で実行する必要があります(モデルビュー変換と射影変換の両方を単一の行列乗算に折りたたむ1つの変換のみを指定できます) 。マトリックスは通常、シェーダーとして指定されますuniforms
。マトリックススタック、モデルビューと投影変換の分離はありません。パイプラインをエミュレートするには、数学を正しくする必要があります。(ところで、パースペクティブ除算とビューポート変換の手順は、頂点シェーダーの完了後にOpenGLによって実行されます。計算を行う必要はありません[できます。wを1.0に設定しない限り、何も害はありません。gl_Position
頂点シェーダー出力)。
アイスペース、ビュースペース、カメラスペースはすべて同じものの同義語です。つまり、カメラに関連する世界です。
レンダリングでは、シーンの各メッシュは通常、モデルマトリックス、ビューマトリックス、および投影マトリックスによって変換されます。最後に、投影されたシーンがビューポートにマッピングされます。
投影、ビュー、およびモデルマトリックスは相互作用して、ビューポートにシーンのオブジェクト(メッシュ)を表示します。
座標系:
モデル座標(オブジェクト座標)
モデル空間は、メッシュを定義または変調するために使用される座標系です。頂点座標はモデル空間で定義されます。
世界座標
ワールドスペースは、シーンの座標系です。さまざまなモデル(オブジェクト)をワールドスペースに複数回配置して、一緒にシーンを形成することができます。
モデルマトリックスは、シーン内のモデル(オブジェクト、メッシュ)の位置、方向、および相対サイズを定義します。モデル行列は、単一のメッシュの頂点位置を単一の特定の配置のためにワールド空間に変換します。モデル(オブジェクト)とワールド空間内のオブジェクトの位置の組み合わせごとに1つずつ、さまざまなモデル行列があります。
ビュースペース(目の座標)
ビュースペースは、シーンへの視点によって定義されるローカルシステムです。ビューの位置、視線、およびビューの上方向は、ワールド座標系を基準にした座標系を定義します。シーンのオブジェクトは、表示位置から「見える」ように、表示座標系に関連して描画する必要があります。ビュー座標系の逆行列は、ビュー行列と呼ばれます。この行列は、ワールド座標からビュー座標に変換されます。
一般に、世界座標とビュー座標はデカルト座標です
ビュー座標系は、シーンが見られる方向と位置を記述します。ビューマトリックスは、ワールド空間からビュー(目)空間に変換されます。
ビュースペースの座標系が右手系であり、X軸が右を指し、Y軸が上を向いている場合、Z軸はビューの外を指します(右手のシステムでは、 Z軸は、X軸とY軸の外積です。
クリップ空間の座標は同次座標です。クリップスペースでは、シーンのクリッピングが実行されます。、およびコンポーネントが、反転されたコンポーネントとポイントの同次座標のコンポーネントによって定義された範囲内に
ある場合、ポイントはクリップ空間にあります。x
y
z
w
w
-w <= x, y, z <= w.
投影行列は、シーンの3Dポイントからビューポートの2Dポイントへのマッピングを記述します。投影行列は、ビュー空間からクリップ空間に変換されます。w
クリップ空間の座標は、クリップ座標の成分で除算することにより、(-1、-1、-1)から(1、1、1)の範囲の正規化されたデバイス座標(NDC)に変換されます。
正投影では、この領域(ボリューム)は、視聴者の位置までの6つの距離(左、右、下、上、近く、遠く)によって定義されます。左、下、および近距離が負で、右、上、および遠距離が正の場合(正規化されたデバイス空間の場合のように)、これはビューアの周りのボックスとして想像できます。スペース(ボリューム)にあるすべてのオブジェクト(メッシュ)は、ビューポートに「表示」されます。このスペースの外にある(または部分的に外れている)すべてのオブジェクト(メッシュ)は、ボリュームの境界でクリップされます。これは、正投影では、ビューアの「背後」にあるオブジェクトが「見える」可能性があることを意味します。これは不自然に見えるかもしれませんが、これが正投影の仕組みです。
透視投影では、表示ボリュームは錐台(角錐台)であり、ピラミッドの上部が表示位置になります。視線の方向(視線)と近距離および遠距離は、ピラミッドを錐台に切り詰めた平面を定義します(視線の方向はこの平面の法線ベクトルです)。左、右、下、上の距離は、視線と近平面の交点から錐台の側面(近平面上)との距離を定義します。これにより、ピンホールカメラから見たシーンのように見えます。
オブジェクトがビューポートに表示されない場合(画面がすべて「黒」)の最も一般的な間違いの1つは、メッシュが投影およびビューマトリックスによって定義されるビューボリューム内にないことです。
正規化されたデバイス座標
正規化されたデバイススペースは、(-1、-1、-1)の右、下、前、および(1、1、1)の左、上、後ろの立方体です。w
正規化されたデバイス座標は、クリップ空間座標をクリップ座標のコンポーネントで割ったものです。これはパースペクティブディバイドと呼ばれます
ウィンドウ座標(画面座標)
ウィンドウの座標は、ビューポートの長方形の座標です。ウィンドウの座標は、ラスタライズプロセスにとって決定的です。
正規化されたデバイス座標は、ビューポートの長方形(ウィンドウ座標/画面座標)および深度バッファーの深度に線形にマッピングされます。ビューポートの長方形はによって定義されglViewport
ます。深度範囲はによって設定されglDepthRange
、デフォルトでは[0、1]です。