Custom shader Curved Diffuse lighting not working

Hi guys, I’m getting mad with this. I’m using Unity 5 and I’m tring to resolve this problem from yesterday searching on Unity Answer or similar. Everything that I’m trying is not working and I don’t know why.

So:
I’m new in Shader coding and I’m trying to figure out how to solve a problem:
My company has a shader

Shader "Curved Diffuse" {

Properties {

    _MainTex ("Base (RGB)", 2D) = "white" {}

     _Color ("Main Color", Color) = (1,0.5,0.5,1)
}

SubShader {

    Tags { "RenderType"="Opaque" }

    LOD 150

    CGPROGRAM

    #pragma exclude_renderers flash

    #pragma surface surf Lambert noforwardadd vertex:vert
    
    sampler2D _MainTex;

    float4 _QOffset;

    float _Dist;
     float4 _Color;
    

    struct Input {

        float2 uv_MainTex;

    };

    

    void vert (inout appdata_full v) {

        // Get the view space vertex position

        float4 vertex_view = mul(UNITY_MATRIX_MV, v.vertex);

        // Calculate the offset in view space

        float zOff = vertex_view.z / _Dist;

        // Convert the offset back to object space and add it to vertex

       v.vertex.xyz += mul(_QOffset*zOff*zOff, UNITY_MATRIX_IT_MV).xyz;

    }

    

    void surf (Input IN, inout SurfaceOutput o) {

        fixed4 c = tex2D(_MainTex, IN.uv_MainTex);

        o.Albedo =c.rgb;
        o.Albedo *= _Color.rgb;

        o.Alpha = c.a;

    }

    

    ENDCG

}


Fallback "Mobile/VertexLit"

}

Now, we add a light (a directional light that cast hard shadows) to the scene and we noticed that shadows don’t follow the deformation. So I start looking for and answer.
Following these istruction: Need to get lighting to work on bending vertex shader... - Unity Answers
I try by erasing the Fallback “VertexLit”
then adding #pragma addshadow
but nothing happen.

So I try to find the solution provided by another source:
http://forum.unity3d.com/threads/modifying-vertex-position-shader-in-a-surface-shader-shadow-problems.216276/
I try to add after my code the code developed from jvo3dc, but nothing change.
Maybe I’m using the code in the wrong way, This is what I did:

Shader "Curved Diffuse shadows" {

Properties {

    _MainTex ("Base (RGB)", 2D) = "white" {}

     _Color ("Main Color", Color) = (1,0.5,0.5,1)
}

SubShader {

	    Tags { "RenderType"="Opaque"  }

	    LOD 150

	 

	    CGPROGRAM

	    #pragma exclude_renderers flash

	    #pragma surface surf Lambert  vertex:vert  addshadow

	   // #pragma surface surf Lambert alpha

	    sampler2D _MainTex;

	    float4 _QOffset;

	    float _Dist;
	    
	    float4 _Color;
	    

	    struct Input {

	        float2 uv_MainTex;

	    };

	    

	    void vert (inout appdata_full v) {

	        // Get the view space vertex position

	        float4 vertex_view = mul(UNITY_MATRIX_MV, v.vertex);

	        // Calculate the offset in view space

	        float zOff = vertex_view.z / _Dist;

	        // Convert the offset back to object space and add it to vertex

	       v.vertex.xyz += mul(_QOffset*zOff*zOff, UNITY_MATRIX_IT_MV).xyz;

	    }

	    

	    void surf (Input IN, inout SurfaceOutput o) {

        fixed4 c = tex2D(_MainTex, IN.uv_MainTex);

        o.Albedo =c.rgb;
            o.Albedo *= _Color.rgb;

        o.Alpha = c.a;

    }

	    ENDCG
	    
	 
// Pass to render object as a shadow caster
Pass {
    Name "ShadowCaster"
    Tags { "LightMode" = "ShadowCaster" }
           
    Fog {Mode Off}
    ZWrite On ZTest LEqual Cull Off
    Offset 1, 1
     
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #pragma multi_compile_shadowcaster
    #pragma fragmentoption ARB_precision_hint_fastest
    #include "UnityCG.cginc"
 
    float4 _QOffset;
    float _Dist;
             
    struct v2f {
        V2F_SHADOW_CASTER;
    };
             
    v2f vert( appdata_base v ) {
        float4 vPos = mul (UNITY_MATRIX_MV, v.vertex);
        float zOff = vPos.z/_Dist;
        vPos += _QOffset*zOff*zOff;
        v.vertex = mul (vPos, UNITY_MATRIX_IT_MV);
        v2f o;
        TRANSFER_SHADOW_CASTER(o)
        return o;
    }
             
    float4 frag( v2f i ) : COLOR {
        SHADOW_CASTER_FRAGMENT(i)
    }
    ENDCG
}
       
// Pass to render object as a shadow collector
Pass {
    Name "ShadowCollector"
    Tags { "LightMode" = "ShadowCollector" }
           
    Fog {Mode Off}
    ZWrite On ZTest LEqual
     
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #pragma fragmentoption ARB_precision_hint_fastest
    #pragma multi_compile_shadowcollector
             
    #define SHADOW_COLLECTOR_PASS
    #include "UnityCG.cginc"
 
    float4 _QOffset;
    float _Dist;
 
    struct appdata {
        float4 vertex : POSITION;
    };
             
    struct v2f {
        V2F_SHADOW_COLLECTOR;
    };
             
    v2f vert (appdata v) {
        float4 vPos = mul (UNITY_MATRIX_MV, v.vertex);
        float zOff = vPos.z/_Dist;
        vPos += _QOffset*zOff*zOff;
        v.vertex = mul (vPos, UNITY_MATRIX_IT_MV);
        v2f o;
        TRANSFER_SHADOW_COLLECTOR(o)
        return o;
    }
             
    fixed4 frag (v2f i) : COLOR {
        SHADOW_COLLECTOR_FRAGMENT(i)
    }
    ENDCG
}
	}

//Fallback "Mobile/VertexLit"

}

