Author Topic: [Solution] Using NGUI in linear lighting  (Read 13709 times)

Codewalker

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 21
    • View Profile
[Solution] Using NGUI in linear lighting
« on: July 25, 2014, 10:04:51 AM »
Hi folks!

I once had the problem using NGUI in combination with linear lighting. The result was: It does not really work.
For my new project, I need to use complex effects (Skyshop IBL, etc.) and need to use linear lighting. The problem with linear lighting is that NGUI (and DFGUI or Noesis) get their atlas textures and color tints washed out (due to gamme correction).
With to changes, I could do a small workaround. It's only half-automatic, because I have not yet found a method to detect the colorSpace within shaders.

First, I made a small change to the "Unlit/Transparent Colored" shader. Just change
  1. fixed4 col = tex2D(_MainTex, IN.texcoord) * IN.color;
  2. return col;
into
  1. fixed4 col = tex2D(_MainTex, IN.texcoord) * IN.color;
  2. col.rgb = pow(col.rgb,2.2); // This is the gamma correction
  3. return col;
which removes all "washed out" effects on your sprites from this atlas. However, if you use UILabel with dynamic fonts, you will get the same problem for the text color.

To correct this, change the following lines in UILabel.cs
  1. public override void OnFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
  2. {
  3.         // NGUI-code
  4.         NGUIText.tint = col;
  5.  

into the following:

  1. public override void OnFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
  2. {
  3.         // NGUI-code
  4.             if (QualitySettings.activeColorSpace == ColorSpace.Linear)
  5.             {
  6.                 col.r = Mathf.Pow(col.r, 2.2f);
  7.             col.g = Mathf.Pow(col.g, 2.2f);
  8.             col.b = Mathf.Pow(col.b, 2.2f);
  9.             }
  10.         NGUIText.tint = col;
  11.  

This worked for me (so far). I think it is still improvable (especially the half-automatic shader), but at least I can used my beloved NGUI for my project.
Let me know, if it helped anyone.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #1 on: July 26, 2014, 01:18:24 AM »
Thanks, but you don't need to modify the shaders if you change UIBasicSprite's drawingColor property instead:
  1.         Color32 drawingColor
  2.         {
  3.                 get
  4.                 {
  5.                         Color colF = color;
  6.                         colF.a = finalAlpha;
  7.                         if (premultipliedAlpha) colF = NGUITools.ApplyPMA(colF);
  8.  
  9.                         if (QualitySettings.activeColorSpace == ColorSpace.Linear)
  10.                         {
  11.                                 colF.r = Mathf.Pow(colF.r, 2.2f);
  12.                                 colF.g = Mathf.Pow(colF.g, 2.2f);
  13.                                 colF.b = Mathf.Pow(colF.b, 2.2f);
  14.                         }
  15.                         return colF;
  16.                 }
  17.         }

stevej

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 117
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #2 on: March 14, 2015, 04:52:30 AM »
Are you able to expand on this topic a little? It seems that in Unity 5, Linear color space is the default and favoured option.

Simply switching to it still washed out the GUI, and I'm not entirely sure what you mean about tweaking that UiBasicSprite code?

Are you able to explain a little better?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #3 on: March 14, 2015, 05:48:53 PM »
UI atlas texture shouldn't be using linear lighting at all...

Read the last part of http://docs.unity3d.com/Manual/LinearLighting.html

stevej

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 117
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #4 on: March 14, 2015, 06:34:40 PM »
What does that mean for resolving the issue though? My UI Atlas textures are set to "Editor GUI and Legacy GUI" which is what that page which you linked suggests. The GUI is still extremely bright when using Linear color space. How do you solve that over-bright issue?

stevej

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 117
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #5 on: March 14, 2015, 06:41:40 PM »
Just to make it clearer - this is what I'm talking about.

Gamma:
http://www.stevejarman.com//temp/unity_gamma.png

Linear:
http://www.stevejarman.com//temp/unity_linear.png

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #6 on: March 16, 2015, 09:16:08 PM »
Having another look at it, there is no way to get the colors to match perfectly because Unity insists on doing something under the hood, but if you use Advanced texture type on your atlas texture and uncheck Bypass sRGB Sampling, it seems to look more proper.

jite

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #7 on: March 23, 2015, 07:59:10 AM »
May be better use that?
Without checking "Bypass sRGB Sampling" in texture.
In UIBasicSprite:
  1. Color32 drawingColor
  2.     {
  3.         get
  4.         {
  5.             Color colF = color;
  6.             colF.a = finalAlpha;
  7.             if (premultipliedAlpha) colF = NGUITools.ApplyPMA(colF);
  8.  
  9.             if (QualitySettings.activeColorSpace == ColorSpace.Linear)
  10.             {
  11.                 colF.r = Mathf.GammaToLinearSpace(colF.r);
  12.                 colF.g = Mathf.GammaToLinearSpace(colF.g);
  13.                 colF.b = Mathf.GammaToLinearSpace(colF.b);
  14.             }
  15.             return colF;
  16.         }
  17.     }
  18.  

It used variable power. For example, values from tests:
RGBA(0.216, 0.216, 0.216, 1.000) => RGBA(0.038, 0.038, 0.038, 1.000)   PowerRGB(2.128869, 2.128869, 2.128869)
RGBA(0.235, 0.843, 0.784, 1.000) => RGBA(0.045, 0.680, 0.578, 1.000)   PowerRGB(2.140385, 2.26423, 2.259379)
RGBA(0.902, 0.255, 0.235, 1.000) => RGBA(0.791, 0.053, 0.045, 1.000)   PowerRGB(2.268569, 2.15096, 2.140385)
RGBA(0.051, 0.157, 0.180, 1.000) => RGBA(0.004, 0.021, 0.027, 1.000)   PowerRGB(1.853064, 2.079946, 2.1021)

where PowerRGB from condition: correctedColor.r = Mathf.Pow(originalColor.r, PowerRGB.r); //same for g, b

Mathf.GammaToLinearSpace() graphics
« Last Edit: March 23, 2015, 10:05:40 AM by jite »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #8 on: March 23, 2015, 09:59:00 AM »
Aha, I didn't realize Unity added that. Nice, thanks.

jite

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #9 on: March 23, 2015, 10:16:28 AM »
Accidentally found it today in Unity 4.6.0. :) Don't know about older versions. Before I used this solution with power bigger than 2.2.

BORODA

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #10 on: November 16, 2017, 05:34:15 AM »
Sorry for digging this up, but does anyone have a solution for washed out fonts on linear color space?
I've attached a screenshot of the problem. Fonts are NGUI font, keep crisp is set to always. And yes, I've applied the modification to OnFill method.


« Last Edit: November 16, 2017, 05:41:50 AM by BORODA »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: [Solution] Using NGUI in linear lighting
« Reply #11 on: November 23, 2017, 01:27:35 AM »
My current game project (Sightseer) uses linear colors, and I see no difference between gamma or linear when switching. I can only suggest checking your font's texture. Make sure it's using an atlas, make sure the font is white, and alpha for it is what you expect. Same goes for widgets. Alpha is handled slightly differently for gamma vs linear.

Last but not least, make sure your NGUI is up to date.