【问题标题】:Fragment shader and coloring a texture片段着色器和着色纹理
【发布时间】:2013-09-17 23:45:43
【问题描述】:

我正在尝试使用片段着色器调整纹理颜色。我的片段着色器超级简单:

uniform sampler2D sampler;

void main() {
  vec4 tex = texture2D ( sampler, uvVarying );
  gl_FragColor = vec4(tex.r, tex.g, tex.b, tex.a);
}

这会按预期绘制我的狗纹理:

如果我将着色器更改为

  gl_FragColor = vec4(tex.r, tex.g, tex.b, 1.0);

结果如我所愿,透明度信息丢失:

但如果我改为将其设置为:

  gl_FragColor = vec4(tex.r, tex.g, tex.b, 0.0);

我原以为它会完全消失,但我得到了:

发生了什么事??

对于我最初的问题:我想为我的纹理添加一点红色调:

  gl_FragColor = vec4(tex.r + 0.5, tex.g, tex.b, tex.a);

现在,我希望它具有与原始纹理相同的透明度信息,但结果却是:

我在这里错过了什么。纹理使用引擎的默认混合,即src = GL_ONE, dst = GL_ONE_MINUS_SRC_ALPHA

【问题讨论】:

  • 好吧,这似乎与纹理具有预乘 alpha 的事实有关。如果我在没有它的情况下加载纹理,它看起来就像我预期的那样。

标签: opengl opengl-es opengl-es-2.0 glsl fragment-shader


【解决方案1】:

您的混合模式假定预乘 alpha,这通常是一个不错的选择。但它需要将 RGB 值与 alpha 值相乘。 alpha 值仅控制在该模式下将多少背景添加到传入片段中。因此,要使 RGB “淡出”,它们也必须通过 alpha 值进行调制。

现在,当您将 alpha 值设置为常数时,您的 RGB 值不再匹配该预乘法。试试这个来为你的红色着色:

gl_FragColor = tex + vec4(0.5, 0, 0, 1)*tex.a;

这会为纹理添加经过 alpha 调制的红色。

如果您希望图像完全消失,则需要不同的混合模式,即 GL_SRC_ALPHA、GL_ONE_MINUS_SRC_ALPHA,但您需要非预乘 alpha 图像,或者您在着色器中补偿预乘:

gl_FragColor = vec4(tex.rgb/tex.a, tex.a);

【讨论】:

  • 我不同意使用预乘 alpha 是“通常是一个不错的选择”,因为我认为“正常”是使用压缩纹理,并且通过压缩,预乘混合会导致沿边缘的值偏差。在着色器中进行预乘,而不是将其烘焙到 .rgb 中,当然经常有用。
猜你喜欢
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-03
  • 2019-01-23
相关资源
最近更新 更多