opengl:非线性加性颜色混合

opengl:非线性加性颜色混合,opengl,alphablending,blending,pyopengl,Opengl,Alphablending,Blending,Pyopengl,我正在编写一个基于PyOpenGL的用户界面,用于手动对齐图像。我将我的两个图像显示为纹理四边形,运动图像位于静态参考的顶部。运动图像以红色显示,带有不同的alpha值,即glColor4f(1,0,0,叠加不透明度),静态图像以青色显示,恒定不透明度等于1,即glColor4f(0,1,1,1.)。然后,用户可以通过鼠标滚动改变overlay\u opacity,以便在移动图像和参考图像之间淡入淡出 目前我使用的是glBlendFunc(GL\u SRC\u ALPHA,GL\u ONE\u减

我正在编写一个基于PyOpenGL的用户界面,用于手动对齐图像。我将我的两个图像显示为纹理四边形,运动图像位于静态参考的顶部。运动图像以红色显示,带有不同的alpha值,即
glColor4f(1,0,0,叠加不透明度)
,静态图像以青色显示,恒定不透明度等于1,即
glColor4f(0,1,1,1.)
。然后,用户可以通过鼠标滚动改变
overlay\u opacity
,以便在移动图像和参考图像之间淡入淡出

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


我想我也许可以在片段着色器中实现这一点,但似乎应该有一种更简单的方法来实现相同的结果,只需使用
glBlendFunc()
。我还尝试了
GL\u SRC\u ALPHA\u SATURATE
,这在我的实现中似乎不起作用。

快速回答:不,仅使用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,而不是将其预乘,这将减少每个像素的一些乘法


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

因为您只混合图像,所以可以使用一个技巧:首先渲染图像a,调整其颜色。然后使用
glBlendFunc(GL\u ONE,GL\u ONE)
在其顶部绘制第二个图像,使其具有相加性并再次调整颜色。通过使后层和前层的调制颜色符合所需的混合曲线,您可以得到所需的颜色。

我会咬紧牙关,快速制作着色器。关于正在发生的事情,没有问题:)@MichaeldOrgane:你无法使用着色器控制混合。即使在现代GPU中,混合仍然是硬连线的东西之一。