## In Review

In this tutorial, you have learned the following:

• Diffuse lighting is a simple lighting model based on the angle between the light source and the surface normal.

• Surface normals are values used, per-vertex, to define the direction of the surface at a particular location. They do not have to mirror the actual normal of the mesh geometry.

• Surface normals must be transformed by the inverse-transpose of the model-to-camera matrix, if that matrix can involve a non-uniform scale operation.

• Light interreflection can be approximated by adding a single light intensity that has no direction.

• Each vertex attribute has its own topology. In order to render these vertices in OpenGL, attribute data must be replicated so that each unique combination of attributes has a topology.

### Further Study

Try doing these things with the given programs.

• Modify the ambient lighting tutorial, bumping the diffuse light intensity up to 1.0. See how this effects the results.

• Change the shaders in the ambient lighting tutorial to use the lighting intensity correction mentioned above. Divide the diffuse color by a value, then pass larger lighting intensities to the shader. Notice how this changes the quality of the lighting.

### Further Research

Lambertian diffuse reflectance is a rather good model for diffuse reflectance for many surfaces. Particularly rough surfaces however do not behave in a Lambertian manor. If you are interested in modelling such surfaces, investigate the Oren-Nayar reflectance model.

### GLSL Functions of Note

 `vec clamp(` vec val, vec minVal, vec maxVal`)`;

This function does a clamping operation of each component of `val`. All of the parameters must scalars or vectors of the same dimensionality. This function will work with any scalar or vector type. It returns a scalar or vector of the same dimensionality as the parameters, where each component of `val` will be clamped to the closed range [`minVal`, `maxVal`]. This is useful for ensuring that values are in a certain range.

All components of `minVal` must be smaller than the corresponding components of `maxVal`.

 `float dot(` vec x, vec y`)`;

This function performs a vector dot product on `x` and `y`. This always results in a scalar value. The two parameters must have the same dimensionality and must be vectors.

 `vec normalize(` vec x`)`;

This function returns a vector in the same direction as `x`, but with a length of 1. `x` must have a length greater than 0 (that is, it cannot be a vector with all zeros).