Sign in to follow this  

[Solved] Lighting/Normal Mapping Issue

Recommended Posts

Edit: I fixed it, the N value of NTB was being set to the the vertex normal instead of the face normal like it should have been.

Hey guys.

Here is a screen shot of the problem I am having:

To explain a bit, I currently have a grid of cubes being lit by a directional light (straight down), and two point lights. As you can see in the screen shot, the light has a repeating pattern across all the blocks for the attenuation. This issue is only present with normal mapping, so I know it's a normal mapping issue. I know there's nothing wrong with the normal map because I get the same effect when I use a blank normal map.

Below is my pixel shader code, followed by the function calculating the point light. If anyone has any ideas or suggestions, I would greatly appreciate the help.


float4 PS(VS_OUT pIn) : SV_Target
// Get materials from texture maps.
float alpha = gDiffuseMap.Sample( gTriLinearSam, pIn.texC0 ).a;

// Discard pixel if texture alpha < 0.1. Note that we do this
// test as soon as possible so that we can potentially exit the shader
// early, thereby skipping the rest of the shader code.
clip(alpha - 0.1f);

float4 diffuse = gDiffuseMap.Sample( gTriLinearSam, pIn.texC0 );

clip(diffuse.a - 0.15f);

float4 spec = gSpecMap.Sample( gTriLinearSam, pIn.texC0 );
float3 normalT = gNormalMap.Sample( gTriLinearSam, pIn.texC0);

// Map [0,1] --> [0,256]
spec.a *= 256.0f;

// [0, 1] to [-1, 1]
normalT = 2.0f * normalT - 1.0f;

// NTB = YXZ
float3 N = normalize(pIn.normalW);
float3 T = normalize(pIn.tangentW - dot(pIn.tangentW, N) * N);
float3 B = cross (N, T);

float3x3 TBN = float3x3(T, B, N);

float3 bumpedNormalW = normalize(mul(normalT, TBN));

// Interpolating normal can make it not be of unit length so normalize it.
float3 normalW = normalize(pIn.normalW);

float shadowFactor;

shadowFactor = CalcShadowFactor(pIn.projTexC);

// Compute the lit color for this pixel.
SurfaceInfo v = {pIn.posW, bumpedNormalW, diffuse, spec};

float3 litColor;

for(int i = 0; i < gLightCount; i++)
if(gLights[i].type == 0)
litColor += ParallelLight(v, gLights[i], gEyePosW, shadowFactor);
litColor += ParallelLight(v, gLights[i], gEyePosW, 1.0f);
else if(gLights[i].type == 1)
litColor += PointLight(v, gLights[i], gEyePosW);
else if(gLights[i].type == 2)
litColor += Spotlight(v, gLights[i], gEyePosW);

// Blend the fog color and the lit color.
float3 foggedColor = lerp(litColor, gFogColor, pIn.fogLerp);

return float4(foggedColor, alpha);

float3 PointLight(SurfaceInfo v, Light L, float3 eyePos)
float3 litColor = float3(0.0f, 0.0f, 0.0f);

// The vector from the surface to the light.
float3 lightVec = L.pos - v.pos;

// The distance from surface to light.
float d = length(lightVec);

if( d > L.range )
return float3(0.0f, 0.0f, 0.0f);

// Normalize the light vector.
lightVec /= d;

// Add the ambient light term.
litColor += v.diffuse * L.ambient;

// Add diffuse and specular term, provided the surface is in
// the line of site of the light.
float diffuseFactor = dot(lightVec, v.normal);
if( diffuseFactor > 0.0f )
float specPower = max(v.spec.a, 1.0f);
float3 toEye = normalize(eyePos - v.pos);
float3 reflectVec = reflect(-lightVec, v.normal);
float specFactor = pow(max(dot(reflectVec, toEye), 0.0f), specPower);

// diffuse and specular terms
litColor += diffuseFactor * v.diffuse * L.diffuse;
litColor += specFactor * v.spec * L.spec;

// attenuate
return litColor / dot(L.att, float3(1.0f, d, d*d));

[Edited by - lifegoeson on September 25, 2010 9:43:19 PM]

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this