片段着色器和着色纹理

ver*_*tti 18 opengl opengl-es glsl fragment-shader opengl-es-2.0

我试图通过片段着色器调整纹理颜色.我的片段着色器非常简单:

uniform sampler2D sampler;

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

这按照预期绘制了我的狗纹理: 正常的狗

如果我然后将着色器更改为

  gl_FragColor = vec4(tex.r, tex.g, tex.b, 1.0);
Run Code Online (Sandbox Code Playgroud)

结果是我的预期,透明度信息丢失:

没有透明度

但如果我把它设置为:

  gl_FragColor = vec4(tex.r, tex.g, tex.b, 0.0);
Run Code Online (Sandbox Code Playgroud)

我期待它完全消失,但我得到:

绿狗

到底是怎么回事??

对于我原来的问题:我想在我的纹理中添加一点红色:

  gl_FragColor = vec4(tex.r + 0.5, tex.g, tex.b, tex.a);
Run Code Online (Sandbox Code Playgroud)

现在,我希望它与原始纹理具有相同的透明度信息,但我得到了这个:

红色的狗

我在这里想念的是什么 纹理使用引擎的默认混合src = GL_ONE, dst = GL_ONE_MINUS_SRC_ALPHA.

dat*_*olf 31

您的混合模式假定为预乘的alpha,这通常是一个很好的选择.但它需要将RGB值与alpha值相乘.alpha值仅控制在该模式下将多少背景添加到传入片段.因此,为了使RGB"淡出",它们也必须由α值调制.

现在,当您将该alpha值弄为常量时,您的RGB值不再与该预乘匹配.试试这个红色着色:

gl_FragColor = tex + vec4(0.5, 0, 0, 1)*tex.a;
Run Code Online (Sandbox Code Playgroud)

这会在纹理中添加alpha调制红色.

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

gl_FragColor = vec4(tex.rgb/tex.a, tex.a);
Run Code Online (Sandbox Code Playgroud)