思路
由于做透明度混合时,关闭了深度写入。关闭原因如下:
导致无法对模型进行像素级别的排序,即排序错误,使得半透明效果异常。
所以,可以使用两个pass, 第一个pass专门用来做深度写入,不处理其他,第二个pass块再处理颜色。
这样可以使得排序正常,透明效果也正常。
实现
Shader "Custom/AlphaBlendZWrite" {
Properties{
_Color("MainTint",Color) = (1,1,1,1)
_MainTex("MainTex", 2D) = "white" {}
_AlphaScale("AlphaScale", Range(0,1)) = 1
}
SubShader{
Tags{"Queue" = "Transparent" "IgnoreProject"="True" "RenderType"="Transparent" }
Pass{//该pass专门用做深度写入
ZWrite On
ColorMask 0
}
Pass{
Tags{ "LightMode" = "ForwardBase" } //前三个是透明度混合的需要标签
ZWrite off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
float _AlphaScale;
struct a2v {
float4 vertex :POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD0;
float3 worldPos : TEXCOORD1;
float2 uv : TEXCOORD2;
};
v2f vert (a2v v ) {
v2f o;
o.pos = UnityObjectToClipPos( v.vertex );
o.worldNormal = UnityObjectToWorldNormal( v.normal );
o.worldPos = mul((float3x3)unity_ObjectToWorld, v.vertex).xyz;
o.uv = TRANSFORM_TEX( v. texcoord, _MainTex);
return o;
};
fixed4 frag( v2f f ) : SV_Target{
fixed3 worldNormal = normalize( f.worldNormal );
fixed3 worldLightDir = normalize( UnityWorldSpaceLightDir(f.worldPos) );
fixed4 texColor = tex2D( _MainTex, f.uv );
fixed3 albedo = texColor.rgb * _Color.rgb;
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb * albedo;
fixed3 diffuse = _LightColor0.rgb * albedo * saturate( dot( worldNormal, worldLightDir ));
return fixed4(ambient + diffuse,texColor.a * _AlphaScale);
};
ENDCG
}
}
FallBack "Diffuse"
}
缺陷
多了一个pass块,性能消耗增加了。