Hi,
I think your problem is in the Normal matrix. Maybe I am wrong because it is early in the morning and I didn't have enough coffee but you are using a vec4 Normal and a mat4 normal matrix which might be the root of all evil.
Detailed answer:
Thing is, your model matrix creates a position vector when multiplied with another position vector from your model. This includes displacements (translation). A normal is not a position vector. It is a direction vector. Directions don't have displacements and you should never use them on direction vectors. The simple trick to disable the displacement of a vector is to set its fourth component to zero while you need a one as their fourth component if you want them to contribute. This works since the displacement part of a transformation matrix is completely stored in the fourth column. Just have a look at the individual components (scaling, rotation, displacement) of a transformation matrix (look at the picture in section 10: http://www.c-jump.com/bcc/common/Talk3/Math/Matrices/Matrices.html)
The rules of matrix-vector multiplication will do the rest for you.
In your case, by using the transposed inverse of your full model matrix, you have some displacement part inside your normal matrix. This displacement part distorts your normals if your displacements are others than 0,0,0. However, I am not sure if the "fourth-component-is-zero" trick will work here since you calculated the inverse of your model matrix and transposed it. So displacement components may have left the fourth column. That's why you usually determine your normal matrix by using the transposed inverse of the upper left 3x3 submatrix instead of the full 4x4 model matrix. This part contains the scaling and rotation part of the transformation.
Short answer:
To solve your problem do the following (might contain coding errors):
mat3 normal_matrix = transpose(inverse(mat3(model_matrix)));
vec3 v_normal_tmp = normalize(normal_matrix * vec3(v_normal));
v_normal = vec4(v_normal_tmp,0)
You should think about using vec3 and mat3 for normals. Otherwise, do it as above.
Think about that too:
1 hour ago, kalle_h said:
And do not normalize that before pixel shader stage.
Addition:
You should also think about why the normal matrix is the transposed inverse of the model matrix: Normals are usually rotated the same as the model itself. But if you have any scaling that is not equal in all directions, the scaling of the normals needs to be inverted, otherwise, you get wrong normals. So you invert your matrix to get inverse scaling. But this inverts also your rotations. The nice thing about rotations is, that their inverse is equal to the transposed matrix. Since scaling happens only on the main diagonal, which is not affected by transposing the matrix, we transpose to undo the inversion of the rotation. If you think about it, it seems a little bit wasteful. That's why I usually calculate the normal matrix together with the model matrix in one function. While the model matrix is Translation * Rotation * Scaling the normal matrix is Rotation * inverse(Scaling). The inverse scaling matrix is just calculating 1/scaling_factor for each component.
Greetings