Commits

Jason McKesson committed f9a380d

Tut12: Basic text done. Still need images.

  • Participants
  • Parent commits 0d40f37

Comments (0)

Files changed (4)

Documents/Basics/Tutorial 00.xml

                 <glossterm>colorspace</glossterm>
                 <glossdef>
                     <para>The set of reference colors that define a way of representing a color in
-                        computer graphics. All colors are defined relative to a particular
+                        computer graphics, and the function mapping between those reference colors
+                        and the actual colors. All colors are defined relative to a particular
                         colorspace.</para>
                 </glossdef>
             </glossentry>

Documents/Illumination/Tutorial 10.xml

                 </imageobject>
             </mediaobject>
         </informalequation>
-        <para>However physically correct this equation is, it has certain drawbacks. And this brings
-            us back to the light intensity problem we touched on earlier.</para>
-        <para>Since our lights are clamped on the [0, 1] range, it doesn't take much distance from
-            the light before the contribution from a light to become effectively nil. In reality,
-            with an unclamped range, we could just pump the light's intensity up to realistic
-            values. But we're working with a clamped range.</para>
-        <para>Therefore, a more common attenuation scheme is to use the inverse of just the distance
-            instead of the inverse of the distance squared:</para>
+        <para>This equation computes physically realistic light attenuation for point-lights. But it
+            often doesn't look very good. Lights seem to have a much sharper intensity falloff than
+            one would expect.</para>
+        <para>There is a reason for this, but it is not one we are ready to get into quite yet. What
+            is often done is to simply use the inverse rather than the inverse-square of the
+            distance:</para>
         <equation>
             <title>Light Attenuation Inverse</title>
             <mediaobject>
                 </imageobject>
             </mediaobject>
         </equation>
-        <para>It looks brighter for more distant lights. It isn't physically correct, but so much
-            about our rendering is at this point that it won't be noticed much.</para>
+        <para>It looks brighter at greater distances than the physically correct model. This is fine
+            for simple examples, but as we get more advanced, it will not be acceptable. This
+            solution is really just a stop-gap; the real solution is one that we will discuss in a
+            few tutorials.</para>
         <section>
             <title>Reverse of the Transform</title>
             <para>However, there is a problem. We previously did per-fragment lighting in model

Documents/Illumination/Tutorial 12.xml

                 away from the lights, but we can reasonably see things.</para>
             <!--TODO: Picture of the dark tutorial, night-optimized vs day-optimized.-->
             <para>The problem is that, in daylight, the point lights are too powerful. They are very
-                visible and have very strong effects on the scene.</para>
+                visible and have very strong effects on the scene. Also, they cause some light
+                problems when one of the point lights is in the right position.</para>
+            <!--TODO: Picture of the night-optimized clipping problem.-->
+            <para>Notice the patch of iridescent green. This is <glossterm>light
+                    clipping</glossterm> or light clamping, and it is usually a very undesirable
+                outcome. It happens when the computed light intensity falls outside of the [0, 1]
+                range, usually in the positive direction (like in this case). The object can't be
+                shown to be brighter, so it becomes a solid color that loses all detail.</para>
             <para>The obvious solution to our lighting problem is to simply change the point light
                 intensity based on the time of day. However, this is not realistic; flashlights
                 don't actually get brighter at night. So if we have to do something that
     <section>
         <?dbhtml filename="Tut12 High Dynamic Range.html" ?>
         <title>High Dynamic Range</title>
