【问题标题】:opengl: nonlinear additive color blendingopengl:非线性加色混合
【发布时间】:2013-04-30 21:42:17
【问题描述】:

我正在编写一个基于 PyOpenGL 的 UI 来手动对齐图像。我将我的两个图像显示为带纹理的四边形,在静态参考之上的移动图像。动态图像显示为红色,具有不同的 alpha,即glColor4f(1.,0.,0.,overlay_opacity),静态图像显示为青色,不透明度为 1,即glColor4f(0.,1.,1.,1.)。然后,用户可以通过鼠标滚动来改变overlay_opacity,以便在移动图像和参考图像之间淡入淡出。

目前我正在使用glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)。虽然这确实让我可以在青色和红色图像之间平滑淡入淡出,但这也意味着当overlay_opacity 等于 0.5 时,我只能得到红色和青色图像最大强度的一半,因此结果看起来暗淡而浑浊。如果我使用glBlendFunc(GL_SRC_ALPHA,GL_ONE),我总是会得到青色图像的最大强度,所以我不能淡出它。我真正想要的是某种非线性混合,如下图第三张所示:

我想我也许可以在片段着色器中执行此操作,但似乎应该有一种更简单的方法来仅使用 glBlendFunc() 来实现相同的结果。我也试过GL_SRC_ALPHA_SATURATE,这在我的实现中似乎不起作用。

【问题讨论】:

  • 我只是硬着头皮做一个快速着色器。没有关于正在发生的事情的问题:)
  • @MichaelDorgan:您无法使用着色器控制混合。混合是即使在现代 GPU 中仍然被硬连线的事情之一。

标签: opengl alphablending blending pyopengl


【解决方案1】:

快速回答:不,仅使用 OpenGL 调用是不可能的。 GL_SRC_ALPHA_SATURATE 也不应该做你想做的事,它的 RGB 因子将是 min(Asrc, (1-Adest)),在你的情况下,它可能最终总是等于 Asrc,因为我假设你的目标 alpha 始终为 0。

长答案:您最好也是唯一的选择是编写所述片段着色器。为了实现你想要的,你必须使用一些诡计。我建议将覆盖颜色与 alpha 因子预先相乘,然后输出另一个 alpha 值来混合目标颜色。一个类似的方程就足够了:

// Note I cap off the alpha values in both cases to achieve the desired non-linear ramp
float alpha = overlay_opacity * 2.0f;
out = vec4(color.rgb * min(1.0f, alpha), min(1.0f, 2.0f - alpha));

然后使用以下混合函数确保目标颜色也混合:

glBlendFunc(GL_ONE, GL_SRC_ALPHA);

进一步的优化,你注意到我将覆盖不透明度乘以 2 来限制两个 alpha 值。取而代之的是,您可以在将其传递给着色器之前将其预先乘以 2,这将减少每个像素的一些乘法。

希望这能解决您的问题,祝您好运!

【讨论】:

    【解决方案2】:

    由于您只混合图像,因此您可以使用一个技巧来做到这一点:首先渲染图像 A,调整其颜色。然后,您使用glBlendFunc(GL_ONE, GL_ONE) 在其上绘制第二张图像以使其相加并再次调制颜色。通过使后层和前层的调制颜色遵循您想要的混合曲线,您可以获得您想要的。

    【讨论】:

      猜你喜欢
      • 2015-05-26
      • 2018-06-06
      • 1970-01-01
      • 2022-10-25
      • 1970-01-01
      • 1970-01-01
      • 2014-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多