For this post, we're going to add basic lighting to the model. This will make the edges pop out and the shape will definitely have a better 3D feel. For this, we will need to add normal data for each vertex. This will allow us to calculate light intensity at each vertex, and the rasterize stage will be able to interpolate those values across the shape. More vertex data means a new attribute, and we'll also need to modify the shaders. Everything else should be unchanged.
I've also compiled what we've done so far, and I put some of the methods in a helper class called GLHelper. Additionally, I dropped the vertex data in a header file. These changes make the Controller's implementation a bit cleaner.
First things first, let's change our CubeVertexData array to incorporate the vertex normals. It would be possible to calculate the normals using the vertex position and a cross product, but we'll keep it simple and just add the data in our array.
We must change the stride since both positions and normals are packed in a single array now. You also need to tell GL where the normals are so that it can pass them to the shader as an attribute.
Since the light must be calculated in eye coordinates, we'll have to split the ModelView and Projection transform matrices. In the shader, we'll transform the positions and the normals to be in eye coordinates, we'll then calculate light, and finally apply the projection matrix.
To transform the normals to eye coordinates, we'll need the Normal Transformation matrix as a uniform, which is calculated using the ModelView transformation matrix. We'll also pass the Light Position as a uniform, that way we can move the light every time we draw if we want to. This is what the uniform loop now looks like:
Finally, here are the modified shaders for basic lighting of our object: