PDA

View Full Version : VBOs and Normals



OmegaDeus
07-03-2011, 09:24 PM
I am working on a project where I need to load some predefined 3D model format in which the normals aren't listed per vertex but per face and therefore there are vertices, normals, indices and a set of indices for normals. I've been trying to use the internet to figure out how I might go about properly displaying this file but not having much luck. Can anyone give me some good ideas on how I might specify an array of indices for the normals and use glDrawElements() or something similar to display the model from a VBO effectively?

blackbird
07-03-2011, 10:24 PM
If you are asking how to get the normals of vertex, you could:
1, for each vertex, find out all faces that include it
2, the normal of the vertex can be calculated by:
n=(n1+n2+n2+...)/face_count
n1, n2... is the normal of the nth face

OmegaDeus
07-03-2011, 10:44 PM
The 3D file already specifies normals and indices of normals, I'm just unsure how to use them. I figure that using the normals provided will save computation. I am just unsure how to figure out the per vertice normal from a file where there are usually more normals than vertices and there's an index showing which normals are used on which faces.

V-man
07-04-2011, 09:39 AM
You have to process your files so that each vertex has a normal.

A vertex is not just a vertex in OpenGL. It is a group {vertex, normal, texcoord, tangent, weight, etc}

An example of such file formats is OBJ
http://www.opengl.org/wiki/FAQ#Multi_indexed_rendering

Cucus
07-04-2011, 09:46 AM
I had the same problem. If I understand your problem, you have a normal for each triangle and not for each vertex.

You can use the normal of the triangle for each vertex of this.
So, if you have:
Triangle i
Normal nx,ny,nz
Vertex1 v1x, v1y, v1z
Vertex2 v2x, v2y, v2z
Vertex3 v3x, v3y, v3z
....
You can assign to each vertex, the normal:
Normal nx,ny,nz
Vertex1 v1x, v1y, v1z
Normal nx,ny,nz
Vertex2 v2x, v2y, v2z
Normal nx,ny,nz
Vertex3 v3x, v3y, v3z

I don't think it's the best way, but it works in my case.

V-man
07-05-2011, 05:53 AM
I had the same problem. If I understand your problem, you have a normal for each triangle and not for each vertex.

You can use the normal of the triangle for each vertex of this.
So, if you have:
Triangle i
Normal nx,ny,nz
Vertex1 v1x, v1y, v1z
Vertex2 v2x, v2y, v2z
Vertex3 v3x, v3y, v3z
....
You can assign to each vertex, the normal:
Normal nx,ny,nz
Vertex1 v1x, v1y, v1z
Normal nx,ny,nz
Vertex2 v2x, v2y, v2z
Normal nx,ny,nz
Vertex3 v3x, v3y, v3z

I don't think it's the best way, but it works in my case.

That is the way to do it.
Each vertex must have a normal.
You can make those normals point in whatever direction that you want of course (GL doesn't care).

OmegaDeus
07-05-2011, 10:25 AM
Okay I think I get it. Having the index of normals and the normals, i think i think of this model in terms of faces instead of vertices and i should be able to load it. i even the texture coordinates upon further inspection seem to be linked to the face instead of just the vertices.

OmegaDeus
07-05-2011, 07:53 PM
Upon further thought, how would i go about doing this properly? I think that one vertex might have different normals depending on which face it is in. So if i work in terms of faces then i end up redefining the same vertex depending on which face uses it and at that time i give it the new normal? Will that cause any lighting/culling issues? I'm very new to 3D programming and OpenGL so please be patient with my lack of knowledge in this subject.

MaxH
07-05-2011, 11:12 PM
I don't work with VBOs. Do they require vertex normals? In old fashioned, fixed pipeline GL, you could have polys with face normals only. It gives your surface a faceted look which is o.k. in some applications such as scientific visualization. If it's o.k. with you, I'd suggest using glBegin and glEnd with GL_TRIANGLE, GL_POLYGON, and glNormal. Then you don't have to worry about manufacturing vertex normals from polygon normals.

Kopelrativ
07-06-2011, 12:55 AM
Upon further thought, how would i go about doing this properly? I think that one vertex might have different normals depending on which face it is in. So if i work in terms of faces then i end up redefining the same vertex depending on which face uses it and at that time i give it the new normal? Will that cause any lighting/culling issues? I'm very new to 3D programming and OpenGL so please be patient with my lack of knowledge in this subject.

The normals are used for computing the effects from incoming light to a surface. Either every vertex (coordinates and normals) is shared with more than one triangle. Or you have different vertices (because the normals are different), even if it is the same coordinate.

There will be visual effects from this, so it depends on what you want. If many triangles share the same vertex (coordinate+normals), then the result will be that you get smooth transitions between triangles (faces). Notice that the normals are interpolated over the triangle, with some side effects.

If you have unique vertex normals for every triangle, you will get hard edges between faces.

OmegaDeus
07-07-2011, 08:49 AM
Okay, I think I'm understanding things a bit better. One final question on this and I think I'll be able to get started on my work. Does OpenGL's vertex buffer objects have a way to pass and index showing which normals correspond to which vertices? I know an index can be passed which tells the GPU which vertices to use to create the faces, but I think that's only useful if I can also specify the normals which go with those vertices via the index as well.

V-man
07-08-2011, 06:00 AM
I know an index can be passed which tells the GPU which vertices to use to create the faces

That's correct.


I think that's only useful if I can also specify the normals which go with those vertices via the index as well

As explained in the link I gave (Wiki), the exact same index is used for for the normal as well.


If vertex 0 is {0.0, 0.0, 0.0}
and normal 0 is {1.0, 0.0, 0.0}

then index=0 will refer to both of them.

index=5001 will refer to vertex 5001 and normal 5001

OmegaDeus
07-08-2011, 08:10 AM
As explained in the link I gave (Wiki), the exact same index is used for for the normal as well.

Hrm, that's not very useful then. The index for normals is different than the one for vertices. In many places they do coincide where say the index of the face is vertices(0, 1, 2) and their normals are normals(0, 1, 2) but in other places the normals use a different set entirely.

Does this mean I'll have to read through the two index arrays myself and generate my own array of vertices and normals? This is doable, but seems like a huge waste of an index of normals.

This would be easier if there weren't sharp edges and rounded edges both on the same object. Otherwise I could just give each vertex a normal and probably end up with a rather rounded object at all times.

BionicBytes
07-08-2011, 08:47 AM
Does this mean I'll have to read through the two index arrays myself and generate my own array of vertices and normals?
Yes it does.

This is doable, but seems like a huge waste of an index of normals.
That's the way indexing works in OpenGL.