-        <para/>
+        <para>In order to answer this question, we must first determine why flashlights appear
+            brighter at night than in the daytime? Much of the answer has to do with our
+            eyes.</para>
+        <para>The pupil is the hole in our eyes that allows light to pass through it; cameras call
+            this hole the aperture. The hole is small, relative to the world, which helps with
+            resolving an image. However, the quantity of light that passes through the hole depends
+            on how large it is. Our iris's can expand and contract to control the size of the pupil.
+            When the pupil is large, more light is allowed to enter the eye; when the pupil is
+            small, less light can enter.</para>
+        <para>The iris contracts automatically in the presence of bright light, since too much like
+            can damage the retina (the surface of the eye that detects light). However, in the
+            absence of light, the iris slowly relaxes, expanding the pupil. This has the effect of
+            allowing more light to enter the eye, which adds to the apparent brightness of the
+            scene.</para>
+        <para>So what we need is not to change the overall light levels, but instead apply the
+            equivalent of an iris to the final lighting computations of a scene. That is, we
+            determine the overall illumination at a point, but we then filter out some of this light
+            based on a global setting. In dark scenes, we filter less light, and in bright scenes,
+            we filter more light.</para>
+        <para>This overall process is called <glossterm>high dynamic range lighting</glossterm>
+                (<acronym>HDR</acronym>). It is fairly simple and requires very few additional math
+            computations compared to our current model.</para>
+        <note>
+            <para>You may have heard this term in conjunction with pictures where bright objects
+                seem to glow. While HDR is typically associated with that glowing effect, that is a
+                different effect called bloom. It is a woefully over-used effect, and we will
+                discuss how to implement it later. HDR and bloom do interact, but you can use one
+                without the other.</para>
+        </note>
+        <para>The first step is to end the myth that lights themselves have a global maximum
+            brightness. That is, light intensity is no longer on the range [0, 1]; lights can now
+            have any positive intensity value.</para>
+        <para>This also means that our accumulated lighting intensity, the value we originally wrote
+            to the fragment shader output, is no longer on the [0, 1] range. And that poses a
+            problem. We can perform lighting computations with a high dynamic range, but monitors
+            can only display colors on the [0, 1] range. We therefore must map from the HDR to the
+            low dynamic range (<acronym>LDR</acronym>).</para>
+        <para>This part of HDR rendering is called <glossterm>tone mapping.</glossterm> There are
+            many possible tone mapping functions, but we will use one that simulates a flexible
+            aperture. It's quite a simple function, really. First, we pick a maximum intensity value
+            for the scene; intensity values above this will be clamped. Then, we just divide the HDR
+            value by the maximum intensity to get the LDR value.</para>
+        <!--TODO: Equation of LDR = HDR/max.-->
+        <para>It is the maximum intensity that we will vary. As the sun goes down, the intensity
+            will go down with it. This will allow the sun to be much brighter in the day than the
+            lights, thus overwhelming their contributions to the scene's illumination. But at night,
+            when the maximum intensity is much lower, the other lights will have an apparently
+            higher brightness.</para>
+        <para>This is implemented in the <phrase role="propername">HDR Lighting</phrase>
+            tutorial.</para>
+        <para>This tutorial controls as the previous one, except that the <keycap>K</keycap> key
+            will activate HDR lighting. Pressing <keycap>L</keycap> or <keycombo>
+                <keycap>Shift</keycap>
+                <keycap>L</keycap>
+            </keycombo> will go back to day or night-time LDR lighting from the last tutorial,
+            respectively.</para>
+        <!--TODO: Image of HDR lighting tutorial.-->
+        <para>The code is quite straightforward. We add a floating-point field to the
+                <classname>Light</classname> uniform block and the <classname>LightBlock</classname>
+            struct in C++. Technically, we just steal one of the padding floats, so the size remains
+            the same:</para>
+        <example>
+            <title>HDR LightBlock</title>
+            <programlisting language="cpp">struct LightBlockHDR
+{
+    glm::vec4 ambientIntensity;
+    float lightAttenuation;
+    float maxIntensity;
+    float padding[2];
+    PerLight lights[NUMBER_OF_LIGHTS];
+};</programlisting>
+        </example>
+        <para>We also add a new field to <classname>SunlightValue</classname>: the maximum light
+            intensity. There is also a new function in the <classname>LightManager</classname> that
+            computes the HDR-version of the light block:
+            <function>GetLightInformationHDR</function>. Technically, all of this code was already
+            in <filename>Light.h/cpp</filename>, since these files are shared among all of the
+            tutorials here.</para>
+        <section>
+            <title>Scene Lighting in HDR</title>
+            <para>Lighting a scene in HDR is a different process from LDR. Having a varying maximum
+                intensity value, as well as the ability to use light intensities greater than 1.0
+                change much about how you set up a scene.</para>
+            <para>In this case, everything in the lighting was designed to match up to the daytime
+                version of LDR in the day, and the nighttime version of LDR at night. Once the
+                division by the maximum intensity was taken into account.</para>
+            <table frame="none">
+                <title>Scene Lighting Values</title>
+                <tgroup cols="11">
+                    <colspec colname="c1" colnum="1" colwidth="3.0*"/>
+                    <colspec colname="c2" colnum="2" colwidth="1.0*"/>
+                    <colspec colname="c3" colnum="3" colwidth="1.0*"/>
+                    <colspec colname="c4" colnum="4" colwidth="1.0*"/>
+                    <colspec colname="c5" colnum="5" colwidth="1.0*"/>
+                    <colspec colname="c6" colnum="6" colwidth="1.0*"/>
+                    <colspec colname="c7" colnum="7" colwidth="1.0*"/>
+                    <colspec colname="c8" colnum="8" colwidth="1.0*"/>
+                    <colspec colname="c9" colnum="9" colwidth="1.0*"/>
+                    <colspec colname="c10" colnum="10" colwidth="1.0*"/>
+                    <colspec colname="c11" colnum="11" colwidth="1.0*"/>
+                    <thead>
+                        <row>
+                            <entry/>
+                            <entry namest="c2" nameend="c5" align="center">
+                                <para>HDR</para>
+                            </entry>
+                            <entry namest="c6" nameend="c8" align="center">
+                                <para>LDR Day-optimized</para>
+                            </entry>
+                            <entry namest="c9" nameend="c11" align="center">
+                                <para>LDR Night-optimized</para>
+                            </entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry>Noon Sun Intensity</entry>
+                            <entry>1.8</entry>
+                            <entry>1.8</entry>
+                            <entry>1.8</entry>
+                            <entry>(3.0)</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                        </row>
+                        <row>
+                            <entry>Noon Ambient Intensity</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                            <entry/>
+                            <entry>0.2</entry>
+                            <entry>0.2</entry>
+                            <entry>0.2</entry>
+                            <entry>0.2</entry>
+                            <entry>0.2</entry>
+                            <entry>0.2</entry>
+                        </row>
+                        <row>
+                            <entry>Evening Sun Intensity</entry>
+                            <entry>0.45</entry>
+                            <entry>0.15</entry>
+                            <entry>0.15</entry>
+                            <entry>(1.5)</entry>
+                            <entry>0.3</entry>
+                            <entry>0.1</entry>
+                            <entry>0.1</entry>
+                            <entry>0.3</entry>
+                            <entry>0.1</entry>
+                            <entry>0.1</entry>
+                        </row>
+                        <row>
+                            <entry>Evening Ambient Intensity</entry>
+                            <entry>0.225</entry>
+                            <entry>0.075</entry>
+                            <entry>0.075</entry>
+                            <entry/>
+                            <entry>0.15</entry>
+                            <entry>0.05</entry>
+                            <entry>0.05</entry>
+                            <entry>0.15</entry>
+                            <entry>0.05</entry>
+                            <entry>0.05</entry>
+                        </row>
+                        <row>
+                            <entry>Circular Light Intensity</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                            <entry/>
+                            <entry>0.2</entry>
+                            <entry>0.2</entry>
+                            <entry>0.2</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                            <entry>0.6</entry>
+                        </row>
+                        <row>
+                            <entry>Red Light Intensity</entry>
+                            <entry>0.7</entry>
+                            <entry>0.0</entry>
+                            <entry>0.0</entry>
+                            <entry/>
+                            <entry>0.3</entry>
+                            <entry>0.0</entry>
+                            <entry>0.0</entry>
+                            <entry>0.7</entry>
+                            <entry>0.0</entry>
+                            <entry>0.0</entry>
+                        </row>
+                        <row>
+                            <entry>Blue Light Intensity</entry>
+                            <entry>0.0</entry>
+                            <entry>0.0</entry>
+                            <entry>0.7</entry>
+                            <entry/>
+                            <entry>0.0</entry>
+                            <entry>0.0</entry>
+                            <entry>0.3</entry>
+                            <entry>0.0</entry>
+                            <entry>0.0</entry>
+                            <entry>0.7</entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
+            <para>The numbers in parenthesis represents the max intensity at that time.</para>
+            <para>In order to keep the daytime lighting the same, we simply multiplied the LDR day's
+                sun and ambient intensities by the ratio between the sun intensity and the intensity
+                of one of the lights. This ratio is 3:1, so the sun and ambient intensity is
+                increased by a magnitude of 3.</para>
+            <para>The maximum intensity was derived similarly. In the LDR case, the difference
+                between the max intensity (1.0) and the sum of the sun and ambient intensities is
+                0.2 (1.0 - (0.6 + 0.2)). To maintain this, we set the max intensity to the sum of
+                the ambient and sun intensities, plus 3 times the original ratio.</para>
+            <para>This effectively means that the light, as far as the sun and ambient are
+                concerned, works the same way in HDR daytime as in the LDR day-optimized settings.
+                To get the other lights to work at night, we simply kept their values the same as
+                the LDR night-optimized case.</para>
+        </section>
     </section>
     <section>
         <?dbhtml filename="Tut12 Monitors and Gamma.html" ?>
         <title>Monitors and Gamma</title>
