这个光晕效果的关键是检测物体边缘,利用模型顶点到摄像机对象的方向和模型法线的夹角大小来判断,不多说上代码:
Shader "Unlit/HaloShader"
{
Properties
{
// 指定颜色,默认为红色信号灯
halo_color("Color", Color) = (1, 0, 0, 1)
// 手动调节闪烁频率
flicker("flicker", float) = 4.0
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" }
Pass
{
// 关闭深度写入
ZWrite Off
// 生成的颜色乘以 src,屏幕已有颜色乘以 dst
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#include"UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
#define PI 3.14159265359
struct a2v
{
float4 pos : POSITION;
float3 n : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 n : NORMAL;
float3 dir : TEXCOORD0;
};
fixed4 halo_color;
float flicker;
v2f vert(a2v data)
{
v2f f;
f.pos = UnityObjectToClipPos(data.pos);
f.n = data.n;
f.dir = normalize(ObjSpaceViewDir(data.pos));
return f;
}
fixed4 frag(v2f f) : SV_Target
{
// 计算 cos( x ) cos(x) 越接近1,则渲染的像素则越处于模型中心
float c = abs(dot(f.n, f.dir));
float pct = abs(sin(_Time * flicker * PI));
// 采用造型函数 y = abs(sin(x)) 得到一个闪烁的信号灯效果
// 调整 x 可以调解闪烁频率abs(sin(x * _Time * PI))
return pct * c * halo_color;
}
ENDCG
}
}
}
效果如下: