Rendering 3D Models & Vertex Normals

Started by
5 comments, last by MJP 11 years, 8 months ago
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!
Advertisement
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

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!
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.
Ah sorry, I didn't understand the question very well, haha. tongue.png

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

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

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.
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.

This topic is closed to new replies.

Advertisement