Opengl es Opengl ES 2.0着色器-丢弃alpha==0的像素,而不丢弃和如果

Opengl es Opengl ES 2.0着色器-丢弃alpha==0的像素,而不丢弃和如果,opengl-es,glsl,shader,opengl-es-2.0,fragment-shader,Opengl Es,Glsl,Shader,Opengl Es 2.0,Fragment Shader,我的片段着色器做两件事: 显示纹理中的原始像素颜色,v_颜色变量设置为r=0、g=0、b=0、a=0 或放弃原始像素颜色,以v_颜色存储。如果我将v_颜色中的alpha设置为1.0,则取该值,在其他情况下使用原始像素的颜色 但是,在第二种情况下,如果我将此着色器应用于具有alpha==0.0像素的图像,则会出现问题。我希望这些像素是不可见的,但它们也是彩色的。在第一种情况下,我没有这个问题。我需要丢弃alpha==0的像素 例如: 我有个人轮廓的纹理,应该是彩色的,但透明像素应该被跳过 在程序开

我的片段着色器做两件事:

  • 显示纹理中的原始像素颜色,v_颜色变量设置为r=0、g=0、b=0、a=0
  • 或放弃原始像素颜色,以v_颜色存储。如果我将v_颜色中的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);
    }
    
    然而,如果我添加了discard,那么所有的工作方式都是预期的。移除alpha==0.0的像素。但我正在使用OpenGL ES 2.0,着色器将在不同的android设备上运行,我读到了“如果”和“丢弃”可能导致的性能问题。这就是为什么我用“mix”代替“if”

    我又试了一次来解决这个问题。我记得纹理中的原始alpha,并在最后应用它。但它仍然给我奇怪的结果。gl_FragColor.a=备份_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(混合(p.rgb,c.rgb*p.a,c.a),p.a);
    
    当您这样做时

    gl_FragColor=mix(p,c,c.a);
    
    如果
    c.a==1.0
    ,则纹理的alpha通道将被丢弃,因为alpha通道也是从
    c
    读取的

    必须混合纹理和颜色的
    .rgb
    组件,但必须使用纹理的alpha通道(在任何情况下)来解决问题:

    gl_FragColor=vec4(混合(p.rgb,c.rgb,c.a),p.a);
    

    如果颜色应为黑色,a表示纹理的alpha通道为0.0的部分,则在混合之前,必须将颜色乘以纹理的alpha通道:

    gl_FragColor=vec4(混合(p.rgb,c.rgb*p.a,c.a),p.a);
    

    但请注意,由于纹理的原因,可能会出现纹理中的一些红色不是完全透明的。如果希望输出颜色完全不透明或完全透明,则必须将alpha通道与阈值进行比较。这可以通过glsl函数完成,该函数返回1.0或0.0:

    gl_FragColor=vec4(混合(p.rgb,c.rgb,c.a),步骤(0.5,p.a));
    

    谢谢你,我也这么认为,但不起作用。它给了我和上次一样的结果。我用discard和gl_FragColor=vec4(mix(p.rgb,c.rgb,c.a),p.a)添加了结果图像;我正在尝试,但仍然没有运气:(这是有效的:gl_FragColor=mix(p,vec4(mix)(p.rgb,c.rgb,p.a),p.a);但我不知道为什么,有人能解释一下吗?
    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;
    }