對於自身層次不齊的模型,自己會阻擋自己,在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常見混合模型: