Download

Washed out Colors from Tone Mapping: How bad it really is, and how to fix it

It is a known problem that the default Tone Mapping/Gamma Correction/Color Grading in UE4 alters the brightness and colors of textures, and not in a good way. Like many other people, I ran into this problem and lost a few days trying to get the engine to show the original colors of my textures.

Here are some old posts that already contain a lot of information and helped me to figure this out:

With this post I would like to

  • Illustrate the problem with a (hopefully) objective reference image
  • Share the solution that I found
  • Make Epic aware of this problem and ask what can be done

Here is my test setup:

No surprises in the material:

8665100776b6d6f666beb85f3b840ff50a92975e.png

I’ve tried to disable all post process settings:

94bd01a2734c5abe5f82012a5d628399c3653f41.png

As texture I’m using the test image http://www.indiev.org/wp-content/uploads/2011/07/color-test-file.jpg
Modified Texture Settings:

  • Never Stream
  • No MipMaps

This is the original test image:

Here is how the image is rendered in UE4 by default using Auto Exposure (this is a screenshot of play in editor):

Pretty bad, I would say.

  • The skin tone is altered a lot
  • Brightness 242 and 255 are nearly identical
  • White at 255 is now actually gray

To solve this, CWeatherman has proposed to change line 303 of \Unreal Engine\4.5\Engine\Shaders\PostProcessTonemap.usf like this:


//OutColor = float4(TonemappedColor, LuminanceForPostProcessAA);
OutColor = float4(LinearColor.rgb, LuminanceForPostProcessAA);

This produces the correct output test image (if sRGB is disabled in the Texture) as shown by CWeatherman, however it makes the Starter Map look like this:

This was not acceptable for me. I tried to find a way how to get the correct output image without altering the look of existing scenes. Here is the solution I found:

  1. Don’t change anyting in PostProcessTonemap.usf
  2. In line 62 of TonemapCommon.usf at the end of the FilmPostProcess function, make this change (then save the usf file and restart the engine):




//return CurveColor;
return MatrixColor;

This just disables the section titled “Apply color curve (includes tonemapping)” of the FilmPostProcess function. The section “Color and exposure control” is still active.

  1. Uncheck the sRGB checkbox in the texture details panel.
  2. In your material, add this after the Texture Sample Node:

d5f6d92affee4c774ad12f4963093ee9fe2e953e.png

Why, you may ask? Because it is the inverse of the function LinearToSrgbBranchingChannel that can be found in line 48 of PostProcessTonemap.usf:


return pow(lin, (1.0/2.4)) * 1.055 - 0.055;

  1. Set Min Brightness and Max Brightness to 1, and play around with the intensity of your directional light until the images match.

With these five steps, the engine renders the following image:

I suggest to open the images in separate tabs to compare them.

The Starter Map looks good too:

So it is definitely possible to get UE4 to render textures correctly. I think this should be the default behavior, the current behavior could be optional and actively enabled by the user.
Imagine you need to import a skin texture, by default it would look like in the image above.
I think Epic should add an option during texture import for people who do not want the look of the texture to change. Alternatively, please provide documentation/tutorials how to achieve accurate colors without changing stuff in the shader source code.
How is the average user supposed to avoid the subtle mistakes demonstrated here with the current behavior of the engine and the state of the documentation?

I hope this helps anyone who struggles with the same problem. Please let me know if you think my solution can be improved. Maybe it is possible to also undo the stuff from “Apply color curve (includes tonemapping)” in the material? This way, we would not need to edit the shader source code.

Edited: Wiring in material screenshot was wrong

Yes, please take a look at this Epic! I too have noticed this issue, problem is the team I work with are in crunch time and making these changes takes time we don’t have. It would be wonderful to have a fix in 4.6.

The current behavior is intended. The base color is a material attribute that combined with light (and view angle) becomes the HDR color which still needs to be tonemapped to become the LDR color so a monitor can display it.
The tone mapping tried to be mostly linear but if the HDR input values get very bright it should softly clamp to white. This is needed as lighting can be brighter than 1 in many areas and we want to avoid clamping artifacts with that.
The pipeline is setup to make it easy to get real (physically based) content. Having a different default (e.g. no tonemapper) would break that goal. We intend to make the tonemapper pass more programmable (You already can override the tonemapper pass creating a Postprocess Material replacing the tonemapper but getting access to the properties is very very limited) so for some applications this default behavior can be altered.

I would love to have a reference shader/material/object type where no color manipulation happened - that would be very useful for reference images. We might do that.

This would be really useful. Any decision on if this is happening or how we might use it?

Just bumping this thread again to see if this is happening. The current distorted colors are unusable if you’re doing non-photorealistic rendering that needs to match a particular concept, and are especially absurd if you’re disabling lighting anyways. We’ve hacked the shaders as described here to make it work, but a reference material mode that disabled color distortion would have made that a LOT easier. I’m also a bit worried you’ll change the shader code here eventually, and this hack will no longer provide accurate coloration.

You just need to disable/replace tone mapping. This does not need any shader/c++ code changes.

Er, yes, it does. There aren’t any settings in the post-process volume that fix the color distortion, as far as I’m aware, and the only way to disable tone mapping fully (last I checked) was using a debug flag in the Editor that doesn’t exist in runtime. You’ve got to do the UE4 shader change that the OP mentions to actually disable it and make the colors accurate.

If that’s changed in the last year, by all means, I’d love to know how - but so far as I’m aware, it has not.

great study of the colors! :3

If you make post process material you can set it to replace tonemapper. Then you just put that as Blendable to Post process volume.

Can you please elaborate?
So I set up a new material, set it to Replace the Tonemapper, Create a Post Process Volume, Assign previously created material to Blendables…
Then what? How do I make this new material in the Post Process Volume to display image unaltered by the Tonemapper?
Or am I misunderstanding something?

Has this been fixed yet?

Hows this going? i cant believe ts even a thing.

Show some picture. I can’t think any possible mechanism to turn totally unlit scene to gray.

I would really like to know how to do this as well!

Sorry for double post. but I got a solution to the tone mapper. Check it out !
Dissable Color Grading and Tone mapper completly or...!? - Rendering - Unreal Engine Forums!

Also I wonder if there is a sweet spot for setting up color grading and tone mapper to where we can get a default non tone mapper look and feel. so that we can still use the tone mapper in specific cases !
Has anyone actually attempted that here? playing with the post process settings in search for the sweet spot?

I desperately need a fix for this, I’m using handpainted textures and need the colours to actually match what I paint. When importing my colours into the engine they look just awefull, and nothing else but turning off the tonemapper takes care of the issue, however turning off the tonemapper comes with its own list of problems that I really want to avoid.

Here’s a link to a facebook post detailing the issue.

And no, screwing with tonemapper settings isn’t fixing it.
No, screwing with texture settings isn’t fixing it.
“It makes your textures pop more” - I don’t want that, I carefully author my textures to pop where they need to pop, I don’t want the engine to guess this stuff for me.

I understand that it is intended behaviour, but this intended behaviour makes working with certain artstyles completely impossible inside of UE4, just give me a switch to turn this mess off.

Maybe you just have to bite the bullet and turn off the tonemapper and go through each problem that causes and see if you can fix or work around?
What are the resulting problems that you get?

I imagine if Unreal suddenly changed the behaviour of the tonemapper then a lot of people would be upset by that as well as they have now tuned their games to look like they want.

Well for starters it completely disables anti aliasing in the forward renderer, so that’s simply not an option.

And I’m not asking for the default tonemapper to change, I just want a nice and convenient button somewhere along the lines of “Stop ■■■■■■■ up my colours”

And after four years, still no solution. Thank you.

Yeah this really needs to get fixed. The only solution I’ve been able to come up with is to just manually adjust the tonemapper settings for each scene. There has to be a better way!