4

glFrustum()パースペクティブ モードを使用して 3D シーンをレンダリングしました。次に、2D オブジェクトを 3D シーン上に配置して、特定の 3D オブジェクトのラベルとして機能させます。gluProject()2D ラベル オブジェクトを配置する位置を使用して 3D オブジェクトの 2D 位置を計算しました。glOrtho()2D ラベル オブジェクトは、正投影モードを使用してレンダリングされます。これは完全に機能し、2D ラベル オブジェクトが 3D オブジェクトの上に移動します。

ここで、2D オブジェクトに az 値を与えて、深度バッファーを使用してシーン内の他の 3D オブジェクトの背後に隠すことができるようにします。2D オブジェクトに az 値を指定しましたが、深度バッファーによって非表示にする必要があることがわかっていますが、オブジェクトをレンダリングすると常に表示されます。

問題は、なぜ 2D オブジェクトがまだ表示されているのに非表示になっていないのかということです。

正射投影と遠近投影が互換性のない深度バッファー値を格納することをどこかで読みました。これは本当ですか?もしそうなら、どうすればそれらの間で変換できますか?

4

2 に答える 2

10

私はそれを変換したくありません。代わりに、常にカメラに面し、画面上で常に同じサイズのままであるフラットな 2D ラベルとして表示したいと考えています。ただし、何かの後ろに隠れている場合は、隠れているように見せたいです。

まず、それを質問に入れる必要がありました。あなたの質問よりも、あなたがやろうとしていることについてはるかに多くのことを説明しています。

これを実現するには、ラベルを表示する場所の射影前空間の z 座標と一致する正投影の z 座標を見つける必要があります。

を使用するgluProjectと、3 つの座標が返されます。Z座標は重要です。に与える zNear 値と zFar 値に基づいて Z 座標を逆変換する必要がありますglOrtho

辛辣な注意: gluProject Z 座標をウィンドウ空間に変換しません。そのためには、glDepthRangeパラメーターを取得する必要があります。実際には、near = 0.0 および far = 1.0 の深度範囲を想定しています。

したがって、最初のステップは、ウィンドウ空間 Z から正規化されたデバイス座標 (NDC) 空間 Z に変換することです。次の単純な方程式を使用します。

ndcZ = (2 * winZ) - 1

十分に単純です。次に、クリップ スペースに移動する必要があります。正投影では、W 座標は 1.0 であると想定されるため、これはノーオペレーションです。W で除算すると、クリップ スペースと NDC スペースの差になります。

clipZ = ndcZ

しかし、クリップ スペース Z は必要ありません。プレ正射投影スペース Z (別名: カメラ スペース Z) が必要です。これには、 に指定した zNear および zFar パラメータが必要ですglOrtho。カメラ空間に到達するには、次のようにします。

cameraZ = ((clipZ + (zFar + zNear)/(zFar - zNear)) * (zFar - zNear))/-2

これで完了です。レンダリングでその Z 位置を使用します。ああ、モデルビュー マトリックスに Z 方向の変換が含まれていないことを確認してください (モデルビュー マトリックスを使用してこの Z 位置をラベルに適用している場合を除きますが、これは問題ありません)。

于 2012-01-24T17:52:58.973 に答える
1

Nicol の回答に基づいて、単純に zNear を 0 に設定することができます (これは一般に、GUI の一部として機能する 2D 要素には意味があります)。

cameraZ = -winZ*zFar
于 2012-01-26T11:47:01.497 に答える