RenderTexture到Texture2D非常慢

时间:2017-07-14 10:43:19

标签: c# unity3d camera texture2d kudan

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

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

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);
}

2 个答案:

答案 0 :(得分:2)

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

1 .Declare 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 ++的Native插件

RenderTexture.GetNativeTexturePtr()发送到C ++的原生端,然后从中创建一个OpenGL纹理,并使用Texture2D.CreateExternalTexture函数从指针加载C#,并使用Texture2D.UpdateExternalTexture函数继续更新它

最快的方法是放弃 RenderTexture。使用OpenGL glReadPixels函数从C ++端获取屏幕截图,然后使用指针将图像发送到Unity并使用Texture2D.CreateExternalTexture函数加载它,并使用Texture2D.UpdateExternalTexture函数继续更新它。您可以修改我的other post中的鼠标像素代码,然后执行此操作。

答案 1 :(得分:0)

如果不需要纹理的系统内存版本或AsyncGPUReadback,请使用CopyTexture()。您需要执行此操作。