Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Image Effect profiling.

Discussion in 'PSM' started by Spidyy, Jul 10, 2014.

  1. Spidyy

    Spidyy

    Joined:
    Mar 6, 2011
    Posts:
    184
    Hey there.

    My game is heavily using image effects, and the vita should be able to manage them on a fair load of framerate, BUT it is not the case here.

    I did some tests using a fairly simple script :

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent(typeof(Camera))]
    5. public class ImageEffect : MonoBehaviour {
    6.    
    7.     RenderTexture targetTexture;
    8.     GameObject ppCamera;
    9.    
    10.     void OnPreCull()
    11.     {
    12.         if (!enabled || !gameObject.activeSelf)
    13.             return;
    14.        
    15.         if (!ppCamera)
    16.         {
    17.             ppCamera = new GameObject("ShaderCamera", typeof(Camera));
    18.             ppCamera.camera.enabled = false;
    19.             ppCamera.hideFlags = HideFlags.HideAndDontSave;
    20.         }
    21.        
    22.         Camera cam = ppCamera.camera;
    23.         cam.CopyFrom (camera);
    24.         cam.backgroundColor = Color.black;
    25.         cam.clearFlags = CameraClearFlags.SolidColor;
    26.  
    27.         targetTexture = RenderTexture.GetTemporary (Screen.width, Screen.height, 0, RenderTextureFormat.ARGBHalf);
    28.         //targetTexture = RenderTexture.GetTemporary (Screen.width/4, Screen.height/4, 0, RenderTextureFormat.ARGBHalf);
    29.        
    30.         cam.targetTexture = targetTexture;
    31.         cam.Render();
    32.     }
    33.    
    34.     // Update is called once per frame
    35.     void OnRenderImage(RenderTexture source, RenderTexture destination)
    36.     {
    37.         Graphics.Blit (targetTexture, destination);
    38.        
    39.         RenderTexture.ReleaseTemporary(targetTexture);
    40.     }
    41. }
    42.  
    This script is based on the one used by most Unity image effects and advised in the Unity documentation.

    I create a purely empty scene, with only the default camera, and apply the script to it. Here the numbers I have from the profiler, using the development build. No Vsync of course. The numbers bellow are taken from Gfx.WaitForPresent

    Nude camera, no script, cull everything : 1.25ms to 1.75ms
    Next, I cull nothing on the main camera, everything on the camera created by the script
    With script, full resolution render texture, with blit : 10.75ms to 11.25ms
    With script, quarter resolution render texture, with blit : 7.90ms to 8.40 ms
    With script, full resolution render texture, no blit : 2.25ms to 3 ms

    So if I follow the numbers, the blit itself is the thing the most time consuming when doing an Image Effect. Now take my game with up to 5 different render and up to 6 blits, the camera rendering take only 6.6ms (Camera.Render), but the Graphics and blit stuff use up to 40ms (Gfx.WaitForPresent)(!).

    Please, Unity guys, could you find a way to optimize the Blit function, even the Graphics stuff in general? The use of Replacement shaders works like a charm, but when I want to blit the result of the shaders on the screen, it use an awefull lot of time.
     
  2. eriQue

    eriQue

    Unity Technologies

    Joined:
    May 25, 2010
    Posts:
    595
    Using any kind of fullscreen effects on a TBDR architecture, such as the SGX, will cause the hardware rendering pipe to stall. You have to be very careful not to completely kill the performance.
    The same issue can be seen when running on a iOS device, or an Android device with similar graphics hardware.

    The measurements above most likely show the actual cost of the graphics hardware executing those blits - that's not Unity code, and there is very little we can do to optimize what you explicitly tell the hardware to do.
    In fact - it's not the cost of the blit itself that is problematic. It's that the graphics hardware has to pause and wait for the source data (the image of the scene you are rendering) to become available, before it can proceed.

    And as you can tell - because the rendering happens deferred, the real cost most often doesn't show up at the actual draw call (Camera.Render) but when the final image is prepared (Gfx.WaitForPresent).