Followers 0

# General questions on hdr and tonemapping

## 8 posts in this topic

Hello,

I am currently implementing HDR rendering into our game. I got a basic version working, but I have a few questions on "how to do it right".

Exposure control and tonemapping are, even though you can do them in the same shader, two "completely" different steps in the pipeline, right? I mean the exposure control does not depend on which tonemapping operator I use?

I am wondering what's the best way to properly adapt the exposure. I've read that I should calculate the geometric mean of the luminance instead of the simple arithmetic mean. At the moment I do the exposure adjustment in a very basic way (found in the ogre engine hdr sample app):
texColor *= MIDDLE_GREY / lum;
Where texColor is obviously the scene. MIDDLE_GREY has a value of 0.72 and lum is the geometric mean of the luminances of all pixels.
Is this the standard way to adjust the exposure or is there a better algorithm to do this?

I first had the same algorithm just using a arithmetic mean. It seams that now with the geometric mean the exposure adjustment has a much smaller effect. It pretty much does only dial down very bright scenes and doesn't seam to lighten dark scenes very much. Am I doing something wrong or is this just the normal effect of using a geometric mean?

Is there some good literature on this topic? I can't find too much online ressources on hdr, exposure and tonemapping.

I hope someone can help ;)

regards
videl
0

##### Share on other sites
I'm not an HDR expert. When you're talking about the geometric mean, are you doing something like in [url="http://mynameismjp.wordpress.com/2010/04/30/a-closer-look-at-tone-mapping/"]this blog[/url]?

I would imagine you might be falling afoul of the logarithm, e.g. that article says to scale by 2^exposure.
1

##### Share on other sites
@jefferytitan Yes I got the information about the geometric mean from the blog post you mentioned.
[quote]To calculate the geometric mean, I simply calculate the log of luminance and write the results to a 1024×1024 texture. I then call GenerateMips to automatically generate the full mip-map chain. At that point I can apply exp() to the last mip level to get a full log-average of the scene.[/quote]

That's exactly what I am doing right now (except I am downsampling using custom shaders and not the mip mapping function). I am not sure which base I should use for the log and exp. Default log and exp functions are using [i]e[/i]. Somehow there must also be a error in my code, using the geometric mean the exposure control does really not help to brighten dark areas. But it works using the arithmetic mean...

@MJP
Ok, separating exposure control and tonemapping makes sense. I've also read the article on John Hable's [url="http://filmicgames.com/archives/75/comment-page-1"]Blog[/url]. He does also separate the exposure correction and the tonemapping I think.

In your demo application (which is very useful ;)) you have a slightly more advanced algorithm to control the exposure. You do also use the geometric mean, right?
Controlling the mood is essential yes. In your application that is the keyValue slider I suppose.

I will take a look at this book, I've already found two of the presentations and your blog article before ;) Edited by videl
0

##### Share on other sites
You want to use a base e logarithm, so log() and exp() are what you should use in the shader.

In that sample I did try out a more complex auto-exposure routine where you could use an average luminance that was localized for a portion of the screen. It was somewhat experimental, and I don't currently use it anywhere else. Edited by MJP
1

##### Share on other sites
Ok, then I will try log and exp.

I am currently implementing a bloom effect, let's see how far I can push the image as a whole. This will require me to completely separate the process of exposure correction and tonemapping. At the moment the pipeline is the following: forward render the image -> downsample to get luminance -> correct exposure and tonemap in one shader
I think I will have to adjust it to: forward render the image -> downsample to get luminance -> correct exposure -> create bloom -> add bloom to render result and tonemap.
0

##### Share on other sites
After implementing bloom and some other stuff I got back to my problem with the geometric mean. The problem is, that the render textures obviously can't store negative values. So I just got the value of 1 (the luminance texture is 0 if luminance < [i]e[/i], so I get exp(0) = 1,) for all dark average luminance values. The solution to this would be to map the luminance range to only positive numbers and then convert back to the real range in the exposure correction shader. I know this is done for example with normal maps. But as the range of values in the texture and luminances is not just [0..1] respectively [-1...1] it's not as easy as with normal maps.

My idea would be to define a lower bound for the log of a specific pixels luminance. Then add this value to the log to get only positive numbers. So if the lower bound would be -10, I would add 10 to the log of the luminance. And then substract 10 again just in the exposure shader.
Written in 'pseudocode' it would be something like this (although the shader does this quite different using several downsample blur passes):

sum = log(P[sub]1[/sub]) + 10 + log(P[sub]2[/sub]) +10 + log(P[sub]N[/sub]) +10
sum = sum / N
->store to luminanceTex

lum = exp(luminanceTex - 10)
...

I hope that makes it clear what I have in mind.

Edit/ this approach seams to work, any better ideas though? Edited by videl
0

##### Share on other sites
I usually just use a floating point texture format like R16_FLOAT or R32_FLOAT for storing log(luminance), and those formats have a sign bit. Which format are you currently using?
1

##### Share on other sites
Haha, I've been told by other programmers on our project that textures can't store negative numbers. Using R16_FLOAT works just perfect with negative numbers, thank you for the hint ;)
0

## Create an account

Register a new account