Rotating object has wrong lighting

Started by
1 comment, last by Atrix256 14 years, 5 months ago
Hey Guys, I am doing lighting of an object in a shader (using directx) but when i rotate the object, the lit part on the object rotates along with it instead of facing the light source. Anyone know what I'm doing wrong? Thank you (shader source below)

//////////////////////////////////////////////////////////////////////
//                         STRUCTURES
//////////////////////////////////////////////////////////////////////

// Vertex shader output structure
struct VS_OUTPUT
{
    float4 Position   : POSITION;
    float2 Texture    : TEXCOORD0;
    float4 Color      : COLOR0;
    float3 Light      : TEXCOORD1;
    float3 Norm       : TEXCOORD2;
};

//////////////////////////////////////////////////////////////////////
//                         GLOBALS
//////////////////////////////////////////////////////////////////////

// vertex globals
float4x4 WorldViewProj;
float4x4 InvTransposeWorld;
float4 Diffuse;

// pixel variables
sampler2D Tex0;

//////////////////////////////////////////////////////////////////////
//                         VERTEX
//////////////////////////////////////////////////////////////////////

VS_OUTPUT vs_main( float4 Position : POSITION, float2 Texture : TEXCOORD0, float3 Normal : NORMAL )
{
    VS_OUTPUT Out;                      //create an output vertex

    Out.Position = mul(Position,WorldViewProj);  //apply vertex transformation
    Out.Texture  = Texture;          //copy original texcoords
    Out.Color    = Diffuse;
 
    Out.Light    = normalize(float3(3,2,-1));
    Out.Norm     = normalize(mul(InvTransposeWorld,Normal));

    return Out;                         //return output vertex
}

//////////////////////////////////////////////////////////////////////
//                         PIXEL
//////////////////////////////////////////////////////////////////////

float4 ps_main( float2 Texture : TEXCOORD0, float4 Color : COLOR0, float3 Light : TEXCOORD1, float3 Norm : TEXCOORD2) : COLOR
{
    float4 Out;

    //look up texture, multiply by color tint, then multiply by ambient light
    Out = tex2D(Tex0, Texture);
    Out *= Color;
    Out *= float4(0.2,0.2,0.2,1.0);

    //apply lighting
    Out += saturate(dot(Light,Norm)) * float4(0.5,0.0,0.0,0.0);

    return Out;
}


Also, i do this every frame (C++) to update the values. The object looks correct but the lighting is wrong.

oid CShader::ApplyShader()
{
	//communicate with shader
	D3DXMATRIXA16 matWorld, matView, matProj;
	LowLevel.D3Ddevice->GetTransform(D3DTS_WORLD, &matWorld);
	LowLevel.D3Ddevice->GetTransform(D3DTS_VIEW, &matView);
	LowLevel.D3Ddevice->GetTransform(D3DTS_PROJECTION, &matProj);

	//make the world view projection matrix and pass it to the shader (useful for projecting 3d to 2d)
	D3DXMATRIXA16 matWorldViewProj = matWorld * matView * matProj;
	ConstantTable->SetMatrix(LowLevel.D3Ddevice,
							 "WorldViewProj",
							 &matWorldViewProj);

	//make the inverse transpose world matrix and pass it to the shader (useful for lighting)
	D3DXMATRIXA16 matInverseTransposeWorld;
	float Determinant;
	D3DXMatrixInverse(&matInverseTransposeWorld,&Determinant,&matWorld);
	D3DXMatrixTranspose(&matInverseTransposeWorld,&matInverseTransposeWorld);
	ConstantTable->SetMatrix(LowLevel.D3Ddevice,
							 "InvTransposeWorld",
							 &matInverseTransposeWorld);

	LowLevel.D3Ddevice->SetVertexDeclaration(VertexDecl);
	LowLevel.D3Ddevice->SetVertexShader(VertexShader);
	LowLevel.D3Ddevice->SetPixelShader(PixelShader);
}


Advertisement
I wouldn't know for DirectX, but it sounds like you are rotation the light position as well.
Bah thanks, i had the math wrong.

instead of this:

Out.Norm = normalize(mul(InvTransposeWorld,Normal));

it needed to be this:

Out.Norm = -normalize(mul(Normal,World));

where World was the world matrix.

thanks (:

This topic is closed to new replies.

Advertisement