Sign in to follow this  
SteveDeFacto

Random lighting problem.

Recommended Posts

I'm having a problem where random vertices are shaded darker than others. I posted my shader on here and I've tried manually generating the normals but nothing works.

Here are some images that show the problem:
[attachment=1428:Untitled1.jpg]


[attachment=1429:Untitled2.jpg]

Here is the code for my shader as well:


[code] float4 Ambient = float4( 0.47f, 0.47f, 0.47f, 1.0f );
float4 Diffuse = float4( 0.5f, 0.5f, 0.5f, 1.0f );
int Light_Count : LIGHTCOUNT;
float4 Lights[255] : LIGHTARRAY;
float4 LightColors[255] : LIGHTCOLORARRAY;
float4x4 World : WORLD;
float4x4 View : WORLDVIEW;
float4x4 Projection : PROJECTION;
float4x4 Bones[255] : BONEARRAY;
struct VS_INPUT
{
float3 pos : POSITION;
float3 norm : NORMAL;
float2 tex : TEXCOORD0;
float4 bw : TEXCOORD1;
float4 bi : TEXCOORD2;
};
struct PS_INPUT
{
float4 pos : SV_POSITION;
float4 pos2 : POSITION;
float2 tex : TEXCOORD0;
float3 norm : NORMAL;
};
PS_INPUT VS( VS_INPUT In )
{
PS_INPUT Out = (PS_INPUT)0;
float4x4 skinTransform = 0;
skinTransform += Bones[In.bi.x] * In.bw.x;
skinTransform += Bones[In.bi.y] * In.bw.y;
skinTransform += Bones[In.bi.z] * In.bw.z;
skinTransform += Bones[In.bi.w] * In.bw.w;
Out.pos = mul(float4(In.pos, 1), skinTransform);
Out.pos2 = Out.pos;
Out.norm = mul(In.norm, (float3x3)skinTransform);
Out.pos = mul(mul(Out.pos, View), Projection);
Out.tex = In.tex;
return Out;
}
float4 PS( PS_INPUT In) : SV_Target
{
float4 color = float4( 0, 0, 0, 0 );
for(int i = 0; i < Light_Count; i++)
{
float4 lightDir = Lights[i] - In.pos2;
float4 NdotL = saturate(dot(In.norm, normalize(lightDir)));
float4 attenuation = 1/length(lightDir);
color += LightColors[i] * NdotL * attenuation * 10;
}
color.w = 1;
return color * Diffuse;
}
technique10 Render
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PS() ) );
}
}[/code]

Any ideas what it could be?

Share this post


Link to post
Share on other sites
[quote name='SteveDeFacto' timestamp='1297890561' post='4775111']
I'm having a problem where random vertices are shaded darker than others. I posted my shader on here and I've tried manually generating the normals but nothing works.

Here are some images that show the problem:
[attachment=1428:Untitled1.jpg]


[attachment=1429:Untitled2.jpg]

Here is the code for my shader as well:


[code] float4 Ambient = float4( 0.47f, 0.47f, 0.47f, 1.0f );
float4 Diffuse = float4( 0.5f, 0.5f, 0.5f, 1.0f );
int Light_Count : LIGHTCOUNT;
float4 Lights[255] : LIGHTARRAY;
float4 LightColors[255] : LIGHTCOLORARRAY;
float4x4 World : WORLD;
float4x4 View : WORLDVIEW;
float4x4 Projection : PROJECTION;
float4x4 Bones[255] : BONEARRAY;
struct VS_INPUT
{
float3 pos : POSITION;
float3 norm : NORMAL;
float2 tex : TEXCOORD0;
float4 bw : TEXCOORD1;
float4 bi : TEXCOORD2;
};
struct PS_INPUT
{
float4 pos : SV_POSITION;
float4 pos2 : POSITION;
float2 tex : TEXCOORD0;
float3 norm : NORMAL;
};
PS_INPUT VS( VS_INPUT In )
{
PS_INPUT Out = (PS_INPUT)0;
float4x4 skinTransform = 0;
skinTransform += Bones[In.bi.x] * In.bw.x;
skinTransform += Bones[In.bi.y] * In.bw.y;
skinTransform += Bones[In.bi.z] * In.bw.z;
skinTransform += Bones[In.bi.w] * In.bw.w;
Out.pos = mul(float4(In.pos, 1), skinTransform);
Out.pos2 = Out.pos;
Out.norm = mul(In.norm, (float3x3)skinTransform);
Out.pos = mul(mul(Out.pos, View), Projection);
Out.tex = In.tex;
return Out;
}
float4 PS( PS_INPUT In) : SV_Target
{
float4 color = float4( 0, 0, 0, 0 );
for(int i = 0; i < Light_Count; i++)
{
float4 lightDir = Lights[i] - In.pos2;
float4 NdotL = saturate(dot(In.norm, normalize(lightDir)));
float4 attenuation = 1/length(lightDir);
color += LightColors[i] * NdotL * attenuation * 10;
}
color.w = 1;
return color * Diffuse;
}
technique10 Render
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PS() ) );
}
}[/code]

Any ideas what it could be?
[/quote]


