I'm rendering a cube using dot3 normal mapping in a hlsl shader. The normal mapping looks fine, except that the world lighting doesn't match up with the normal mapping lighting. For instance, if I rotate the light to the right, the normal map shows that the light is rotating upwards. I'm not sure why this is occurring, all my lighting is done on the single normal mapping pass. Perhaps the problem is in my vertex shader space matrix multiplications, or perhaps i'm generating the tangent space coordinates wrong. Any advice would be great.
vertex shader
// normal mapping vertex shader
VSOutput VS_NormalMapping(VSInput a_Input)
{
VSOutput output;
// calculate homogenous position
output.pos = mul(float4(a_Input.pos, 1.0f), g_matWVP);
// copy texture coordinates across
output.tex = a_Input.tex;
// calculate matrix to tangent space
float3x3 toTangentSpace = transpose(float3x3(a_Input.tan, a_Input.bin, a_Input.nor));
// calculate light's direction relative to tangent space
float3 lightDirL = mul(float4(g_lightDir, 0.0f), g_matWI);
output.lightDir = mul(lightDirL, toTangentSpace);
return output;
}
pixel shader
// normal mapping pixel shader
float4 PS_NormalMapping(VSOutput a_Input) : COLOR
{
// index into textures
float4 colour = tex2D(sampTexture, a_Input.tex);
float3 normal = tex2D(sampNormalMap, a_Input.tex);
// convert normal from (0 - 1) to (-1 - 1)
normal = 2.0f * (normal - 0.5f);
// renormalise light direction
float3 light = normalize(a_Input.lightDir);
// calculate diffuse component
float diffuse = max(dot(normal, light), 0.0f);
// return texture colour modified by diffuse component
return (colour * diffuse);
}
TBN coordinates generation -
// create box with texture coordinates
V_RETURN(CreateBox(5.0f, 5.0f, 5.0f, &g_pMeshBox))
// calculate tangential coordinates
D3DVERTEXELEMENT9 VertexElems[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, // position
{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
{0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
{0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 48, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, // texture coords
D3DDECL_END()
};
LPD3DXMESH pMeshClonedBox = NULL;
V_RETURN(g_pMeshBox->CloneMesh(D3DXMESH_MANAGED, VertexElems, pd3dDevice, &pMeshClonedBox))
SAFE_RELEASE(g_pMeshBox);
V_RETURN(D3DXComputeTangentFrameEx(pMeshClonedBox, D3DDECLUSAGE_TEXCOORD, 0,
D3DDECLUSAGE_BINORMAL, 0,
D3DDECLUSAGE_TANGENT, 0,
D3DDECLUSAGE_NORMAL, 0, 0, 0,
0.01f, 0.25f, 0.01f, &g_pMeshBox, 0))
SAFE_RELEASE(pMeshClonedBox);
Cheers.