我试图创造一个“雾中洞”效果。我有一个背景网格图像,重叠到我有一个“雾”纹理,我用来表明某些区域不在视野中。我试图从“雾”中切出一块,这将显示当前正在查看的区域。我试图“屏蔽”屏幕上的一部分雾。
我制作了一些图片来帮助解释我的目标:
背景:
“Mask Image”(完全透明度必须在内部,而不是外边缘,以便我将使用它):
雾(对不起,很难看到......大部分是透明的):
我想要的最终产品:
我试过了:
以前的一些代码:
glEnable(GL_BLEND); // This is not really called here... It is called on the init function of the program as it is needed all the way through the rendering cycle.
renderFogTexture(delta, 0.55f); // This renders the fog texture over the background the 0.55f is the transparency of the image.
glBlendFunc(GL_ZERO, GL11.GL_ONE_MINUS_SRC_ALPHA); // This is the one I tried from one of the many website I have been to today.
renderFogCircles(delta); // This just draws one (or more) of the mask images to remove the fog in key places.
(我会发布更多代码,但在我尝试了很多东西之后,我开始删除一些旧代码,因为它变得非常混乱(我在块注释中“支持它们”))
答案 0 :(得分:2)
如果您当前没有对帧缓冲区的 alpha 做任何事情,这是可行的。
第1步:确保将帧缓冲区的alpha清除为零。所以你的glClearColor调用需要将alpha设置为零。然后正常调用glClear。
第2步:在绘制“雾”之前绘制蒙版图像。正如蒂姆所说,一旦你与雾混合,就无法撤消。所以你首先需要掩码数据。
但是,您还需要专门渲染蒙版。你只希望掩码修改帧缓冲区的alpha。你不希望它弄乱RGB颜色。为此,请使用此功能:glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE)
。这将关闭对RGB部分颜色的写入;因此,只会修改alpha。
你的面具纹理在可见的地方看起来是零,而在它看不到的地方。但是,算法需要相反,因此您应该修复纹理或使用有效翻转alpha的glTexEnv
模式。
在此步骤之后,你的帧缓冲区应该有一个alpha值为0,我们想要看到雾,而alpha值为1,我们不想看到。
另外,在渲染蒙版后,不要忘记撤消glColorMask
调用。你需要恢复这些颜色。
第3步:渲染雾。这很容易;要进行遮罩工作,您需要一种特殊的混合模式。像这样:
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ZERO, GL_ONE);
RGB和A混合部分之间的分离很重要。你不想更改帧缓冲区的alpha(以防你想要渲染多层雾)。
你已经完成了。
答案 1 :(得分:1)
你正在采取的方法是行不通的,因为一旦你在整个屏幕上画了雾,就没有办法“抹掉”它。
如果您使用固定管道:
您可以将多纹理(glTexEnv)与固定管道结合使用,在一次通过中组合雾和圆纹理。如果您以前没有使用它,这个功能可能有点令人困惑,您可能不得不花一些时间研究手册页。您将执行类似绑定雾到glActiveTexture 0的操作,并屏蔽到glActiveTexture 1,启用多重纹理,然后将它们与glTexEnv组合。我不记得确切的正确参数。
如果您正在使用着色器:
使用多纹理着色器,将雾alpha与圆形纹理相乘(将圆形区域中的alpha置零),然后在单次传递中将此组合纹理混合到背景中。这可能是一种概念上更简单的方法,但不确定您是否使用着色器。
我不确定你是否有办法在单独的传递中绘制雾和蒙版,因为它们都有自己的alpha值,很难将它们组合起来以获得正确的颜色结果。