Yes, I've discovered another bug in one of the Warp3D Nova tutorials. The tutorial itself has been corrected already, but let's take a closer look at this bug.
The problem is with this line of code:
// Transform the normal normal = normalize(NormalMatrix * vec4(vertNormal, 1.0)).xyz;
Can you see the mistake? It's a really subtle one.
The normalize() function rescales a vector so that it's magnitude is one. This is important because our surface normals need to be a pure direction vector. Otherwise later calculations will be skewed.
Anyway, look very closely at the code. See the problem yet? Here's a clue, the following returns a 4D vector:
NormalMatrix * vec4(vertNormal, 1.0)
The code uses homogeneous coordinates where a 3D vector is augmented with a 1. This enables us to multiply by a 4×4 matrix containing both rotation and translation. While translation isn't needed for surface normals, I avoid 3×3 matrices in GLSL due to possible alignment issues (drivers have had incorrect padding in the past).
What's happening is that normalize() is being called on the 4D homogeneous vector with the added 1, and this is then truncated back to 3D. Look at the offending line of code:
normal = normalize(NormalMatrix * vec4(vertNormal, 1.0)).xyz;
See it now? It's pure luck that the demo looks okay. Results could have been quite different with other lighting parameters.
What's missing is a pair of brackets:
// Transform the normal normal = normalize((NormalMatrix * vec4(vertNormal, 1.0)).xyz);
Yes, two missing characters; that's all.
Let me make it more obvious by splitting the line into two:
// Transform the normal normal = (NormalMatrix * vec4(vertNormal, 1.0)).xyz; normal = normalize(normal);
The transformed normal is truncated back to 3D before being normalized, producing the correct result.
These subtle bugs can be difficult to track down. It takes a trained eye to spot, and the "training" is usually getting caught out by such bugs and spending hours searching for them. Hopefully, seeing this one will help you spot others like it.