Search Unity

Question Getting a render texture byte[] using AsyncGPUReadback.Request

Discussion in 'General Graphics' started by Nir_Tevel, Dec 29, 2020.

  1. Nir_Tevel

    Nir_Tevel

    Joined:
    Apr 23, 2019
    Posts:
    8
    Converting a camera render to a byte array using a render texture is very slow.
    I've tried comparing this to the new AsyncGPUReadback.Request method, but the results I'm getting are 5x-10x slower, as can be seen in the attached project (Unity 2019.2.9f1)

    What am I missing?

    Thanks
     

    Attached Files:

  2. Nir_Tevel

    Nir_Tevel

    Joined:
    Apr 23, 2019
    Posts:
    8
    Here is the relevant code:

    public RenderTexture colorRenderTexture;
    Texture2D colorTexture;
    byte[] colorBytes;

    public Camera topCamera;

    float startTime;

    public bool useAsync;

    IEnumerator Start()
    {

    colorTexture = new Texture2D(640, 480, TextureFormat.ARGB32, false);

    while (true)
    {
    yield return new WaitForSeconds(1);
    yield return new WaitForEndOfFrame();


    if(useAsync)
    {

    RenderTexture rt = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, RenderTextureFormat.ARGB32);
    topCamera.targetTexture = rt;
    topCamera.Render();
    Stopwatch_Start("With Async: ");
    AsyncGPUReadback.Request(rt, 0, TextureFormat.ARGB32, OnCompleteReadback);
    topCamera.targetTexture = null;
    RenderTexture.ReleaseTemporary(rt);
    }
    else
    {
    Stopwatch_Start("Without Async: ");
    RenderTexture.active = colorRenderTexture;
    colorTexture.ReadPixels(new Rect(0, 0, 640, 480), 0, 0);
    colorTexture.Apply();
    Stopwatch_Stop("", true);
    }
    }
    }

    void OnCompleteReadback(AsyncGPUReadbackRequest request)
    {
    if (request.hasError)
    {
    UnityEngine.Debug.Log("GPU readback error detected.");
    return;
    }

    var tex = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);
    tex.LoadRawTextureData(request.GetData<uint>());
    tex.Apply();
    Stopwatch_Stop("", true);

    Destroy(tex);
    }
     
  3. whitexroft

    whitexroft

    Joined:
    Oct 22, 2012
    Posts:
    48
    i didn't look in your project, but if you were to check the profiler, most probably the frame drop is coming from .Render function
    So instead of double rendering, you could wait for a frame and then make the copying