1. ホーム
  2. オープングラム

[解決済み] OpenGL - glDepthMaskの使い方についての質問です。

2022-03-03 14:23:19

質問

以下のようなシーンで、あるオブジェクトAをレンダリングしています。このシーンには、他にも多くのオブジェクトがあります。

void Draw()
{    
    if( glIsList( displayListID ) )
    {
        glPushAttrib( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT );

        glEnable( GL_BLEND );
        glEnable( GL_DEPTH_TEST );
        //glDepthMask( GL_FALSE );
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

        glEnable( GL_LINE_SMOOTH );
        glEnable( GL_POINT_SMOOTH );
        glEnable( GL_POLYGON_SMOOTH );

        glMatrixMode( GL_MODELVIEW ); 

        color.setAlpha(alpha); // set alpha transparent of this objectA
        glCallList( displayListID );

        //glDepthMask( GL_TRUE );
        glDisable( GL_BLEND );  

        glPopAttrib();
    }
}

さて、ここで問題です。

図のように、2つの行をコメントアウトしています。 //glDepthMask( GL_FALSE ); //glDepthMask( GL_TRUE );

を実行すると、objectA やその他のオブジェクトが正しく深度レンダリングされます。しかし objectA のアルファ値の変更がうまくいかなくなりました(例:color.setAlpha(alpha) )。

上の2行のコメントを外すと、アルファの修正が機能するようになります。しかし、深度レンダリングは正しくありません。つまり、objectAが他のオブジェクトの後ろにあるべきなのに、objectAがすべてのオブジェクトの前にあるように見えることがあるのです。

どうすればこの問題を解決できますか?

ありがとうございました

解決方法は?

  1. ターン オン デプスマスク glDepthMask( GL_TRUE )
  2. すべての不透明なオブジェクトを任意の順序で描画する
  3. デプスマスクをオフにする glDepthMask( GL_FALSE )
  4. をオンにします。 BLEND_MODE
  5. 半透明オブジェクトをソートして描画 最も遠い から 最も近い

なぜこのようなことをするのですか?

心配する必要のあるバッファは2つあります。 深度バッファ カラーバッファ . これらのバッファは、実際には大きな2次元配列で、それぞれ画面の幅×高さです。

その カラーバッファ は、当然ながら各ピクセルの最終的な色調を保持することになる。 カラーバッファには、1画面ピクセルにつき1つのエントリーがあります。 そのため デプスバッファ は、1画面ピクセルにつき1つのエントリーがあるという点ではカラーバッファと同じですが、異なる用途に使われます。 のエントリは 深度バッファ は、各色画素が実際にどの程度近いかを示す尺度です。

カメラから遠くにある1つの三角形をレンダリングすると、画面上でカバーしたい各ピクセルに対して、色と深度の値のセットが生成されます。次に、より近くにある別のポリをレンダリングすると、これも深度とカラーバッファの値のセットを生成します。 ここで、ピクセル着色時に一種のコンテストが発生し、「遠くのフラグメント」(大きな深度バッファ値)は破棄され、「近くのフラグメント」だけが保持されます。 近いフラグメントは、あなたが持っていたピクセルの色付けを終了します。 (2つのポリゴンがほぼ重なっている場合。 Zファイトが発生することがある )

まず、深度マスクをオンにして、シーン内のオブジェクトをレンダリングします。 つまり、レンダリングするすべての形状は、そのピクセルに色が付くと、深度バッファはコンテストの勝者で更新されます。

次に、3) glDepthMask( GL_FALSE ) 回る オフ 深度バッファに書き込む、4) ブレンドをオンにする、5) 遠いものから近いものへ半透明の図形をレンダリングする。 変な感じでしょう?

深度マスクをオフにして、半透明な図形をレンダリングすると、OpenGLはまだ 読む 深度バッファを使用して、どのフラグメントを捨てるかを決定します(つまり、半透明の形状がすでにレンダリングされたソリッド形状の背後にある場合、その半透明形状のフラグメントを捨てます)。 しかし、それは はしません。 は深度バッファに書き込むので、半透明の図形が本当に本当に近くにある場合 (例えば半透明のフロントガラスのような)。 そのフロントガラスの破片は、実際にはもっと遠くにある他の破片が描かれるのを妨げない。 . これは重要なことで、フロントガラスが目の前にあって、それを半透明にレンダリングした場合。 なぜなら、OpenGLは、「おい、このフロントガラスだけが、深度バッファの読み取りのために、ユーザーに見えるべきものだ、だから、このフロントガラスより遠くにあるものは、わざわざレンダリングしないぞ」と考えるからです。 深度マスクをオフにすることは、非常に近いが半透明な断片があることをOpenGLに知られないようにする方法です。