美文网首页unity
VR网络图片加载造成的丢帧问题

VR网络图片加载造成的丢帧问题

作者: Levi_Wan | 来源:发表于2017-08-16 21:36 被阅读96次

  最近在跟一个VR项目。需要将从服务器返回的数据展示在VR商品列表里面。使用的是UGUI,每当图片异步加载返回刷新UI界面时会出现卡帧的现象,根据图片大小不同相应的卡1-3帧。造成很不好的用户体验。

  根据网上参考,使用了AsyncImageDownload(http://blog.csdn.net/daijinghui512/article/details/38066119)来做图片异步加载的封装。但在VR中出现了卡帧的问题。代码如下:

using UnityEngine;
using System.Collections;
using System.IO;
using UnityEngine.UI;
public class AsyncImageDownload : MonoBehaviour
{

public Texture placeholder;
public static AsyncImageDownload Instance = null;

private string path = Application.persistentDataPath + "/ImageCache/";


void Awake()
{
   
}
//构建单例  
public static AsyncImageDownload CreateSingleton()
{
    if (!Directory.Exists(Application.persistentDataPath + "/ImageCache/"))
    {
        Directory.CreateDirectory(Application.persistentDataPath + "/ImageCache/");
    }

    GameObject obj = new GameObject();
    obj.name = "AsyncImageDownload";
    obj.AddComponent<AsyncImageDownload>();

    AsyncImageDownload loader = obj.GetComponent<AsyncImageDownload>();
    Instance = loader;  
    loader.placeholder = Resources.Load("placeholder") as Texture;
    return loader;

}

public void SetAsyncImage(string url, RawImage texture)
{



    //开始下载图片前,将UITexture的主图片设置为占位图  
    texture.texture = placeholder;

    //判断是否是第一次加载这张图片  

    if (!File.Exists(path + url.GetHashCode()))
    {
        //如果之前不存在缓存文件  


        StartCoroutine(DownloadImage(url, texture));


    }
    else
    {

        StartCoroutine(LoadLocalImage(url, texture));

    }

}
IEnumerator DownloadImage(string url, RawImage texture)
{
    Debug.Log("downloading new image:" + path + url.GetHashCode());
    WWW www = new WWW(url);
    yield return www;

    Texture2D image = www.texture;
    //将图片保存至缓存路径  
    byte[] pngData = image.EncodeToPNG();
    File.WriteAllBytes(path + url.GetHashCode(), pngData);

    texture.texture = image;

}
IEnumerator LoadLocalImage(string url, RawImage texture)
{
    string filePath = "file:///" + path + url.GetHashCode();

    Debug.Log("getting local image:" + filePath);
    WWW www = new WWW(filePath);
    yield return www;


    //直接贴图  
    texture.texture = www.texture;

  }  
}

  根据自己项目本身的需求对这个异步加载图片做了很多修改和处理。经过Unity Profiler的跟踪定位到了问题。

  • CoroutineDelayCall中AsyncImageDownload 协程的MoveNext占用了cpu大多时间50ms-500ms不等。从而造成了卡帧。

  • 原因定位:

    • byte[] pngData = image.EncodeToPNG(); 将纹理转换为字节流时发生了耗时操作。
    • File.WriteAllBytes(path + url.GetHashCode(), pngData);将纹理存储本地化时IO发生了耗时。
  • Coroutine协程并不等于线程。只是通过IEnumerator接口中的MoveNext实现了控制代码在特定的时间段执行。耗时操作仍然影响主线程的UI刷新造成卡帧现象。

  • VR中占用cpu最多的是Camera.Render,通过Normalized View Port Rect实现双眼相机分屏渲染,对于渲染开销很大(尤其是在移动端),当IO流或者其他加载耗时操作时,由于Camra每帧都在渲染画面,会出现卡帧。

  • 解决方案,通过线程池来进行网络请求图片的加载以及本地化缓存。

  构建图片的数据模型ImageModel:

using UnityEngine;
using System.Collections;
using System.IO;


public class ImageModel  {

string path;

public string Path
{
    get { return path; }
    set { path = value; }
}

Texture2D imageData;

public Texture2D ImageData
{
    get { return imageData; }
    set { imageData = value; }
}
public ImageModel() { }
public ImageModel(string path, Texture2D tex) { this.Path = path; this.ImageData = tex; }

public void DownImageLocalization(object obj)
{
    ImageModel temp = obj as ImageModel;
    byte[] pngData = temp.ImageData.EncodeToPNG();
    File.WriteAllBytes(temp.Path, pngData);
}

}

  修改加载方案:

 Texture2D image = www.texture;

    //压缩
    image.Compress(false);
    //替换
    texture.texture = image;
    
    //将图片保存至缓存路径
    ImageModel im = new ImageModel(path + url.GetHashCode(), image);
    ThreadPool.QueueUserWorkItem(new WaitCallback(im.DownImageLocalization),im);
  • 解决VR卡帧问题,主要针对移动端VR。

  欢迎讨论各种缺陷与不足,本人原创转载请注明文章出处,谢谢。

相关文章

  • VR网络图片加载造成的丢帧问题

      最近在跟一个VR项目。需要将从服务器返回的数据展示在VR商品列表里面。使用的是UGUI,每当图片异步加载返回刷...

  • 性能优化

    问题:setImageResource()造成卡顿和oom解决方案:使用图片加载框架Glide加载图片

  • uniapp实现加载图片失败显示占位图

    平常在项目中,我们会经常需要有加载网络图片的功能,但是存在图片地址问题、网络问题等导致图片加载失败,需要展示一个占...

  • iOS SDWebImage 加载GIF图片没效果

    //加载本地GIF图片 //加载网络GIF图片 (SDWebImage 4.0 之前) //加载网络GIF图片(S...

  • Flutter 图片无法缓存

    问题:使用CachedNetworkImage加载网络图片时, 图片无法缓存, 离屏后重新显示就会重新加载 解决:...

  • H5图片未加载出来问题排查步骤

    H5图片未加载出来问题排查步骤: 1.排查是否时网络问题,保证网络正常 2.是否设置了节省流量的模式,不加载图片 ...

  • 图片预加载、瀑布流+图片预加载

    图片预加载 图片预加载是为了解决网络卡等一些其他情况造成该显示的图片不能及时的显示,但为了提高网页的完整性,给未能...

  • flutter 图片

    加载网络图片网络图片 加载本地图片效果 实现图片圆角的几种方式 CircleAvatarCircleAvatar ...

  • 微信小程序-image(图片)

    在微信小程序中,要显示一张图片,有两种图片加载方式: 加载本地图片 加载网络图片 加载本地图片 加载网络图片 微信...

  • 视觉工程师必须知道的工业相机50问

    1:工业相机的丢帧的问题是由什么原因引起的? 经常会有一些机器视觉工程师认为USB接口的工业相机会造成丢帧现象。一...

网友评论

    本文标题:VR网络图片加载造成的丢帧问题

    本文链接:https://www.haomeiwen.com/subject/ewjwrxtx.html