Shader mesh not being effected by directional lights?

I’ve written a simple shader which takes two heightmaps and distorts a flat plane mesh accordingly. You can find this below:

   Shader "Extrusion" {
    Properties {
      _WaveTex ("Texture", 2D) = "white" {}
      _HeightTex ("Texture", 2D) = "white" {}
      _Amount ("Height Extrusion Amount", Range(-1,1)) = 0.5
      _WaveAmount ("Wave Extrusion Amount", Range(-1,1)) = 0.5
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }

      CGPROGRAM
      #pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:vert nolightmap
      struct Input {
          float2 uv_HeightTex;
      };

      sampler2D _WaveTex;
      sampler2D _HeightTex;
       sampler2D _OutputTex;

      float _Amount;
      float _WaveAmount;

      void vert (inout appdata_full v) {
 		float4 waveTex = tex2Dlod (_WaveTex, float4(v.texcoord.xy,0,0));
 		float4 heightTex = tex2Dlod (_HeightTex, float4(v.texcoord.xy,0,0));

    	v.vertex.y += ((waveTex.b * _WaveAmount) + (heightTex.b * _Amount)) / 2.0;      
   		}

      void surf (Input IN, inout SurfaceOutput o) {
          o.Albedo = 1.0;
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

The weird thing is that it doesn’t seem to interact correctly with directional lights. The entire distorted plane is a uniform single colour - even in areas where you’d expect the light to be much darker such as cracks and crevices. This isn’t the case when a point light is placed near to the plane, then it is shaded as you’d expect.

Erroneous uniform colour (directional light):

Interestingly, the plane is definitely receiving the directional light because if I rotate it around then the lighting changes - it’s just always a completely uniform colour!

Any help would be greatly appreciated - I’m really tearing my hair out over it!

You’re modifying the vertex positions on the mesh, but you aren’t making the same adjustments for the normals.

If you want to generate appropriate lighting in the vertex shader to work with the vertex positions, you’ll need some more texture samples.

// 
//     Y
//     |
//     O---X
// 

Consider the “O” to be the pixel you’re currently sampling on your texture. The “X”, then, is the neighboring pixel at float4(v.texcoord.x + _WaveHeight_TexelSize.x, v.texcoord.y, 0, 0). The “Y” is the same, adjusted accordingly. http://forum.unity3d.com/threads/_maintex_texelsize-whats-the-meaning.110278/

Once you’ve established your variations of waveTex, waveTexPlusX and waveTexPlusY (and heightTex, by association), you take the cross product of them to get a new normal.

// Names shortened for simplicity (waveTex -> wt)
float3 newNormal = normalize(cross(wtpY - wt, wtpX - wt));

Hope this gets you started in the right direction!