对于自身层次不齐的模型,自己会阻挡自己,在blend透明度的时候因为关闭了深度写入,自己的一部分可能会透明自己的一部分,而另一部分又会透明这一部分,造成重影,所以解决方案就是开启另外一个通道来写入模型的深度信息,先决定哪些像素需要显示,在决定需要显示的哪些像素的透明度混合。
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
shader "Custom/透明度混合及测试"{
Properties{
_Color("漫反射自身颜色",color) = (1,1,1,1)
_MainTex("透明度测试用的贴图",2D) = "white"{}
_AlphaScale("Alpha Scale",Range(0,1)) = 0
}
SubShader{
Tags{"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
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;
fixed _AlphaScale;
struct a2v{
float4 vertex:POSITION;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD;
};
struct v2f{
float4 pos:SV_POSITION;
float3 worldNormal:NORMAL;
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(unity_ObjectToWorld, v.vertex).xyz;
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
fixed4 frag(v2f o):SV_Target
{
fixed4 texColor = tex2D(_MainTex,o.uv); //采样出来的结果值应该是一个颜色值
//再计算颜色值
fixed3 albedo = texColor.rgb*_Color.rgb;
fixed3 worldNormal = normalize(o.worldNormal);
fixed3 worldLight = normalize(UnityWorldSpaceLightDir(o.worldPos));
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb*albedo;
fixed3 diffuse = albedo*_LightColor0.rgb*saturate(dot(worldNormal,worldLight)); //别忘了,漫反射也受光的影响
return fixed4(ambient + diffuse, texColor.a*_AlphaScale);
}//第二个通道控制会渲染像素的透明度,和前面已绘制不透明物体进行一个混合
ENDCG
}
}
FallBack "Diffuse"
}
PS常见混合模型: