3

我正在尝试创建一个“雾中的洞”效果。我有一个背景网格图像,重叠在上面我有一个“雾”纹理,用于显示某些区域不在视图中。我正在尝试从“雾”中切出一大块,以显示当前可见的区域。我试图“掩盖”屏幕上的一部分雾。

我制作了一些图片来帮助解释我所追求的:
背景:

BG

“蒙版图像”(完全透明必须在内部而不是外缘,因为我将使用它):

面具

雾(抱歉,很难看到......大部分是透明的):

多雾路段

我想要的最终产品:

完成品

我试过了:

  • Stencil-Buffer:除了一个事实外,我完全可以正常工作......我无法弄清楚如何保留“蒙版”图像的褪色透明度。
  • glBlendFunc:我尝试了许多不同版本的参数和许多其他方法(glColorMask、glBlendEquation、glBlendFuncSeparate)我首先使用了我在这个网站上找到的一些参数:here。我使用了“glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);” 因为这似乎是我一直在寻找的但是......这就是最终发生的结果:(很难说这里发生了什么,但是......背景中有雾覆盖网格。虽然,当它应该是雾中的透明部分时,面具只是最终成为一个完全不透明的黑色斑点。
    glBlendFunc 的结果

之前的一些代码:

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.

(我会发布更多代码,但在我尝试了很多东西之后,我开始删除一些旧代码,因为它变得非常混乱(我在块评论中“支持它们”))

4

2 回答 2

3

这是可行的,前提是您当前没有对帧缓冲区的alpha进行任何操作。

第 1 步:确保帧缓冲区的 alpha 被清除为零。因此,您的 glClearColor 调用需要将 alpha 设置为零。然后像往常一样调用 glClear 。

第 2 步:在绘制“雾”之前绘制蒙版图像。正如蒂姆所说,一旦你融入了你的迷雾,你就无法撤消它。所以你首先需要那里的掩码数据。

但是,您还需要专门渲染蒙版。您希望掩码修改帧缓冲区的 alpha。您不希望它与 RGB 颜色混淆。为此,请使用此功能:glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE). 这将关闭对颜色的 RGB 部分的写入;因此,只有 alpha 会被修改。

您的蒙版纹理在可见的地方似乎为零,而在不可见的地方似乎为零。但是,算法需要相反,因此您应该修复纹理或使用glTexEnv有效翻转 alpha 的模式。

在这一步之后,您的帧缓冲区应该有一个 0 的 alpha 值,我们希望看到雾,而我们不希望看到的 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(以防万一您想要渲染多于一层的雾)。

你完成了。

于 2012-06-06T11:22:41.857 回答
1

您当前采用的方法将不起作用,因为一旦您在整个屏幕上绘制雾,就无法“擦除”它。

如果您使用的是固定管道:

您可以使用具有固定管道的多重纹理 (glTexEnv) 将雾纹理和圆形纹理组合在一个通道中。如果您以前没有使用过此功能,可能会有些困惑,您可能需要花一些时间研究手册页。您将执行一些操作,例如将雾绑定到 glActiveTexture 0,将掩码绑定到 glActiveTexture 1,启用多重纹理,然后将它们与 glTexEnv 组合。我不记得完全正确的参数。

如果您使用着色器:

使用多纹理着色器,将雾 Alpha 与圆形纹理相乘(将圆形区域中的 Alpha 置零),然后将这个组合纹理一次性混合到背景中。这可能是一种概念上更简单的方法,但不确定您是否使用着色器。

我不确定有没有一种方法可以在单独的通道中绘制雾和蒙版,因为它们都有自己的 alpha 值,很难将它们组合起来以获得正确的颜色结果。

于 2012-06-06T08:17:09.840 回答