UnityShader案例(八)——透明效果(1)

来源:互联网 发布:祁县哪个宽带网络好 编辑:程序博客网 时间:2024/06/06 04:48

一、实现原理

透明度测试:它采用一种这样一种机制,只要一个片元的透明度不满足条件(通常是小于某个阈值),那么它对应的片元就会舍弃。被舍弃的片元将不会进行任何的处理,也不会对颜色缓冲产生任何影响;否则,就会按照普通的不透明的物体来处理它,即进行深度测试。
通常我们就是根据这个原理来实现透明效果的,我们会在片元着色器中使用clip函数来进行透明度测试。Clip是CG中的一个函数。

二、代码实现

Shader "Custom/Transparent/AlphaTest"{    Properties    {        _MainTex ("Texture", 2D) = "white" {}        _Color("Color",Color)=(1,1,1,1)        _Cutoff("AlphaTest",Range(0,1))=0.5    }    SubShader    {        Tags { "Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout" }        LOD 100        Pass        {            Tags{"LightMode"="ForwardBase"}            CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"            #include "Lighting.cginc"            #include "AutoLight.cginc"            sampler2D _MainTex;            fixed4 _Color;            float4 _MainTex_ST;            fixed _Cutoff;            struct appdata            {                float4 vertex : POSITION;                float4 uv : TEXCOORD0;                float3 normal:NORMAL;            };            struct v2f            {                float2 uv : TEXCOORD0;                float3 worldNormal:TEXCOORD1;                float3 worldPos:TEXCOORD2;                float4 vertex : SV_POSITION;            };            v2f vert (appdata v)            {                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                o.worldNormal=UnityObjectToWorldNormal(v.normal);                o.worldPos=mul(unity_ObjectToWorld,v.vertex);                o.uv = TRANSFORM_TEX(v.uv, _MainTex);                return o;            }            fixed4 frag (v2f i) : SV_Target            {                float3 worldNormal=normalize(i.worldNormal);                float3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));                fixed4 col = tex2D(_MainTex, i.uv);                clip(col.a-_Cutoff);                fixed3 albedo=col.rgb*_Color.rgb;                fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;                fixed3 diffuse=_LightColor0.rgb*albedo*max(0,dot(worldNormal,worldLightDir));                return fixed4(ambient+diffuse,1.0);            }            ENDCG        }    }    FallBack "Transparent/Cutout/VertexLit"}

纹理图片,每一块的纹理的Alpha值各不相同
这里写图片描述
这里写图片描述
这里写图片描述

三、代码详解

1、变量属性_Cutoff参数用于决定我们调用clip进行透明度测试时使用的判断条件,它的范围在0到1之间,这是因为纹理的像素的透明度就是在此范围之间。
2、在Unity中透明度测试使用的渲染队列是名为AlphaTest的队列,因此我们需要把Queue标签设置为AlphaTest,而RenderType标签可以让Unity把这个Shader归入到提前定义的组(TransparentCutout组)中,以指明该shader是一个透明度测试的shader。RenderType通常被用于着色器替换功能。我们还把IgnoreProjector设置为true,这意味着这个shader不会受投影器的影响。

原创粉丝点击