Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time
75 lines (63 sloc) 2.83 KB
Shader "Tutorial/031_SteppedToon" {
//show values to edit in inspector
Properties {
[Header(Base Parameters)]
_Color ("Tint", Color) = (0, 0, 0, 1)
_MainTex ("Texture", 2D) = "white" {}
[HDR] _Emission ("Emission", color) = (0 ,0 ,0 , 1)
[Header(Lighting Parameters)]
_ShadowTint ("Shadow Color", Color) = (0.5, 0.5, 0.5, 1)
SubShader {
//the material is completely non-transparent and is rendered at the same time as the other opaque geometry
Tags{ "RenderType"="Opaque" "Queue"="Geometry"}
//the shader is a surface shader, meaning that it will be extended by unity in the background to have fancy lighting and other features
//our surface shader function is called surf and we use our custom lighting model
//fullforwardshadows makes sure unity adds the shadow passes the shader might need
#pragma surface surf Stepped fullforwardshadows
#pragma target 3.0
sampler2D _MainTex;
fixed4 _Color;
half3 _Emission;
float3 _ShadowTint;
//our lighting function. Will be called once per light
float4 LightingStepped(SurfaceOutput s, float3 lightDir, half3 viewDir, float shadowAttenuation){
//how much does the normal point towards the light?
float towardsLight = dot(s.Normal, lightDir);
// make the lighting a hard cut
float towardsLightChange = fwidth(towardsLight);
float lightIntensity = smoothstep(0, towardsLightChange, towardsLight);
//for directional lights, get a hard vut in the middle of the shadow attenuation
float attenuationChange = fwidth(shadowAttenuation) * 0.5;
float shadow = smoothstep(0.5 - attenuationChange, 0.5 + attenuationChange, shadowAttenuation);
//for other light types (point, spot), put the cutoff near black, so the falloff doesn't affect the range
float attenuationChange = fwidth(shadowAttenuation);
float shadow = smoothstep(0, attenuationChange, shadowAttenuation);
lightIntensity = lightIntensity * shadow;
//calculate shadow color and mix light and shadow based on the light. Then taint it based on the light color
float3 shadowColor = s.Albedo * _ShadowTint;
float4 color;
color.rgb = lerp(shadowColor, s.Albedo, lightIntensity) * _LightColor0.rgb;
color.a = s.Alpha;
return color;
//input struct which is automatically filled by unity
struct Input {
float2 uv_MainTex;
//the surface shader function which sets parameters the lighting function then uses
void surf (Input i, inout SurfaceOutput o) {
//sample and tint albedo texture
fixed4 col = tex2D(_MainTex, i.uv_MainTex);
col *= _Color;
o.Albedo = col.rgb;
o.Emission = _Emission;
FallBack "Standard"