先介绍两种方法
- 基于法线方向与视角夹角是否垂直或位于边缘
- 两个 Pass, 一个 Pass 将模型边缘向外扩散一定距离,另一个 Pass 正常渲染
# 扩散外边界方式
这种方式只能扩散外边界 (比如内部纹理的描边就不行了), 而且规则模型的限制也很大
# 效果
# 代码
Shader “Custome/Outline”
{
Properties
{
[Header(Texture Group)]
[Space(10)]
_Albedo(“Albedo”,2D) = “white” {}
[NoScaleOffset]_Specular(“Specular (RGB-A)”,2D) = “black” {}
[NoScaleOffset]_Normal(“Normal”,2D) = “bump” {}
[NoScaleOffset]_AO(“Ambient Occlusion”,2D) = “white” {}
[Header(Outline Properties)]
[Space(10)]
_OutlineColor(“Outline Color”,Color) = (1,0,1,1)
_OutlineWidth(“Outline Width”,Range(0,0.1)) = 0.01
}
SubShader
{
Tags { "RenderType" = "Opaque" "Queue" = "Transparent" }
//---------Outline Layer-------------
Pass
{
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 vertex : SV\_POSITION;
};
fixed4 \_OutlineColor;
fixed \_OutlineWidth;
v2f vert(appdata\_base v) {
v2f o;
v.vertex.xyz += v.normal \* \_OutlineWidth;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f i) : SV\_Target{
return \_OutlineColor;
}
ENDCG
}
//-----------Regular Layer---------
CGPROGRAM
#pragma surface surf StandardSpecular fullforwardshadows
struct Input {
float2 uv\_Albedo;
};
sampler2D \_Albedo;
sampler2D \_Specular;
sampler2D \_Normal;
sampler2D \_AO;
void surf(Input IN, inout SurfaceOutputStandardSpecular o) {
fixed4 c = tex2D(\_Albedo, IN.uv\_Albedo);
o.Albedo = c.rgb;
fixed4 specular = tex2D(\_Specular, IN.uv\_Albedo);
o.Specular = specular.rgb;
o.Smoothness = specular.a;
o.Normal = UnpackNormal(tex2D(\_Normal, IN.uv\_Albedo));
o.Occlusion = tex2D(\_AO, IN.uv\_Albedo);
}
ENDCG
}
}