How it works...

The vertex shader computes the shading equation in eye coordinates. It begins by transforming the vertex normal into camera coordinates and normalizing, then storing the result in n. The vertex position is also transformed into camera coordinates and stored in camCoords.

The ambient component is computed and stored in the variable ambient

Next, we compute the normalized direction towards the light source (s). This is done by subtracting the vertex position in camera coordinates from the light position and normalizing the result.

The dot product of s and n is computed next. As in the preceding recipe, we use the built-in function max to limit the range of values to between zero and one. The result is stored in the variable named sDotN, and is used to compute the diffuse component. The resulting value for the diffuse component is stored in the variable diffuse

Before computing the specular component, we check the value of sDotN. If sDotN is zero, then there is no light reaching the surface, so there is no point in computing the specular component, as its value must be zero. Otherwise, if sDotN is greater than zero, we compute the specular component using the equation presented earlier.  

If we did not check sDotN before computing the specular component, it is possible that some specular highlights could appear on faces that are facing away from the light source. This is clearly an unrealistic and undesirable result. Another way to solve this problem is to multiply both the specular and diffuse components by sDotN (instead of only the diffuse component as we are doing now). This is actually somewhat more physically accurate, but is not part of the traditional Phong model.

The direction toward the viewer (v) is the negation of the position (normalized) because in camera coordinates the viewer is at the origin.

We compute the direction of pure reflection by calling the GLSL built-in function reflect, which reflects the first argument about the second. We don't need to normalize the result because the two vectors involved are already normalized.

When computing the specular component, we use the built-in function max to limit the range of values of the dot product to between zero and one, and the function pow raises the dot product to the power of the Shininess exponent (corresponding to f in our lighting equation).

The sum of the three components is then stored in the output variable LightIntensity. This value will be associated with the vertex and passed down the pipeline. Before reaching the fragment shader, its value will be interpolated in a perspective correct manner across the face of the polygon.

Finally, the vertex shader transforms the position into clip coordinates, and assigns the result to the built-in output variable gl_Position (refer to the Diffuse and per-vertex shading with a single point light source recipe in this chapter).

The fragment shader simply applies the interpolated value of LightIntensity to the output fragment by storing it in the shader output variable FragColor.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.19.30.232