天天看點

【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個人原創,版權所有,轉載注明,謝謝。