gpt4 book ai didi

opengl - 与帧缓冲区的先前内容混合

转载 作者:行者123 更新时间:2023-12-03 13:41:45 25 4
gpt4 key购买 nike

我正在通过帧缓冲区对象渲染到纹理,当我绘制透明图元时,这些图元与在该单个绘制步骤中绘制的其他图元正确混合,但它们没有与帧缓冲区的先前内容正确混合。

有没有办法将纹理的内容与传入的新数据正确混合?

编辑:要求提供更多信息,我将尝试更清楚地解释;

我使用的混合模式是 GL_SRC_ALPHA、GL_ONE_MINUS_SRC_ALPHA。 (我相信这通常是标准的混合模式)

我正在创建一个跟踪鼠标移动的应用程序。它绘制将前一个鼠标位置连接到当前鼠标位置的线条,并且由于我不想在每一帧中再次绘制线条,我想我会绘制到纹理,从不清除纹理,然后用它绘制一个矩形纹理上显示它。

这一切都很好,除了当我在纹理上绘制 alpha 小于 1 的形状时,它不能与纹理的先前内容正确混合。假设我在纹理上绘制了一些带有 alpha = .6 的黑线。几个绘制周期后,我在这些线上绘制一个 alpha = .4 的黑色圆圈。圆圈“下方”的线条被完全覆盖。尽管圆圈不是纯黑色(它与白色背景正确融合),但圆圈下方没有您所期望的“暗线”。

但是,如果我在同一帧中绘制线条和圆圈,它们会正确融合。我的猜测是纹理与之前的内容不融合。就像它只与 glclearcolor 混合一样。 (在这种情况下是 <1.0f, 1.0f, 1.0f, 1.0f>)

最佳答案

用透明黑色 (0, 0, 0, 0) 清除 FBO,用

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

并绘制 FBO
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

得到准确的结果。

正如 Ben Supnik 所写,FBO 包含的颜色已经与 alpha channel 相乘,因此不再使用 GL_SRC_ALPHA 进行此操作,而是使用 GL_ONE 进行绘制。目标颜色通常使用 GL_ONE_MINUS_SRC_ALPHA 衰减。

以这种方式在缓冲区中混合 alpha channel 的原因是不同的:

结合透明度的公式是
resultTr = sTr * dTr

(我使用 s 和 d 是因为与 OpenGL 的源和目标平行,但正如您所见,顺序并不重要。)

用不透明度(alpha 值)写成
    1 - rA = (1 - sA) * (1 - dA)
<=> rA = 1 - (1 - sA) * (1 - dA)
= 1 - 1 + sA + dA - sA * dA
= sA + (1 - sA) * dA

这与默认 blend equation GL_FUNC_ADD 的混合函数(源和目标因子)(GL_ONE,GL_ONE_MINUS_SRC_ALPHA)相同.

作为旁白:

以上回答了问题中的具体问题,但是如果您可以轻松选择绘制顺序,理论上可能会更好绘制 premultiplied颜色从前到后进入缓冲区
    glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);

否则使用相同的方法。

我的理由是显卡可能能够跳过已经稳定的区域的着色器执行。不过我还没有测试过,所以在实践中可能没有什么不同。

关于opengl - 与帧缓冲区的先前内容混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2171085/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com