【问题标题】:How to handle alpha compositing correctly with OpenGL如何使用 OpenGL 正确处理 Alpha 合成
【发布时间】:2013-10-24 02:56:05
【问题描述】:

我正在使用 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 进行 alpha 撰写,正如文档所述(实际上,在 Direct3D 文档中也说了同样的话)。

一开始一切都很好,直到我从 GPU 下载结果并将其制作为 PNG 图像。结果 alpha 分量是错误的。在绘图之前,我已经用不透明的黑色清除了帧缓冲区。在我画了一些半透明的东西之后,帧缓冲区变成了半透明的。

【问题讨论】:

    标签: opengl alpha


    【解决方案1】:

    嗯,原因很明显。使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA),我们实际上忽略了目标 Alpha 通道并假设它始终为 1。当我们将帧缓冲区视为不透明的东西时,这是可以的。

    但是如果我们需要正确的 alpha 值怎么办? glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) 并使源预乘(预乘纹理/顶点颜色或将 alpha 分量与 alpha 分量相乘,然后将其设置为 gl_FragColor)。

    glBlendFunc 只能将原始颜色分量乘以一个因子,但 alpha 合成需要目标与 one_minus_src_alphadst_alpha 相乘。所以它必须是预乘的。我们不能在帧缓冲区中进行预乘,但只要源和目标都预乘,结果就是预乘。也就是说,我们首先用任何预乘颜色清除帧缓冲区(例如:0.5, 0.5, 0.5, 0.5 表示 50% 透明白色而不是 1.0, 1.0, 1.0, 0.5),然后用glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) 在其上绘制预乘片段,我们将有正确的 alpha 通道结果。 但如果最终结果不需要预乘,请记住撤消预乘

    【讨论】:

    • 另一个需要考虑的重要事项:您的帧缓冲区是否甚至有目标 alpha 位平面?这不是一种常见的像素格式,信不信由你。通常你会得到类似 RGBx8(x 表示忽略)、Depth:Stencil (24:8) 之类的东西,除非你明确要求 RGBA。你会认为这很明显,但由于一般 alpha 混合不需要目标 alpha,人们经常忽略这一点......
    • 您可以使用 glBlendFuncSeparate 为 rgb 和 alpha 指定单独的混合函数,这将允许您获得正确的 alpha 值进行合成,而无需使用预乘 alpha。
    • @rdb,我对您提到的 glBlendFuncSeparate 的示例感兴趣。您能否提供此方法的典型值?
    • @mgouin 例如:glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
    • @rdb:这是不正确的。要正确混合到 RGBA 帧缓冲区中,您需要在混合后将目标 RGB 除以目标 A,但是 OpenGL 混合模式都不允许这样做。
    猜你喜欢
    • 2018-01-28
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多