我根据以下概念在 OpenGL 中实现了遮罩:
- 面具由黑色和白色组成。
- 前景纹理应该只在蒙版的白色部分可见。
- 背景纹理应该只在蒙版的黑色部分可见。
我可以使用 glBlendFunc() 使白色部分或黑色部分按预期工作,但不能同时使用两者,因为前景层不仅融合到蒙版上,还融合到背景层上。
有没有人知道如何以最好的方式做到这一点?我一直在网上搜索并阅读有关片段着色器的内容。这是要走的路吗?
这应该有效:
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 上下文时不要忘记请求一个 alpha 缓冲区。否则,可以在没有 alpha 缓冲区的情况下获得上下文。
编辑:在这里,我做了一个插图。
编辑:自从写了这个答案,我了解到有更好的方法来做到这一点:
此答案中描述的方式有效,并且性能并不比这两个更好的选项特别差,但不太优雅且不太灵活。
Stefan Monov 的回答很好!但是对于那些仍然有问题让他的答案起作用的人:
如果你得到 0 - 转到 EGLConfig 并确保你传递了 alpha 位
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,