I added normal mapping to my project a while back, which seemed to work as intended so I didn't think much about it until now that I tried to also add specular mapping. This did not look right at all and after some debugging it seems that my normals (sampled from a normal map) don't get converted into world space properly after all.
So here is how I'm reading the normals:
float3x3 matIT = transpose(float3x3(normalize(IN.tangent), normalize(IN.binormal), normalize(IN.normal)); float3 normal = NormalMap.Sample(DSampler, IN.texcoord).xyz * 2 - 1; // Convert to -1 .. +1 range normal = normalize(normal.x * matIT + normal.y * matIT + normal.z * matIT); // Bring into world space
The IN.normal, IN.tangent and IN.binormal come from the per-vertex input data and are multiplied by the rendered mesh's world matrix prior to being sent to the pixel shader (where the above calculations occur).
The odd thing is that this does yield properly looking normal mapping results, but when I try to use these normals for specular highlights it is off.
Rendering the output normal vector of a spinning cube further suggests that for example the vertices facing upwards (after rotation by mutation of its world matrix) will have the correct, upwards facing normal direction for 4 faces but not all 6 as I can only imagine it should if this was working properly.
The fact that the cube normals do indeed change when rotating (albeit not always correctly) suggests that it shouldn't be a mere oversight of the above actually transforming the normal into object space instead of world space either.
It is times like these I regret I didn't take some extra math courses when I had the chance...
Any help or pointers would be greatly appreciated.