GLSL Programming/Blender/Smooth Specular Highlights

This tutorial covers per-pixel lighting (also known as Phong shading).

It is based on the tutorial on specular highlights. If you haven't read that tutorial yet, you should read it first. The main disadvantage of per-vertex lighting (i.e. of computing the surface lighting for each vertex and then interpolating the vertex colors) is the limited quality, in particular for specular highlights as demonstrated by the figure to the left. The remedy is per-pixel lighting which computes the lighting for each fragment based on an interpolated normal vector. While the resulting image quality is considerably higher, the performance costs are also significant.

Per-Pixel Lighting (Phong Shading)
Per-pixel lighting is also known as Phong shading (in contrast to per-vertex lighting, which is also known as Gouraud shading). This should not be confused with the Phong reflection model (also called Phong lighting), which computes the surface lighting by an ambient, a diffuse, and a specular term as discussed in the tutorial on specular highlights.

The key idea of per-pixel lighting is easy to understand: normal vectors and positions are interpolated for each fragment and the lighting is computed in the fragment shader.

Shader Code
Apart from optimizations, implementing per-pixel lighting based on shader code for per-vertex lighting is straightforward: the lighting computation is moved from the vertex shader to the fragment shader and the vertex shader has to write the attributes required for the lighting computation to varyings. The fragment shader then uses these varyings to compute the lighting (instead of the attributes that the vertex shader used). That's about it.

In this tutorial, we adapt the shader code from the tutorial on specular highlights to per-pixel lighting. The resulting vertex shader looks like this:

Most of the work is now done in the fragment shader: Note that the vertex shader writes a normalized vector to  in order to make sure that all directions are weighted equally in the interpolation. The fragment shader normalizes it again because the interpolated directions are no longer normalized.

Summary
Congratulations, now you know how per-pixel Phong lighting works. We have seen:
 * Why the quality provided by per-vertex lighting is sometimes insufficient (in particular because of specular highlights).
 * How per-pixel lighting works and how to implement it based on a shader for per-vertex lighting.