OpenGL – 具有多个纹理的遮罩

我已经根据以下概念在OpenGL中实现了遮罩:

  • 面具由黑色和白色组成。
  • 前景纹理只能在蒙版的白色部分可见。
  • 背景纹理应该只在遮罩的黑色部分可见。

我可以使用glBlendFunc()来设置白色部分或黑色部分,但不是同时使用这两个部分,因为前景层不仅可以混合到蒙版上,还可以混合到背景层上。

有没有人知道如何以最好的方式完成这个任务? 我一直在寻找networking并阅读有关片段着色器的内容。 这是要走的路吗?

这应该工作:

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); 

这是相当棘手的,所以告诉我,如果有什么不清楚。

创buildGL上下文时不要忘记请求一个alpha缓冲区 。 否则,有可能获得没有alpha缓冲区的上下文。

编辑:在这里,我做了一个例子。 插图

编辑:由于写这个答案,我知道有更好的方法来做到这一点:

  • 如果您仅限于OpenGL的固定functionpipe线,请使用纹理环境
  • 如果您可以使用着色器,请使用片段着色器。

在这个答案中描述的方式是有效的,在性能方面并没有比这两个更好的选项更糟糕,但是不够优雅和不太灵活。