Skip to content

Lab 8: Calculating Per Pixel Normals from a Height Map

drebain edited this page Jun 28, 2017 · 1 revision

Lab 8: Calculating Per-Pixel Normals from a Height Map

In this lab you will add shading and texturing using the Phong lighting model to your Perlin Noise terrain from the previous lab.

You will need to incorporate your noise implementation with the new code in the assignment3 subfolder, which has been updated for this exercise.

Basic Diffuse Phong Lighting

Recall that the Phong lighting model has three terms: ambient, diffuse, and specular.

The ambient term is given as a constant in the shader for this exercise, as it depends only on the intensity of ambient light in the scene, and the ambient reflection constant of your material.

The diffuse term requires the world-space normal vector of your surface at a pixel. For your terrain, which is distorted dynamically in the vertex shader, you will need to calculate this value from the height map. You can numerically evaluate the u or v slope of the height map by sampling it at a one pixel offset and taking the difference. A convenient shader function for reading textures with integer pixel offsets is textureOffset():

textureOffset(height_map, uv, ivec2(0,1)) // this reads the texture at position uv plus one pixel in the v direction

Once you have the slope, you can construct a vector perpendicular to the terrain at the point of interest, which is the normal vector needed for Phong lighting.

Adding Specular

To compute the specular term, you will need to also know the world space position of each pixel. You can get this by adding an 'in' parameter in the fragment shader and corresponding 'out' parameter in the vertex shader that you write the world space position to. OpenGL will then take care of interpolating the value for you.