Albedo G-buffer Normal G-buffer
Position G-buffer Deferred shading result

Before you start

This assignment builds on the previous one. If yours worked, I strongly recommend using your own code as a starting point for this assignment. If not, you will find my sample solution in the "a4sample" directory of your GitHub repository. You are free to either use that code to figure out what was wrong with your assignment, or use it as a base for this one. Whichever you choose, be sure to do all of your work for this assignment in the "GLapp" directory of your repository (i.e. copy my code over to that directory if you are going to use it as a base).

This assignment will require adapting code from online tutorials to our GLapp. For this assignment, it is explicitly OK to adapt such code found online, as long as you credit the source in your assn5.txt. As usual, you are also free to discuss concepts and share pointers to resources. It is still not OK to share actual code with others in the class.

The Assignment

The goals of this assignment are to implement a multi-pass technique, including both OpenGL C++ code and shading code.

The specific technique you will implement is deferred shading. In deferred shading, rather than compute the full lighting contribution at each fragment as it is drawn, only to have it potentially hidden by other fragments, you just compute any per-vertex values and look up any texture data while drawing the geometry. These results are rendered into several textures known as G-buffers. Then, in a second rendering pass, you draw a triangle or rectangle that covers every pixel on the screen, using a shader that looks up the G-buffer values and computes the final color from them.

Your first G-buffer should contain the albedo (aka base surface color) in RGB and specular glossiness in A. Your second G-buffer should contain the world-space normal in RGB and specular intensity in A (as a single float rather than full color). Your third G-buffer should contain the world-space pixel position in RGB and ambient intensity in A (as a single float rather than full color). So you don't need to worry about clamping and precision, use the GL_RGBA32F data type for all three textures (32-bit float per color component).

To render and use the G-buffers, adapt the directions in this render-to-texture OpenGL tutorial. We will want three textures as GL_COLOR_ATTACHMENT0-2, and a GL_RENDERBUFFER for the GL_DEPTH_ATTACHMENT. All of these should be resized by calling glTexImage2D or glRenderbufferStorage again with the new size if the screen size changes.

Add key controls passed to the shaders in a uniform value (similar to the way the ambient intensity control works), to show G-buffers 0, 1 and 2 when the user presses the '0', '1', or '2' keys, and the final result when they press '-'.

Extra Credit

For up to 15 points of extra credit, use the position and normal together with data from nearby pixels to implement Screen Space Ambient Occlusion (SSAO). You will have to google for information about SSAO, select from among the algorithms you find, and adapt their techniques to our GLapp.

634 only

Instead of using a world-space position G-buffer, derive the world space position in your shader using the pixel position, from gl_FragCoord, and pixel depth. Note that in your deferred shading pass, the depth in gl_FragCoord will be the depth of the screen-sized quad. You can get the depth of the original geometry, either by using a texture instead of renderbuffer for the depth attachment, or by storing the depth into the unused channel the G-buffer with the normal. To get back to world space, you will need to convert image coordinates into clip-space, then apply the transform from clip space to world space.


What to turn in

Turn in this assignment electronically by pushing your source code to your class git repository by 11:59 PM on the day of the deadline and tagging the commit assn5. Do your development in the GLapp directory so we can find it. See the assn0 project description if you accidentally tag the wrong commit and need to retag.

Also include an assn5.txt file at the top level of your repository telling us about your assignment. Tell us what works, and what does not. Also tell us what (if any) help you received from books, web sites, or people other than the instructor and TA. Finally, if you did anything toward the extra credit, be sure to tell us about it in this file. For the extra credit, be sure to tell us about the algorithm you used and where you found it.

You must make multiple commits along the way with useful checkin messages. We will be looking at your development process, so a complete and perfectly working assignment submitted in a single checkin one minute before the deadline will NOT get full credit. Individual checkins of complete files one at a time will not count as incremental commits. Do be sure to check in all of your source code, but no build files, log files, generated images, zip files, libraries, or other non-code content.