最近做头发shader的时候做了这么一个简单测试,用的模型是以前制作的一个角色头部,在这里用来记录一下作为学习的总结。
基本思路就是利用3个Pass处理带描边的半透明材质
看下最终的测试截图(头发的材质不在本次讨论范围,有机会单独做一个总结):
关于Blend部分也测试下截图保留:
1.第一个Pass开启深度写入,处理AlphaTest,但不输出颜色
//第一个Pass,开启深度写入,不输出颜色,处理AlphaTest部分
Pass{
// 仅仅是把模型的深度信息写入深度缓冲中从而剔除模型中被自身遮挡的片元
ZWrite On
// 用于设置颜色通道的写掩码(Wirte Mask)ColorMask RGB|A|0|(R/G/B/A组合)
// 当为0时意味着该Pass不写入任何颜色通道,也就不会输出任何颜色
//也可以不用,这样就能刻意控制AlphaTest导致的发丝边缘的颜色
ColorMask 0
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
fixed _AlphaTest;
struct a2v {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD2;
};
v2f vert(a2v v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag(v2f i) : SV_Target{
fixed4 texColor = tex2D(_MainTex, i.uv);
//AlphaTest
clip(texColor.a - _AlphaTest);//clip函数,但参数为负数则舍弃该片元输出
return fixed4(0,0,0,1);
}
ENDCG
}
2.第二个Pass关闭深度写入,处理半透明物体以及主体部分
//第二个Pass,关闭深度写入,处理AlphaBlend半透明,处理光照等部分
Pass{
// 向前渲染路径的方式
Tags{ "LightMode" = "ForwardBase" }
Cull Off //关闭剔除,让头发双面显示
ZWrite Off //关闭深度写入
//透明度混合需要关闭深度写入
//Orgb = SrcAlpha * Srgb + OneMinusSrcAlpha * Drgb
//Oa = SrcAlpha * Sa + OneMinusSrcAlpha * Da
//将本Shader计算