Here is the code
Shader "Custom/CelShadeLighting"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Texture (RGB)", 2D) = "white" {}
_ShadingRamp ("Shading Ramp", 2D) = "white" {}
}
SubShader
{
Pass
{
Tags
{
"LightMode" = "ForwardBase"
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#pragma multi_compile_fwdbase
struct appdata
{
float4 vertex : POSITION;
float4 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldNormal : NORMAL;
float2 uv : TEXCOORD0;
float3 viewDir : TEXCOORD1;
// Macro found in Autolight.cginc. Declares a vector4
// into the TEXCOORD2 semantic with varying precision
// depending on platform target.
SHADOW_COORDS(2)
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _Color;
sampler2D _ShadingRamp;
v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.viewDir = WorldSpaceViewDir(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// Defined in Autolight.cginc. Assigns the above shadow coordinate
// by transforming the vertex from world space to shadow-map space.
TRANSFER_SHADOW(o)
return o;
}
float4 frag(v2f i) : COLOR
{
float4 color;
UNITY_INITIALIZE_OUTPUT(fixed4, color);
float4 texColor = tex2D(_MainTex, i.uv);
half3 worldNormal = (i.worldNormal); //get world normal
float4 tintcolor = _Color;
// -Receiving Shadows-
half shadow = SHADOW_ATTENUATION(i); //get shadow attenuation
shadow = tex2D(_ShadingRamp, float2(shadow, 0.5));
// -Cel Shade effect-
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); //light direction
float lightAmt = dot(worldNormal, lightDir);
lightAmt = (lightAmt + 1) / 2;
lightAmt *= shadow;
float2 coordinates = float2(lightAmt, 0.5);
float4 rampColor = tex2D(_ShadingRamp, coordinates);
// -Combining all elements together
color.rgb = texColor * tintcolor * rampColor * _LightColor0;
return color;
}
ENDCG
}
Pass //Add more Lighting
{
Tags
{
"LightMode" = "ForwardAdd"
}
BlendOp Max
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdadd
//#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
//#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
struct appdata
{
float4 vertex : POSITION;
float4 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldNormal : NORMAL;
float2 uv : TEXCOORD0;
float3 viewDir : TEXCOORD1;
LIGHTING_COORDS(3, 4)
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _Color;
sampler2D _ShadingRamp;
v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.viewDir = WorldSpaceViewDir(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
TRANSFER_VERTEX_TO_FRAGMENT(o); //lighting
return o;
}
float4 frag(v2f i) : COLOR
{
float4 color;
UNITY_INITIALIZE_OUTPUT(fixed4, color);
float4 texColor = tex2D(_MainTex, i.uv);
half3 worldNormal = (i.worldNormal); //get world normal
float4 tintcolor = _Color;
// -Additional Light-
half attenuation = LIGHT_ATTENUATION(i);
//attenuation = tex2D(_ShadingRamp, float2(attenuation, 0.5));
// -Cel Shade effect-
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); //light direction
float lightAmt = dot(worldNormal, lightDir);
lightAmt = (lightAmt + 1) / 2;
lightAmt *= attenuation;
float2 coordinates = float2(lightAmt , 0.5);
float4 rampColor = tex2D(_ShadingRamp, coordinates) * _LightColor0;
// -Combining all elements together
color.rgb = texColor * tintcolor * rampColor;
return color;
}
ENDCG
}
// Shadow casting support.
UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
}
}