Hi everyone. I have a sphere model in .x format with normals, prooven by opening the directX viewer. I have loaded the model into a D3D9 Mesh using just D3DXLoadMeshFromX() and have also tried to clone the mesh with a defined vertex declaration. But I cant get my diffuse lighting to work.
//my models only need Normals, UV and position.
D3DVERTEXELEMENT9 tempElem[4]=
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL , 0},
{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
D3DDECL_END()
};
meshSys->CloneMesh(D3DXMESH_SYSTEMMEM,tempElem,m_D3DDevice,&m_mesh);
/******************************************************STRUCTURES**********************/
struct VS_INPUT
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float2 UV : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Position : POSITION;
float2 UV : TEXCOORD0;
float4 WorldPos : TEXCOORD1;
float4 WorldNormal : TEXCOORD2;
};
/****************************************************************************************/
/****************************************************SHADERS**********************/
VS_OUTPUT vs_default(VS_INPUT In)
{
VS_OUTPUT Out;
//TRANSFORM VERTEX INFO
Out.Position = mul( In.Position, gWVP );
Out.WorldPos = mul( In.Position, gWorldMatrix);
Out.WorldNormal = mul(float4(In.Normal,0.0), gWorldMatrix);
Out.UV = In.UV;
return Out;
}
float4 ps_default(VS_OUTPUT In) : COLOR0
{
//////////////////////////////////////////////
//CALCULATE LIGHT AMOUNT
//////////////////////////////////////////////
//PIXEL TO LIGHT POSITION
float3 PixelToLightVec = gLightPosition - In.WorldPos;
//COMPUTE SQUARED DISTANCE
float LenSq = dot( PixelToLightVec, PixelToLightVec );
PixelToLightVec = normalize(gLightPosition - In.WorldPos);
float3 WorldNormal = normalize(In.WorldNormal.xyz);
float3 LightAmount = gRange * saturate( dot( WorldNormal, PixelToLightVec ) ) * gLightColour *(gLightFalloff * gLightFalloff) / LenSq;
float3 reflection = normalize((PixelToLightVec + gCameraPos) * 0.5);
float3 LightSpecular = LightAmount * pow( max( dot(WorldNormal, reflection), 0.0000001 ), gSpecularPower );
//////////////////////////////////////////////
//CALCULATE DIRECTIONAL LIGHT AMOUNT
/////////////////////////////////////////////
float3 DirectionalLight = gDirectionalLightColour * max( dot(WorldNormal, normalize(gDirectionalLight)), 0.0 );
reflection = normalize((gDirectionalLight + gCameraPos) * 0.5);
float3 DirectionalSpecular = DirectionalLight * pow( max( dot(WorldNormal, reflection), 0.0000001 ), gSpecularPower );
//////////////////////////////////////////////
//TOTAL LIGHT = RETURNED COLOUR
//////////////////////////////////////////////
float3 DiffuseLight = gAmbientColour + DirectionalLight + LightAmount;
float3 SpecularLight = DirectionalSpecular + LightSpecular;
float4 colour = (tex2D(DiffuseSampler, In.UV) * float4(DiffuseLight,1.0f)) + (gSpecularMaterial * float4(SpecularLight,1.0f));
return colour;
}
/**************************************************************************************/
There is the shader which I use. The lights are in world space and so I transform the normal and the position into world space. I am only rotating and translating the mesh so I thought I didnt require the transpose inverse matrix. The problem is the sphere appears with ambient lighting only. I have entered a vector where 'WorldNormal' is, manually in the DP calculations and this can brighten the sphere so the problem must be with the normals passed in from the mesh or the transformation from Vertex Shader, not the lights or their calculations. Any ideas.
Thank you