OpenGL - 具有多个纹理的蒙版

red*_*red 16 c++ opengl blending mask

我已根据以下概念在OpenGL中实现了屏蔽:

  • 面具由黑色和白色组成.
  • 前景纹理应仅在蒙版的白色部分中可见.
  • 背景纹理应仅在蒙版的黑色部分中可见.

我可以通过使用glBlendFunc()使白色部分或黑色部分工作,但不能同时使用两个,因为前景层不仅混合到蒙版上,而且还混合到背景层上.

有没有人知道如何以最好的方式实现这一目标?我一直在网上搜索片段着色器.这是要走的路吗?

Ste*_*nov 38

这应该工作:

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);
Run Code Online (Sandbox Code Playgroud)

这是相当棘手的,所以告诉我是否有任何不清楚的地方.

创建GL上下文时,不要忘记请求alpha缓冲区.否则,可以获得没有alpha缓冲区的上下文.

编辑:在这里,我做了一个插图. 插图

编辑:自从写完这个答案后,我了解到有更好的方法可以做到这一点:

  • 如果您仅限于OpenGL的固定功能管道,请使用纹理环境
  • 如果可以使用着色器,请使用片段着色器.

这个答案中描述的方式有效,并且在性能上并不比这两个更好的选项更差,但是不太优雅且不够灵活.