0

我正在尝试重现相当复杂的混合操作的效果(已更正)。

(1-(1-src_alpha)*dest_alpha)*src+(1-src_alpha)*dest_alpha*dest

srcdest参考源缓冲区和目标缓冲区中各自的 rgba 组件。我想做的是把它变成一个混合链,使用glBlendFunc和/或可以被调用以产生与上述表达式相同的结果,也许通过在每次调用glBlendFuncSeparate后多次渲染相同的场景。glBlend*虽然很遗憾我无法将复杂的混合作为单个调用进行,但在我看来,通过使用不同的参数glBlend*多次渲染我的场景,我仍然可以达到我想要的效果。glBlend*我在想我可能需要 3 次这样的电话,但可以分两次进行。

编辑:

要了解 blend 函数的作用,请首先考虑常规 alpha blend src * src_alpha + dest * (1 - src_alpha)。这种混合风格适用于几乎所有源不包含预乘 Alpha 的 Alpha 混合,特别是当我们渲染到最终设备(例如屏幕或其他设备)时,目标明确为或可能假定为不透明。

如果目标已经是不透明的,那么这个复杂的混合函数将产生与前面提到的普通混合函数相同的结果,而目标是不透明的,而如果目标恰好是完全透明的,那么复杂的混合函数会降级为源副本而是继承源的透明度。因此,复杂混合函数实际上所做的只是根据目标 alpha 在这两个极端值之间进行线性插值。

编辑:需要更正上面的混合功能......我错误地考虑了它。我在下面显示推导以进行验证:

首先,我从一个基本的混合功能开始:

src * src_alpha + dest * (1 - src_alpha)

而我想要做的是将它与 src 混合具体取决于 dest_alpha,因此上述函数乘以 dest_alpha,然后我将其添加到源乘以 1 - dest_alpha,如下所示:

src * (1-dest_alpha) + (src * src_alpha + dest * (1 - src_alpha)) * dest_alpha

算术重构给了我这个:

(1-(1-src_alpha)*dest_alpha)*src+(1-src_alpha)*dest_alpha*dest
4

1 回答 1

0

我想通了,所以如果其他人有任何需要,这就是我发现的:

首先,我打电话

glblendfuncseparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE)

然后我正常绘制场景。假设源具有非预乘 alpha 并且正在与不透明背景混合,这将在颜色通道上产生正确的混合样式。虽然保留了目标的原始 alpha,但可以在下一步使用:

glblendfuncseparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)

然后我重新绘制与以前完全相同的场景。这进一步线性插值原始源和基于目标 alpha 的上述混合结果之间的颜色通道,并以结果始终大于或等于源 alpha 或目标 alpha 的方式组合 alpha 分量,但是仍然总是限制在 0 和 1 之间,就像源和目标 alpha 值一样。

于 2016-04-16T00:18:48.993 回答