C#for Unity中大型Texture2D的无阻塞加载和复制 [英] Non-blocking loading and copying of large Texture2D's in C# for Unity

查看:1342
本文介绍了C#for Unity中大型Texture2D的无阻塞加载和复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Android开发一个Unity应用程序,该应用程序可以动态加载很多大纹理(所有图像的大小都超过png的6MB).这些纹理可以来自Amazon S3服务器(在这种情况下它们作为流到达),也可以来自用户的设备本身.

I'm building a Unity app for Android which deals with loading a lot of large textures dynamically (all images are over 6MB in size as png's). These textures can either come from an Amazon S3 server, in which case they arrive as a stream, or from the user's device itself.

在两种情况下,我都可以异步获取原始数据或纹理,而不会出现问题.在第一部分中,我查询服务器并获取数据流的回调,在第二部分中,我使用WWW类使用"file://"协议来获取纹理.

In both cases I'm able to get hold of the raw data or texture asynchronously without a problem. In the first I query the server and get a callback with the stream of data, and in the second I use the WWW class to get hold of the texture making use of the "file://" protocol.

当我想将此数据复制到Texture2D到我可以使用的某个位置(例如复制到Texture2D私有成员)后,就会发生问题.

The problem happens as soon as I want to copy this data into a Texture2D to some place I can make use of, such as onto a Texture2D private member.

对于流,我将其转换为byte []并尝试调用LoadImage(),对于WWW类,我仅尝试使用myTexture = www.texture复制它.两次加载或复制纹理时,我都会得到一个很大的帧.我想根除此框架,因为该应用程序根本无法附带它.

With the stream I convert it into a byte[] and try calling LoadImage(), and with the WWW class I simply try copying it with myTexture = www.texture. Both times I get a massive frame out as the texture is loaded or copied. I want to eradicate this frame out because the App is simply un-shippable with it.

using (var stream = responseStream)
{
   byte[] myBinary = ToByteArray(stream);
   m_myTexture.LoadImage(myBinary);  // Commenting this line removes frame out
}

...

WWW www = new WWW("file://" + filePath);
yield return www;
m_myTexture = www.texture;  // Commenting this line removes frame out

不幸的是,Unity似乎不喜欢在与主线程不同的线程上运行这些操作,并且在我尝试时会引发异常.

Unfortunately Unity doesn't seem to like running these operations on a separate thread from the main thread and throws an exception when I try.

有没有办法对这些操作进行分块处理,以便占用多个帧?还是执行某种不会使主线程停顿的快速内存复制操作?

Is there any way to perhaps chunk up these operations so that it takes multiple frames? Or do some sort of fast memcopy operation that won't stall the main thread?

提前谢谢!

PS:我在以下回购中创建了该问题的有效示例: https://github. com/NeoSouldier/Texture2DTest/

PS: I've created a working example of the problem in the following repo: https://github.com/NeoSouldier/Texture2DTest/

推荐答案

最终,通过创建一个C ++插件(通过Android Studio 2.2构建)解决了此问题,该插件使用"stb_image.h"加载图像和OpenGL生成纹理并将一组扫描线在多个框架上映射到纹理上.然后通过Texture2D.CreateExternalTexture()将纹理移交给Unity.

Eventually this problem was solved by creating a C++ Plugin (built through Android Studio 2.2) that makes use of "stb_image.h" for loading the image, and OpenGL to generate textures and map a set of scanlines onto the texture over multiple frames. The texture is then handed over to Unity through Texture2D.CreateExternalTexture().

此方法不会使工作异步,而是将加载成本分散在多个帧上,从而删除了同步块和后续帧.

This method does not make the work asynchronous but spreads the loading cost over multiple frames removing the synchronous block and subsequent frame out.

我无法使纹理创建异步,因为要使OpenGL函数正常工作,您需要从Unity的主渲染线程运行代码,因此必须通过GL.IssuePluginEvent()-Unity的函数来调用函数docs使用以下项目来解释如何使用此功能: https://bitbucket.org/Unity-Technologies/graphicsdemos/

I wasn't able to make the texture creation asynchronous because in order for the OpenGL functions to work you are required to be running the code from Unity's main Render Thread, so functions must be called through GL.IssuePluginEvent() - Unity's docs use the following project to explain how to make use of this functionality: https://bitbucket.org/Unity-Technologies/graphicsdemos/

我已经清理了我正在处理的测试仓库,并在README中编写了说明,以尽可能容易地理解我所遇到的最终解决方案.我希望这对某人有用,他们只要我为解决这个问题所做的工作就不必花时间了! https://github.com/NeoSouldier/Texture2DTest/

I've cleaned up the test repo I was working on and written instructions in the README to make it as easy as possible to understand the final solution I came to. I hope that it will be of use to someone at some point and that they won't have to spend as long as I've done to solve this problem! https://github.com/NeoSouldier/Texture2DTest/

这篇关于C#for Unity中大型Texture2D的无阻塞加载和复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