Let me preface this post by saying that I touched on some of these topics before. I decided to revisit them because I have learned a great deal since then, and felt I should make a little update on my progress. In particular, I wanted to correct some things that I got wrong in my prior post on the topic.
For the longest time, I was having trouble reconciling some of my results with those achieved in published Image-Based Lighting (IBL) papers. As it turns out, there were some problems in both my rendering code, and the console app that I wrote to convert an input gradient image into an Radially Symmetric Reflection Map (RSRM). The net result of my mistakes was that my RSRMs' lower specular powers were getting progressively darker when they shouldn't have been.
During this time, I had the incorrect notion that I needed specular power zero to represent my diffuse IBL. Naturally, this was incompatible with the non-linear mapping I have been touting so much. So I tried a remapping scheme to store specular power zero, but access it as if was specular power one. Unsurprisingly, this threw off the results for all my specular lighting, on top of producing incorrect diffuse lighting.
As a result, I was afraid I was going to have to use a different approach to generate and store my diffuse lighting (eg. Spherical Harmonics (SH)). Fortunately, when I fixed my RSRM generation app, I realized that specular power one can adequately represent diffuse IBL. This way, I can generate all my IBL data using one pipeline, and store all related lighting data in one RSRM texture.
In the process of fixing these problems, I took the opportunity to add some improvements to the system. All of which had the effect of greatly improving both the lighting quality, and reducing both storage and runtime costs for my RSRMs.
In my prior article, I demonstrated how a non-linear mapping of specular powers can reduce storage costs for IBL . It accomplishes this by accounting for the fact that the specular lighting has a non-linear rate of change for increasing specular powers. So we can store more samples for the rapidly changing lower powers, and less for the slowly changing higher powers. This allows us to reduce the number of discrete samples needed to recreate the full range of specular lighting. As it turns out, that was merely scratching the surface of how this technique can benefit the graphics pipeline.
Firstly, it allows artists to use a more intuitive "smoothness" parameter [0, 1] to handle the transition from rough to smooth materials. This allows them to use linear values to effect a perceptually linear change in the smoothness of the material. Compare that to using specular powers directly, which make it hard to tweak materials as their smoothness gets higher.
Secondly, this new parameter can be represented quite efficiently using only byte precision. As a result, it works great with g-buffers that use RGBA8 targets to reduce storage costs. Of course this also applies to storing the data in a smoothness map texture for materials. So it can be sampled directly from the texture into the g-buffer with no need for packing instructions.
Thirdly, this parameter is efficient to use at runtime, because it can be used to directly sample an RSRM. Plus it is cheap to recover the specular power for analytical lights, which only requires a pow(2048.0f, smoothness). This way, the two lighting systems gel together perfectly!
Finally, I decided to go with 256x32 for the map's resolution. This seems to be adequate for representing all the specular powers I want while being reasonably compact. Plus, it establishes a good habit for if I ever develop for the XBOX 360 (ie. 360 uncompressed textures have a lower size limit of 32x32, including the mipmaps).
Here are some videos and screenshots showing the new improvements in action. Please note that for all these tests, the only sources of illumination are an RSRM and a directional light.
Figure 1. 1, Linear [1, 2048]; 2, Non-Linear [1, 2048]
Figure 2. 1, Iron Sphere; 2, Plastic Sphere; 3, Plastic Statue; 4, Plastic-Metal composite (Model by Ben Mathis)
After much testing, tweaking, and re-testing my RSRM implementation has developed to the point where I feel safe integrating it into my project. The next step will be to add RSRMs to my Light Pre-Pass renderer, and see how they will look with local lights using physically-based BRDFs. I'll keep everyone posted on my progress.
As always, questions and suggestions are welcome in the comments section. ;)