Unity用Shader实现矩形mesh的边框,同时边框可以近大远小
这个shader原本是用做项目中矩形物体的描边,因为项目中需要描边的物体都是矩形面片,而且比较多,所以用这个比一般的描边插件要节省性能
近大远小的原理就是,计算相机空间下物体的中心的点和摄像机的距离,然后与描边宽度做权重算法
ShortSide是矩形的短边长度
SideRatio是矩形的宽高比(width/height)
下面是shader代码:
Shader "UnlitEdge" {
Properties{
_Color("Main Color", Color) = (1,1,1,1)
_OutlineColor("Outline Color", Color) = (1,1,1,1)
_Outline("Outline Width", Range(0.001, 0.01)) = 0.005
_ShortSide("Short Side", Float) = 1
_SideRatio("SideRatio", Float) = 1
}
SubShader{
Tags {"Queue" = "Transparent" "Queue" = "Overlay" }
LOD 200
ZTest Always
Cull Off
Cull Back
Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float4 color : COLOR;
UNITY_VERTEX_OUTPUT_STEREO
};
float4 _Color;
float4 _OutlineColor;
float _Outline;
float _ShortSide;
float _SideRatio;
v2f vert(appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = v.texcoord;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
float3 center = float3(unity_ObjectToWorld._m03, unity_ObjectToWorld._m13, unity_ObjectToWorld._m23);
float dist = distance(_WorldSpaceCameraPos, center);
dist = clamp(dist / _ShortSide, 1, 50);
float widthX = dist * _Outline;
float widthY = widthX * _SideRatio;
if (i.texcoord.x < widthX || i.texcoord.y < widthY || i.texcoord.x >1 - widthX || i.texcoord.y > 1 - widthY)
{
i.color = _OutlineColor;
}
else
{
i.color = _Color;
}
return i.color;
}
ENDCG
}
}
}
参考的文章:
https://blog.csdn.net/MonoBehaviour/article/details/82707795
https://blog.csdn.net/alla_Candy/article/details/129751758
https://blog.csdn.net/weixin_43933605/article/details/103815167
https://zhuanlan.zhihu.com/p/535452034