Shader "Unlit/ToonShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Brightness("Brightness", Range(0,1)) = 0.3
_Strength("Strength", Range(0,1)) = 0.5
_Color("Color", COLOR) = (1,1,1,1)
_Detail("Detail", Range(0,1)) = 0.3
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
//Pass for Toon shader
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
half3 worldNormal: NORMAL;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Brightness;
float _Strength;
float4 _Color;
float _Detail;
float Toon(float3 normal, float3 lightDir) {
float NdotL = max(0.0,dot(normalize(normal), normalize(lightDir)));
return floor(NdotL / _Detail);
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
col *= Toon(i.worldNormal, _WorldSpaceLightPos0.xyz) * _Strength * _Color + _Brightness;
return col;
}
ENDCG
}
//Pass for Casting Shadows
Pass
{
Name "CastShadow"
Tags { "LightMode" = "ShadowCaster" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
struct v2f
{
V2F_SHADOW_CASTER;
};
v2f vert( appdata_base v )
{
v2f o;
TRANSFER_SHADOW_CASTER(o)
return o;
}
float4 frag( v2f i ) : COLOR
{
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
}
}
by definition, this is a lit shader. you account for a light direction and calculate light accordingly, so it is lit.
but i assume you want to account for point and spot lights as well.
there are a billion tutorials for shader graph that exist on youtube, so i’d find one that suits your fancy. shader graph seems to be the intended way to write urp shaders, as there’s basically no documentation for writing them.
the only important part of toon shading is making sure that your light is rounded to fewer values with
floor(lighting * bandnum) / bandnum.
The thing is, the shader doesnt respond correctly with objects with the same material, i can put some object over a default unity material plane and it does generate a shadow or respond accordly to the directional light, but when its over an object with the same material with the shader it doesnt cast a shadow or respond to lights.

your shader only has a shadow caster pass, but does no shadow receiving.
on this page, they describe how to make your shader support receiving unity’s shadows about 3/4 down.
Unity - Manual: Custom shader fundamentals (unity3d.com)
i saw you said you’re using urp, i’m not sure if this will make anything differ, but i’ve never written shaders for it.