在 OpenGL 中绘制到半透明帧缓冲区时如何抗锯齿?

How to antialias when drawing to semitransparent frame buffers in OpenGL?

我目前正在学习 OpenGL 并尝试制作一个简单的 GUI。到目前为止,我对着色器知之甚少,也没有使用过。

我用来加速文本渲染的技巧之一是在将文本四边形渲染到屏幕之前将它们渲染到透明的帧缓冲区对象。加速是显着的,但我注意到文本的边缘绘制不佳。然后我注意到,如果我将透明纹理设为另一种透明颜色,那么文本将与该颜色混合。在我渲染为透明绿色纹理的示例中:

我使用以下参数进行混合:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE)

默认使用 glBlendEquation (GL_ADD)。

我对文档的理解是,每个像素都通过一个等式发送 source_rgb * blend_factor + dest_rgb * blend_factor

我通常希望,当纹理透明时,混合两侧的 RGB 被忽略,所以如果可以的话,我会用类似的方程式计算 rgb:

source_rgb * source_alpha / total_alpha + dest_rgb * dest_alpha / total_alpha

其中 total_alpha 是 alpha 的总和。似乎不支持。

有什么东西可以帮助我减轻头痛吗?我乐于接受建议,从修复到重写所有内容,再到使用已经完成的库。

完整的源代码可用 here 如果您有兴趣。如果您需要相关摘录,请告诉我。

编辑:我之前确实尝试过从我的 alpha 混合中删除 GL_ONE、GL_ONE 并简单地对 RGBA 使用 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA),但结果也不是很好。我得到了类似的结果。

按照建议使用预乘解决了问题。

首先,total_alpha 不是 alpha 的总和,而是以下各项:

total_alpha = 1 - (1 - source_alpha)*(1 - dest_alpha)

正如您正确指出的那样,OpenGL 不支持最后除以 total_alpha。但它不需要。您所需要的只是转换为根据 预乘 alpha 进行思考和工作。有了这个简单的

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)

做正确的事。