Help understanding Vertex normals?

I must be doing something wrong. I’m trying to explore how to manipulate Meshes at the vertex level, so I wrote up a quick debugging method to print out the position and normals of vertices in a Mesh (using a Box as an example), but I’m getting weird results (or I don’t understand vertex normals).

Here’s the code:
[java]
Mesh m = new Box(1f,1f,1f);

	VertexBuffer pb = m.getBuffer(Type.Position);
	VertexBuffer nb = m.getBuffer(Type.Normal);
	IndexBuffer ib = m.getIndicesAsList();
	int tCount = ib.size() / 3;    //triangle count

	FloatBuffer pfb = (FloatBuffer) pb.getData();
	FloatBuffer pnb = (FloatBuffer) nb.getData();
	for (int i = 0; i < tCount; i++) {
		// acquire triangle's vertex indices
		System.out.println("p"+ib.get(i*3)+": {"+pfb.get(ib.get(i*3))+", "+pfb.get(ib.get(i*3+1))+", "+pfb.get(ib.get(i*3+2))+"}, n"+ib.get(i*3)+": {"+pnb.get(ib.get(i*3))+", "+pnb.get(ib.get(i*3+1))+", "+pnb.get(ib.get(i*3+2))+"}");
	}

[/java]

And here are the results:
[java]
p2: {-1.0, -1.0, -1.0}, n2: {-1.0, 0.0, 0.0}
p3: {1.0, -1.0, -1.0}, n3: {0.0, -1.0, 0.0}
p6: {1.0, -1.0, -1.0}, n6: {0.0, -1.0, 0.0}
p7: {1.0, 1.0, -1.0}, n7: {0.0, 0.0, 0.0}
p10: {1.0, -1.0, -1.0}, n10: {0.0, 0.0, -1.0}
p11: {-1.0, 1.0, -1.0}, n11: {-1.0, 0.0, -1.0}
p14: {-1.0, -1.0, 1.0}, n14: {0.0, 0.0, 1.0}
p15: {1.0, -1.0, 1.0}, n15: {1.0, 0.0, 1.0}
p18: {1.0, 1.0, -1.0}, n18: {1.0, 0.0, 0.0}
p19: {1.0, 1.0, -1.0}, n19: {0.0, 1.0, 0.0}
p22: {1.0, 1.0, 1.0}, n22: {0.0, 1.0, 0.0}
p23: {-1.0, 1.0, 1.0}, n23: {0.0, 0.0, 0.0}
[/java]

The first thing I noticed is that not all vertices are referenced from the indexBuffer. This may be normal, since when I ignore the indexBuffer, I get a lot of duplicate vertices.

Second thing is, according to my understanding of vertex normals (which might be wrong), the normal for a vertex on this cube, centered at origin, should essentially be the normalized position vector. So for a position of (1,1,1), the normal would be sqrt(3) / 3 = (0.5773502691896258, 0.5773502691896258, 0.5773502691896258) or thereabouts, and not… whatever it is I'm getting out of the normal buffer (looks like face normals?).

So: Am I misunderstanding Vertex normals, using the indexbuffer incorrectly, or what?

Those values are totally legit.
Vertex normals are vectors perpendicular to the surface they produce.

Loads of awsome examples at google Image Search!

The shader pipeline interpolates those by using barycentric coordinates to calculate the fragment normal which is sued for per-pixel lighting etc. Just an example for usage… You can do a lot of stuff with normals. I like normals. Normals are awsome. Always treat your normals good or they may run away from you and leave you in unspeakable misery.

Edit: That shouldnt mean “sued for…” but its so funny i will keep it in.

@roach374 said: The first thing I noticed is that not all vertices are referenced from the indexBuffer.

That’s because your are skipping every second and third value in the index buffer.

Edit: actually that code is kind of messed up. I will help you debug it but you will need to split it out into separate lines so I can more easily point at the errors. You are using ib.get(i * 3 + 1) in the wrong places, though.

Edit: actually that code is kind of messed up.

Yep! After I posted, I realized that the indexBuffer doesn’t actually do what I thought it did, and that my code is completely jacked up. As I understand it NOW, the indexBuffer contains an ordered list of indicies into the position / normal / texture vertex buffers. In the case of a triangle-mode Mesh (I think), every three indices indicates a right-hand poly (3 vertices, in counter-clockwise order). So yeah, the same index will show up for every use of the same vertex (if a vertex is used by ten triangles, it’ll be in the index buffer ten times).

…This may seem obvious to all you old hands, but it was an eye-opener for me. Thanks!

@KuroSei said: Vertex normals are vectors perpendicular to the surface they produce.

But a Vertex can contribute to multiple Faces / Polys (which is what I assume you mean by “surfaces”?). According to Wikipedia Vertex normals should be the normalized average vector of the normals for all the faces to which this vertex contributes. According to my intuitive understanding of a cube, this means that the “corner” vertex normals should point “out” diagonally from the center, which is not what I’m seeing above. What did I get wrong?

Oh. You are right indeed. :slight_smile:
I guess the cube doesnt share vertices and thus doesnt share normals.
I am not sure about that tho.

If it looks like the smooth one they share em, if it looks ‘flat’ they dont… I guess.

That is correct. This is also why smooth shading is more efficient - you need far fewer vertices.

Yeah, more generally, in this case a “vertex” is a collection of attributes: position, texture coordinate, normal, etc… if all of those are the same then the vertex can be shared. If any of those are different then the vertex cannot.

Pedantically speaking, the flat non-smooth cube does share some vertexes since each of the six faces is two triangles that share two vertexes. This is why there are 24 vertexes instead of 36. (6x4 instead of 6x6)

But still 3 times as many as the smooth shaded cube with 8 :slight_smile:

@zarch said: But still 3 times as many as the smooth shaded cube with 8 :)

Yep, OP said:

@KuroSei said: I guess the cube doesnt share vertices and thus doesnt share normals. I am not sure about that tho.

I was clarifying.

Holy crap, I think I actually understood all of that. Thanks guys!