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