• Create Account

Rendering 3D Models & Vertex Normals

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

6 replies to this topic

#1Orangeatang  Members

2692
Like
0Likes
Like

Posted 20 August 2012 - 03:35 PM

Hey folks,

I've been experimenting with DX11 over the last couple of weeks, and am currently writing a Wavefront .obj importer (Blender), and (I guess this must be the case for most file formats) the normals for the vertices are given as a set of indices for each face of the exported model (in this case a simple cube).

I'm guessing that in this case form most formats, and since I can't really send the normals though with the vertex buffer I was wondering what the best strategy is?

Is it possible to send the array of normals through as part of the vertex shader constants, and supply the index in the vertex format?

Thanks for your help!

#2Seabolt  Members

781
Like
1Likes
Like

Posted 20 August 2012 - 05:32 PM

You'd have to generate a vertex buffer for your mesh that has n-faces (or n-polys) * 2. Then you'll calculate the middle point for each face, (or poly), and project another point by the normal of each face, (do a cross product from the vectors of one vert to the others, then average them for each poly). Scale that point by how long you want the normal to be. Then just draw that vertex buffer after your mesh using the line list topology.
Perception is when one imagination clashes with another

#3Orangeatang  Members

2692
Like
0Likes
Like

Posted 21 August 2012 - 01:09 AM

You'd have to generate a vertex buffer for your mesh that has n-faces (or n-polys) * 2. Then you'll calculate the middle point for each face, (or poly), and project another point by the normal of each face, (do a cross product from the vectors of one vert to the others, then average them for each poly). Scale that point by how long you want the normal to be. Then just draw that vertex buffer after your mesh using the line list topology.

Hey thanks for the quick response.

I should have been clearer though, I don't actually want to render the normals; I want to use them for things like lighting calculations.

My issue is that I don't see how to supply the normals to the vertex shader. Since I'm rendering a cube in this example I have eight vertices and six normal values (one for each face of the cube). Aside from creating extra vertices in my vertex buffer (6 for each face) and dispensing with the index buffer (supplying the normal values as part of my vertex buffer format), I can't see how to get them through to the shader.

Cheers!

#4Orangeatang  Members

2692
Like
0Likes
Like

Posted 21 August 2012 - 01:53 AM

Hmm from what I've been reading it looks like I have to have a separate vertex instance for every vertex/normal combination I need. Makes sense I guess.

#5Seabolt  Members

781
Like
1Likes
Like

Posted 21 August 2012 - 01:24 PM

Ah sorry, I didn't understand the question very well, haha.

Generally you'd pass the normal per vertex in your input layout. If you only have access to the face normals, then you'd want the average normal of all faces that the vertex is apart of.
Perception is when one imagination clashes with another

#6french_hustler  Members

479
Like
1Likes
Like

Posted 21 August 2012 - 01:52 PM

Ah sorry, I didn't understand the question very well, haha.

Generally you'd pass the normal per vertex in your input layout. If you only have access to the face normals, then you'd want the average normal of all faces that the vertex is apart of.

This. The Wavefront .obj normals are usually not suited for direct transfer. You'll have to do some pre-work and create a buffer of per-vertex normals. As a matter of fact, I always export my models to a .obj format WITHOUT normals. I pre-compute the normals myself at load time (though that's a bit inefficient for high poly count models).

Anyways, here is an example of how to do this:
http://www.lighthouse3d.com/opengl/terrain/index.php3?normals

Basically you want to get the 3 vertices that make up a face.
Get the 2 perpendicular vectors and cross them to get a normal.
Accumulate that normal for the faces' vertices.
Do that for all faces and in the end you will average by dividing the amount of times you've accumulated for that specific vertex. That number should be equal to the amount of faces that use that vertex.

There are other fancier ways to calculate normals (such as adding weights). But a simple averaging should get you started properly.

Edited by french_hustler, 21 August 2012 - 01:55 PM.

#7MJP  Moderators

18236
Like
0Likes
Like

Posted 21 August 2012 - 07:21 PM

You need to split verts so that you have enough for each unique combination of position + normal. So for instance if you had a cube you'd have 8 positions and 6 normals (1 for each side of the face). However once you combine them you need 4 vertices for each face, which gives you 6 * 4 = 24 vertices.

The obj loading sample in the SDK (MeshFromOBJ10) should show you what to do, if you need some code.

Edited by MJP, 21 August 2012 - 07:22 PM.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.