# Per-pixel lighting looks like per-vertex o_O

This topic is 3841 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I wrote simple vertex and pixel shaders with per pixel lighting and one directional light. Well, it works but lighting looks like per-vertex, not per-pixel. I'd like to know if there is something wrong with my HLSL code, or could the problem maybe be elsewhere? I've calculated normals per vertex in my program, there shouldn't be anything wrong with them I think.. /////////////////// // VERTEX SHADER // /////////////////// float4x4 matWorldViewProj : WORLDVIEWPROJECTION; float4x4 matWorld; struct VS_OUTPUT { float4 Position : POSITION; float2 TexCoord : TEXCOORD0; float3 Normal : TEXCOORD1; }; VS_OUTPUT vs_main(float4 Position : POSITION, float2 TexCoord : TEXCOORD0, float3 Normal : NORMAL) { VS_OUTPUT Out = (VS_OUTPUT) 0; Out.Position = mul(Position, matWorldViewProj); Out.TexCoord = TexCoord; Out.Normal = Normal; return Out; } /////////////////// // PIXEL SHADER // ////////////////// sampler2D Tex0 = sampler_state { MIPFILTER = LINEAR; MAGFILTER = LINEAR; MINFILTER = LINEAR; }; float4 ps_main(float4 Position : POSITION, float2 TexCoord : TEXCOORD0, float3 Normal : TEXCOORD1) : COLOR0 { float4 LightDir = {1.0f, 1.0f, 0.0f, 1.0f}; return tex2D(Tex0, TexCoord) * dot(LightDir, Normal); } Pic: http://img266.imageshack.us/img266/893/lolqe6.jpg

##### Share on other sites
Per-vertex lighting performs the dot product at each vertex and then interpolates the result.

Your per-pixel lighting interpolates the normal across the polygon and then performs the dot product per pixel. Mathematically this should give the same result as per-vertex lighting - and that is exactly what you are seeing.

In order to improve your results, you need to normalize the normal per-pixel, along the lines of:
return tex2D(Tex0, TexCoord) * dot(LightDir, normalize(Normal));

##### Share on other sites
Quote:
 Original post by bakery2k1In order to improve your results, you need to normalize the normal per-pixel, along the lines of:return tex2D(Tex0, TexCoord) * dot(LightDir, normalize(Normal));

Didn't help, still looks like per-vertex.

http://www.gamasutra.com/features/20030418/engel_02.shtml

My HLSL code is basically the same as there, but mine gives per-vertex lighting while that in gamasutra gives per-pixel... I don't really get this.

##### Share on other sites
In general your lighting looks a little broken - but I'd hazard a guess its more down to the data than the processing.

Be careful of your coordinate spaces. A terrain engine can have it's normals untransformed as the geometry is typically in world space anyway, but it's an easy thing to slip up on at a later date.

Directional lights aren't the best example of per-pixel lighting as by definition their input vectors are constant! Something like a point/spot light where the input vectors have to be recomputed per-pixel will show off the difference much more.

hth
Jack

##### Share on other sites
God damn I'm going crazy! I borrowed HLSL code straight from the article in Gamasutra I mentioned earlier and tried rendering a DX teapod \o/. It looks horrible: http://img260.imageshack.us/img260/2425/teapodta8.jpg

So this must mean the problem isn't in HLSL, but where could it be? Not in my normal calculations 'couse the teapod looks bad too, and shouldn't it have proper normals?

##### Share on other sites
Quote:
 float4 LightDir = {1.0f, 1.0f, 0.0f, 1.0f};

Your light direction isn't of unit length.

Regards,
ViLiO