Tone Mapping Washing out Detail

Started by
7 comments, last by CDProp 10 years ago

I'm having trouble with my tone mapping (currently using Reinhard's operator). For testing, I used an HDR cube map and got results to match various demos (DX SDK and MJP's

Where I am seeing issues is when I integrated it into my engine. In particular, given a daytime seen (not looking at a light source), the non-tonemapped image (left) looks more detailed in my opinion than the tonemapped version (right). If I plot the Reinhard curve x/(1+x) I think I can see how non-HDR values are getting shifted darker and I'm probably losing precision in this transformation.

Right now in my engine, the only HDR values are light sources? So how do I keep good image detail when I have scenes with mostly LDR values to begin with?

Is Filmic tone mapping the solution? I actually like the way Reinhard looks for the HDR cube map, just not scenes with LDR values.

-----Quat
Advertisement

If your scene is being rendered using a HDR range of values, then there's no need to tone-map it. With your left image, all the colours already seem to be in a displayable range... What kind of range of lighting / brightness values exist in your scene?

With your Reinhard implementation, are you remapping the luminance alone, or are you remapping R, G and B separately?

In that screen, they are all LDR values. I'm not really sure how to add HDR lights to my outdoor day scenes because I am just using the sun directional light, and it will affect pixels equally, so I'm not sure there is an advantage to bumping my sun to HDR values.

For my night scenes, I do have HDR lights and thus HDR values. Maybe I should just enable tonemapping at night, but I was hoping I could get some uniform solution.

I am remapping like this:

float pixelLuminance = CalcLuminance(exposedColor);
float toneMappedLuminance = pixelLuminance / (pixelLuminance + 1);

float3 toneMappedColor = (toneMappedLuminance / pixelLuminance) * exposedColor;

-----Quat

In that screen, they are all LDR values. I'm not really sure how to add HDR lights to my outdoor day scenes because I am just using the sun directional light, and it will affect pixels equally, so I'm not sure there is an advantage to bumping my sun to HDR values.

For my night scenes, I do have HDR lights and thus HDR values. Maybe I should just enable tonemapping at night, but I was hoping I could get some uniform solution.

It's hard to just "toggle" HDR/LDR. You will find yourself setting the lighting setup twice.

The ideal of HDR is that you should use them together with PBS (Physically Based Shading) and Global Ilumination techniques so that you can use real values for sun and sky and let the math do its magic; then apply tonemap to get the output to the monitor's range.

Also, Reinhard's look sucks (but it's great for preserving all the range in photographs though).

Reinhard is generally good at preserving details in an HDR image, but it doesn't always result in one that's subjectively pleasing. "Filmic" tone mapping operators attempt to emulate film response, and film is carefully tuned to have an S-shaped response curve (which Reinhard doesn't have). This S-shaped curve can boost contrast and saturation in key parts of time image, and can make the image a lot more pleasing to the eye.

I don't think you're losing detail or precision. What you're losing is contrast and a bit of saturation, which is pretty typical of Reinhard. Not a very nice operator IMO. Try integrating the Uncharted Hable operator instead. Not perfect but much much better.

SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.

I think your luminance calculations might be off, is it calculated from linear RGB? F.ex. this is what I get when running Reinhard's operator on your image, but calculating luminance directly on sRGB values:

[attachment=19790:yours.png]

Using linear values I get something that looks much better:

[attachment=19786:reinhard.png]

Using the slightly more complex Ld = (L*(1.0+L/Lwhite^2))/(1.0+L) instead of just Ld = L/(1.0+L) you can also change the look by adjusting the whitepoint, for example:

[attachment=19787:reinhard_lmax.png][attachment=19788:reinhard2.png]

And for fun two filmic curves (Hejl / Burgess-Dawson and Uncharted 2, both from John Hable's blog):

[attachment=19783:hejl_burgess.png] [attachment=19789:uncharted.png]

Both Reinhard's and Hable's operators also will require tuning parameters (at least white-point, exposure (for Hable) and key (for Reinhard)) to make it all look good in different lighting settings.

Also simply doing C = C/(1.0+C) on your colors is not really a simple version of Reinhard's operator, so I don't know why this always gets brought up as a comparison.

I've come to the following conclusion:

Don't try to make image pretty in tonemapper. It only needs to scale the HDR range.

Of course always convert the RGB source into some HSB type colorspace and scale only the luminance component. Then convert back to RGB. This way colors are preserved better.

First use basic Reinhard curve just to scale the HDR range. This might produce dark/grey toned image but that's the case with photography in general.

After this perform post processing to adjust brightness, colors etc. This means using a filmic curve in a color LUT and what not. Just like photography.


Also simply doing C = C/(1.0+C) on your colors is not really a simple version of Reinhard's operator, so I don't know why this always gets brought up as a comparison.

THANK you.

This topic is closed to new replies.

Advertisement