At SIGGRAPH 2014, the

__Ray Histogram Fusion__paper got my interests, for it seems like a low hanging fruit to enhance one's renderer, at least from what I could tell looking at the demos. It worked really well cleaning up the noisy images computed by Monte Carlo methods, and its implementation seems really easy and simple. So I decided to try adding it to__EDXRay__. I will post some of my results in this post, and please click to enlarge the following images to view some before/after comparisons.First let me briefly describe how the algorithm works. The technique is really about averaging pixels with its surrounding neighbors. However it does so at a per-patch scale. Let's assume assume we use 3x3 as our patch size, and for each pixel we loop through patches whose center pixel lies within a 5x5 window of the current pixel. For each patch-pair, we calculate the chi-square distance of the color histogram that we built. And finally we set the current patch as the average of all patches within the search window whose chi-square distance is smaller than a certain threshold. That's the gist of this algorithm. It might help with understanding the process if I draw this as a diagram. For details on chi-square distance calculation, or what's the optimal patch sizes or search window please consult the paper.

The black grids are pixels. The gold pixel is the current one. The lavender square is the 5x5 search window. We move the green pixel through the 5x5 window, and calculate the chi-square distance between the 3x3 red and blue patch pair, before finally set the blue patch as the average of all patches with a small chi-square distance.

I was actually disappointed a little by the result. The biggest disappointment is that the algorithm is really slow (I implemented this on CPU, it does look like good candidate for GPU acceleration at the 1st glance though). Even with multi-threading, it takes minutes to denoise a 1280x720 sized image. So it has little use for interactive or real-time applications. And it doesn't work as well when your scene contains lots of detailed textures. The top images show the San Miguel scene rendered with 64 samples per pixel. Applying this technique does get rid of the noise, but also makes the textures a lot blurrier. This is ameliorated when the SPP increases. The following show the same scene with 256 SPP, and its denoised version does look much better. Nevertheless I think this is an useful tool to accelerate Monte Carlo methods based rendering in some scenario.

Finally this is the ground truth. And one of the merits of RHF is that applying it to the ground truth doesn't make any noticeable difference. The algorithm is consistent in this sense. Users could also balance between noise and bias by tweaking the parameters like search window size, chi-square distance threshold.