OpenGL alpha混合突然停止

时间:2014-08-28 11:54:56

标签: c++ opengl glsl

我正在使用OpenGL将屏幕尺寸四边形绘制到每个帧上具有低alpha(小于0.1)的相同位置,而它们之间没有glClear(GL_COLOR_BUFFER_BIT)。这样四边形应该越来越多地抑制前一帧图形的可见性。

然而,阻尼效果在几秒钟后停止。如果我对四边形使用不低于0.1的alpha值,它会按预期工作。在我看来,OpenGL混合方程经过多次迭代后失败(更高的alpha值需要更少的迭代来累积到1,所以如果alpha >= 0.1问题没有发生)。 8位的alpha下限约为0.0039,即1/255,因此alpha 0.01应该没问题。

我尝试了几种混合设置,使用以下渲染方法:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClear(GL_DEPTH_BUFFER_BIT);
// draw black quad with translucency (using glDrawArrays)

简单片段着色器:

#version 450

uniform vec4 Color;
out vec4 FragColor;

void main()
{
    FragColor = Color;
}

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:4)

  

在我看来,OpenGL混合方程在一个数字之后失败了   迭代次数(较高的alpha值需要较少的迭代才能累积   到1,所以如果alpha> = 0.1,则不会出现问题)。的下限   8位的alpha大约是0.0039(1/255),所以alpha 0.01应该是   细

你的推理在这里是错误的。如果您绘制alpha为0.01的黑色四边形以及您描述的混合设置,则每次迭代基本上都会获得new_color = 0.99 * old_color。作为迭代编号i的函数,它将是new_color(i) = original_color * pow (0.99,i)。现在无限精度,这将朝着0。

但正如您已经指出的那样,精确度并非无限制。每一步都会得到重新量化。因此,如果您的new_color颜色值不低于整数值的阈值,它将保持与之前相同。现在,如果我们考虑x范围[0,255]中的非均匀颜色值,并且我们假设量化只是通过通常的舍入规则来完成,那么我们必须得到至少0.5的差值才能获得不同的值: x - x * (1-alpha) > 0.5,或只是x > 0.5 / alpha

所以在你的情况下,你得到x> 50,这就是混合会“停止”的地方(下面的所有东西都会保持原样,所以你得到了黑暗部分的“阴影”)。对于0.1的alpha,它将在x = 5处结束,这可能接近零而你没有注意到它(使用你的特定显示和设置)。

修改

让我推荐一款能够奏效的怯懦。您必须避免迭代compontation(至少使用非浮点帧缓冲区)。你想实现淡出黑色效果。因此,您可以将原始内容渲染为纹理,并一遍又一遍地渲染,同时通过逐帧更改alpha值将其混合为黑色,因此您最终将alpha作为时间(或帧编号)的函数)。使用线性过渡可能最有意义,但你甚至可以使用一些非线性函数来减慢淡出,因为你的原始方法具有无限精度。

请注意,您根本不需要混合,只需将纹理中的颜色值与片段着色器中的某些统一“alpha”值相乘即可。