   Calculating normals gives wrong result
  I'm trying to render a mesh with simple diffuse lighting. Since the mesh doesn't come with normals I'm calculating them on the fly using the standard "sum triangle normals per vertex and normalize" method. However the result is not what I expected.Take a look at this image:Stanford Bunny model, the yellow box is a point light. I would expect the ears to be lit on one side and dark on the other, but they are solid black, as is the head of the bunny. Also, if I look on the underside of the model it is lit, even though the normals should be pointing away from the light. So, either the normals are wrong, or my lighting calculations are wrong.Here is the code I use to calculate the normals:private void UpdateNormals(){for (int index = 0; index < mVertices.Length; ++index){mVertices[index].Normal = Vector3.Zero;}for (int face = 0; face < mIndices.Length; face += 3){Vector3 v1 = mVertices[mIndices[face]].Position;Vector3 v2 = mVertices[mIndices[face + 1]].Position;Vector3 v3 = mVertices[mIndices[face + 2]].Position;Vector3 e1 = Vector3.Normalize(v2 - v1);Vector3 e2 = Vector3.Normalize(v3 - v2);Vector3 e3 = Vector3.Normalize(v1 - v3);Vector3 n = Vector3.Cross(e1, -e3);n.Normalize();float a1 = (float)Math.Acos(Vector3.Dot(e1, -e3));float a2 = (float)Math.Acos(Vector3.Dot(e2, -e1));float a3 = (float)Math.Acos(Vector3.Dot(e3, -e2));mVertices[mIndices[face]].Normal += n * a1;mVertices[mIndices[face + 1]].Normal += n * a2;mVertices[mIndices[face + 2]].Normal += n * a3;}for (int index = 0; index < mVertices.Length; ++index){mVertices[index].Normal.Normalize();}}Pretty straight forward. Only twist is that I weight the normals per vertex based on the angle between the edges extending from the vertex.The relevant parts of the shader:VS_Output VS_SimpleColor( VS_Input IN ) {VS_Output OUT;OUT.position = mul( float4( IN.position, 1 ), worldViewProjection );OUT.normal = mul( float4( IN.normal, 1 ), inverseTransposeWorld ).xyz;OUT.worldPos = mul( float4( IN.position, 1 ), world ).xyz;OUT.texcoord = IN.texcoord;return OUT;}float4 PS_SimpleLit( VS_Output IN ) : COLOR0 {float3 L = normalize(lightPosition - IN.worldPos);float3 N = normalize(IN.normal);float diff = max( dot( L, N ), 0 );return float4( diff * color.rgb, color.a );}
  Well, I would try to not "weight the normals per vertex" first. Comment it out to how it goes. Also subtract the vectors so that there's no need to negate them. Something like Vector3 e1 = Vector3.Normalize(v2 - v1);Vector3 e2 = Vector3.Normalize(v2 - v3);Vector3 n = Vector3.Cross(e1, e2);n.Normalize();;  Removing the normal weighing doesn't change the rendered image, the normals are still strange.   ;  Have you tried changing:Vector3 n = Vector3.Cross(e1, -e3);toVector3 n = Vector3.Cross(-e3, e1); ?;  Can you change your shader to display the normals?   ;  Flipping the normal (Buckeyes suggestion) doesn't change the output, which seems to indicate that the problem isn't in the normal calculation, but somewhere else.Outputing the normals looks like this:Output by replacing the return in the pixel shader with (N is the normalized normal)return float4( ( N + 1 ) / 2, 1 );There is some variance in the values, but they all almost point in the same direction. I just can't figure this one out...   ;  It's really strange that all your normals points in the same direction. My only idea is that in some function (probably normalize) you get an error and the math library simply set the vector in this direction.Vector3 e1 = Vector3.Normalize(v2 - v1);Vector3 e2 = Vector3.Normalize(v3 - v2);Vector3 e3 = Vector3.Normalize(v1 - v3);Vector3 n = Vector3.Cross(e1, -e3);n.Normalize();There is no need to normalize the vectors e1, e2 and e3 because the direction of the vector computed with the cross product doesn't depend on their length.[Edited by - apatriarca on September 8, 2009 11:34:39 AM];  in the last resort you could fall back on D3DXComputeNormals( mesh, 0);   ;  How about using this in the shader:OUT.normal = mul(IN.normal, floatx3x3(inverseTransposeWorld));;  The way I always do it is (if you are sure that the normals are correct):- in the vertexshader multiply the normal of the vector with the rotationmatrix of that object and pass it to the pixelshader.also pass to the vertexshader the untransformed position of the vertex- calculate the color as followsfloat factor = 0;float3 direction = normalize(lightpos - pos3d)// where pos3d is the position of the vertex and lightpos is a variable , the light positionfactor = dot(direction,normal)output.color = tex2d(...etc) * factor * energy // energy is the strength of the lightgood luck   