Mesh loader and normal discontinuity

Hi,

I have written a mesh loader for MS DirectX .x files (just the mesh components for now, no textures, animation) and can display the loaded mesh using lwjgl drawing triangles and setting normals etc.

The problem is that when I specify a gl.normal3f() for each triangle (at a right angle to the triangle), the faces are predictably heavily faceted under lighting (like a crystal).

Does anyone have any recommendations for how I can display a poly model consisting of triangles so that the surface is smooth rather than heavily faceted (like a crystal)

I am happy to share the mesh loader on this forum when it is finished

Pixel :wink:

Edit:

Having a look around, it seems that I will need to specify per vertex normals which are averaged between normals for each face.

Additionally, the gl.enable(gl.NORMALIZE) call seems to be important in rendering with Gouraud shading.

Does anyone have any working examples or links to an applicable tutorial (C or C++ is fine) for per vertex normal calculation and OpenGL rendering of triangle meshes with Gouraud shading?

Pixel

You need to do what’s called normal averaging. Basically smoothly interpolating between the normals of a face. Instead of calculating the normal for just the face, calculate the normal for each vertex. Where the normal for a single vertex is the average of the normals of each face it touches. Hope that helps.

Thanks Mojomonkey,

Does anyone have sample code to calculate per vertex normals?

Once I have them, do I just call gl.normal3f() just before gl.vertex3f()?

My Mesh object contains (amongst other things)

  1. a Vertex [] of vertices
  2. a Vertex [] of normals for each triangle
  3. a Triangle [] where each triangle lists the index of each point and an index for the normal for the triangle

Pixel

I suppose I could:

  1. walk the triangle array indexing each vertex according to the triangles that contain that point.

  2. Accumulate the indexes to the normals for each attached triangle for every vertex.

  3. Acquire an average normal by adding each x,y,z component from the adjacent triangle normals and dividing each component total by the number of normals.

avNormal.x = (adjNormal1.x + adjNormal2.x + adjNormal3.x) / 3.0f;

avNormal.y = (adjNormal1.y + adjNormal2.y + adjNormal3.y) / 3.0f;

avNormal.z = (adjNormal1.z + adjNormal2.z + adjNormal3.z) / 3.0f;

Is it that easy? Or is there some funky vector math that I should use to average a set of normals?

Pixel :-/

That’s basically it, but for smoother results you can take the size of each face into account, instead of giving each the same weighting in the average.

I believe that this is done in idx3d, which can be found here. It’s a software renderer that does phong shading, environment mapping and other stuff, all in java 1.1. Digging around the source may turn up some tips.

Thanks Bleb,

I tried what I was suggesting and the results are very promising. The loader just calculates the per vertex normal as it is loading the mesh.

The result is certainly smooth enough for the engine I am writing.

Now for some texturing…