Marathon Progress

The following improvements have been made to Marathon’s HDR implementation:

  • Fixed all gamma correction issues. I had significant trouble with this, but after correcting a couple of stupid mistakes I did with the first implementation, it was quite simple. You bring everything to linear space when rendering (most importantly when texturing sampling - EXT_texture_sRGB helps a lot here) and you go back to gamma space at the very end.

  • Improved the bloom quality in 3 ways:

    a. All textures used for blooming are floating point now. With 8bit textures there was no way to conserve decent luminance values, especially from bright but tiny light sources. Simply moving to FP textures fixed this, with no significant loss in performance or memory (the bloom textures are small anyway).

    b. A new blurring algorithm is now used. First a chain of bloom “mips” is generated (from 1/4x1/4 to 1/32x1/32 of the framebuffer dimensions) and then each one is gaussian blurred with the same number of samples. This has the effect of progressively fainting but also expanding the bloom. This way, even tiny bright spots can generate bloom on big parts of the screen and generally it looks much better.

    One note here, the gaussian blur is separable and implemented as two passes (one horizontal and one vertical). But I wanted to avoid having two textures for each bloom level. So, I reused the initial bright-pass texture as a temporary buffer (e.g. 80x64 bloom => (horizontal blur) => 320x256 temp => (vertical vlur) => 80x64 bloom). The problem of course was that the vertical blur would grab samples from outside the current bloom level in the temp buffer. I fixed this by clamping the y texture coordinate to the appropriate point for each bloom level.

    c. I figured out how to fix the color saturation mentioned by Markus on the second post of this thread. Code:

// Old bright-pass
color.rgb *= max(color.rgb - vec3(HIGHLIGHT_THRESHOLD), vec3(0.0));

// New bright-pass
float luminance = dot(color.rgb, vec3(0.30, 0.59, 0.11));
color.rgb *= max(luminance - HIGHLIGHT_THRESHOLD, 0.0) / HIGHLIGHT_THRESHOLD;

So, suppose we have a pixel (4.0, 2.0, 0.0) and we've set the threshold at 2.0. The first code would result in a bloom pixel (2.0, 0.0, 0.0) and the second (0.76, 0.38, 0.0). It's clear that, from the original yellowish, we get plain red with the old code, whereas the new code produces the correct yellowish color (the lower intensity is not a problem).
  • When downscaling the scene luminance to find the average, I now also calculate the minimum and maximum of the whole scene. These have the following uses:

    a. ATI cards do not support filtering on FP textures, so I’m using 16bit fixed-point for the bloom textures on ATI. The maximum luminance is necessary for an efficient conversion from FP to fixed and back.

    b. It is possible to automatically calculate the tone mapping parameters from the min, max and average luminances, in a way that produces good quality in a variety of situations. I haven’t tried this yet though.

Other than the HDR improvements, and if anyone noticed, the shadows in the videos are true area light shadows (especially in the 2nd, 32 jittered samples are used). The technique I’m trying is still problematic (produces excellent quality with great performance, but flickers a bit), so I’ll post details when (if) I perfect it.

The videos look absolutely stunning! :o

what can i say, looks absolutely smashing, most definiety looks next-gen, however does look like something that would need super hardware to run in realtime, what sort of spec does it use?

Thanks guys!

kapta, without HDR it runs on the minimum spec (GeFX+ and R9500+) at full speed. There are many settings of course, that can give you a good balance of quality/performance. With HDR on my 6800 AGP and high (but not extreme) quality settings I get an average ~45 fps. The most important issue is memory usage though. If you want everything maxed out, 256MB on the GPU may be not enough.

Holy crap batman! To the batmobile…

That is really nice looking; loving the 32 jitter samples on the shadows in the second movie :slight_smile: