Search Unity

Toon Shader Shadows

Discussion in 'Shaders' started by zitiache, Feb 27, 2017.

  1. zitiache

    zitiache

    Joined:
    Dec 11, 2016
    Posts:
    1
    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):
    1. {
    2.     Properties {
    3.         _Color ("Color", Color) = (1,1,1,1)
    4.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    5.         _DiffuseThreshold("Diffuse Threshold", Range(0,1))= 0.1
    6.         _Shininess ("Shininess", Float)=10
    7.  
    8.     }
    9.     SubShader {
    10.        
    11.         Pass{
    12.             Name "FirstPass"
    13.             Tags{"LightMode"="ForwardBase"}
    14.                
    15.             CGPROGRAM
    16.             #pragma vertex vert
    17.             #pragma fragment frag
    18.             #pragma multi_compile_fwdbase
    19.  
    20.             #include "UnityCG.cginc"
    21.             #include "AutoLight.cginc"
    22.             uniform float4 _LightColor0;
    23.             uniform float4 _Color;
    24.             uniform float _DiffuseThreshold;
    25.             uniform float4 _SpecColor;
    26.             uniform float _Shininess;
    27.  
    28.  
    29.  
    30.             struct vertexInput{
    31.                 float4 vertex : POSITION;
    32.                 float3 normal : NORMAL;
    33.                 float2 uv : TEXCOORD2;
    34.             };
    35.             struct v2f{
    36.                 float4 pos : SV_POSITION;
    37.                 float4 posWorld : TEXCOORD0;
    38.                 float3 normalDir : TEXCOORD1;
    39.                 float2 uv : TEXCOORD2;
    40.                 LIGHTING_COORDS(3,4)
    41.             };
    42.             v2f vert(vertexInput input)
    43.             {
    44.                 v2f o;
    45.                 o.posWorld = mul(unity_ObjectToWorld, input.vertex);
    46.                 o.normalDir = mul(float4(input.normal, 0.0),unity_WorldToObject).xyz;
    47.                 o.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    48.                 o.uv=input.uv;
    49.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    50.                 return o;
    51.             }
    52.             sampler2D _MainTex;
    53.             float4 frag(v2f i) : COLOR
    54.             {
    55.                 float3 normalDirection= normalize (i.normalDir);
    56.  
    57.                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
    58.                 float3 lightDirection;
    59.                 float attenuation;
    60.  
    61.                 if (0.0 == _WorldSpaceLightPos0.w) //directional light
    62.                 {
    63.                     attenuation = SHADOW_ATTENUATION(i); //no attenuation
    64.                     lightDirection = normalize (_WorldSpaceLightPos0.xyz);
    65.                 }
    66.                 else //point or spot light
    67.                 {
    68.                     float3 vertexToLightSource=_WorldSpaceLightPos0.xyz-i.posWorld.xyz;
    69.                     float distance = length(vertexToLightSource);
    70.                     attenuation = SHADOW_ATTENUATION(i)/distance;//linear attenuation
    71.                     lightDirection = normalize(vertexToLightSource);
    72.                 }
    73.                 // default: unlit
    74.                 float3 fragmentColor =  _Color.rgb*tex2D(_MainTex, i.uv);
    75.  
    76.  
    77.                 if (attenuation*max(0.0, dot(normalDirection, lightDirection))< _DiffuseThreshold)
    78.                 {
    79.                    
    80.                     fragmentColor =   1.0-((1.0-unity_AmbientSky)/fragmentColor);
    81.                 }
    82.  
    83.                 if(attenuation * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), _Shininess)*max(0.0,dot(normalDirection, lightDirection)) > 0.5)
    84.                 {
    85.                     fragmentColor = 1.0-(1.0-_LightColor0.rgb)* (1.0-fragmentColor);
    86.                 }
    87.  
    88.                 return float4(fragmentColor, 1.0);
    89.             }
    90.             ENDCG
    91.         }
    92.         Pass {
    93.             Name "Additional"
    94.             Tags {"LightMode" = "ForwardAdd"}
    95.        
    96.             Blend One OneMinusSrcColor
    97.                
    98.             CGPROGRAM
    99.  
    100.             #pragma vertex vert
    101.             #pragma fragment frag
    102.             #pragma target 3.0
    103.             #include "UnityCG.cginc"
    104.             #include "AutoLight.cginc"
    105.             uniform float4 _LightColor0;
    106.  
    107.             uniform float4 _Color;
    108.             uniform float _DiffuseThreshold;
    109.             uniform float _Shininess;
    110.  
    111.             struct vertexInput{
    112.                 float4 vertex : POSITION;
    113.                 float3 normal : NORMAL;
    114.                 float2 uv : TEXCOORD2;
    115.             };
    116.             struct v2f{
    117.                 float4 pos : SV_POSITION;
    118.                 float4 posWorld : TEXCOORD0;
    119.                 float3 normalDir : TEXCOORD1;
    120.                 float2 uv : TEXCOORD2;
    121.                 LIGHTING_COORDS(3,4)
    122.             };
    123.  
    124.             v2f vert(vertexInput input)
    125.             {
    126.                 v2f o;
    127.  
    128.                 float4x4 modelMatrix= unity_ObjectToWorld;
    129.                 float4x4 modelMatrixInverse = unity_WorldToObject;
    130.  
    131.                 o.posWorld = mul(modelMatrix, input.vertex);
    132.                 o.normalDir = normalize(mul(float4(input.normal, 0.0),modelMatrixInverse).rgb);
    133.                 o.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    134.                 o.uv=input.uv;
    135.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    136.                 return o;
    137.             }
    138.             sampler2D _MainTex;
    139.             float4 frag(v2f i) : COLOR
    140.             {
    141.                 float3 normalDirection= normalize (i.normalDir);
    142.  
    143.                 float3 viewDirection = normalize(_WorldSpaceCameraPos - i.posWorld.rgb);
    144.                 float3 lightDirection;
    145.                 float attenuation;
    146.  
    147.                 if (0.0 == _WorldSpaceLightPos0.w)
    148.                 {
    149.                     attenuation = SHADOW_ATTENUATION(i);
    150.                     lightDirection = normalize (_WorldSpaceLightPos0.xyz);
    151.                 }
    152.                 else
    153.                 {
    154.                     float3 vertexToLightSource= _WorldSpaceLightPos0.xyz-i.posWorld.xyz;
    155.                     float distance = length(vertexToLightSource);
    156.                     attenuation = SHADOW_ATTENUATION(i)/distance;
    157.                     lightDirection = normalize(vertexToLightSource);
    158.                 }
    159.  
    160.                 float4 fragmentColor = float4(0.0, 0.0, 0.0, 0.0);
    161.  
    162.  
    163.                 if(attenuation * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), _Shininess)*max(0.0,dot(normalDirection, lightDirection)) > 0.5)
    164.                 {
    165.                     fragmentColor = float4( _LightColor0.rgb, 1.0);
    166.  
    167.                 }
    168.                 return fragmentColor;
    169.             }
    170.             ENDCG
    171.  
    172.         }
    173.  
    174.  
    175.     }
    176.     FallBack "VertexLit"
    177. }
    178.  
    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.