Are you sure those spots don't have bad normals? Try outputting In.norm from your pixel shader and see if those spots look dark (i.e. facing the opposite way from the other normals). Are you sure you don't have some triangles that are wound backwards (causing even your manually generated normals to be bad in those spots), turn on backface culling (if it's not already on) to check this.

Share this post


Link to post
Share on other sites
[quote name='SteveDeFacto' timestamp='1297890561' post='4775111']
I'm having a problem where random vertices are shaded darker than others. I posted my shader on here and I've tried manually generating the normals but nothing works.

Here are some images that show the problem:
[attachment=1428:Untitled1.jpg]


[attachment=1429:Untitled2.jpg]

Here is the code for my shader as well:


[code] float4 Ambient = float4( 0.47f, 0.47f, 0.47f, 1.0f );
float4 Diffuse = float4( 0.5f, 0.5f, 0.5f, 1.0f );
int Light_Count : LIGHTCOUNT;
float4 Lights[255] : LIGHTARRAY;
float4 LightColors[255] : LIGHTCOLORARRAY;
float4x4 World : WORLD;
float4x4 View : WORLDVIEW;
float4x4 Projection : PROJECTION;
float4x4 Bones[255] : BONEARRAY;
struct VS_INPUT
{
float3 pos : POSITION;
float3 norm : NORMAL;
float2 tex : TEXCOORD0;
float4 bw : TEXCOORD1;
float4 bi : TEXCOORD2;
};
struct PS_INPUT
{
float4 pos : SV_POSITION;
float4 pos2 : POSITION;
float2 tex : TEXCOORD0;
float3 norm : NORMAL;
};
PS_INPUT VS( VS_INPUT In )
{
PS_INPUT Out = (PS_INPUT)0;
float4x4 skinTransform = 0;
skinTransform += Bones[In.bi.x] * In.bw.x;
skinTransform += Bones[In.bi.y] * In.bw.y;
skinTransform += Bones[In.bi.z] * In.bw.z;
skinTransform += Bones[In.bi.w] * In.bw.w;
Out.pos = mul(float4(In.pos, 1), skinTransform);
Out.pos2 = Out.pos;
Out.norm = mul(In.norm, (float3x3)skinTransform);
Out.pos = mul(mul(Out.pos, View), Projection);
Out.tex = In.tex;
return Out;
}
float4 PS( PS_INPUT In) : SV_Target
{
float4 color = float4( 0, 0, 0, 0 );
for(int i = 0; i < Light_Count; i++)
{
float4 lightDir = Lights[i] - In.pos2;
float4 NdotL = saturate(dot(In.norm, normalize(lightDir)));
float4 attenuation = 1/length(lightDir);
color += LightColors[i] * NdotL * attenuation * 10;
}
color.w = 1;
return color * Diffuse;
}
technique10 Render
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PS() ) );
}
}[/code]

Any ideas what it could be?
[/quote]

I normalized the normals after they are transformed by skinTransform and the problem is greatly reduced or in some cases completely gone. I think I can consider this problem solved. Here is the shader:


[code]
float4 Ambient = float4( 0.47f, 0.47f, 0.47f, 1.0f );
float4 Diffuse = float4( 0.5f, 0.5f, 0.5f, 1.0f );
int Light_Count : LIGHTCOUNT;
float4 Lights[255] : LIGHTARRAY;
float4 LightColors[255] : LIGHTCOLORARRAY;
float4x4 World : WORLD;
float4x4 View : WORLDVIEW;
float4x4 Projection : PROJECTION;
float4x4 Bones[255] : BONEARRAY;
struct VS_INPUT
{
float3 pos : POSITION;
float3 norm : NORMAL;
float2 tex : TEXCOORD0;
float4 bw : TEXCOORD1;
float4 bi : TEXCOORD2;
};
struct PS_INPUT
{
float4 pos : SV_POSITION;
float4 pos2 : POSITION;
float2 tex : TEXCOORD0;
float4 norm : NORMAL;
};
PS_INPUT VS( VS_INPUT In )
{
PS_INPUT Out = (PS_INPUT)0;
float4x4 skinTransform = 0;
skinTransform += Bones[In.bi.x] * In.bw.x;
skinTransform += Bones[In.bi.y] * In.bw.y;
skinTransform += Bones[In.bi.z] * In.bw.z;
skinTransform += Bones[In.bi.w] * In.bw.w;
Out.pos = mul(float4(In.pos, 1), skinTransform);
Out.pos2 = Out.pos;
Out.norm = normalize(mul(float4(In.norm, 0), skinTransform));
Out.pos = mul(mul(Out.pos, View), Projection);
Out.tex = In.tex;
return Out;
}
float4 PS( PS_INPUT In) : SV_Target
{
float4 color = float4( 0, 0, 0, 0 );
for(int i = 0; i < Light_Count; i++)
{
float4 lightDir = Lights[i] - In.pos2;
float4 NdotL = saturate(dot(In.norm, normalize(lightDir)));
float4 attenuation = 1/length(lightDir);
color += LightColors[i] * NdotL * attenuation * 10;
}
color.w = 1;
return color * Diffuse;
}
technique10 Render
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PS() ) );
}
}[/code]

Share this post


Link to post
Share on other sites
This is a typical sign of vertex normals pointing inward, even when normalized, they are still pointing inward. This is not a problem of the shader, but of the model data. Go into your modelling tool and try to check your normals (when using blender, select all vertices and press ctrl+N to led all normals point outward.)

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