思路
关闭深度写入,使用纹理本身的a值,乘以自定义材质属性scale,得到最后的a值,并返回
主要代码:
return fixed4(ambient + diffuse,texColor.a * _AlphaScale);
实现
Shader "Custom/AlphaBlend" {
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{
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"
}
缺陷
交错复杂的结构,会导致错误的透明效果