OpengL Light Blending

时间:2014-02-20 22:16:00

标签: opengl rendering alphablending blending

我正在使用Java和LWJGL为我的游戏编写Lights / Shadows系统。对于每个发光实体,我生成这样的纹理:

Blue Light with Shadows Red Light with Shadows

我应该警告你,这些纹理充满了(0,0,1)或(1,0,0)个像素,并且使用alpha通道实现了渐变效果。我将Alpha通道解释为梯度因子。

之后,我希望将每个光/阴影纹理混合在一个纹理上,每个纹理位于相应的正确位置。为此,我使用了Framebuffer。我尝试使用以下混合方程式/函数组合来实现所需效果:

glBlendEquationSeparateEXT(GL_FUNC_ADD, GL_MAX);
glBlendFuncSeparateEXT(GL_SRC_ALPHA, GL_DST_ALPHA, GL_ONE, GL_ONE);

我选择GL_ONE / GL_ONE作为Alpha通道混合功能,因为GL_MAX只会执行最大值(Sa,Da),如here所述,这意味着不使用缩放因子。这种组合的结果如下: Blended Lights/Shadows 这张图片是用Apple的OpenGL Driver Profiler获得的,所以我没有使用我的应用程序渲染它(这可能会弄乱最终结果)。下一步是使用乘法混合在实际游戏中渲染此纹理,以使图像变暗,但是灯光/阴影纹理显然是错误的,因为我们可以看到各个光/阴影纹理的边缘相互重叠

我应该如何才能达到预期的效果?

修改 我忘了解释我对缩放因子的选择: 我认为简单地添加每个光的颜色(用它们各自的alpha值思考每个光的颜色)是正确的,并选择最终片段的alpha作为每个重叠光的最大值。

1 个答案:

答案 0 :(得分:1)

想象一下,你的一个纹理矩形在其当前边界之外延伸了一些任意图案,如纯绿色。想象一下,我们以某种方式允许使用两种不同的混合功能,一种在边界内,一种在外面。如果在边界外使用混合函数

,您将获得与此处相同的图像(没有绿色显示)
glBlendFuncSeparateEXT(GL_ZERO, GL_ONE, GL_ONE, GL_ONE)

然后我们想要我们在里面使用的任何混合函数给我们一个连续的混合结果。混合功能

glBlendFuncSeparateEXT(GL_SRC_ALPHA, GL_DST_ALPHA, GL_ONE, GL_ONE)

不会给我们这样的结果。这不是因为第一个参数意味着忽略边界附近的源(边界上的小alpha,如果我正确读取你的图像描述)。所以它必须是第二个参数。我们只在源alpha很小时才想要目的地。将GL_DST_ALPHA更改为GL_ONE_MINUS_SRC_ALPHA。这会更标准,但也许我不了解你的目标?