Search Unity

Is Linear lighting more CPU intensive than Gamma lighting on mobile?

Discussion in 'General Graphics' started by protopop, Mar 26, 2019.

  1. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,560
    If i switch to linear lighting in a project, is that a more intensive pipeline than gamma lighting? Or is it about the same?

    Is there any kind of drawback (besides potential visual changes and shader recompilation) tio using linear light?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Zero difference in performance. Has no impact on the CPU or GPU perf.*

    * Unless there's something really dumb going on and the GPU is lying about what it's capable of, like old Intel IGPs which would revert to software rendering when you asked for linear rendering! Yeah, really.

    Colors may not look like you expect if you're using shaders or other rendering features that aren't color space aware (like older particle shaders applying a generic multiplier to the color in the shader, old particle systems w/o the "Apply Color Space" check box, or vertex colors on meshes). Also, some mobile hardware doesn't support linear rendering, in which case they'll revert to gamma space.
     
    hippocoder and protopop like this.
  3. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,560
    Thank you. This is basically exactly the kind of information i was hoping to get.

    Im building for mobile but it is all OpenGL ES3 or Metal so i think im safe.

    I think i prefer Gamma for the moment because ive built in it, but also because my games have a more painterly look. But i would like to experiment with linear. Especially if its the same then no harm in trying. For some reason i was under the impression that Linear was a really intensive process. I think because it was unavailable on earlier devices, so that led me to believe it was performance thing.

    I don;t think its possible, but is there a way to switch between Linear and Gamma at Runtime?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    No ... and yes.

    It's a build time player setting that can't be changed at runtime from c#, though clearly Unity is capable of doing so internally if required. You can also technically override the camera's render buffer to use a gamma space render texture or linear space render texture, but any of Unity's built in systems that do respect the color space (several stuff related to setting colors on materials, that "apply color space" check box on particle systems, and a few other things) won't know to act differently in that case and then those will be wrong. Really there's a number of random texture import settings on assets that change, so the content may be subtly different between the two. If you're using linear on a device that doesn't support linear rendering, those settings are also likely not respected, but they'll look different than if the project were built with the appropriate color space.
     
    protopop likes this.
  5. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,560
    That makes sense. Ill just run some linear tests, and when/if im ready to make the leap visually ill commit to it. And if Unity ever opens this up that could be really interesting. Thank you.
     
  6. Ng0ns

    Ng0ns

    Joined:
    Jun 21, 2016
    Posts:
    197
    I'm getting quite a large performance drop switching to linear in my project (about 50% fps decrease on my old Samsung galaxy core). Had originally attributed this to the age of the phone (It should support OpenGLES3 though), but now testing on a newer HTC 10 I'm seeing huge drops as well.

    The scene mainly use the buildin mobile shaders and a few custom, all lighting is baked. Forward rendering, no hdr, msaa etc. All at the very basic.

    Remember testing this on new projects as well, seeing the same performance characteristics.
     
    protopop likes this.
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Then I suspect those mobile GPUs are cheating their support of linear frame buffers, or Unity's implementation of linear lighting on mobile is cheating. Unreal supported linear lighting on mobile long before mobile devices actually supported it by doing a ton of hacks (using in-shader gamma correction, and a post process to adjust back, which are all expensive). I think I read somewhere that mobile GPUs are essentially doing those same hacks, just internally, where as desktop GPUs have fixed function hardware doing all of it so there's essentially zero cost.
     
    hippocoder likes this.
  8. BrandyStarbrite

    BrandyStarbrite

    Joined:
    Aug 4, 2013
    Posts:
    2,076
    Interesting.
     
  9. AljoshaD

    AljoshaD

    Unity Technologies

    Joined:
    May 27, 2019
    Posts:
    229
    We recommend you using linear since this gives you the most accurate lighting.

    Probably the most important reason that Unity still has gamma mode is to support OpenGL ES 2. These devices don't support sRGB sampling that does the conversion in hardware from the gamma encoded texture to the linear color value you can use in the shader.

    Using linear values on these devices will therefor result in a GPU performance hit because of the additional shader instructions required for the transformation (no hardware support). I don't think Unity supports linear on OpenGL ES2.

    In OpenGL ES 3.0 there is support for sRGB sampling. I'm not sure on how these devices support sRGB sampling exactly but I assume most will have hardware for it and make this cheap performance wise.

    The choice for linear or gamma should be made at the start of your production because switching between these will give different lighting results.

    You can read more here https://blogs.unity3d.com/2016/12/07/linear-rendering-support-on-android-and-ios/
     
    Last edited: Oct 3, 2019
    goldcloud144, PutridEx and gz7190 like this.
  10. Ng0ns

    Ng0ns

    Joined:
    Jun 21, 2016
    Posts:
    197
    The Samsung galaxy core should support OpenGLES3.0, but if I switch to linear the game tanks so hard it will barely launch (single digit fps vs ~30 fps with gamma).
     
  11. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    Linear rendering on Android requires two things - sRGB sampling and sRGB backbuffer. sRGB sampling is supported on OpenGL ES 3.0 and higher, as mentioned earlier. The latter is provided by a EGL extension (EGL_KHR_gl_colorspace). If your device runs Android 8.1, this extension is broken and Unity reverts to conversion using a full-screen blit, which can affect performance.
    @Ng0ns It shouldn't affect FPS that much, though.
    Can you please submit a bug report so that we can investigate?
     
  12. DonPaol0

    DonPaol0

    Joined:
    Sep 30, 2019
    Posts:
    11
    Interesting side note:

    Oculus' performance analysis article for the Quests statest transparent sampling is more expensive in linear mode:

    Will test this evening...
     
    protopop likes this.
  13. DonPaol0

    DonPaol0

    Joined:
    Sep 30, 2019
    Posts:
    11
    Just tested a simple scene with dense grass on:

    - Oculus Quest (latest OS)
    - URP 8.0.1
    - Very lightweight custom billboard shader with AlphaToMask
    - Heavy overdraw due to the grass

    My results are, well... shocking.

    In critical areas with screen-filling overdraw I get around 40 fps in Linear Space.
    And rocksolid 72 fps with rare drops in Gamma Space.
    Of course there is a downside: now lighting & colours look like crap :/

    So there is a severe performance hit with transparency and linear colour space!
    How can this be the case? Am I missing something?
     
  14. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
  15. DonPaol0

    DonPaol0

    Joined:
    Sep 30, 2019
    Posts:
    11
    Hi aleksandrk,

    Display.displays[0].requiresSrgbBlitToBackbuffer returns false on my Quest.
    Right now I'm in Gamma Space, but doesn't make a difference, right?
     
  16. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    @DonPaol0 it does. Can you try it on linear?
     
  17. DonPaol0

    DonPaol0

    Joined:
    Sep 30, 2019
    Posts:
    11
    Assumed its some driver capabilities flag passed through :) Will test tonight...
     
    aleksandrk likes this.
  18. DonPaol0

    DonPaol0

    Joined:
    Sep 30, 2019
    Posts:
    11
  19. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    This means that your device doesn't support rendering to a sRGB backbuffer. It means linear -> sRGB conversion will happen in a separate blit pass, which, obviously, makes things slower.
     
  20. DonPaol0

    DonPaol0

    Joined:
    Sep 30, 2019
    Posts:
    11
    Which consequentially means, all Oculus Quest headsets suffer from this issue, right?

    So, sadly, I'll have to stay in gamma space on the Quest, as every small performance increase is desperately needed on this device.

    Thanks for your help and responsiveness, though, much appreciated!
     
  21. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    I have just tested it and Display.displays[0].requiresSrgbBlitToBackbuffer returns FALSE for me on Unity 2019.3.8f1 Built-In Forward renderer + use 32bit display buffer DISABLED + Disable Depth and Stencil + GLES 3 + require ES 3.1 + require ES 3.1 AEP + require ES 3.2 (player settings)
    EDIT: using 4xMSAA and it's on an Oculus Quest, of course.
    @DonPaol0 I read on another thread you are using URP. Maybe that's an URP bug?
     
    Last edited: May 9, 2020
  22. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    It is an Adreno 540, so it does support sRGB buffers and targets though as far as I can see. Could it mean erroneous check?
     
  23. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    It does on my Quest with built-in forward. Could be an URP thing.
    Benchmarking Gamma vs Linear again right now.
     
  24. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Well it's just the device is fully certified for ES 3.1 in hardware, so the chances of it being a bug on Unity's side is possible. Also that Oculus article mentioned elsewhere is for Built-in on 2018.

    Can anyone take a look at Adreno 540 on Quest properly? I know this VR device was pretty much ignored up until recently.
     
  25. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    By "properly" do you mean?
     
  26. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    That Unity devote more time to the Quest because up until a few months ago it wasn't in any of their testing.
     
    liam_unity628 and atomicjoe like this.
  27. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Hahaha! yes. The Oculus Quest success has taken everyone by surprise. Even Oculus themselves. :D
    The Quest sales literally exploded the last Christmas. Seems like everyone and their dog were waiting for Black Friday to get one!
     
  28. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Finished benchmarking.
    Linear color space is FASTER than Gamma color space on the Oculus Quest with built-in forward render and it doesn't have to blit from linear.
    Details on the other thread.
     
  29. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    @atomicjoe just for the sake of checking... Do you have Android Blit Type set to Auto or Always?
    In this case it will not need to perform a separate blit, so the flag returns false.
    Please try with Android Blit Type set to Never.

    @hippocoder HW support is one thing, but driver/EGL support sometimes comes with surprises :)
    Yes, Adreno 540 is capable of doing this, but Quest seems to run Android 7.1, and e.g https://opengles.gpuinfo.org/listreports.php?eglextension=EGL_KHR_gl_colorspace lists exactly one device that has this extension on 7.1.1 (Shield TV).
     
    hippocoder likes this.
  30. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Android Blit Type was in AUTO.
    Setting it to NEVER, changes Display.displays[0].requiresSrgbBlitToBackbuffer to TRUE.
    FPS stays exactly the same though.
    Does this mean we can expect faster performance if Oculus updates their Android version?
    And how much would it be?
     
  31. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Now I'll have to recheck Gamma Color Space with Android Blit Type set to NEVER to really know which is faster, Gamma or Linear Color Space.
    Ok, here we go again... :rolleyes:
     
  32. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    GLES3 with Linear Color Space and Android Blit Type set to AUTO: 66 fps
    GLES3 with Gamma Color Space and Android Blit Type set to NEVER: 64 fps (Display.displays[0].requiresSrgbBlitToBackbuffer = FALSE)

    So Gamma is still slower than Linear no matter the Blit is ON or OFF.
     
  33. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    When blit type is set to anything other than "Never", Unity may perform a blit that, among other things, does a linear->sRGB conversion when necessary. In Oculus case, we do this blit.
    Not doing it will save some instructions, but if you're not bound by ALU, it will not give a perf boost. I suppose Adreno can merge this blit with previous rendering without leaving the tile memory, this is why you don't see the frame rate drop. If this wasn't the case, the FPS would've dropped significantly.
    66 FPS vs 64 FPS is 15.15ms vs 15.625ms, which is around 3%. I'd say this is within error margin :)
     
    dyupa and hippocoder like this.
  34. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    It's actually consistent. Even if it doesn't matter after all :)
    The thing is: Linear is at least as fast as Gamma, blit or no blit.
    I'm pretty sure that's what's happening here: the Quest will do it's head-tracking motion compensation anyway, so it will have to do some blits no matter what.
     
  35. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    727
    What was the consensus here? Did anyone ever figure out why it seems that linear is running slower on mobile?
     
  36. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    727
  37. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    There is no consensus, only personal experiences:

    On some mobile GPUs, Linear is a lot slower. On others, Linear is actually a tiny little faster.
    This seems to happen because some GPUs and Android versions can't handle sRGB backbuffers and need the rendered image to be converted, adding a full framebuffer copy at the end of the render.
    If you want to play it safe for all GPUs out there, use Gamma.

    On the Quest specifically, Linear is a tiny little faster than Gamma using the Built-In Forward Renderer with MSAAx4 because it bypasses some internal shader operations. (my experience)
    Using URP however, Ng0ns found Linear to be much slower than Gamma on the same Quest.
    Why is that, we don't know.

    Conclusion:
    Gamma mode is the safest bet in general. If you are developping for compatibility, use Gamma mode.
    If you are targeting specific hardware however, Linear can be an option but you will have to test it to be sure.
     
  38. jacobian

    jacobian

    Joined:
    Jul 20, 2015
    Posts:
    17
    I seem to be having similar results when messing with Oculus quest.
    Linear slows down the fps while looking through a transparent mesh used for sun rays.
    Looking through water it was still at 72fps.

    While on gamma its at 72 fps constantly.
     
  39. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Interesting.
    Built-in render pipeline or URP?
    Also, GLES3 or Vulkan?
     
  40. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    727
    Looking through a transparent mesh will drop frames regardless due to overdraw, but maybe linear is pushing it over the edge?
     
  41. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    I have just rechecked: on the Quest with the built-in render pipeline, Gamma mode is 1% slower than Linear mode, even on overdraw heavy zones with fullscreen transparencies.
    GLES3.2 without HDR frame buffer. (Vulkan is extremely slow on the Quest. Use GLES)
    Maybe it's an URP thing.
     
  42. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,756
    The problem is the setting on player for "Blit Type". If you use Linear, your device may be forced to "always" do blit, so whatever you gained from switching to linear, you made it slower with the blit.
     
  43. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Linear is still at least as fast as gamma anyway.
     
  44. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,756
    No. If you are forced to turn the "always blit" on, it's impossible linear is faster than gamma with "blit none". It's just impossible. Your case works only if the device supports the same Blit Type for both. This is the case for modern devices but not for older ones. Quoting from a previous post from Unity team in this thread... these are the requirements for it to work.

    "Linear rendering on Android requires two things - sRGB sampling and sRGB backbuffer. sRGB sampling is supported on OpenGL ES 3.0 and higher, as mentioned earlier. The latter is provided by a EGL extension (EGL_KHR_gl_colorspace). If your device runs Android 8.1, this extension is broken and Unity reverts to conversion using a full-screen blit, which can affect performance."
     
    Last edited: Apr 5, 2021
  45. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Stop talking and benchmark it.
     
  46. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,756
    That's exactly what I did before posting. Why so rude?
    I tested both scenarios. If my phone supports the specs I choose linear. Otherwise it drops around 20% on performance because of the blit type. And you can't deactivate that if you use linear on certain phones. Just get an old phone and benchmark instead of talking. What kind of comment is that?
     
  47. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Sorry I didn't want to upset you :p
    It's just that plenty of people talk theoretically without actually measuring it.
    My tests were done on the Oculus Quest, and there linear is actually a little bit faster.
    What phone is it and what GPU does it have?
     
    Last edited: Apr 6, 2021
  48. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    On the Quest, it blits and it's faster. So much for it being impossible.
    Theory is just speculation. There are so many things that can and will impact the final result in practice that the only way to know for sure is to test and benchmark it, and that's what I did on this whole thread.
    I'm still interested in your results on your specific phone though, if you are still wanting to share them.
     
  49. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,756
    You are still failing to understand the post. Let me reinforce the important parts: Your case works only if the device supports the same Blit Type for both. This is the case for modern devices but not for older ones.

    You are using as a comparison the Quest, which DOES SUPPORT THAT SETTING. I´m explaining that if your phone DOES NOT, I repeat, IF YOUR DEVICE DOES NOT support ¨blit none¨ on linear settings, it cannot be faster. You are basically saying that doing calculations is faster than doing absolutely nothing. It´s like saying that rendering water is faster than not rendering anything. And you just keep insisting.

    You are using a Quest that supports the option on both gamma and linear, which then has the same settings and you compare the speed between gamma and linear and claim Linear is faster. It may well be. NOBODY is arguing that. But this thread is not ONLY about the specific case of Quest. If you get an older device that doesn't allow for the same blit settings for linear and gamma, it is IMPOSSIBLE, that "blit always" is faster than "blit none". IMPOSSIBLE. And the problem is that some old devices and Android 8.1 will FORCE YOU to set it to "blit always" if you set it to linear instead of gamma.
     
  50. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    The Quest does Blit when using linear, as evidenced in this post. It does not when using gamma.