Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

OnRenderImage() - How to avoid performance hit when not in use?

Discussion in 'Image Effects' started by TwiiK, Jan 24, 2017.

  1. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    I'm working on a glow/outline post processing effect. It's very much based on this one:
    http://xroft666.blogspot.no/2015/07/glow-highlighting-in-unity.html

    But I noticed that I use resources even when no objects are highlighted. I guess that's because all the code inside OnRenderImage() is run no matter what. So I tried putting a conditional return in there, but that broke it and after reading here:
    https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnRenderImage.html

    It seems you have to do actual work in that method if you use it. I tried just having a
    Graphics.Blit(src, dest) with nothing else in there, but that still seems to use some resources.

    So how do I make my effect only use resources when I'm actually highlighting something? Do I have to turn the entire component on/off?

    I realize that there's a million ways of doing post processing effects or shaders inside Unity and I have no idea about the pros/cons of the different approaches, I'm just trying to make this one do what I want and perhaps learn something in the process. :p
     
  2. Kronnect

    Kronnect

    Joined:
    Nov 16, 2014
    Posts:
    2,876
    Why not disable the script while not in use?
     
  3. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    That's what I meant by turning the component on/off. It's what I'm doing now, I just felt it was a bit hacky, but perhaps it's the standard way of having an effect like this that's only supposed to be visible when you for example mouseover something?
     
  4. Kronnect

    Kronnect

    Joined:
    Nov 16, 2014
    Posts:
    2,876
    Yes, that's correct AFAIK.
     
  5. bellicapax

    bellicapax

    Joined:
    Oct 5, 2016
    Posts:
    14
    Performance tips / other workaround from my own adventures in designing a similar outline:

    As mentioned in this thread on OnRenderImage(), if you do not assign a RenderTexture to the camera your script is attached to, it reads the entire screen to give you your source RenderTexture which is highly inefficient.

    As an alternative, you can do something like:

    Code (csharp):
    1. // Set these up on your own
    2. private Rendertexture _rt;
    3. private Camera _camera;
    4.  
    5.     private void OnPreRender()
    6.     {
    7.         _camera.targetTexture = _rt;
    8.     }
    9.  
    10.     private void OnRenderImage(RenderTexture source, RenderTexture destination)
    11.     {
    12.         if (_shouldOutline)
    13.         {
    14.             DoOutline(source);
    15.         }
    16.         _camera.targetTexture = null;
    17.         Graphics.Blit(source, null as RenderTexture);
    18.     }
    This won't have a performance hit like OnRenderImage() normally does because you are rendering to the texture (and not the screen) and then blitting to the screen. This assumes that you will blit your outline to combine with the source texture as your last blit so you can then blit that result to the screen by first nulling the RenderTexture on the camera (necessary) and then blitting to null (which blits to the screen)

    Hope this helps!
     
  6. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    2,005
    This does not sound correct to me. Where are you getting this information from?

    Though I guess I've always assumed that if Unity detects you are using imageEffects it will render to a renderTexture instead of the backbuffer. Then of course on Android Unity is already rendering to RT due to some hardware bug on specific devices and for deferred rendering it has to go into RenderTextures anyway.

    To double check I tweeted Aras about this, his reply 'I don't think so' - which unfortunately is not really a concrete answer, maybe because it varies based on renderer and target device?

    So anyway i'm intrigued and would like to know more, as if true, even if under specific circumstances it would be very useful knowledge to have.
     
  7. Sammael

    Sammael

    Joined:
    Dec 11, 2012
    Posts:
    24