The POV-Ray Cyclopedia

Warp's mesh smoothing utility contains a great explination of how to smooth triangles. A question was asked in the advanced users group if the normals of a smooth triangle should be weighted or not. The answer was, of couse, "however you want it."

Part Zero
Setting Up

Setting up is pretty simple. We're going to describe a cirle with points on it, and connect them to another point not on the same plane, so it is tent like in shape:

#declare n =90;
#declare rp = array[n]
#declare rp[0] = <1,0,0>;
#declare cnt = 1;
#while ( cnt < n )
  #declare rp[cnt] = vrotate(rp[cnt-1],<0,(360/n),0>);
  //sphere { rp[cnt] 0.05 pigment { red 1 } }
  ReportV(rp[cnt])
  #declare cnt = cnt + 1;
#end

#declare q = <0,0.15,0>;

#declare cnt = 0;
#while ( cnt < n )
  #if ((cnt + 1 ) = n )
     #declare nx = 0;
  #else
     #declare nx = cnt+1;
  #end
  triangle { q rp[cnt] rp[nx] texture { tritex } }
  #declare cnt = cnt + 1;
#end

The first two images show 4 and 12 triangles. We are not worried with the look around the ring, put the area around point q. The second image looks smoother because of the larger number of triangles. If there 30 or 40 triangles, at this resolution, it looks completely smooth. Creating more triangles isn't always an option. Smooth triangles are the solution we want here.

We will look at using normalized normal vectors and standard normal vectors and we will offset q so it is closer to one side of the ring than the others.

Describe the image
1. 4 triangles
Describe the image
1. 12 triangles
Part One
Creating smooth triangles

The easiest way to create three normal vectors per triangle is to use POV-Ray's vcross function. The other thing to keep in mind is that the normals need to be on the same face of the triangle. If one of them is "above" the triangle and the other two "below", then the triangle will crash, or give an error as being degenerate and not render. To play is safe, we want to make sure that our vectors are being treated as "clockwise."

The code below is part of a loop that finds all of three normal vectors for each triangle (Image 3, the normal lengths are 25% of what they should be):

#declare cnt = 0;
#while ( cnt > n )
  #if ((cnt + 1 ) = n )
     #declare nx = 0;
  #else
     #declare nx = cnt+1;
  #end
  #declare qnorm[cnt] = vnormalize(vcross(rp[cnt]-q,rp[nx]-q));
  #declare qplace = q + 0.05*(rp[cnt]-q) + 0.05*(rp[nx]-q);

  #declare anorm[cnt] = vnormalize(vcross(rp[nx]-rp[cnt],q-rp[cnt]));
  #declare aplace = rp[cnt] + 0.05*(q-rp[cnt]) + 0.05*(rp[nx]-rp[cnt]);

  #declare bnorm[cnt] = vnormalize(vcross(q-rp[nx],rp[cnt]-rp[nx]));
  #declare bplace = rp[nx] + 0.05*(q-rp[nx]) + 0.05*(rp[cnt]-rp[nx]);
  #declare cnt = cnt + 1;
#end
This code normalizes all three vectors, so when we average them together they will all have an equal weight. Of course, in this case, since each triangle is the same size, then normalizing the vectors does not change the way the averaging will work.

Image number 4 shows the same four triangles, smoothed out. It is hard to see the shape, even with the light-source moved up to give a bit more hightlight.

Describe the image
3. The normal vectors of unsmoothed triangles
Describe the image
4. 4 smooth triangles
Part Two
Uneven triangles

Now we are going to move q to <0.8,0.35,0>, and using smooth triangles with normalized vectors we have image 5. Notice the two corners are in shadow, because the normals are pointing away from the light. This is similar to the hard shadow artifact that POV-Ray gives us. Image 6 is exactly the same, but the normalization of the normal vectors is omitted. The shadow effect is lessened.

Here is the code to draw the smooth triangles.

#declare cnt = 0;
#while ( cnt < n)
  #declare nx =(( cnt+1 = n)? 0:cnt+1);
  
  #declare qplace = q + 0.05*(rp[cnt]-q) + 0.05*(rp[nx]-q);
  #declare aplace = rp[cnt] + 0.05*(q-rp[cnt]) + 0.05*(rp[nx]-rp[cnt]);
  #declare bplace = rp[nx] + 0.05*(q-rp[nx]) + 0.05*(rp[cnt]-rp[nx]);
  smooth_triangle { q qn rp[cnt] anorm[cnt] rp[nx] anorm[nx] texture { tritex } }
  #declare cnt = cnt + 1;
#end

Describe the image
5. Normalized normals
Describe the image
6. Unnormalized normals

Send feedback, or head back to the Cyclopedia.

Thanks for watching.