透明度测试:只要一个片元的透明度不满足条件(通常是小于某个阈值),那它对应的片元就会被舍弃。被舍弃的片元不会再进行任何处理,也不会对颜色缓冲产生任何影响;否则就会按照普通的不透明物体的处理方式来处理它。
通常,我们会在片元着色器中使用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(关闭剔除),效果如下: