RenderTexture 到 Texture2D 非常慢

RenderTexture to Texture2D is very slowly

我们在 Unity3D 上开发了一个应用程序,它将从屏幕上获取图像并将其传输到 Texture2D。 我们在普通(弱)设备上的性能有困难。
代码如下。我们截屏,然后读取像素 (ReadPixels) - 问题出现了,应用程序运行速度非常慢。

我们尝试从相机获取纹理,但它不起作用,因为我们的扫描仪与 Kudan 并行工作,反过来它会阻止对相机的访问。然后我们尝试限制要扫描的屏幕区域(通过扫描一个小 window,但不是全屏)——但性能没有明显提高。
有人能帮忙吗?
这是我们的代码:

IEnumerator DecodeScreen()
 {
   yield return new WaitForEndOfFrame();
   RenderTexture RT = new RenderTexture(Screen.width, Screen.height,24);
   Texture2D screen = new Texture2D(RT.width, RT.height, TextureFormat.RGB24, false, false);
   screen.ReadPixels(new Rect(0, 0, RT.width, RT.height), 0, 0);
   screen.Apply(); 
   Debug.Log(resultText.text);
   GetComponent().targetTexture = null;
   Destroy(RT);
}

有几种方法可以改进此代码或将 RenderTexture 转换为 Texture2D 的可选方法。

1。将 WaitForEndOfFrame 声明为函数外部的变量,这样您就不必在每次调用该函数时都这样做。

2。您每次调用该函数时都会创建一个新的 Texture2D。在 Start 函数中执行一次,然后重新使用它。如果 RenderTexture 宽度或高度发生变化,您可以自由调整纹理大小。

3。您每次调用该函数时也会创建新的 RenderTexture。 使用 RenderTexture.GetTemporary 获得临时 RenderTexture 速度更快。使用完毕后,您可以RenderTexture.ReleaseTemporary释放它。

Texture2D screen = null;
WaitForEndOfFrame frameEndWait = new WaitForEndOfFrame();

void Start()
{
    screen = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false, false);
}

IEnumerator DecodeScreen()
{
    yield return frameEndWait;
    RenderTexture RT = RenderTexture.GetTemporary(Screen.width, Screen.height, 24);
    //Resize only when Texture2D is null or when its size changes
    if (screen == null || screen.width != RT.width || screen.height != RT.height)
    {
        screen.Resize(RT.width, RT.height, TextureFormat.RGB24, false);
        //screen = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false, false);
    }
    screen.ReadPixels(new Rect(0, 0, RT.width, RT.height), 0, 0);
    screen.Apply();
    RenderTexture.ReleaseTemporary(RT);
}

您还有其他选择:

使用 C++ 原生插件:

发送RenderTexture.GetNativeTexturePtr() to a native side of your C++ then create a OpenGL texture from that and load it from C# with pointer using the Texture2D.CreateExternalTexture function and keep updating it with the Texture2D.UpdateExternalTexture函数。


最快的方法是放弃 RenderTexture。使用 OpenGL glReadPixels 函数从 C++ 端截取屏幕截图,然后使用指针将图像发送到 Unity 并使用 Texture2D.CreateExternalTexture function and keep updating it with the Texture2D.UpdateExternalTexture function. You can modify the mouse pixel code from my 加载它并使其执行此操作。

如果不需要纹理的系统内存版本,或者 AsyncGPUReadback.Request 需要,请使用 CopyTexture()。