web-dev-qa-db-ja.com

クリップ空間から画面座標への移行はいつ行われますか?

私はレンダリングパイプラインを研究していましたが、クリッピングステージに達したとき、ビュー(目またはカメラ)空間からクリップ空間に渡す必要があると説明されました正規化されたデバイス空間(NDC)とも呼ばれ、-1から1の立方体空間です。

ただし、この空間から画面座標空間への移行がいつ行われるのか、今はわかりません。

  1. クリッピング直後およびラスタライズ前?

  2. ラスタライズ後、ハサミとZテストの前に?

  3. フレームバッファに書き込む直前の最後に?

31
Geoffrey91

いいえ、クリップスペースとNDCスペースは同じものではありません。

クリップスペースは実際にはNDCから1ステップ離れており、すべての座標はClip.W NDCを生成します。結果のNDC空間の範囲[-11]の外側にあるものは、クリッピングボリュームの外側にあるポイントに対応します。 NDCの前の座標空間がクリップ空間と呼ばれる理由があります;)

ただし、厳密に言えば、NDCスペースは必ずしも立方体ではありません。 NDCスペースがOpenGLのキューブであることは事実ですが、Direct3Dではそうではありません。 D3Dでは、NDC空間のZ座標は.から1.の範囲ですが、-1.から1.の範囲ですGLで。 XとYは、GLとD3Dで同じように動作します(つまり、-1.から1.の範囲です)。NDCは標準です。座標空間ですが、APIごとに表現が異なります。

最後に、NDCスペースからスクリーンスペース(ウィンドウスペース)は、ラスタライズ中に発生し、ビューポートと深度範囲によって定義されます。フラグメントの位置は、他の座標空間では実際には意味がありません。これが、ラスタ化によって生成されるものです。fragments


更新:

OpenGL 4.5で導入された拡張機能 GL_ARB_clip_control を使用すると、GLでD3DのNDC規則を採用できます。

従来のOpenGLの動作は次のとおりです。

glClipControl (GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE);

Direct3Dの動作は、次の方法で実現できます。

glClipControl (GL_UPPER_LEFT, GL_ZERO_TO_ONE); // Y-axis is inverted in D3D
45

クリップスペースとNDC(正規化されたデバイス座標)は同じものではありません。そうでなければ、異なる名前はありません。

クリップ空間は、投影行列による点変換の後、ただしwによる正規化の前に、空間点が存在する場所です。

NDC空間は、wによる正規化後の空間点です。

http://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/projection-matrix-GPU-rendering-pipeline-clipping

Camera space --> 
x projection matrix ---> 
Clip space (before normalisation) --->
Clipping ---> 
Normalisation by w (x/w, y/w, z/w) --->
NDC space (in the range [-1, 1] in x and y)
10
user18490

どうやら、Appleによると、クリップスペースはNDCと同じです。

https://developer.Apple.com/documentation/metal/hello_triangle

見積もり:

「頂点関数(頂点シェーダーとも呼ばれます)の主なタスクは、着信頂点データを処理し、各頂点をビューポート内の位置にマッピングすることです。これにより、パイプラインの後続のステージはこのビューポート位置を参照し、ピクセルをレンダリングできます頂点関数は、任意の頂点座標をクリップスペース座標としても知られる正規化されたデバイス座標に変換することにより、このタスクを達成します。」

サンプルコードのコメントからの別の引用:

「すべての頂点シェーダーの出力位置は、クリップ空間(正規化されたデバイス座標空間、またはNDCとも呼ばれます)にあります。」

おそらく、これはチュートリアルが2Dであるためでしょうか?誤解を招く声明..

1
Siamaster

NDCスペースはクリップスペースです。NDCスペースからウィンドウスペースまではハードウェアによって行われ、NDCの後、ラスタライズの前に発生します。

幅と高さを設定するAPIがあり、デフォルト値はウィンドウサイズと同じサイズです。

// metal
func setViewport(_ viewport: MTLViewport)
// OpenGL
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);

OpenGLのNDCスペース、xyz範囲[-1、1]。金属の場合、Zは0〜1です。

NDCスペースは通常、左側のシステムです。

0
lbsweek