《Unity 入门精要》第8章 透明效果( 二 )


要设置的渲染队列,可以通过在中指定相应标签:
SubShader {// 指定渲染队列为 AlphaTestTags { "Queue"="AlphaTest" }Pass {...}}
也可以直接在编辑器中直接指定的渲染队列:
8.3 透明度测试
透明度测试原理:只要一个片元的透明度不满足条件(通常是小于某个阈值),那么它对应的片元就会被舍弃 。被舍弃的片元将不会再进行任何处理,也不会对颜色缓冲产生任何影响;否则,就会按照普通的不透明物体的处理方式来处理它 。
通常我们在片元着色器中使用 clip 函数来进行透明度测试,它是 Cg 中的一个函数 。
下面我们实现一个包含透明度测试的:
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'Shader "Chaptor 8/SHA_AlphaTest"{Properties{_Color ("Color Tint", Color) = (1, 1, 1, 1)_MainTex ("Main Tex", 2D) = "white" {}// 用于控制透明度测试的边界值_CutOff ("Alpha CutOff", Range(0, 1.0)) = 0.5}SubShader{// 通过标签 Queue 指定渲染队列为 AlphaTest// RenderType 标签可以让Unity把这个Shader归入到提前定义的组中,以指明该 Shader 是一个使用了透明度测试的Shader 。// RenderType标签通常被用于着色器替换功能// IgnoreProjector 设置为 true 意味着这个 Shader 不会受投影器影响// 通常,一个透明度测试 Shader 都需要设置这三个标签Tags {"Queue"="AlphaTest" "IgnoreProjector"="true" "RenderType"="TransparentCutout"}Pass{Tags {"LightMode" = "ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"fixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;fixed _CutOff;struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float4 vertex : SV_POSITION;float3 worldNormal : TEXCOORD0;float3 worldPos : TEXCOORD1;float2 uv : TEXCOORD2;};v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;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 texColor = tex2D(_MainTex, i.uv);// 使用 clip 函数进行透明度测试,等价于代码// if((texColor.a - _CutOff) < 0.0){//discard// }clip(texColor.a - _CutOff);fixed3 albedo = texColor * _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 "Specular"}
效果如下,左侧为正常方块,右侧为开启了透明度测试的方块:
可以在编辑器中通过参数参数来设置透明度效果 。
可以看出,透明度测试得到的透明效果很“极端”——要么完全透明,要么完全不透明,它的效果往往像在一个不透明物体上挖了一个空洞 。而且,得到的透明效果在边缘处往往参差不齐,有锯齿,这是因为在边界处纹理的透明度的变化精度问题 。为了得到更加柔滑的透明效果,就可以使用透明度混合 。
8.4 透明度混合
透明度混合:使用当前片元的透明度作为混合因子,与已经存储在颜色缓冲中的颜色值进行混合,得到新的颜色 。但是,透明度混合需要关闭深度写入,这使得我们要非常小心物体的渲染顺序 。
为了进行混合,我们需要使用 Unity 提供的混合命令Blend 。Blend 是 Unity 提供的设置混合模式的命令 。想要实现半透明的效果就需要把当前自身的颜色和已经存在于颜色缓冲中的颜色值进行混合,混合时使用的函数就是由该指令决定的 。
只有开启了混合,设置片元的透明通道才有意义 。