IBL + Non-Linear Mappings:
Monday, December 20, 2010 at 3:48PM
n00body in IBL, RSRMs


I've written a new article continuing what I started with this one. In particular, I explain what I got wrong, and how I improved on it. As for this article, I wanted to mention that my remapping scheme to get specular power zero is incorrect and will make for worse results. Also, mipmapping the RSRMs doesn't improve quality, but it does speed up texture fetches.



As it stands, the major problem with Prefilted IBL is that it requires us to store an environment map for every specular power [0,255]. It may not seem like much for RSRMs, but it is seriously wasteful for cubemap IBL. In either case, we are left with the question of how best to reduce storage costs without having to drastically reduce shading fidelity.



The first and most obvious trick is to reduce the number of slices used to represent that range of specular powers. Then we can simply let the texture interpolation hardware fill in the gaps to recover what was lost. Sadly, it turns out that it isn't so simple, as I will now illustrate. Please note, these examples show the orginal 256x256 map, as well as one that was upsampled from 8x256.


Linear mapping:

The first approach continues using a linear mapping of slices to specular powers [0,255], and simply reduces the number of slices. Sadly, while this does a good job for higher specular powers, it is abysmal for the lower powers. This can be explained by the fact that the lower powers have a much higher rate of change, and lose significantly more information as you reduce the number of slices.


[RSRM] linear[RSRM] linear, resized  

Figure 1. 1; Original; 2, Resized


Non-linear mapping:

The second approach was surprisingly unclear in most of the IBL articles I was able to find on the web. Basically, you use a non-linear mapping of specular powers to slices (ex. 255^n), so that we store significantly more information about the lower specular powers. Sadly, a power function like this doesn't ever reach zero, meaning we can't use it in its raw form to represent diffuse lighting. In order to fix this problem we have to remap the specular powers so that they are stored/accessed as [1,256], but store information as [0,255].


Generation:  sp = powf(256.0f, n) - 1.0f;

Runtime : n = log(sp + 1.0f) / log(256.0f);

[RSRM] non-linear[RSRM] non-linear, resized  

Figure 2. 1; Original; 2, Resized



As you can see, the non-linear mapping does a much better job preserving the lower specular powers despite the drastically reduced resolution. As a result, my RSRMs go from taking 256KB of storage to a measly 8KB. Not the most impressive gain ever, but it will make a big difference at runtime where RAM can be a precious resource. This will be especially important once I add mipmapping to my RSRMs to improve their shading quality.

Article originally appeared on Crunchy Bytes (http://n00body.squarespace.com/).
See website for complete article licensing information.