Assignment 1: Physically-Based Shading

CMSC 491/691, Spring 2014

NOW Due Friday, February 21, 2014


Create a fragment shader for a physically-based lighting model for point light sources, along with any vertex shader and C++ changes necessary to get it the data it needs. You should change the code as necessary to be able to rotate both the view and light position (e.g. move the view with the mouse, move the light with w,a,s,d). Use the provided sample code as a starting point. I may allow you to use another language, graphics API, or shading language if you clear it with me first, but I will 1) need to be able to get it running myself, and 2) it will have to support all of the assignment objectives described below.

Your shader should use three textures: a diffuse albedo map, a normal map, and a gloss/specular map. It should use energy normalization, a physically plausible normal distribution function, shadowing and masking terms, and a Fresnel reflectance term. The normal map can be unpacked to a tangent space normal using the transformation normalize(2*tex-1) for all components. The gloss map can be unpacked to a Blinn-Phong exponent using pow(8096,tex). If your normal distribution function uses a different roughness parameter, you should be able to convert this Blinn-Phong exponent to that roughness/variance/etc.

Here are some game development blog resources for physically-based shading models:

691 students

Your project should also include specular antialiasing: LEAN map, LEADER map, Toksvig, or related technique. Part of your work should include researching and evaluating the alternatives and choosing which to use. You may need to process the normal and gloss map into alternate intermediate textures. If you do this as a separate program, include your processing code in your submission.

While most games use the minimum precision textures possible to save memory, you may just switch to floating point textures if you need something better than 8 bits per component. If you do, I recommend pfm as a simple extension of ppm to floating point.

What to turn in

You will submit your work to your class cvs repository. Submit your project source only. I do not want your intermediate build files, executables, copies of GLFW, or other stuff I can get or build myself. Do include necessary texture or model files.

Check in a readme.txt file telling me what external sources you used, what you did for your assignment, and what I should notice. Check in all of your source code files, and anything else that cannot be regenerated from them, including any external textures or models. Do not include any compiled object files, libraries or executables. They won't do me any good, and can lead to strange hard to find bugs when compiled code not corresponding to your current source is resurrected from the repository. Do not package all of your files up into a single archive. CVS has limited ability to deal with binary files, and you'll quickly end up using more space than you think you're saving.

If you need your GL system quota increased (now, or at any time during the semester), let me know.

External help

I am expecting you will need make heavy use of web resources and sample code for this assignment. Such use is explicitly allowed for this assignment, provided you document your sources. In particular, it is even OK to look at other people's physically-based shader code


You will probably need to download, build and install GLFW and possibly GLEW on your system. Allow time to get it working. See piazza for details.

Develop incrementally and check in OFTEN! Keep a spare copy checked out in addition to your development copy. This will allow you to get prior versions when things go wrong. However, be careful copying files between the copies, as

Plan everything you'll need to do, but make small changes you can run and test rather than large code changes all at once. Graphics bugs can often result in objects that don't appear anywhere, or just appear black. Finding the cause can be tricky and frustrating if you don't know which change caused the error.

Here's one way you could approach the development:

  1. Add code to move the light position
  2. Add code to load additional textures
  3. Add code to get the surface tangents into the shader
  4. Use the tangents, normal and normal map to find the new normal
  5. Add physically-based specular
  6. Plug the gloss map into the physically based specular


The first thing I hope you get out of this assignment is a working sand-box environment for future development. In addition, you should get some experience with OpenGL "plumbing": adding uniform variables, textures and attributes to graphics API code, adding simple controls for uniform variables, passing data through a vertex shader, and in development and debugging of a fragment shader. In addition, much of game development is about incorporating ideas into an existing codebase, usually written by somebody else. While the sample application is way smaller than you would usually see, it is still not as familiar to you as it would be if you had written the whole thing yourself. All of these skills will be useful later.