In Review

In this tutorial, you have learned the following:

Further Study

Try doing these things with the given programs.

  • Add a fifth light, a directional light representing the moon, to the gamma-correct scene. This will require creating another set of interpolators and expanding the SunlightValues structure to hold the lighting intensity of the moon. It also means expanding the number of lights the shaders use from 4 to 5 (or removing one of the point lights). The moon should be much less bright than the sun, but it should still have a noticeable effect on brightness.

  • Play with the ambient lighting intensity in the gamma-correct scene, particularly in the daytime. A little ambient, even with a maximum intensity as high as 10, really goes a long way to bringing up the level of brightness in a scene.

Further Research

HDR is a pretty large field. This tutorial covered perhaps the simplest form of tone mapping, but there are many equations one can use. There are tone mapping functions that map the full [0, ∞) range to [0, 1]. This would not be useful for a scene that needs a dynamic aperture size, but if the aperture is static, it does allow the use of a large range of lighting values.

When doing tone mapping with some form of variable aperture setting, computing the proper maximum intensity value can be difficult. Having a hard-coded value, even one that varies algorithmically, works well enough for some scenes. But for scenes where the user can control where the camera faces, it can be inappropriate. In many modern games, they actually read portions of the rendered image back to the CPU and do some computational analysis to determine what the maximum intensity should be for the next frame. This is delayed, of course, but it allows for an aperture that varies based on what the player is currently looking at, rather than hard-coded values.

Just remember: pick your HDR and tone mapping algorithms before you start putting the scene together. If you try to change them mid-stream, you will have to redo a lot of work.

OpenGL Functions of Note

glGetIntegerv

Retrieves implementation-dependent integer values and a number of context state integer values. There are also glGetFloatv, glGetBooleanv, and various other typed glGet* functions. The number of values this retrieves depends on the enumerator passed to it.

Fork me on GitHub