ShaderLab: Legacy Alpha Testing

2018-11-03  本文已影响0人  Bonging

原文链接:https://docs.unity3d.com/Manual/SL-AlphaTest.html

        Alpha测试是阻止一个像素被写到屏幕上的最后一个机会。

        请注意:当进行片段shader编程时,AlphaTest命令无效,在大多数平台上,alpha测试在shader中是使用HLSL的clip()函数完成的。现在,我们推荐使用可编程的shader来代替SetTexture命令。

        在最后输出的颜色被计算出来后,可以选择性的把这个颜色的透明度与一个固定值相比较。如果测试失败,像素将不会写入到显示上。


语法

AlphaTest Off

        渲染所有像素(默认),或者...

AlphaTest comparison AlphaValue

        建立一个Alpha测试只渲染alpha值在某个确定区间内的像素。


比较

        下面是比较语句:

        Greater                   只渲染Alpha值比AlphaValue值大的像素。

        GEqual                   只渲染Alpha值大于等于AlphaValue值的像素。

        Less                       只渲染Alpha值比AlphaValue值小的像素。

        LEqual                   只渲染Alpha值小于等于AlphaValue值的像素。

        Equal                     只渲染Alpha值等于AlphaValue值的像素。

        NotEqual               只渲染Alpha值不等于AlphaValue值的像素。

        Always                   渲染所有像素,这个功能相当于关闭了Alpha测试。

        Never                     不渲染任何像素。


AlphaValue

        一个0-1之间的浮点数字。它也可以是一个浮点变量或是一个范围属性,在这种情况下它必须使用方括号来表示([VariableName])。


细节

        当渲染凹面的物体的透明部分的时候Alpha测试是重要的。显卡会持有每个要显示到屏幕上的像素的深度值记录。如果一个新的像素比已经渲染的像素更远,新的像素将不会写入到显示上。这意味着即使有融合,对象将不会显示。

(图片见原网页)

        在这个图中,左边的树使用透明度测试来渲染。请注意它上面的像素要么是透明的要么是不透明的。中间的树只使用透明度融合来渲染,请注意由于深度buffer,树枝附近的透明部分是怎样覆盖远处的叶子的。右边的树使用下面的案例shader来渲染,此shader使用融合和alpha测试混合的方式来隐藏所有工件。


例子

         最简单的可能性的例子,给其分配了一个纹理的alpha通道。只有纹理中Alpha值大于0.5才会被显示。

Shader "Simple Alpha Test" {

    Properties {

        _MainTex ("Base (RGB) Transparency (A)", 2D) = "" {}

    }

    SubShader {

        Pass {

            // Only render pixels with an alpha larger than 50%

            AlphaTest Greater 0.5

            SetTexture [_MainTex] { combine texture }

        }

    }

}


        只靠它自己不是特别好。让我们添加一些光照并且使测试值可以调节。

Shader "Cutoff Alpha" {

    Properties {

        _MainTex ("Base (RGB) Transparency (A)", 2D) = "" {}

        _Cutoff ("Alpha cutoff", Range (0,1)) = 0.5

    }

    SubShader {

        Pass {

            // Use the Cutoff parameter defined above to determine

            // what to render.

            AlphaTest Greater [_Cutoff]

            Material {

                Diffuse (1,1,1,1)

                Ambient (1,1,1,1)

            }

            Lighting On

            SetTexture [_MainTex] { combine texture * primary }

        }

    }

}

        当渲染植物和树,很多游戏都有典型的Alpha测试硬边。一个解决方案是渲染对象两次。在第一个pass中,我们使用Alpha测试只去渲染透明度大于50%的不透明的像素。在第二个pass中,我们使用Alpha融合被截取掉的图像,不记录像素的深度值。由于更远的分支会覆盖更近的分支,我们会有一些混乱,但是事实上,这种情况很难看到因为叶子上面有很多视觉细节。

Shader "Vegetation" {

    Properties {

        _Color ("Main Color", Color) = (.5, .5, .5, .5)

        _MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}

        _Cutoff ("Base Alpha cutoff", Range (0,.9)) = .5

    }

    SubShader {

        // Set up basic lighting

        Material {

            Diffuse [_Color]

            Ambient [_Color]

        }

        Lighting On

        // Render both front and back facing polygons.

        Cull Off

        // first pass:

        // render any pixels that are more than [_Cutoff] opaque

        Pass {

            AlphaTest Greater [_Cutoff]

            SetTexture [_MainTex] {

                combine texture * primary, texture

            }

        }

        // Second pass:

        // render in the semitransparent details.

        Pass {

            // Dont write to the depth buffer

            ZWrite off

            // Don't write pixels we have already written.

            ZTest Less

            // Only render pixels less or equal to the value

            AlphaTest LEqual [_Cutoff]

            // Set up alpha blending

            Blend SrcAlpha OneMinusSrcAlpha

            SetTexture [_MainTex] {

                combine texture * primary, texture

            }

        }

    }

}

        请注意,我们在SubShader中有一些设置,而不是在每个独立的pass中。在SubShader中的设置将被其pass继承为默认设置。

上一篇下一篇

猜你喜欢

热点阅读