So I'm writing my own toon Shader, and I like how it looks so far, but I have issues with the shadows. I'm using very hard shadows with no transition, and I'm noticing the shadow threshold "flickering" when I zoom the camera in/out. I think it has something to do with Autolight(I want objects to cast shadows), because if I set attenuation to one (rather than LIGHT_ATTENUATION() or SHADOW_ATTENUATION()) there's no flickering. Code (CSharp): { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _DiffuseThreshold("Diffuse Threshold", Range(0,1))= 0.1 _Shininess ("Shininess", Float)=10 } SubShader { Pass{ Name "FirstPass" Tags{"LightMode"="ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase #include "UnityCG.cginc" #include "AutoLight.cginc" uniform float4 _LightColor0; uniform float4 _Color; uniform float _DiffuseThreshold; uniform float4 _SpecColor; uniform float _Shininess; struct vertexInput{ float4 vertex : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD2; }; struct v2f{ float4 pos : SV_POSITION; float4 posWorld : TEXCOORD0; float3 normalDir : TEXCOORD1; float2 uv : TEXCOORD2; LIGHTING_COORDS(3,4) }; v2f vert(vertexInput input) { v2f o; o.posWorld = mul(unity_ObjectToWorld, input.vertex); o.normalDir = mul(float4(input.normal, 0.0),unity_WorldToObject).xyz; o.pos = mul(UNITY_MATRIX_MVP, input.vertex); o.uv=input.uv; TRANSFER_VERTEX_TO_FRAGMENT(o); return o; } sampler2D _MainTex; float4 frag(v2f i) : COLOR { float3 normalDirection= normalize (i.normalDir); float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz); float3 lightDirection; float attenuation; if (0.0 == _WorldSpaceLightPos0.w) //directional light { attenuation = SHADOW_ATTENUATION(i); //no attenuation lightDirection = normalize (_WorldSpaceLightPos0.xyz); } else //point or spot light { float3 vertexToLightSource=_WorldSpaceLightPos0.xyz-i.posWorld.xyz; float distance = length(vertexToLightSource); attenuation = SHADOW_ATTENUATION(i)/distance;//linear attenuation lightDirection = normalize(vertexToLightSource); } // default: unlit float3 fragmentColor = _Color.rgb*tex2D(_MainTex, i.uv); if (attenuation*max(0.0, dot(normalDirection, lightDirection))< _DiffuseThreshold) { fragmentColor = 1.0-((1.0-unity_AmbientSky)/fragmentColor); } if(attenuation * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), _Shininess)*max(0.0,dot(normalDirection, lightDirection)) > 0.5) { fragmentColor = 1.0-(1.0-_LightColor0.rgb)* (1.0-fragmentColor); } return float4(fragmentColor, 1.0); } ENDCG } Pass { Name "Additional" Tags {"LightMode" = "ForwardAdd"} Blend One OneMinusSrcColor CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #include "UnityCG.cginc" #include "AutoLight.cginc" uniform float4 _LightColor0; uniform float4 _Color; uniform float _DiffuseThreshold; uniform float _Shininess; struct vertexInput{ float4 vertex : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD2; }; struct v2f{ float4 pos : SV_POSITION; float4 posWorld : TEXCOORD0; float3 normalDir : TEXCOORD1; float2 uv : TEXCOORD2; LIGHTING_COORDS(3,4) }; v2f vert(vertexInput input) { v2f o; float4x4 modelMatrix= unity_ObjectToWorld; float4x4 modelMatrixInverse = unity_WorldToObject; o.posWorld = mul(modelMatrix, input.vertex); o.normalDir = normalize(mul(float4(input.normal, 0.0),modelMatrixInverse).rgb); o.pos = mul(UNITY_MATRIX_MVP, input.vertex); o.uv=input.uv; TRANSFER_VERTEX_TO_FRAGMENT(o); return o; } sampler2D _MainTex; float4 frag(v2f i) : COLOR { float3 normalDirection= normalize (i.normalDir); float3 viewDirection = normalize(_WorldSpaceCameraPos - i.posWorld.rgb); float3 lightDirection; float attenuation; if (0.0 == _WorldSpaceLightPos0.w) { attenuation = SHADOW_ATTENUATION(i); lightDirection = normalize (_WorldSpaceLightPos0.xyz); } else { float3 vertexToLightSource= _WorldSpaceLightPos0.xyz-i.posWorld.xyz; float distance = length(vertexToLightSource); attenuation = SHADOW_ATTENUATION(i)/distance; lightDirection = normalize(vertexToLightSource); } float4 fragmentColor = float4(0.0, 0.0, 0.0, 0.0); if(attenuation * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), _Shininess)*max(0.0,dot(normalDirection, lightDirection)) > 0.5) { fragmentColor = float4( _LightColor0.rgb, 1.0); } return fragmentColor; } ENDCG } } FallBack "VertexLit" } I'm a self-taught programmer, and this shader is made up of bits and pieces I've found online, so maybe this isn't the most well-written code, but I would appreciate any help I can get.