Announcement

Collapse
No announcement yet.

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

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    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:

    Click image for larger version

Name:	Scene.png
Views:	1
Size:	284.6 KB
ID:	1140600

    No surprises in the material:

    Click image for larger version

Name:	MaterialDefault.png
Views:	1
Size:	60.6 KB
ID:	1140601

    I've tried to disable all post process settings:

    Click image for larger version

Name:	postprocess.png
Views:	1
Size:	32.7 KB
ID:	1140602

    As texture I'm using the test image http://www.indiev.org/wp-content/upl...-test-file.jpg
    Modified Texture Settings:
    • Never Stream
    • No MipMaps

    This is the original test image:

    Click image for larger version

Name:	40.png
Views:	1
Size:	432.4 KB
ID:	1140603

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

    Click image for larger version

Name:	DefaultAuto.png
Views:	1
Size:	725.2 KB
ID:	1140604

    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:

    Code:
    //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:

    Click image for larger version

Name:	StarterMap.png
Views:	1
Size:	400.3 KB
ID:	1140590

    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):
    Code:
    //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.

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

    Click image for larger version

Name:	MaterialFixed2.png
Views:	1
Size:	78.9 KB
ID:	1140611

    Why, you may ask? Because it is the inverse of the function LinearToSrgbBranchingChannel that can be found in line 48 of PostProcessTonemap.usf:
    Code:
    return pow(lin, (1.0/2.4)) * 1.055 - 0.055;
    5) 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:

    Click image for larger version

Name:	Fixed.png
Views:	1
Size:	753.9 KB
ID:	1140591

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

    The Starter Map looks good too:
    Click image for larger version

Name:	StarterMapFixed.png
Views:	1
Size:	781.0 KB
ID:	1140598

    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
    Last edited by Theokoles; 11-09-2014, 03:30 PM.

    #2
    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.
    --
    Joshua
    Multimedia Artist, Druid Gameworks
    www.joshuaezzell.com
    www.druidgameworks.com

    Comment


      #3
      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.

      Comment


        #4
        Originally posted by Martin Mittring View Post
        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?

        Comment


          #5
          Originally posted by Martin Mittring View Post
          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.
          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.

          Comment


            #6
            Originally posted by megalomanium View Post
            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.

            Comment


              #7
              Originally posted by Jenny Gore View Post
              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.

              Comment


                #8
                great study of the colors! :3

                Comment


                  #9
                  Originally posted by megalomanium View Post
                  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.
                  If you make post process material you can set it to replace tonemapper. Then you just put that as Blendable to Post process volume.

                  Comment


                    #10
                    Originally posted by Jenny Gore View Post
                    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?

                    Comment


                      #11
                      Has this been fixed yet?

                      Comment


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

                        Comment


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

                          Comment


                            #14
                            Originally posted by SimplyMark View Post
                            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?
                            I would really like to know how to do this as well!

                            Comment


                              #15
                              Sorry for double post. but I got a solution to the tone mapper. Check it out !
                              https://forums.unrealengine.com/show...-completly-or-!

                              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?

                              Comment

                              Working...
                              X