2011-07-31 18 views
2

私は飛行シミュレータを書いており、このジャンルの古典的な問題に悩まされていました。視錐台の近くの平面は、航空機の操縦席を見えるように近くになければなりません。遠方の平面は、最大40km。OpenGLでz-fightingの問題を取り除くには?

可視距離または近/遠の比率は、実際には、OpenGLのzバッファ精度の能力を超えており、遠くのオブジェクトは激しくちらつきます。これは、ファンシーな3Dエンジンがあなたの問題をあなたに残してくれる場所であり、あなたはopenglに関する本当の知識が必要です:)。おそらく私は問題を解決する正しい方法を見つけました(私が間違っているとOpenGLの専門家が私を修正します)が、私のソリューションは重要な問題を逃しています。変更されたレンダラは、二重パスレンダリング実行します。最初のパス遠くのオブジェクトで

  1. を、背景を表示することがあり、近くに飛行機が離れ、zバッファが幸せで、地形が良いが、近くの物体が離れてクリップさに見えます。
  2. 2番目のパスでは、投影行列が近距離オブジェクトに対して調整され、コックピットが表示されます。

未解決問題:すべての遠くの物体と背景が見えない第二のパスにおいては、それゆえ私はコックピットとその背後にある黒い背景を有します。第2パスの結果は、第1パスの結果を完全に無駄にする。 Ergoの計画オーバーレイは発生しません。質問: 2番目のパスでOpenGLが背景色を無視するようにして、両方の結果が目的のオーバーレイを作成するようにするには?

P.S.現状のイメージを示します(近/遠平面はすべての詳細を表示するための極端なもので、投影調整なしのシングルパスです)。

http://www.flickr.com/photos/[email protected]/5995604542/sizes/l/in/photostream/

バッファクリアレンダリングサイクルごとに一度だけ発生し、2回のパスの間には関与しません。ここでクリアコード:

JoglContext jctx = (JoglContext) ctx; 
GLContext context = context(ctx); 
GL gl = context.getGL(); 
// Mask of which buffers to clear, this always includes color & depth 
int clearMask = GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT; 
gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT); 
gl.glDepthMask(true); 
gl.glClearColor(r, g, b, jctx.getAlphaClearValue()); 
gl.glClear(clearMask); 
gl.glPopAttrib(); 

あなたが記述アプローチはまた、2回のパスで使用される:1.「遠距離」投影及び地形2.「近距離」と操縦室との間にはクリアが、第2の後コックピットの背後に背景を渡す黒です。おそらく、glDepthRange関数が役立ち、マニュアルをチェックする必要があります。

zバッファの深さは24ビットです。

答えて

6

2つのパスの間に画面を消去しないでください。デプスバッファをクリアしたいだけの場合は、デプスバッファからクリアしてください。 GL_COLOR_BUFFER_BITglClearに渡さないでください。

いずれにしても、すべてを再レンダリングする必要がないように、これを行うより良い方法は、適切な深度範囲を使用することです。あなたのコックピットはシーンと交差することができないので、シーンの奥行き範囲に描画する理由はありません。

まず、妥当な遠近法マトリックス(すなわち、z-近辺が相当に大きいもの、数フィート程度のオーダー)を使用してシーンを描画します。あなたのシーンはあなたのコックピットではありません。このレンダリングのglDepthRangeは、[0.05、1.0]のようなものでなければなりません。

その後、コックピットだけに合理的な視点マトリックスを使用してコックピットを描きます。このためのglDepthRangeは[0、0.05]です。これは、シーンと操縦席の両方のための深さのビットをたくさん与える必要があります。

ああ、24ビットの奥行きバッファを取得していることを確認してください。

+0

迅速な対応に感謝します.Nicol。私のコメントは時間がかかり、元の投稿に貼り付ける必要がありました。 glDepthRangeを詳しく見ていきます。 – Paul

2

コクピットと外側は、HUDとシーンのようなステンシルバッファの古典的なケースです。ステンシルの利点は、zを一切必要としないため、近くの面をもっと遠くに設定できることです。また、あなたが見ているWindowsは変わらない(コックピットの中であなたの仮想ヘッドを回転させる時を除いて)ので、それは一度の再利用である。

また、logarithmic zはお読みになることがあります。

+0

Damonありがとう、とても便利ですね!どのようにステンシルバッファ/ sb関数を適用するには、OpenGLの初心者のためのヒント? – Paul

+0

ステンシルは、あなたが何をする必要があるのか​​がすぐにわからないので、やや紛らわしいものです。さまざまなオプションがあります。主な機能[glStencilFunc](http://www.opengl.org/sdk/docs/man3/xhtml/glStencilFunc.xml)と[glStencilOp](http://www.opengl.org/sdk/docs/man3/) xhtml/glStencilOp.xml)。 'glStencilFunc'を使って実際のテスト(陰影付きフラグメントを破棄)し、' glStencilOP' _first_を使って実際にステンシルバッファの内容を定義します。 – Damon

+0

できるだけ安価なシェーダ(ライティング/テクスチャを無効にする!)でGL_REPLACEステンシルオペレーションを使用し、その後にGL_EQUALステンシル関数を使用したいと思うでしょう。コックピットを描くときにzバッファリングを使用すると、深度不合格のGL_KEEPもオプションになることがあります(帯域幅を節約できるかもしれません)。 – Damon

関連する問題