An attempt to use old 32 bit RGBA rendertarget for HDR, using RGBE8 encoding. Multisampling should Just Work on all DX9 hardware. See description below.
Requirements: DX9 video card: pixel shaders 2.0 and floating point textures required. Good performance is also a plus!
Usage: Run. Press arrow keys and A/Z to control the camera; the rest is via UI sliders. Press F2 for device selection dialog, try out anti aliasing.
Note: It seems that anti aliasing does not work on some ATI hardware at the moment. I'm still figuring out whether this is my bug or HW feature (e.g. MSAA does not resolve alpha channel, or something like that).
- HDR rendering: mostly copied from DX SDK sample HDRLighting (tone mapping, luminance adaptation, blue shift, bloom).
- Diffuse lighting from environment (9 coeff. SH) and direct sunlight with shadow map; using per-vertex ambient occlusion term. Shadow map uses DST if available, else fallbacks to R32F.
- Model is still a WIP version of St. Anne’s Church in Vilnius, Lithuania. Modeling is done by Siger, see thread at cgtalk.lt (Lithuanian). The model is not authored with realtime rendering in mind, that’s why it has approx. 500 thousand vertices at the moment.
- The light probe is courtesy of Paul Debevec. You can swap in your own probe in
data/tex/HdrEnv.ddsin native DDS cubemap or vertical cross HDR format (just rename to .dds).
Thumbnails, click for a larger shot.
The big problem with HDR renderers is that multisampling does not work with floating point rendertargets on most DX9 hardware right now (2005 Nov). Doing manual supersampling is often not an option either because of performance loss. This demo is an attempt to do HDR rendering without floating point rendertargets - good old A8R8G8B8 format is used, with RGBE8 encoding when rendering and decoding in the tone mapping process.
Of course, multisampling RGBE does not produce “correct” results when all components are simply interpolated/averaged (as is the case with MSAA). However, multisampling is a hack (in a sense “not fully correct”) anyway - it just increases sampling frequency in an attempt to better represent the underlying signal. In RGBE case, we’re increasing sampling frequency, but the samples will not be simply averaged (RGB and E will be averaged separately). The result should be fairly good, as averaging RGB and E separately will still produce final value that is “between” the sample values, which is good.
By the way, ATI has a whitepaper HDR Texturing on a similar subject in Radeon SDK (October 05) - though they focus on interpolation, not MSAA.
Note: for RGBE and MSAA, you really do not want to use full -128..127 range for the exponent. Because MSAA will interpolate the exponent, you will want it to have intermediate (non-integer) values as well. What I did was: use -64..63 range, thus leaving one bit for exponent interpolation - this is often enough.