在GLSL着色器中混合RGBA和ALPHA格式图像

时间:2016-06-08 04:09:24

标签: opengl glsl

我正在编辑为RGBA纹理编写的着色器。

这与RGBA纹理一样正常,例如:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

...然后在glsl着色器中,可以使用它来访问它的值。 texture2D(tex, coord);

这一切都正常。

然而,该软件的一部分使用仅alpha纹理
(其format arg为GL_ALPHA),例如:

glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, x, y, 0, , GL_ALPHA, GL_UNSIGNED_BYTE, NULL);

在这种情况下,来自texture2D()的RGB分量都为零。

虽然这是预期的行为,但我想知道是否有某种方法:

  • 设置仅{alpha}纹理的RGB值,由texture2D返回(不会破坏RGBA纹理)。
  • 在着色器中检查这种纹理,以区别对待它。

请注意,这可以作为最后的手段使用预处理器定义来处理,但它已经满了#if,所以我宁愿避免,因为这个数字预处理器组合增加了我们需要存储的着色器数量。

1 个答案:

答案 0 :(得分:4)

您可以使用texture swizzling设置从纹理的任何组件中提取的值。因此,如果你真的有一个只有alpha的纹理,你可以使用swizzle mask将RGB值设置为1.或者在其他三个上广播alpha值。或者您可以将它们设置为0,但如果它们不在纹理中,那么它就是默认值。

//Set other components to 1.
GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA};
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);

显然必须绑定纹理。

但这些是你唯一的选择。您无法将缺失的组件设置为任意值。

不,没有,着色器无法从单独的采样器中检测到该纹理使用的格式。您当然可以传递着色器可以检测并使用的制服来更改它如何使用提取的值。这样做甚至不会很昂贵,因为你的着色器代码看起来像这样:

vec4 val = texture(tex_unit, ...);
val.xyz = fill_defaults ? defaults : val.xyz;

动态统一值上的简单?:对性能没有实际影响。