You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不调用discard的情况下终止片元着色器?

片元着色器Alpha测试:保留深度写入的像素舍弃方案

针对你遇到的问题——需要在片元着色器执行后,对低于阈值的Alpha像素进行舍弃,同时维持深度写入,这里提供几种可行的解决思路:

  • 手动写入深度后执行discard
    这是最直接的方案:在判断Alpha低于阈值时,先通过gl_FragDepth手动将当前片元的深度值写入深度缓冲区,再调用discard舍弃片元。这样既保证了深度被正确写入,又终止了后续片元着色流程,同时满足“片元着色器必须执行”的要求。
    示例代码:

    uniform sampler2D u_texture;
    uniform float u_threshold;
    varying vec2 v_uv;
    
    void main() {
        vec4 texColor = texture(u_texture, v_uv);
        if (texColor.a < u_threshold) {
            // 手动写入当前片元的深度值
            gl_FragDepth = gl_FragCoord.z;
            // 舍弃片元,此时深度已完成写入
            discard;
        }
        gl_FragColor = texColor;
    }
    

    注意事项:需要确保开启深度写入(glDepthMask(GL_TRUE));手动设置gl_FragDepth会关闭GPU的早期深度测试优化,但这正好符合你“片元着色器必须执行”的要求。

  • 预绘制深度缓冲区
    如果场景允许额外的绘制调用,可以先执行一次只写入深度、不输出颜色的几何体绘制(片元着色器仅写入gl_FragDepth或直接使用默认深度),之后再执行带Alpha测试的绘制。此时第二次绘制时深度缓冲区已有正确值,即使使用discard也不会影响深度结果,但这种方法会增加渲染开销,适合对性能要求不高的场景。

  • 特殊混合模式(替代舍弃)
    若不需要严格终止片元着色流程,可通过设置混合模式让Alpha低于阈值的像素最终颜色透明,同时保留深度写入。例如设置混合因子为GL_ZERO, GL_ONE,此时低于阈值的像素颜色会被置为0,但深度仍会写入。不过这种方法并未真正终止片元处理,仅实现了视觉上的透明,适合不需要严格终止流程的场景。

内容的提问来源于stack exchange,提问作者Zebrafish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 08:17:08