【发布时间】:2019-12-27 11:25:15
【问题描述】:
我的片段着色器做了两件事:
- 显示来自纹理的原始像素颜色,v_Color 变量设置为 r=0,g=0,b=0,a=0
- 或将原始像素颜色丢弃为存储在 v_Color 中的颜色。如果我将 v_Color 中的 alpha 设置为 1.0,则使用此值,在其他情况下使用原始像素的颜色。
但是,如果我将此着色器应用于具有 alpha == 0.0 的像素的图像,我在第二种情况下会遇到问题。我预计这些像素将是不可见的,但它们也是彩色的。在第一种情况下,我没有这个问题。我需要丢弃 alpha == 0 的像素
例如: 我有人物剪影的纹理,应该着色,但应该跳过透明像素。
在我设置的程序开始时:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
这是我的片段着色器:
void main()
{
vec4 c = vec4(v_Color);
vec4 p = texture2D( s_texture, v_texCoord);
gl_FragColor = mix(p, c, c.a);
}
但是,如果我添加丢弃,那么所有工作都像预期的那样。删除 alpha==0.0 的像素。但是我正在使用 OpenGL ES 2.0,着色器将在不同的 android 设备上运行,并且我读到了由“if”和“discard”引起的可能的性能问题。这就是我使用“mix”而不是“if”的原因。
void main()
{
vec4 c = vec4(v_Color);
vec4 p = texture2D( s_texture, v_texCoord);
if (p.a == 0.0) {
discard;
}
gl_FragColor = mix(p, c, c.a);
}
我尝试了另一种尝试来解决这个问题。我记得纹理中的原始 alpha,并在最后应用它。但它仍然给了我奇怪的结果。 gl_FragColor.a = backup_alpha 对结果 alpha 进行处理,它在某种程度上是透明的,但不完全。
void main()
{
vec4 c = vec4(v_Color);
vec4 p = texture2D( s_texture, v_texCoord);
float backup_alpha = p.a;
gl_FragColor = mix(p, c, c.a);
gl_FragColor.a = backup_alpha;
}
感谢@Rabbid76 的帮助,这是正确的:
gl_FragColor = vec4(mix(p.rgb, c.rgb*p.a, c.a), p.a);
【问题讨论】:
标签: opengl-es glsl shader opengl-es-2.0 fragment-shader