-        <para/>
+        <para>There is one major issue left, and it is one that has been glossed over since the
+            beginning of our look at lighting: your screen.</para>
+        <para>The fundamental assumption underlying all of our lighting equations is the idea that
+            the surface colors and light intensities are all in a linear
+                <glossterm>colorspace</glossterm>. A colorspace defines how we translate from a set
+            of numerical values to actual, real colors that you can see. A colorspace is a
+                <glossterm>linear colorspace</glossterm> if doubling any value in that colorspace
+            results in a color that is twice as bright. The linearity refers to the relationship
+            between values and overall brightness of the resulting color.</para>
+        <para>This assumption can be taken as a given for our data thus far. All of our diffuse and
+            specular color values were given by us, so we can know that they represent values in a
+            linear RGB colorspace. The light intensities are likewise in a linear colorspace. When
+            we multiplied the sun and ambient intensities by 3 in the last section, we were
+            increasing the brightness by 3x. Multiplying the maximum intensity by 3 had the effect
+            of reducing the overall brightness by 3x.</para>
+        <para>There's just one problem. Your screen doesn't work that way. Time for a short history
+            of television/monitors.</para>
+        <para>The original televisions used an electron gun fired at a phosphor surface to generate
+            light and images; this is called a <acronym>CRT</acronym> display (cathode ray tube).
+            The strength of the electron beam determined the brightness of that part of the image.
+            However, the strength of the beam did not vary linearly with the brightness of the
+            image.</para>
+        <para>The easiest way to deal with that in the earliest days of TV was to simply modify the
+            incoming image at the source. TV broadcasts sent image data that was non-linear in the
+            opposite direction of the CRT's normal non-linearity. This resulted in a color
+            reproduction in a linear colorspace.</para>
+        <para>The term for this process, de-linearizing an image to compensate for a non-linear
+            display, is <glossterm>gamma correction</glossterm>.</para>
+        <para>You may be wondering why this matters. After all, odds are, you don't have a CRT-based
+            monitor; you probably have some form of LCD, plasma, LED, or similar technology. So what
+            does the vagaries of CRT monitors matter to you?</para>
+        <para>Because gamma correction is everywhere. It's in DVDs, video-tapes, and Blu-Ray discs.
+            Every digital camera does it. And this is how it has been for a long time. Because of
+            that, you couldn't sell an LCD monitor that tried to do linear color reproduction;
+            nobody would buy it because all media for it (including your OS) was designed and
+            written expecting CRT-style non-linear displays.</para>
+        <para>This means that every non-CRT display must mimic the CRT's non-linearity; this is
+            built into the basic video processing logic of every display device.</para>
+        <para>So for twelve tutorials now, we have been outputting linear RGB values to a display
+            device that expects gamma-corrected non-linear RGB values. But before we started doing
+            lighting, we were just picking nice-looking colors, so it didn't matter. Now that we're
+            doing something vaguely realistic, we need to perform gamma-correction. This will let us
+            see what we've <emphasis>actually</emphasis> been rendering, instead of what our
+            monitor's gamma-correction circuitry has been mangling.</para>
+        <section>
+            <title>Gamma Functions</title>
+            <para>A <glossterm>gamma function</glossterm> is the function mapping linear RGB space
+                to non-linear RGB space. The gamma function for CRT displays was fairly standard,
+                and all non-CRT displays mimic this standard. It is ultimately based on a math
+                function of CRT displays. The strength of the electron beam is controlled by the
+                voltage passed through it. This correlates with the light intensity as
+                follows:</para>
+            <!--TODO: Equation of linearRGB varies with voltage^γ-->
+            <para>This is called a gamma function due to the Greek letter γ (gamma). The input
+                signal directly controls the voltage, so the input signal needed to be corrected for
+                the power of gamma.</para>
+            <para>Modern displays usually have gamma adjustments that allow the user to set the
+                display's gamma. The default is usually a gamma of around 2.2; this is a useful
+                compromise value and an excellent default for our gamma-correction code.</para>
+            <para>So, given the gamma function above, we need to output values from our shader that
+                will result in our original linear values after the gamma function is applied. This
+                is gamma correction, and the function for that is straightforward.</para>
+            <!--TODO: Equation of gammaRGB = linearRGB^(1/γ)-->
+            <para>It would be interesting to see a graph of these functions, to speculate about what
+                we will see in our gamma-correct images.</para>
+            <!--TODO: Picture, recreating the Wikipedia article's gamma function.-->
+            <para>Without gamma correction, our linearRGB colors (the diagonal line in the graph)
+                would become the CRT gamma curve at the bottom. This means that what we have been
+                seeing is a <emphasis>severely</emphasis> darkened version of our colors. A
+                linearRGB value of 0.5 drops to an intensity of 0.218; that's more than half of the
+                brightness gone.</para>
+            <para>With proper gamma correction, we can expect to see our scene become much
+                brighter.</para>
+        </section>
+        <section>
+            <title>Gamma in Action</title>
+            <para>Gamma correction is implemented in the <phrase role="propername">Gamma
+                    Correction</phrase> tutorial.</para>
+            <para>The <keycap>K</keycap> key toggles gamma correction. The default gamma value is
+                2.2, but it can be raised and lowered with the <keycap>Y</keycap> and
+                    <keycap>H</keycap> keys respectively.</para>
+            <!--TODO: Picture of the gamma correction, with HDR lighting.-->
+            <para>That is very bright; it uses the same HDR-based lighting environment from the
+                previous tutorials. Let's look at some code.</para>
+            <para>The gamma value is an odd kind of value. Conceptually, it has nothing to do with
+                lighting, per-se. It is a global value across many shaders, so it should be in a UBO
+                somewhere. But it isn't a material parameter; it doesn't change from object to
+                object. In this tutorial, we stick it in the <classname>Light</classname> uniform
+                block and the <classname>LightBlockGamma</classname> struct. Again, we steal a float
+                from the padding:</para>
+            <example>
+                <title>Gamma LightBlock</title>
+                <programlisting language="cpp">struct LightBlockGamma
+{
+    glm::vec4 ambientIntensity;
+    float lightAttenuation;
+    float maxIntensity;
+    float gamma;
+    float padding;
+    PerLight lights[NUMBER_OF_LIGHTS];
+};</programlisting>
+            </example>
+            <para>For the sake of clarity in this tutorial, we send the actual gamma value. For
+                performance's sake, we should send 1/gamma, so that we don't have to do it in every
+                fragment.</para>
+            <para>The gamma is applied in the fragment shader as follows:</para>
+            <example>
+                <title>Fragment Gamma Correction</title>
+                <programlisting language="glsl">accumLighting = accumLighting / Lgt.maxIntensity;
+vec4 gamma = vec4(1.0 / Lgt.gamma);
+gamma.w = 1.0;
+outputColor = pow(accumLighting, gamma);</programlisting>
+            </example>
+            <para>Otherwise, the code is mostly unchanged from the HDR tutorial. Speaking of which,
+                gamma correction does not require HDR per se, but both are necessary for quality
+                lighting results.</para>
+        </section>
+        <section>
+            <title>Gamma Correct Lighting</title>
+            <para>This is what happens when you apply HDR lighting to a scene who's light properties
+                were defined <emphasis>without</emphasis> gamma correction. Look at the scene at
+                night; the point lights are extremely bright, and their lighting effects seem to go
+                farther than before. This last point bears investigating.</para>
+            <para>When we first talked about light attenuation, we said that the correct attenuation
+                function for a point light was an inverse-square relationship with respect to the
+                distance to the light. We also said that this usually looked wrong, so people often
+                used a plain inverse attenuation function.</para>
+            <para>Gamma is the reason for this. Or rather, lack of gamma correction is the reason.
+                Without correcting for the display's gamma function, the attenuation of <inlineequation>
+                    <mathphrase>1/r<superscript>2</superscript></mathphrase>
+                </inlineequation> becomes <inlineequation>
+                    <mathphrase>(1/r<superscript>2</superscript>)<superscript>2.2</superscript></mathphrase>
+                </inlineequation>, which is <inlineequation>
+                    <mathphrase>1/r<superscript>4.4</superscript></mathphrase>
+                </inlineequation>. The lack of proper gamma correction magnifies the effective
+                attenuation of lights. A simple <inlineequation>
+                    <mathphrase>1/r</mathphrase>
+                </inlineequation> relationship looks better without gamma correction because the
+                display's gamma function turns it into something that is much closer to being
+                physically correct: <inlineequation>
+                    <mathphrase>1/r<superscript>2.2</superscript></mathphrase>
+                </inlineequation>.</para>
+            <para>Since this lighting was not designed while looking at gamma correct results, let's
+                look at some scene lighting that was developed that way. Turn on gamma correction
+                and set the gamma value to 2.2 (the default if you did not change it). The press <keycombo>
+                    <keycap>Shift</keycap>
+                    <keycap>L</keycap>
+                </keycombo>:</para>
+            <!--TODO: Picture of the gamma correction, with Gamma lighting.-->
+            <para>This is more like it.</para>
+            <para>If there is one point you should learn from this exercise, it is this: make sure
+                that you implement gamma correction and HDR <emphasis>before</emphasis> trying to
+                light your scenes. If you don't, then you may have to adjust all of the lighting
+                parameters again. In this case, it wasn't even possible to use simple math to make
+                the lighting work right. This lighting environment was developed from
+                scratch.</para>
+            <para>One thing we can notice when looking at the gamma correct lighting is that proper
+                gamma correction improves shadow details substantially. And looking at the function,
+                this makes sense. Without proper gamma correction, fully half of the linearRGB range
+                is shoved into the bottom one-fifth of the available light intensity. That doesn't
+                leave much room for areas that are dark, but not too dark to see anything.</para>
+            <para>As such, gamma correction is a key process for producing color-accurate rendered
+                images.</para>
+        </section>
     </section>
     <section>
         <?dbhtml filename="Tut12 In Review.html" ?>
                     work in a linear colorspace, where twice the brightness of a value is achieved
                     by multiplying its value times two. It is vital for proper imaging results to
                     make sure that the final result of lighting is in the colorspace that the output
