There’s another mistake in your shader.

Basically, every time you calculate anything in a shader, you should be asking yourself: what coordinate system do I want to be working in? There are lots of coordinate systems to choose from, but most calculations are done in one of these: model space, world space, camera space.

So take this calculation, for instance:

float3 EyeDir = normalize(k_EyePos - l_position);

I don’t know for sure, but I’m betting you were thinking of this taking place in world space. If so, then this is buggy, because l_position is not in world space, it’s in model space.

To convert model space to world space, you could do this:

world_position = mul(trans_model_to_world, l_position);

But remember, that’s only one possible solution. Another idea would be, since l_position is already in model space, to do all the calculations in model space. Then you would need to make sure that the k_EyePos that you pass in is also in model space. My suggestion would be: don’t pass in k_EyePos. Instead, use this:

uniform float4 mspos_camera;

That’s “model space position of the camera.” Pretty much the same as what you were saying with k_EyePos, except that panda converts it to model space for you.

After that, you’ll end up with an EyeDir which is also in model space.

There’s no right answer, but long story short, don’t get your coordinate systems confused.