Confuzed with Phong HLSL shader

Started by
3 comments, last by DumpAlien 16 years, 3 months ago
Hello there! I am trying to implement Phong lighting. If my object is at the origin or the world (0,0,0) then it works. If I move the object around then i get wrong lighting... here is my shaders:

struct VS_INPUT
{
    float4 Position : POSITION;
    float4 Normal	: NORMAL;
    float2 Texture	: TEXCOORD;
};

struct PS_INPUT
{
    float4 Position	: SV_POSITION;
    float3 viewVec	: ViewVec;
    float2 Texture	: TEXCOORD0;
    float3 vecLight	: TEXCOORD1;
    float3 Normal	: TEXCOORD2;
};

Vertex Shader:

cbuffer test1
{
	matrix viewMatrix; /*View Matrix */
	matrix projectionMatrix; /*Projection Matrix*/
	matrix worldMatrix; /*World Matrix*/
	float3 camPos;   /*Camera position */
	float3 lightPos; /*Light Position*/
};

PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
    //	Calculate ViewProjection Matrix
    matrix viewProjMatrix = mul( viewMatrix, projectionMatrix );
    //	Calculate WorldViewProjection
    matrix worldViewProjMatrix = mul( worldMatrix, viewProjMatrix );
    //	Calculate Vertex position
    output.Position = mul( input.Position, worldViewProjMatrix );
    
    float3 posWorld = normalize( mul( input.Position, worldMatrix ) );
    output.viewVec = normalize( camPos - posWorld );
    output.Normal = normalize( mul( input.Normal, worldMatrix ) );
    output.vecLight =  lightPos;
    
    output.Texture = input.Texture;
    return output;
}

Pixel Shader:

float4 PS( PS_INPUT input) : SV_Target
{
    // Set the output colours
    float4	diffuse		= float4( 1.0f, 0.0f, 0.0f,1.0f );
    float4	ambient		= float4( 0.5f,0.0f,0.0f,1.0f   );
    float3	Normal		= normalize( input.Normal );
    float3	Vert2Light	= normalize( input.vecLight );
    float3	ViewDir		= normalize( input.viewVec );
    float4	Diff		= saturate( dot( Normal, Vert2Light ) );
    float4	Reflect		= normalize( 2 * Diff * Normal - Vert2Light );
    float4	Specular	= pow( saturate( dot( Reflect, ViewDir ) ), 256 );
       
    return ambient + diffuse * Diff + Specular;
}

Should I do some transformation to the light position? Thanks for your time!
Advertisement
Yes you need to do a conversion for the light position. Your vert2light in your pixel shader should be a normalized vector pointing from the interpolated world vertex position to the world light position. As it is right now, this vector is the same as the world light position and this will only be correct for a worldspace vertex at the origin. The furthur the object deviates from the worldspace origin, the less accurate you will get.

In your vertex shader try computing vecLight as lightPos - posWorld.
nah.. It does not work.. :/ pff I am a little confuzed right now :/ I will try it later again. thanks anyway!
hmm, a bunch of things don't quite sit right with me:

float3 posWorld = normalize( mul( input.Position, worldMatrix ) );

Why are you normalizing it?! With this code you can never have a position other than on the surface of the unit sphere?!

output.viewVec = normalize( camPos - posWorld );

If posWorld is wrong then so is this calculation.

output.Normal = normalize( mul( input.Normal, worldMatrix ) );

You should be casting worldMatrix to a float3x3 to chop off the translation components of the world matrix. Normal vectors don't have a position.

THIS MIGHT BE WHY IT ONLY WORKS FOR (0,0,0) - NO TRANSLATION COMPONENT IN THE MATRIX [wink]

output.vecLight = lightPos;

Is this genuinely the light's position or is it the direction?? In your pixel shader you treat it as a direction (or you're doing some obscure thing by projecting it onto the surface of the unit sphere like you're doing with your position).

float3 Vert2Light = normalize( input.vecLight );

The naming is here is misleading; you're NOT varying the vector based on the vertex so it is simply a directional light vector, not a point light that requires a vertex-to-light direction.


hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

you are right! dunno what I was thinking! normalizing is not needed! I also cut off the translation component from the world matrix and fixed the light position.. now works perfectly! thanks man!!!
thanks for help all of you!!!

This topic is closed to new replies.

Advertisement