I really don’t know what to do, I’m tring to read as much as possible about SurfaceShader, but I’m not understanding why things are not working in the proper way.
Any help will be really appreciated.
Thanks a lot

I still try to understand how to create a proper curved diffuse with good shadows.

The first part of the shader works fine, the geometry is correctly deformed and adding addshadow to the #pragma vertex vert allows me to have good natural shade effect on the models of the game.

The part witch is not working are the shadows, witch are controlled from the two Passes that follows, and i still don’t understand why they don’t work.

This is the shader:

Shader "Curved Diffuse Mod 2 shadows" {

Properties {

    _MainTex ("Base (RGB)", 2D) = "white" {}

     _Color ("Main Color", Color) = (1,0.5,0.5,1)
}

SubShader {

	    Tags { "RenderType"="Opaque"  }

	    LOD 150

	    CGPROGRAM

	    #pragma exclude_renderers flash

	    #pragma surface surf Lambert  
	    #pragma vertex vert  addshadow

	    sampler2D _MainTex;

	    float4 _QOffset;

	    float _Dist;
	    
	    float4 _Color;
	    

	    struct Input {

	        float2 uv_MainTex;

	    };

	    

	    void vert (inout appdata_full v) {

	        // Get the view space vertex position

	        float4 vertex_view = mul(UNITY_MATRIX_MV, v.vertex);

	        // Calculate the offset in view space

	        float zOff = vertex_view.z / _Dist;

	        // Convert the offset back to object space and add it to vertex

	       v.vertex.xyz += mul(_QOffset*zOff*zOff, UNITY_MATRIX_IT_MV).xyz;

	    }

	    

	    void surf (Input IN, inout SurfaceOutput o) {

        fixed4 c = tex2D(_MainTex, IN.uv_MainTex);

        o.Albedo =c.rgb;
        o.Albedo *= _Color.rgb;

        o.Alpha = c.a;

    }

	    ENDCG

This part is the part that should manage shadows. I don’t understand why but the ShadowCollector Pass is not working. I commented the Pass and shader continue to work without any change. Worst, I put some code line with evident bugs, like this one commented in the code: o.pos = mul(UNITY_MATRIX_IT_MV, v.vertex); Still nothing change. The shader continue to work like the ShadowCollector Pass doesn’t exist. Dunno why. Please help!
To help myself in understanding what was happening i try to understand the behaviour of Shadow caster pass helpers in “UnityCG.cginc” and i copy in the script the #define part of each function. Sadly this operation confuse me more than before, because for what I understand about the ShadowCollector and the ShadowCaster, this two Passes should work.

// Pass to render object as a shadow collector
Pass {
    Name "ShadowCollector"
    Tags { "LightMode" = "ShadowCollector" }
           
    Fog {Mode Off}
    ZWrite On ZTest LEqual
     
    CGPROGRAM
    #pragma vertex vert 
    #pragma fragment frag
    #pragma fragmentoption ARB_precision_hint_fastest
    #pragma multi_compile_shadowcollector
             
    #define SHADOW_COLLECTOR_PASS
    #include "UnityCG.cginc"
 
    float4 _QOffset;
    float _Dist;
 
    struct appdata {
        float4 vertex : POSITION;
    };
             
    struct v2f {
        V2F_SHADOW_COLLECTOR;
    };
             
    v2f vert (appdata v) {
        float4 vPos = mul (UNITY_MATRIX_MV, v.vertex);
        float zOff = vPos.z/_Dist;

	    v.vertex.xyz += mul(_QOffset*zOff*zOff, UNITY_MATRIX_IT_MV).xyz;
        
        
        v2f o;
        //o.pos = mul(UNITY_MATRIX_IT_MV, v.vertex);
        TRANSFER_SHADOW_COLLECTOR(o);
        
        o.pos += mul(_QOffset*zOff*zOff, UNITY_MATRIX_IT_MV);
        //TRANSFER_SHADOW_COLLECTOR(o) definition in "UnityCG.cginc"
        // o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
        // float4 wpos = mul(_Object2World, v.vertex);
        // o._WorldPosViewZ.xyz = wpos;
        // o._WorldPosViewZ.w = -mul( UNITY_MATRIX_MV, v.vertex ).z;
        // o._ShadowCoord0 = mul(unity_World2Shadow[0], wpos).xyz;
        // o._ShadowCoord1 = mul(unity_World2Shadow[1], wpos).xyz;
        // o._ShadowCoord2 = mul(unity_World2Shadow[2], wpos).xyz;
        // o._ShadowCoord3 = mul(unity_World2Shadow[3], wpos).xyz;
        
        
//        o.vec = mul( _Object2World, v.vertex ).xyz - _LightPositionRange.xyz; 
//        o.pos = mul(UNITY_MATRIX_MV, v.vertex);
        
        return o;
    }
             
    fixed4 frag (v2f i) : COLOR {
        SHADOW_COLLECTOR_FRAGMENT(i);

        //SHADOW_COLLECTOR_FRAGMENT(i) definition in "UnityCG.cginc"
        // float4 viewZ = i._WorldPosViewZ.w;
        // float4 zNear = float4( viewZ >= _LightSplitsNear );
        // float4 zFar = float4( viewZ < _LightSplitsFar );
        // float4 cascadeWeights = zNear * zFar;
        // float shadowFade = saturate(i._WorldPosViewZ.w * _LightShadowData.z + _LightShadowData.w);
        // COMPUTE_SHADOW_COLLECTOR_SHADOW(i, cascadeWeights, shadowFade)
        
        // COMPUTE_SHADOW_COLLECTOR_SHADOW(i, weights, shadowFade) definition in "UnityCG.cginc"
        // float4 coord = float4(i._ShadowCoord0 * weights[0] + i._ShadowCoord1 * weights[1] + i._ShadowCoord2 * weights[2] + i._ShadowCoord3 * weights[3], 1); 
        // SAMPLE_SHADOW_COLLECTOR_SHADOW(coord) 
        // float4 res; 
        // res.x = saturate(shadow + shadowFade); 
        // res.y = 1.0; \ res.zw = EncodeFloatRG (1 - i._WorldPosViewZ.w * _ProjectionParams.w); 
        // return res;
    }
    ENDCG
}	    	    
	 
// Pass to render object as a shadow caster
Pass {
    Name "ShadowCaster"
    Tags { "LightMode" = "ShadowCaster" }
           
    Fog {Mode Off}
    ZWrite On ZTest LEqual Cull Off
    //Offset 1, 1
     
    CGPROGRAM
    #pragma vertex vert 
    #pragma fragment frag
    #pragma multi_compile_shadowcaster
    #pragma fragmentoption ARB_precision_hint_fastest
    #include "UnityCG.cginc"
 
    float4 _QOffset;
    float _Dist;
             
    struct v2f {
        V2F_SHADOW_CASTER;
        
        //V2F_SHADOW_CASTER is this structure: 
        //float4 pos : SV_POSITION; float3 vec : TEXCOORD0
    };
             
    v2f vert( appdata_full v ) {
        float4 vPos = mul (UNITY_MATRIX_MV, v.vertex);
        float zOff = vPos.z/_Dist;

	    v.vertex.xyz += mul(_QOffset*zOff*zOff, UNITY_MATRIX_IT_MV).xyz;
        
        v2f o;

        TRANSFER_SHADOW_CASTER(o);
        
      //TRANSFER_SHADOW_CASTER(o) makes this operations: 
      // o.vec = mul( _Object2World, v.vertex ).xyz - _LightPositionRange.xyz; 
      // o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

      return o;
    }
             
    float4 frag( v2f i ) : COLOR {
        SHADOW_CASTER_FRAGMENT(i);
    }
    ENDCG
}
       
}

}

Some knows why the Shadow Collector is not working?