Rim lighting
This shader uses the difference between the view direction and the polygon surface normal to add additional color offset to the surface.
Shader
Shader "Shaders/Material/RimLight" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Color ("Color", Color) = (1, 1, 1, 1)
_Rim ("Rim", Range(0,1)) = 0.1
}
SubShader {
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Standard
sampler2D _MainTex;
float4 _Color;
float _Rim;
#define RIM (1.0 - _Rim)
struct Input {
float2 uv_MainTex;
float3 worldNormal;
float3 viewDir;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
// Calculate the angle between normal and view direction
float diff = 1.0 - dot(IN.worldNormal, IN.viewDir);
// Cut off the diff to the rim size using the RIM value.
diff = step(RIM, diff) * diff;
// Smooth value
float value = step(RIM, diff) * (diff - RIM) / RIM;
// Sample texture and add rim color
float3 rgb = tex2D(_MainTex, IN.uv_MainTex).rgb;
o.Albedo = float3(value) * _Color + rgb;
}
ENDCG
}
FallBack "Diffuse"
}
Shader Notes
Notice that initially the value of step(RIM, diff) * diff
will be in the range [1:RIM]; although this works, if the value of RIM is high, the falloff at the edge of the rim lighting is extremely harsh.
To fix this, the value is scaled into the range [1:0] using:
float value = step(RIM, diff) * (diff - RIM) / RIM;
This makes the transition from the rim color to the original texture smoother.