Advertisement

Vertex normals (again)

Started by September 26, 2003 02:53 AM
5 comments, last by Ruudje 21 years, 5 months ago
Take a look at my code here

void file_3ds::calculate_normals(void)
{
        int i, j;

        // Set all vertex normals to 0
        for (i = 0; i < object->vertices_qty; i++)
        {
                for (j = 0; j < 3; j++)
                {
                        object->vertex.norm[j] = 0.0;
                }
        }

        // Loop through all faces
        for(i = 0; i < object->polygons_qty; i++)
        {
                vector vec1;
                vec1.x = object->vertex[object->face.b].x - object->vertex[object->face.a].x;
                vec1.y = object->vertex[object->face.b].y - object->vertex[object->face.a].y;
                vec1.z = object->vertex[object->face.b].z - object->vertex[object->face.a].z;

                vector vec2;
                vec2.x = object->vertex[object->face.c].x - object->vertex[object->face.a].x;
                vec2.y = object->vertex[object->face.c].y - object->vertex[object->face.a].y;
                vec2.z = object->vertex[object->face.c].z - object->vertex[object->face.a].z;

                float x, y, z;
                x = vec1.y * vec2.z - vec1.z * vec2.y;
                y = vec1.z * vec2.x - vec1.x * vec2.z;
                z = vec1.x * vec2.y - vec1.y * vec2.x;

                float mag = sqrt(x*x + y*y + z*z);


                /*

                        The following lines have been replaced
                        since they could cause errors

                */
                        // object->polygon.norm[0] = x / mag;
                        // object->polygon.norm[1] = y / mag;
                        // object->polygon.norm[2] = z / mag;

                /*

                        This is the new code. It prevents
                        division of zero, which would cause an
                        error

                */
                if(x != 0)
                        object->face.norm[0] = x / mag;
                else
                        object->face.norm[0] = 0;

                if(y != 0)
                        object->face.norm[1] = y / mag;
                else
                        object->face.norm[1] = 0;

                if(z != 0)
                        object->face.norm[2] = z / mag;
                else
                        object->face.norm[2] = 0;

                // Now we calculate the vertex normals 
                for (j = 0; j < 3; j++)
                {
      	                object->vertex[object->face.a].norm[j] += object->face.norm[j];
      	                object->vertex[object->face.b].norm[j] += object->face.norm[j];
      	                object->vertex[object->face.c].norm[j] += object->face.norm[j];
                }
        }
}
 </pre> 
Though I get proper lighting, Im suspecting its not 100% acurate, since it looks strange to me. &#79;ne thing I noticed is that some areas can get very bright, and I think sometimes a surface is lit up when it shouldnt be, but im not sure… Is this code proper for calculating the normals? And if it is, should I render my faces by setting the normal of the face, and then for each vertex set the normal of that vertex as well?

Tx in advance  </i>  
Do you normalize all vertex normals in the end ?
As you add several normals to get a vertex normal, you might get a non-normalized normal for each vertex.
You can also add non-normalized face normals, this would be equivalent to weighting the normals with the triangles surfaces.
Hope it helps.
BTW, when normalizing the normals, instead of testing x, y and z, you might want to test mag.


SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.
The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)

[edited by - rodzilla on September 26, 2003 4:15:38 AM]
SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)
Advertisement
hmm, i implemented the above, but one thing remains.

Under some angles the object (a cube, made up of triagles) will show its diagonal lines. They will be lit up extra
|-------||     / ||   /   || /     ||-------| 

Like this this line would be extra bright, relative to the rest of the surfaces you see here. Im not sure this is normal though..

[edited by - Ruudje on September 26, 2003 8:53:18 AM]
If the object is a cube, why do you want vertex normals instead of face normals ?


SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.
The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)
SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)
I got similar problems and as I remember it was due to the unnormalized vertex normals . Use glEnable(GL_NORMALIZE); to let opengl do it for you.

See http://www.gamedev.net/community/forums/topic.asp?topic_id=142184
quote:
Original post by rodzilla
If the object is a cube, why do you want vertex normals instead of face normals ?


SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.
The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)


Cuz im TESTING with a cube. The model can be anything.

But now we''re talking about these 2 types of normals... I am using both, but should I only use the vertex normals?
Advertisement
It will be easier if you only use per vertex normals.
If a vertex needs more than one normal (i.e. your cube mesh) you''ll have to duplicate it (that''s what smoothing groups are for in milkshape, for example).
Sure you''ll have more vertices, but you then can mix "planar" and "curved" geometry.


SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.
The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)
SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)

This topic is closed to new replies.

Advertisement