shader描边效果的原理:两个pass,第一个pass渲染背面(将顶点沿着 法线方向外拓),第二个pass渲染正面
Cull 指令:(详细命令介绍参考:https://blog.youkuaiyun.com/a133900029/article/details/80593513)
原图:
描边后:
顶点外拓可以是 模型空间,世界空间,视角空间,这里在模型空间中进行法线外拓
Shader "Unlit/OutLine"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_OutLineSize("OutLineSize",Range(0,1))=0.5
_OutLineColor("OutLineColor",Color)=(1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Cull Front
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 normal:NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _OutLineColor;
float _OutLineSize;
v2f vert (appdata v)
{
v2f o;
v.vertex += v.normal * _OutLineSize;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : Color
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
return _OutLineColor;
}
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal:NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
//物体空间法线外拓
v.vertex.xyz += v.normal * _Outline;
o.vertex = UnityObjectToClipPos(v.vertex);
//视角空间法线外拓
//float4 pos = mul(UNITY_MATRIX_V, mul(unity_ObjectToWorld, v.vertex));
//float3 normal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV,v.normal));
//pos = pos + float4(normal,0) * _Outline;
//o.vertex = mul(UNITY_MATRIX_P, pos);
//裁剪空间法线外拓
//o.vertex = UnityObjectToClipPos(v.vertex);
//float3 normal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV,v.normal));
//float2 viewNoraml = TransformViewToProjection(normal.xy);
//o.vertex.xy += viewNoraml * _Outline;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
}
Cull指令:默认是剔除背面。
cull front: 剔除前面
cull off:前后都渲染
cull back:剔除背面