I’m trying to implement a geometry shader that does a uniform tesselation of triangles. For the interpolation I use a Bezier triangle. The required control points I compute based on the original triangle’s vertices and normals. This idea is also known as (curved) PN triangles.
My math is based on the following article:
Note that this article has a few typo’s. A significant one is for computing a normal n(u,v), where for the last three terms a factor 2 is missing. But apart from that it looks OK.
Now here is the problem: for certain geometries the Bezier triangle produces unexpected bumps and incorrect normals.
I have searched the web for any comments or discussions on this but found none. I think this originates from an incorrect definition of the reflection plane used to compute the normals, and consequently an incorrect calculation for the center control point p111. But also in various scientific articles on this topic I always get the same definitions, and I never found this problem addressed.
Here is a simple example showing where it goes wrong:
Take a quad build of two triangles that represents a square in the x-z plane. The four quad vertices are
A = (0,0,0), B = (0,0,1), C = (1,0,1), D = (1,0,0)
The corresponding normals are
Na = (0,1,0), Nb = (0,1,1), Nc = (0,1,1), Nd = (0,1,0)
The two normals at z=0 point straight up, the other two tilt forward. Lets build the quad using two triangles: ABD, BCD.
The Bezier triangle should interpolate such that the y-value changes as a function of z, and only z. Just think of the quad as a piece taken from a coarse cylinder with it’s axis parallel to the x-axis. Moving on the cylinder’s surface in the x-direction does not change the y and z coordinates. On this quad it should be the same. The x-coordinate must not affect the y-coordinate in the interpolation.
At the first sub-division (splitting the edges of both triangles), the vertices are correct, but the normal in the center of edge BD is wrong. Instead of lying in the plane spanned by Na and Nb (or Nd and Nc), which means it does have a non-zero x-coordinate. This is because the reflection plane that used is perpendicular to the edge BD, but it is not as - it should be - perpendicular to the rotation plane for transforming normal Nb into Nd. This incorrect normal results in an incorrect lighting. For sub-division level 1.
The second sub-division level creates 9 additional vertices: 2 on each edge, which are OK, and 3 inside the triangle. The latter ones are incorrect. As mentioned earlier, changing only the x-coordinate should leave the y-value unchanged. However, it is not the case. Instead, increasing the x-value first increases y, then decreases y, and finally increases it again.
Can anyone help me with this?