The latest version of my application MNRT supports adaptive selection of sample points for irradiance calculation using final gathering. The used method is that of Wang et. al and is implemented entirely on the GPU. I applied this method to the Sponza scene by Crytek with about 280k triangles. The result is shown in the next screenshot:

We select the irradiance samples points according to some error metric. This error metric should describe the geometric variation relative to some reference point *x _{cluster}* with normal vector

*n*. For a given shading point

_{cluster}*x*with normal vector

_{p}*n*we define the geometric variation

_{p}*ε*relative to this reference point as:

Here *α* is a constant that controls the influence of position variation on normal variation. A reference point is a possible sample point candidate. We start by creating initial reference points using a quad tree. For each node of that tree we compute the average geometric variation. We do that because we want to pick sample points in areas of large geometric variation. Such areas presumably have abrupt irradiance changes.

Afterwards we rework these initial sample points. To do that, we assign each shading point to it’s nearest sample point according to the above error metric. Doing that, we get clusters of shading points. We now replace each sample point with the average point of the corresponding cluster. After some iterations we pick in each cluster the shading point with minimal geometric variation as irradiance sample point. Subsequent figure shows the approx. 4000 clusters for the scene shown in figure 1.

The idea behind picking final gather sample points is that their number (that is the number of clusters) is quite small compared to the number of shading points. Selecting 2000 to 5000 sample points gives good results. When we only perform final gathering for these sample points, we can save a lot of time.

However we still need to compute irradiance at each shading point somehow. This can be done using interpolation: For each shading point we search the nearest sample points and interpolate their irradiance values. Let x be some shading point and S the set of nearest sample points. Now we can compute the irradiance as:

Here *L _{i(s_j)}* is the irradiance value at sample point

*s*.

_{j}*w(s*is an interpolation weight. It weights irradiance values according to distance and normal vector difference between sample point and shading point. For fast determination of sample point set

_{j})*S*we make use of a kd-tree of sample points. Further details can be found in the original paper (Wang et. al).

Figure 1 shows that this method delivers good results even when performing such few final gathers at some carefully selected sample points. Rendering took about one minute as shown in the screenshot. This is far from optimal as my implementation isn’t optimized at all. However, compared to previous 10 minutes for the simpler Sponza scene (70k triangles) using full final gathering the timings are a lot better. Of course, this comparison is unfair as we used a much more complex scene here, different camera position, photon distribution, super sampling settings, …