简体   繁体   English

RenderTexture到Texture2D的速度非常慢

[英]RenderTexture to Texture2D is very slowly

We develop an application on Unity3D which shall take the image from the screen and transfer it to Texture2D. 我们在Unity3D上开发了一个应用程序,该应用程序将从屏幕上获取图像并将其传输到Texture2D。 We have difficulties with performance on everage (feeble) devices. 我们在普通(廉价)设备上的性能存在困难。
The code is given below. 代码如下。 We do a screenshot, then we read pixels (ReadPixels) - here the problem arises, an app runs terribly slow. 我们进行屏幕截图,然后读取像素(ReadPixels)-出现问题,应用运行非常慢。

We tried to take the texture from the camera, but it doesn't work because our scanner works in parallel with Kudan, and in turn it blocks access to the camera. 我们尝试从相机上获取纹理,但由于我们的扫描仪与Kudan并行工作,从而阻止了对相机的访问,因此该纹理不起作用。 Then we tried to limit the area of screen to scan (by taking for scanning a small window, but not full screen) - but there wasn't visible increase in the performance. 然后,我们尝试限制扫描的屏幕区域(通过扫描一个小窗口,而不是全屏)-但是性能没有明显提高。
Can anyone help with this? 有人能帮忙吗?
Here is our code: 这是我们的代码:

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

There are few ways to improve this code or optional way to convert RenderTexture to Texture2D . 没有什么方法可以改进此代码,也没有几种方法可以将RenderTexture转换为Texture2D

1 .Declare WaitForEndOfFrame as a variable outside the function so that you don't have to do that each time that function is called. 1。WaitForEndOfFrame为函数外部的变量,这样就不必在每次调用该函数时都这样做。

2 .You are creating a new Texture2D each time you call that function. 2。每次调用该函数时,您都在创建一个新的Texture2D Do that once in the Start function then re-use it. 在“ Start功能中执行一次操作,然后重新使用它。 You can freely resize the Texture if RenderTexture width or height changes. 如果RenderTexture宽度或高度发生变化,则可以自由调整纹理的大小。

3 .You are also creating new RenderTexture each time you call that function too. 3。您每次也调用该函数时,还将创建新的RenderTexture It's faster to use RenderTexture.GetTemporary to get temporary RenderTexture . 使用RenderTexture.GetTemporary来获取临时RenderTexture更快。 When you are done using it, you can RenderTexture.ReleaseTemporary to release it. 使用RenderTexture.ReleaseTemporary ,可以使用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);
}

Here are other options you have: 您还有其他选择:

Use Native plugins with C++ : 在C ++中使用本机插件

Send 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 function. 发送RenderTexture.GetNativeTexturePtr()到C的机端++然后创建一个OpenGL的纹理和C#与使用指针加载它Texture2D.CreateExternalTexture功能,时刻保持与更新它Texture2D.UpdateExternalTexture功能。


The fastest way to do this is to abandon RenderTexture . 最快的方法是放弃 RenderTexture Use OpenGL glReadPixels function to take screenshot from C++ side then send the image to Unity with pointer and load it with the Texture2D.CreateExternalTexture function and keep updating it with the Texture2D.UpdateExternalTexture function. 使用OpenGL glReadPixels函数从C ++端获取屏幕截图,然后使用指针将图像发送到Unity并使用Texture2D.CreateExternalTexture函数加载它,并继续使用Texture2D.UpdateExternalTexture函数对其进行更新。 You can modify the mouse pixel code from my other post and make it do this. 您可以从我的其他帖子中修改鼠标像素代码,然后执行此操作。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM