# Normal from normal?

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

## Recommended Posts

Hello. I would ask something about normals. Usually, beyond vertices positions, we store in our structs also normals. Suppose i need to compute the normal to a face, i usually use this code
float3 GetNormal( float3 A, float3 B, float3 C )
{
float3 AB = B - A;
float3 AC = C - A;
return normalize( cross(AB,AC) );
}


With A,B,C the 3 vertices. But after i thought: <<"Why have i to compute normals in this way, if i've got normals information in vertex structure?">> So, how can i obtain the normal from normal vertices informations?

##### Share on other sites
its probaly a lot simpler to do it the way you are already doing it, you have to add all normals of the face's vertices and find the average.

##### Share on other sites
So i just should do

float3 Normal = (Vertex1.Nor+Vertex2.Nor+Vertex3.Nor) / 3;

##### Share on other sites
Quote:
 Original post by staticVoid2its probaly a lot simpler to do it the way you are already doing it, you have to add all normals of the face's vertices and find the average.

'Find' the average?

Face_normal = (A.normal + B.normal + C.normal) / 3

There is, however, a subtle difference. The OP's way calculates the face's normal from the geometry, but this wouldn't look good, for instance, with a curved surface. By averaging the vertex normals you ensure the face normal follows the curvature of the surface. So the latter is the preferred way, in most cases.

##### Share on other sites
Thank you for the answer, now it's more clear.

But why, from geometry, i may have issues with curved surface? Can you explain me it?

##### Share on other sites
A sphere is approximated with triangles and can obviously never be entirely round. If you were to light every triangle according to its face normal, you'd see a faceted sphere. To avoid this, the vertices have their normals pointing outward as a true sphere normal. Then, the lighting is calculated at the three vertices, which produces three different colors and then interpolated over the triangle, to give a much smoother look.

Also see this lighting tutorial. Scroll down to "Smooth shading".

The point is that the vertex normals are the 'true' normals at those points. And the face normal should be the 'true' normal as well, and the best you can get is to interpolate the true normals of the vertices of the face. If you just take the cross product of AB and AC, you'll get the normal pointing straight out of the face, as defined by the geometry, but that's not necessarily the 'true' normal that it's meant to have.

Of course, this depends on what you need the normal for. There might be cases where you really just want to know the geometric normal.

##### Share on other sites
Quote:
 Original post by Mike nlFace_normal = (A.normal + B.normal + C.normal) / 3

The normal will not be unit length if you do this.

Face_normal = normalize(A.normal + B.normal + C.normal)

##### Share on other sites
not to mention it doesnt give correct results
cause u cant really add normals

normalize(vec3(-1,0,0)+vec3(1,0,0));

but for most cases it looks ok enuf

##### Share on other sites
Quote:
 Original post by zedznot to mention it doesnt give correct resultscause u cant really add normalsnormalize(vec3(-1,0,0)+vec3(1,0,0));but for most cases it looks ok enuf

So? Is there a "definitive" method to get normals from normal information in vertices?

##### Share on other sites
If you think of the problem as finding the interpolated normal at some point within the triangle, then you would find the barycentric coordinates of that point and use those as weights when combining your normals from the vertices. It so happens that at the centroid of the triangle, the barycentric coordinates happen to be (1/3, 1/3, 1/3) - which is the average.

So basically I'm saying that the correct answer is indeed
normalize( 1/3*A.normal + 1/3*B.normal + 1/3*C.normal)
which is equilavent to
normalize(A.normal + B.normal + C.normal).

You are correct, zedz, that you cannot simply add normals - but in this case we're doing an interpolation that just so happens to simplify to simple addition.:) And incidentally your example won't work because it is a very malformed triangle. If you correctly interpolate the normals across that triangle - for per-pixel lighting for example - incorrect results would also be generated (ie normalize(0) at the centroid, probably resulting in a white or black pixel if running on a GPU).

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 11
• 11
• 15
• 11
• 11
• ### Forum Statistics

• Total Topics
634149
• Total Posts
3015834
×