2011-08-02 3 views
0

http://www.opengl.org/wiki/Rendering_Pipeline_Overviewは、ジオメトリシェーダが実行され、フラグメントがラスタライズされる前に、「表示ボリュームの内側と外側の境界にあるプリミティブが複数のプリミティブに分割されている」と述べています。私がOpenGLについて読んだことのあるものは、同じようにクリッピングプロセスについても説明しています。しかし、フラグメントシェーダのgl_FragDepthを、それを生成した三角形上のポイントの実際の深さよりもカメラに近い値に設定することで(固定小数点をコピーした場合にフラグメントがデプステストに合格するように、パイプラインの機能性)、私は、たとえそれが遠くの表示面と部分的に重なっていても、オリジナルの三角形全体に対してフラグメントが生成されていることを発見しています。一方、すべての頂点が平面の後ろにある場合は、三角形全体がクリップされ、フラグメントシェーダにフラグメントが送信されません(私は、それが切り捨てられ、切り捨てられないと言うよりも技術的にはそうです)。ジオメトリシェーダのOpenGLクリッププリミティブが、部分的にビューボリューム外にあるのはなぜですか?

ここでは何が起こっていますか?ジオメトリシェーダがデフォルトの機能を置き換えていますか?レンダリングパイプラインの次のステップで部分的なクリッピングを行う方法を知るために、書き込む必要のあるフラグやヒントが必要ですか?

私はNVIDIA GeForce 9400MでGL_EXT_geometry_shader4拡張機能を備えたGLSLバージョン1.2を使用しています。

答えて

0

ドライバのバグのようです。表示領域外にあるはずのフラグメントの結果が表示された場合(つまり、深さの書き込みをオフにするとフラグメントが完全に消滅する場合)、これは仕様の動作とは異なります。

私は誰もそれについて何もしないと思うようなコーナーケースです。

ほとんどのグラフィックスハードウェアは、実際には三角形をクリッピングすることを避けるため、可能な限りハードにしようとします。三角形をクリッピングすると、単一の三角形から三つの三角形を生成する可能性があります。それはパイプラインを詰まらせる傾向があります(どんな速度でも事前テッセレーション)。したがって、三角形が単純に拒否されない限り(すなわち、クリップボックスの外に)、または信じられないほど大きなモダンなGPUはそれを無視します。彼らは、ハードウェアを破棄しているフラグメントがそれを処理するようにします。

この場合、フラグメントシェーダは深度ライティングシェーダであるため、フラグメントシェーダが終了するまでそれらのフラグメントを拒否できないと考えています。


注:私はあなたが深クランプをオンにした場合、それは近くと遠く完全をクリッピングオフにしていることに気づきました。それはあなたが望むものかもしれません。フラグメントシェーダから書き込まれたデプス値は、現在のglDepthRangeにクランプされます。

デプスクランプはOpenGL 3.2の機能ですが、NVIDIAは10年近くNV_depth_clampでサポートしています。あなたのドライバが最近のものであれば、あなたは3.2の互換性の文脈を得なくてもARB_depth_clampを使うことができます。

+0

ここで正しく私があなたを理解していることを確認したいだけです。クリッピングが発生したはずですが、フラグメントシェーダで深さの書き込みが発生します。それらがフラグメントシェーダに入ると、私は好きな深さの値を設定でき、私が期待するように動作します。予期せぬ動作は、最初にフラグメントシェーダに移動すべきでない事前処理されたフラグメントが、とにかくそこにあるということです。 – Kyle

+0

私は、通常のパイプラインでは、クリッピングによって削除されるフラグメントは、クリッピングされていないと深さテストに失敗するため、破棄されても差がないことを理解しています(ただし、フラグメントプロセッサ用のものもあります)が、実際には深度値を変更したい場合がありますか?たとえば、深さに忠実な詐称者を作成するために必要です。 – Kyle

+0

@ Kyle:遠くのクリッププレーンまたは近くのクリッププレーンと交差する深度で_and_を書くときにのみ問題が表示されるため、コーナーケースと呼んでいます。だから、あなたは近くに/遠くにぶつかり、深みのある執筆をする必要があります。とにかく、カメラの位置を合わせる傾向があるので、三角形が完全にビューの外側にあるか、まったくビューの外側にないかのどちらかです。その行動の理由はコメントには大きすぎるので、私は自分の答えを編集します。 –

-1

私はあなたを正しく理解していれば、あなたの三角形は遠くの平面には挟まれていないのだろうか?
Afaik OpenGLは、頂点アセンブリ後に4つのボーダープレーンにクリップするだけです。フラグメントシェーダの後で、farとnearのクリッピングが行われます(spec afaikによって)。つまり、極端にズームインすると、ポリゴンが近い面に衝突して、その点にレンダリングされ、全体として飛び出さないようにします。
そして、スペックはプリミティブの分割に気づいていないと思います。(たとえhwがfragdepthを無視しても画面空間でそれを行うかもしれませんが)プリミティブ全体をスキップするだけです。(ビューの錐台に頂点がない場合)。
また、単語厳密な規則のためにwikiに依存することは、常に悪い考えです。

PS:http://fgiesen.wordpress.com/2011/07/05/a-trip-through-the-graphics-pipeline-2011-part-5/は実際のボーダーを示しており、近くでは非常に良好なクリッピングの&に近いものです。

+0

-1:正しくありません。 OpenGL 3.3コア仕様のセクション2.19 "プリミティブクリッピング"の最初の段落では、 "プリミティブは_view volume_にクリップされます。クリップ座標では、_view volume_はで定義されます。"これには、クリップ空間W(透視分割後は[-1、1])に基づくX、Y、** Z **クリッピングディメンションが続きます。ですから、OpenGL仕様では、表示ボリュームのほぼすべての次元に対してクリッピングが発生することが明確に述べられています。 –

+0

PS:この記事では、_Direct3D_がクリッピングを定義する方法を指定しています。 –

+0

さて、OpenGLはクリッピングや新しい頂点の生成に関して非常に特化しています。それでも、実際のGPUとは異なります。ええ、彼らは仕様に違反するかもしれません。しかし、現時点では視覚的な違いはありませんでした。現在は、変換フィードバックを使用して実際の最終頂点ストリームを取得したり、フラグメントシェーダのフラグメント深度をオーバーライドしたり、フラグメントシェーダのバッファに書き込んだりできます。また、記事/ブログがD3D10/11を念頭に置いて書かれていても、実際のGPU /ドライバの内容をよく説明しています。 – jKei

関連する問題