法线外扩
Pass
{
Name"OutLine"
Cull Front
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 PositionClip : SV_POSITION;
};
float _EdgeWidth;
float4 _EdgeColor;
v2f vert (appdata v)
{
v2f o;
float3 PositionView= UnityObjectToViewPos(v.vertex);
float3 NormalWS=UnityObjectToWorldNormal(v.normal);
float3 NormalView =normalize(mul((float3x3)UNITY_MATRIX_V, NormalWS));//相机空间法线
PositionView += NormalView * _EdgeWidth*0.001;
o.PositionClip=mul(UNITY_MATRIX_P,float4(PositionView,1.0));
return o;
}
half4 frag (v2f i) : SV_Target
{
return _EdgeColor;
}
ENDCG
}
基于模版测试的法线外扩
//Base Pass中确认模版值
Stencil
{
Ref 1
Comp Always
Pass Replace
}
//OutLine Pass
Pass
{
Stencil
{
Ref 1
Comp NotEqual
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float _EdgeWidth;
fixed4 _EdgeColor;
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
};
v2f vert (a2v v)
{
v2f o;
float4 pos = mul(UNITY_MATRIX_MV, v.vertex);
float3 normal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);
normal.z = -0.5;
pos = pos + float4(normalize(normal), 0) * _EdgeWidth*0.01;
o.pos = mul(UNITY_MATRIX_P, pos);
return o;
}
float4 frag(v2f i) : SV_Target
{
return float4(_EdgeColor.rgb, 1);
}
ENDCG
}