-                    display expects. This process is generally called gamma correction.</para>
+                    display expects. This process is called gamma correction.</para>
             </listitem>
         </itemizedlist>
         <section>
                 </listitem>
                 <listitem>
                     <para>Play with the ambient lighting intensity in the gamma-correct scene,
-                        particularly in the daytime. A little ambient, even with a high dynamic
-                        range value like 10, goes a long way to bringing up the level of brightness
+                        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.</para>
                 </listitem>
             </itemizedlist>
         </section>
         <section>
+            <title>Further Research</title>
+            <para>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 wouldn't 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.</para>
+            <para>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, 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.</para>
+            <para>Just remember: pick your HDR and tone mapping algorithms
+                    <emphasis>before</emphasis> you start putting the scene together. If you try to
+                change them mid-stream, you will have to redo a lot of work.</para>
+        </section>
+        <section>
             <title>OpenGL Functions of Note</title>
             <glosslist>
                 <glossentry>
                 </glossdef>
             </glossentry>
             <glossentry>
-                <glossterm/>
+                <glossterm>light clipping</glossterm>
                 <glossdef>
-                    <para/>
+                    <para>Light values drawn to the screen are clamped to the range [0, 1]. When
+                        lighting produces values outside of this range, the light is said to be
+                        clipped by the range. This produces a very bright, flat section that loses
+                        all detail and distinction in the image. It is something best
+                        avoided.</para>
+                </glossdef>
+            </glossentry>
+            <glossentry>
+                <glossterm>high dynamic range lighting</glossterm>
+                <glossdef>
+                    <para>Lighting that uses values outside of the [0, 1] range. This allows for the
+                        use of a full range of lighting intensities.</para>
+                </glossdef>
+            </glossentry>
+            <glossentry>
+                <glossterm>tone mapping</glossterm>
+                <glossdef>
+                    <para>The process of mapping HDR values to a [0, 1] range. This may or may not
+                        be a linear mapping.</para>
+                </glossdef>
+            </glossentry>
+            <glossentry>
+                <glossterm>colorspace</glossterm>
+                <glossdef>
+                    <para>The set of reference colors that define a way of representing a color in
+                        computer graphics, and the function mapping between those reference colors
+                        and the actual colors. All colors are defined relative to a particular
+                        colorspace.</para>
+                </glossdef>
+            </glossentry>
+            <glossentry>
+                <glossterm>linear colorspace</glossterm>
+                <glossdef>
+                    <para>A colorspace where the brightness of a color varies linearly with its
+                        values. Doubling the value of a color doubles its brightness.</para>
+                </glossdef>
+            </glossentry>
+            <glossentry>
+                <glossterm>gamma correction</glossterm>
+                <glossdef>
+                    <para>The process of converting from a linear colorspace to a non-linear
+                        colorspace that a display device expects, usually through the use of a power
+                        function. This process ensures that the display produces an image that is
+                        linear.</para>
                 </glossdef>
             </glossentry>
         </glosslist>

Documents/Tutorial Documents.xpr

             <file name="Illumination/Tutorial%2009.xml"/>
             <file name="Illumination/Tutorial%2010.xml"/>
             <file name="Illumination/Tutorial%2011.xml"/>
+            <file name="Illumination/Tutorial%2012.xml"/>
         </folder>
         <folder name="Positioning">
             <file name="Positioning/Tutorial%2003.xml"/>