透明度测试

透明度测试:只要一个片元的透明度不满足条件(通常是小于某个阈值),那它对应的片元就会被舍弃。被舍弃的片元不会再进行任何处理,也不会对颜色缓冲产生任何影响;否则就会按照普通的不透明物体的处理方式来处理它。

通常,我们会在片元着色器中使用clip函数来进行透明度测试。clip是Cg中的一个函数,它的定义如下。

void clip(float4 x);
void clip(float3 x);
void clip(float2 x);
void clip(float1 x);
void clip(float x);

参数:裁剪时使用的标量或矢量条件。

描述:如果给定参数的任何一个分量是负数,就会舍弃当前像素的输出颜色。它等同于下面的代码:

void clip(float4 x)
{
    if(any(x<0))
      discard;//显式剔除片元
}    

接下来写一个透明度测试的实例:

 1 Shader "Custom/AlphaTest" {
 2     Properties {
 3         _Color ("Main Tint", Color) = (1,1,1,1)
 4         _MainTex ("Albedo (RGB)", 2D) = "white" {}
 5         _Cutoff("Alpha Cutoff",Range(0,1))=0.5
 6     }
 7     SubShader {
 8     /*
 9     "Queue"="AlphaTest":Unity中透明度测试使用的渲染队列是名为AlphaTest的队列
10     "IgnoreProjectors"="True":意味着这个Shader不会受到投影器的影响
11 RenderType标签可以让Unity把这个Shader归入到提前定义的组(这里就是TransparentCutout组)
12     通常使用了透明度测试的shader都应该在SubShader中设置这3个标签
13     */
14     Tags{"Queue"="AlphaTest""IgnoreProjectors"="True""RenderType"="TransparentCutout"}
15         Pass
16         {
17         Tags{"LightMode"="ForwardBase"}
18         //Cull Off//控制双面渲染开关
19         CGPROGRAM
20         #pragma vertex vert
21         #pragma fragment frag
22         #include"Lighting.cginc"
23 
24         fixed4 _Color;
25         sampler2D _MainTex;
26         float4 _MainTex_ST;
27         fixed _Cutoff;
28 
29         struct a2v
30         {
31         float4 vertex:POSITION;
32         float3 normal:NORMAL;
33         float4 texcoord:TEXCOORD0;
34         };
35         struct v2f
36         {
37         float4 pos:SV_POSITION;
38         float3 worldNormal:TEXCOORD0;
39         float3 worldPos:TEXCOORD1;
40         float2 uv:TEXCOORD2;
41         };
42         v2f vert(a2v v)
43         {
44         v2f o;
45         o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
46         o.worldNormal=UnityObjectToWorldNormal(v.normal);
47         o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
48         o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
49         return o;
50         }
51 
52         fixed4 frag(v2f i):SV_Target
53         {
54         fixed3 worldNormal=normalize(i.worldNormal);
55         fixed3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));
56         fixed4 texColor=tex2D(_MainTex,i.uv);
57         clip(texColor.a-_Cutoff);//当texColor.a小于材质参数_Cutoff时u,该片元就会产生完全透明的效果。
58         fixed3 albedo=texColor.rgb*_Color.rgb;
59         fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;
60         fixed3 diffuse=_LightColor0.rgb*albedo*max(0,dot(worldNormal,worldLightDir));
61         return fixed4(ambient+diffuse,1.0);
62         }
63 
64         ENDCG
65         }
66     }
67     FallBack "Transparent/Cutout/VertexLit"
68 }
透明度测试

 效果如下:

双面渲染:在Pass中Cull Off(关闭剔除),效果如下:

posted @ 2017-03-01 10:25  露夕逝  阅读(1327)  评论(0)    收藏  举报