这个光晕效果的关键是检测物体边缘,利用模型顶点到摄像机对象的方向和模型法线的夹角大小来判断,不多说上代码:

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
    }
  }
}

 效果如下:

 

posted on 2021-09-09 22:30  辽州小虾米  阅读(365)  评论(0编辑  收藏  举报