天天看点

【Shader】边缘发光效果的两种写法

     我们可以看到很多游戏经常会有这种模型边缘发光的效果,看起来很高大上的样子。其实实现起来挺简单的,网上也有很多这样的例子分享,现在我也来分享一下两种Shader实现的代码吧。

1.Surface Shader

Shader "Custom/Rim Light" {
       Properties {
              _MainTex("Base (RGB)", 2D) = "white" {}
              _RimColor("_RimColor", Color) =(0.17,0.36,0.81,0.0)
              _RimWidth("_RimWidth", Range(0.6,9.0)) = 0.9
       }
 
       SubShader {
              Tags{ "RenderType" = "Opaque"}
			  LOD 150

              CGPROGRAM
 
              #pragma surface surf Lambert
             
              struct Input {
                     float2 uv_MainTex;
                     float3 viewDir;
              };
 
              sampler2D _MainTex;
              fixed4 _RimColor;
              fixed _RimWidth;
 
              void surf (Input IN, inout SurfaceOutput o) {
					 fixed4 t = tex2D (_MainTex, IN.uv_MainTex);
                     o.Albedo = t.rgb;
					 o.Alpha = t.a;
                     half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
                     o.Emission= _RimColor.rgb * pow (rim, _RimWidth);
              }

              ENDCG
       }
 
       Fallback "Diffuse"
}           

主要是这两句起到关键作用。

half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
o.Emission= _RimColor.rgb * pow (rim, _RimWidth);           

如果不想受灯光影响,可以在Tags加上"LightMode"="Always"

2.Vetex and Fragment Shader

Shader "Custom/Rim Light VF" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _Color ("Main Color", Color) = (1,1,1,1)
        _RimColor ("Rim Color", Color) = (1, 1, 1, 1)
        _RimWidth ("Rim Width", float) = 0.9
    }
    SubShader {
        Pass {
       		Lighting Off
            CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"

                struct appdata 
                {
                    float4 vertex : POSITION;
                    float3 normal : NORMAL;
                    float2 texcoord : TEXCOORD0;
                };

                struct v2f 
                {
                    float4 pos : SV_POSITION;
                    float2 uv : TEXCOORD0;
                    fixed3 color : COLOR;
                };

                uniform float4 _MainTex_ST;
                uniform fixed4 _RimColor;
                float _RimWidth;

                v2f vert (appdata_base v) {
                    v2f o;
                    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);

                    float3 viewDir = normalize(ObjSpaceViewDir(v.vertex));
                    float dotProduct = 1 - dot(v.normal, viewDir);
                   
                    o.color = smoothstep(1 - _RimWidth, 1.0, dotProduct);
                    o.color *= _RimColor;

                    o.uv = v.texcoord.xy;
                    return o;
                }

                uniform sampler2D _MainTex;
                uniform fixed4 _Color;

                fixed4 frag(v2f i) : COLOR {
                    fixed4 texcol = tex2D(_MainTex, i.uv);
                    texcol *= _Color;
                    texcol.rgb += i.color;
                    return texcol;
                }
            ENDCG
        }
    }
}           

当然最关键的还是vert方法里的代码,具体两种方法大家可以根据需求使用。看看效果,赶紧试试吧。

【Shader】边缘发光效果的两种写法

Ricky Yang个人原创,版权所有,转载注明,谢谢。