【问题标题】:Mixing RGBA and ALPHA format images in GLSL shaders在 GLSL 着色器中混合 RGBA 和 ALPHA 格式的图像
【发布时间】:2016-06-08 04:09:23
【问题描述】:

我正在编辑一个为 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,所以我宁愿尽可能避免,因为预处理器组合的数量会增加着色器的数量我们需要存储。

【问题讨论】:

  • "但是,软件的一部分使用仅 alpha 纹理(其格式 arg 为 GL_ALPHA),例如:” 仅供参考:这不是“仅 alpha 纹理” ”。 pixel transfer format 描述了您正在上传的数据。纹理中数据的格式是internal format,你没有显示。因此,据我们所知,您的仅 alpha 纹理实际上可能是 RGBA 纹理。
  • @nicol-bolas,想避免 noise,但你的权利,更新了问题。

标签: opengl glsl


【解决方案1】:

您可以使用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;

动态统一值上的简单?: 不会对性能产生实际影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多