一、工程截图
二、Shader代码
Shader "Custom/Glow"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_GlowColor ("Glow Color", Color) = (0, 1, 0, 1)
_GlowSize ("Glow Size", Range(0.01, 1)) = 0.2
//图片高宽比
_AspectRatio ("Aspect Ratio", Float) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _GlowColor;
half _GlowSize;
fixed _AspectRatio;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
fixed center = 0.5;
//平移原点到图片中心
fixed2 uv = i.uv - fixed2(center, center);
uv.x = abs(uv.x);
uv.y = abs(uv.y);
fixed glowSizeX = _GlowSize * _AspectRatio;
fixed glowSizeY = _GlowSize;
//内矩形最大角
fixed2 innerMax = fixed2(center-glowSizeX, center-glowSizeY);
//普通版代码
/* if (uv.x >= innerMax.x || uv.y >= innerMax.y)
{
fixed t = 0;
if (uv.x > innerMax.x && uv.y > innerMax.y) {
if ((uv.x - innerMax.x)/_AspectRatio > uv.y - innerMax.y) {
t = (uv.x - innerMax.x)/glowSizeX;
}else{
t = (uv.y - innerMax.y)/glowSizeY;
}
}else if(uv.x >= innerMax.x) {
t = (uv.x - innerMax.x)/glowSizeX;
}else if(uv.y >= innerMax.y) {
t = (uv.y - innerMax.y)/glowSizeY;
}
return col*(1-t) + _GlowColor*t;
} */
//优化后的代码(即,对上面版本的代码消除流程控制)
fixed margin = max(step(innerMax.x, uv.x), step(innerMax.y, uv.y));
fixed t = 0;
fixed tx = (uv.x - innerMax.x)/glowSizeX;
fixed ty = (uv.y - innerMax.y)/glowSizeY;
fixed innerCorner = step(innerMax.x, uv.x) * step(innerMax.y, uv.y);
fixed leftRight = step(innerMax.x, uv.x);
fixed topBottom = step(innerMax.y, uv.y);
fixed nearX = step(uv.y - innerMax.y, (uv.x - innerMax.x)/_AspectRatio);
fixed tc = tx * nearX + ty * (1 - nearX);//当uv坐标落在四个角时的插值t
t = tc * innerCorner + tx * (1-innerCorner) * leftRight + ty * (1-innerCorner) * topBottom;
col = col * (1-margin) + (col*(1-t) + _GlowColor*t) * margin;
return col;
}
ENDCG
}
}
}
效果, 通过调整GlowSize值来调整发光边缘大小