I've always enjoyed playing with methods of HDR rendering in the past; my first experiment involved adding HDR rendering using 64-bit floating-point surfaces to the Torque Shader Engine -- now called the Torque Game Engine Advanced. That seemed to work well at the time but when I looked back to the methods I used during that project I found that they were lacking, so I went with a different series of techniques when I added HDR rendering to my XNA project (more screenshots can be found in my XNA dev gallery). I don't actually remember a great deal about my implementation there or else I'd relate what I learned from that but all I really know is that when I looked at the code a few weeks ago my eyes bled a little bit.
This implementation, for the most part, went very smoothly. I chose to use 128-bit floating-point surfaces and, as of now, they remain that way. I'm not sure how well various types of cards support floating-point surfaces as render targets, since I felt no need to limit myself with last week's implementation with Direct3D 10 but, as I'm now realizing, I'm going to have to think of some decent ways to scale the system when I write the Direct3D 9 portion of Rawr's rendering routines (which I'm in the process of doing now). There are a bunch of test shots of my first few iterations of testing the code over at their usual home in my Direct3D 10 dev gallery but most of them don't have any real remarkable story behind them. I found the best methods for blurring the results of the brightness-filtered scene came from a separable Gaussian filter (with values computed by the CPU; hard-coding them into the shader proved to be annoying and inflexible). One of the best changes I found to alter the final pass of the process (the composition stage) involved darkening the portions of the tone-mapped, blurred surface where the bloom intensity was particularly high. Once I added that single line to the shader code the results were noticeably nicer as can be seen from the before (left) and after (right) below:
The next troublesome portion of the process was changing the HDR render target to be multi-sampled. Direct3D 10 does support this but not only is it poorly documented -- the DirectX SDK docs don't even list the correct texture object Load declaration -- but, despite numerous attempts and example comparisons, I simply could not get texture sampling through the Load functionality to work. Eventually I fell back to making the HDR render target multi-sampled then used ID3D10Device::ResolveSubresource to resolve the render target to a non-multi-sampled surface and sent that to the shader. This came with a drop from 200 frames-per-second (from the non-antialiased code) to 100 frames-per-second and the video memory allocation of another full screen-sized 128-bit surface. The results were still acceptable but hopefully some later tweaking proves to be more practical.
This time I held off on mentioning the show-of-the-week until the end of the article so as to avoid any unintentional tangents. The show worth mentioning now is Showtime's Californication which showcases all-around excellent acting (especially on the part of David Duchovny) and some of the best writing I've ever seen in a comedy/drama. I may make a short entry tomorrow about the rendering structure of Rawr but, if not, Merry Christmas and such.