Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interpolate vertex normals?

I am trying to render a 3D model (from volvis.org) with Gouraud shading using the marching cubes algorithm. So far I have the normals for each vertex with:

GetNormalForVertex(vertex &b, vertex &a, vertex &c) {
    u.X = a.X - b.X;
    u.Y = a.Y - b.Y;
    u.Z = a.Z - b.Z;
    v.X = c.X - b.X;
    v.Y = c.Y - b.Y;
    v.Z = c.Z - b.Z;

    return  Cross(u,v);
}

I can see a nice flat shading when its rendered. Now, far as I know I need to interpolate those vertex normals to find normal at the intersection point to get Gouraud shading. How could I interpolate the vertex normals?

like image 379
Floyd Barber Avatar asked Mar 25 '13 21:03

Floyd Barber


2 Answers

First of all, you are not computing vertex normals. You are computing face normals. This is step 1 in the process of computing vertex normals.

The next step is not interpolating anything. What you do is compute the (unnormalized) face normal for each face attached to a vertex. Then add them all together and normalize the result. That is the vertex normal.

How you determine which faces are attached to a vertex is another matter. In your case, because you're building this data via marching cubes, it shouldn't be too difficult to generate or retrieve the triangles from adjacent cubes. But if you're pass the generation step and just have a bag of triangles, then you're going to need an appropriate mesh topology data structure. Winged-edge or Quad-edge are both good choices.

like image 71
Nicol Bolas Avatar answered Sep 20 '22 18:09

Nicol Bolas


What are a, b and c?

If they're the vertices of a triangle, then you are computing the normal for the triangle, not for any particular vertex. The assumption in that case, is that the entire triangle is flat. This is called flat shading.

If, on the other hand, you wish to interpolate the surface normal across the interior of a triangle (used in Gouraud shading), then you need to have three different normals at the three vertices to begin with. This is a bit less trivial, but still easy. One way is to average the normals of all triangles that share a vertex in order to obtain the normal at that vertex. This obviously requires connectivity information (or you need to extract it somehow).

Once you have three different normals (say na, nb, nc), then the normal at any interior point can be computed via barycentric coordinates. Let the vertices be va, vb, vc and the interior point's barycentric coords be α and β. Then, the interior point v and its normal n are given by:

v = α*va + β*vb + (1 - α - β)*vc
n = α*na + β*nb + (1 - α - β)*nc

This interpolated normal (n) should be used for Gouraud shading.

like image 29
Rahul Banerjee Avatar answered Sep 19 '22 18:09

Rahul Banerjee