18

次の概念に従って、OpenGLにマスキングを実装しました。

  • マスクは黒と白の色で構成されています。
  • 前景のテクスチャは、マスクの白い部分にのみ表示されます。
  • 背景テクスチャは、マスクの黒い部分にのみ表示されます。

glBlendFunc()を使用すると、白い部分または黒い部分を想定どおりに機能させることができますが、前景レイヤーがマスクだけでなく背景レイヤーにも溶け込むため、2つを同時に使用することはできません。

これを最善の方法で達成する方法を知っている人はいますか?私はネットを検索していて、フラグメントシェーダーについて何かを読んでいます。これは行く方法ですか?

4

2 に答える 2

43

これは機能するはずです:

glEnable(GL_BLEND);
// Use a simple blendfunc for drawing the background
glBlendFunc(GL_ONE, GL_ZERO);
// Draw entire background without masking
drawQuad(backgroundTexture);
// Next, we want a blendfunc that doesn't change the color of any pixels,
// but rather replaces the framebuffer alpha values with values based
// on the whiteness of the mask. In other words, if a pixel is white in the mask,
// then the corresponding framebuffer pixel's alpha will be set to 1.
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ZERO);
// Now "draw" the mask (again, this doesn't produce a visible result, it just
// changes the alpha values in the framebuffer)
drawQuad(maskTexture);
// Finally, we want a blendfunc that makes the foreground visible only in
// areas with high alpha.
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
drawQuad(foregroundTexture);

これはかなりトリッキーなので、不明な点があれば教えてください。

GLコンテキストを作成するときに、アルファバッファを要求することを忘れないでください。それ以外の場合は、アルファバッファなしでコンテキストを取得することが可能です。

編集:ここでは、イラストを作成しました。 図

編集:この答えを書いて以来、私はこれを行うためのより良い方法があることを学びました:

  • OpenGLの固定機能パイプラインに制限されている場合は、テクスチャ環境を使用してください
  • シェーダーを使用できる場合は、フラグメントシェーダーを使用してください。

この回答で説明されている方法は機能し、これら2つの優れたオプションよりもパフォーマンスが特に悪くはありませんが、エレガント性と柔軟性が劣ります。

于 2011-02-24T00:21:43.580 に答える
0

ステファンモノフは素晴らしい答えです!しかし、彼の答えを機能させるのにまだ問題がある人のために:

  1. GLES20.glGetIntegerv(GLES20.GL_ALPHA_BITS、ib)をチェックする必要があります-ゼロ以外の結果が必要です。
  2. 0を取得した場合-EGLConfigに移動し、アルファビットを渡すようにします

    EGL14.EGL_RED_SIZE, 8,
    EGL14.EGL_GREEN_SIZE, 8,
    EGL14.EGL_BLUE_SIZE, 8,
    EGL14.EGL_ALPHA_SIZE, 8, <- i havn't this and spent a much of time
    EGL14.EGL_DEPTH_SIZE, 16,
    
于 2020-02-11T12:28:49.803 に答える