Original Post
I have a slight problem. I''m new to writing shaders. I wrote a simple vertex shader in HLSL for diffuse + specular lighting. It shows up fine, but if you rotate the teapot, you will see that the light seems to rotate with it as if i''m the one who''s rotating and not the teapot. If you rotate the teapot, say 180 degrees, you will see the back of it with the highlight on the front. I can''t figure out what i''m doing wrong so if someone else has had this problem before, your expertise will be greatly appreciated. The code is below:
Vertex Shader fx file:
// Transposed matrix sent from the application
float4x4 WorldViewProj; // sent from app
float4x4 World; // sent from app
// Light attributes
float4 globalAmbient = { 0.1f, 0.1f, 0.1f, 1.0f };
float4 lightColor = { 1.0f, 1.0f, 1.0f, 1.0f };
float4 lightDir; // sent from app
// Camera attribute sent from app
float3 eyePosition;
float3 Kd = { 1.0f, 0.0f, 0.0f };
float3 Ks = { 1.0f, 1.0f, 1.0f };
float shininess = 30.0f;
// -------------------------------------------------------------
// Output channels
// -------------------------------------------------------------
struct VS_OUTPUT
{
float4 Pos : POSITION;
float4 Color : COLOR;
};
// -------------------------------------------------------------
// vertex shader function (input channels)
// -------------------------------------------------------------
VS_OUTPUT VS(float4 Pos : POSITION, float3 Normal : NORMAL)
{
VS_OUTPUT Out = (VS_OUTPUT)0;
Out.Pos = mul(Pos, WorldViewProj); // transform Position
float4 P = Pos;
float3 N = Normal;
float3 L = lightDir;
float diffuseLight = max(dot(N,L), 0.0f);
float3 diffuse = Kd * lightColor * diffuseLight;
// Compute the specular term
float3 V = normalize(eyePosition - P);
float3 H = normalize(L + V);
float specularLight = pow(max(dot(N, H), 0), shininess);
if (diffuseLight <= 0) specularLight = 0;
float3 specular = Ks * lightColor * specularLight;
Out.Color.xyz = diffuse + specular;
Out.Color.w = 1.0f;
return Out;
}
technique TBasic
{
pass P0
{
PixelShader = NULL;
VertexShader = compile vs_1_1 VS();
Lighting = False;
CullMode = None;
}
}
Some code from the app:
HRESULT CMyD3DApplication::FrameMove()
{
// TODO: update world
D3DXVECTOR3 vUpVec(0,1,0);
D3DXVECTOR3 vEyePt(0,0,-5);
D3DXVECTOR3 vLookatPt(0,0,0);
D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);
D3DXVECTOR4 lightDir = D3DXVECTOR4(0.0f, -1.0f, 2.0f, 1.0f);
// Update user input state
UpdateInput( &m_UserInput );
// Update the world state according to user input
D3DXMATRIX matRotY;
D3DXMATRIX matRotX;
if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
m_fWorldRotY += m_fElapsedTime;
else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
m_fWorldRotY -= m_fElapsedTime;
if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
m_fWorldRotX += m_fElapsedTime;
else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
m_fWorldRotX -= m_fElapsedTime;
D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
D3DXMatrixRotationY( &matRotY, timeGetTime()/1000.0f );
D3DXMatrixMultiply( &matWorld, &matRotX, &matRotY );
// Concatenate the matrix into a world-view-projection matrix
D3DXMATRIX WorldViewProjection = matWorld * matView * matProj;
// Send the matrix to the shader
m_pEffect->SetMatrix("WorldViewProj", &WorldViewProjection);
// Send the world matrix to the shader
m_pEffect->SetMatrix("World", &matWorld);
m_pEffect->SetVector("lightDir", &-lightDir);
m_pEffect->SetVector("eyePosition", &D3DXVECTOR4(vEyePt.x, vEyePt.y, vEyePt.z, 0));
return S_OK;
}