In this post, I am going to talk about the normal vector and the correct way to transform it.
What is the difference between a point and a vector?
A geometric point does not have any length, area, volume, or any other dimensional attribute. A common interpretation is that the concept of a point is meant to capture the notion of a unique location in Euclidean space, whereas a vector represents a direction. This leads to a number of important differences in how they are treated. We can add a vector to a point, offsetting it in the given direction to obtain a new point. Alternately, one can subtract one point from another, obtaining the vector between them, as shown in the following picture.
What is a normal vector?
In 3D, the surface normal, or simply normal, to a surface at a point P is a vector that is perpendicular to the tangent plane to that surface at P.
As you can see in the previous picture, it can be defined as the cross product of any two non-parallel vectors that are tangent to the surface at a point.
Although normals are vectors, it is important to distinguish between the two of them, because normals are defined in terms of their relationship to a particular surface. They behave differently than vectors, for example, when applying transformations.
From a mathematical point of view, suppose N is the normal vector and V is the tangent vector. Since they are perpendicular its dot product is zero. M is any 3×3 invertible transformation (M^-1 * M = I). N’ and V’ are the vectors transformed by M. With the tangent vector V, we can use the same transformation matrix used with the geometry (M); obtaining V’. But with N, the situation is different:
Given this, you can see that the dot product between N’ and V’ is zero. Therefore, N after the transformation by the inverse transpose of the transformation matrix (N’) is perpendicular to V’. You could think that N’ could end being a binormal vector after the transformation. It will be perpendicular to V’ but it is not a normal vector of the surface.
But again, you can get the same conclusion with B instead of V. Then if N’ is perpendicular to transformed tangent vector V’ and transformed binormal vector B’, then it must be a normal vector to the surface.
From a geometric point of view, we can see a circle with a normal vector in the following picture.When scaling the circle to be half as tall in the y direction, simply treating the normal as a direction and scaling it, in the same manner, gives a normal that is no longer perpendicular to the surface.In the following picture, you can see a properly transformed normal.Another example to consider is the following (consider the shear transformation below)
Ok, we understood the big picture but is this going to be noticeable in a real application?
The following picture is a screenshot of a scene that was generated using PBRT-3. The scale is the same in x, y and z-axis.
Now, I modified the same scene by scaling the teapot in a non-uniform way (2.0 in x-axis, 1.0 in y-axis and 1.0 in z-axis). The left picture shows the scene where the normals were transformed using the same matrix that was used for geometry transformation. The right picture shows the scene where the normals were transformed by the inverse transpose transformation matrix.
I also fixed my rendering engine with this transformation. In the following video, you can see the difference, the first part shows the incorrect transformation and the second part shows the correct transformation.