在 OpenGL 中,有没有办法根据着色器中单独通道的值进行混合?

Dav*_*vid 2 opengl graphics fragment-shader

在 OpenGL(不是 ES)中,是否有一种通用的方法可以在基于另一个纹理或变量的值进行绘制时基于纹理进行混合?在 OpenGLES 上,我知道我可以通过 GL_EXT_shader_framebuffer_fetch 等扩展在某些平台上进行自定义混合。我问的原因是我有一个特殊的纹理,其中第四个通道不是 alpha,我需要能够将它混合到不同地图上可用的单独 alpha 上。

Die*_*Epp 6

您需要双源混合,它在 OpenGL 3.3 的核心中可用。这允许您提供具有两个输出的片段着色器,并在混合函数中使用它们。

您可以像这样在片段着色器中声明输出:

layout(location = 0, index = 0) out vec4 outColor;
layout(location = 0, index = 1) out vec4 outAlpha;
Run Code Online (Sandbox Code Playgroud)

然后,您可以像这样设置混合函数,用于预乘 alpha:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC1_COLOR);
Run Code Online (Sandbox Code Playgroud)

或非预乘 alpha:

glBlendFunc(GL_SRC1_COLOR, GL_ONE_MINUS_SRC1_COLOR);
Run Code Online (Sandbox Code Playgroud)

请注意,SRC1这里是片段着色器的第二个输出。如果我没记错的话,这种混合只适用于一个位置。

  • “*如果我没记错的话,这种混合仅适用于一个位置。*”对于所有实际目的来说,这是事实。但这是硬件限制,而不是 API 限制。您可以[查询使用双源混合获得了多少个位置](https://www.opengl.org/wiki/Blending#Dual_Source_Blending),这是不使用非双源混合时的不同限制。只是,对于当前几乎所有支持它的硬件来说,该限制将为 1。 (2认同)