OpenGL 中小 alpha 值的错误混合

Wrong blending in OpenGL on small alpha value

我从纹理中绘制了很多白色的三角形。但是当它在黄色圆圈上绘制时,包含小 alpha 值(但不等于 0)的点混合错误,我在屏幕上得到一些较暗的像素(见屏幕截图,它被放大了)。哪个可能是问题? 蓝底一切正常

正如@tklausi 在评论中指出的那样,此问题与结合传统 alpha 混合的纹理插值有关。在从具有高 alpha 的值过渡到具有 alpha=0 的 "background" 时,您将得到一些插值结果,其中 alpha > 0,并且 RGB 与您的 "background" 颜色混合。

@tlkausi 的解决方案是将背景的 RGB 值更改为白色。但这会导致与以前相同的问题:如果您的实际图像颜色较暗,那么您会在其周围看到明亮的伪像。

正确的解决方案是重复实际边框像素的 RGB 颜色,这样插值将始终产生相同的颜色,只是具有较低的 alpha 值。

但是,有一个更好的解决方案:预乘 alpha。 您不是在每个像素的纹理中存储 (R,G,B,a),而是存储 (aR,aG,aB,a)。混合时,不使用 a*source + (1-a) * background,而只使用 source + (1-a)*background。不同之处在于您现在有一个 "neutral element" (0,0,0,0) 并且对其进行插值不会造成任何问题。它与过滤配合得很好,也适用于 mipmap 和其他技术。

一般来说,我建议总是使用预乘alpha而不是"traditional"。预乘可以直接应用于图像文件,或者您可以在纹理上传时进行,但它根本不会产生运行成本。

可以找到有关预乘 alpha 的更多信息in this MSDN blog article or over here at NVIDIA