Unity VR&AR Unity播放全景视频及优化极点变形twist问题


2016年是VR元年,这一年度多少少做了点东西,都是关于VR&AR的,虽然现在是冷冬期,个人认为前景还是有的,只不过会曲折前进,工业革命还分好几次呢,对吧!

好了,最近比较空闲,会整理一些VR&AR的一些经验。

这一篇会讲一下如何在Unity中播放全景视频,以及对全景视频的优化。

楼主写这篇教程一用ouclus 为例。

一、Unity播放视频

新建一个工程,写放进去一个全景视频,如果放不进去就安装个quicktime,这个具体的网上有很多前辈已经写了教程,这里我就不多说了,导入视频后显示成这样:

如果显示成白的,就是没有导入成功。

播放视频我们这里用的Unity自带的MovieTexture,条件好的话可以使用Untiy的插件AV Pro.

我们新建一个场景,场景中新建一个Sphere,命名为UntiySphere,

然后新建一个材质,这个材质的shader设置成Particles/Alpha Blended,把这个材质给到UnitySphere,然后把全景视频拖到Particle Texture上

然后新建一个脚本,叫做PlayMovie,加入下面两行代码:

MovieTexture mov = (MovieTexture)GetComponent().material.mainTexture;

        mov.Play();

将此脚本挂到UnitySphere上,然后将相机的Transform Reset,这个操作是把相机放到原点,坐标旋转置为0,大小设为1,

同样我们把UntiySphere的Transform也Reset,然后将大小改到3,就是把相机包含到球里面。

我们连接好Ouclus,将Untiy的PlayerSettings设置为VR Supported,ouclus,如下图所示:

然后我们运行,就可以看到播放的全景视频

戴上oculus头显可以360度自由旋转。

当然到这里你可能疑问,为啥没有声音,这里很简单,在UnitySphere上添加组件AudioSource,

然后把全景视频下的音频文件拖进去,让它自动播放:

好了播放去全景视频就是这么简单,代码只需要两行就好了。

二、全景视频的优化

但是这里我们往头顶上看的时候会发现一个问题,头顶的图片看的不是连接自然的,能看到明显的缝隙,如图:

那下面我们就来优化这个问题,有三种思路:

1.从Untiy这边解决

从Untiy这边解决就是,我们不用Untiy自带的Sphere,因为它自带的贴图uv分部不均匀,极点会产生Twist效果,我们自己使用Mesh建立一个自己的Octahedron球,就是正八面体拆分的球,然后贴图吻合,材质我们使用跟上面一致的,具体这个球的怎么建立的详见我之前写的关于球的两篇博客:

Mesh画球    Mesh给球贴图

然后我们播放全景视频的代码做稍稍改动:

// Use this for initialization
    IEnumerator Start()
    {
        //此处等待是为了保证Mesh创建球的时间,实际根据电脑性能或调整脚本执行顺序即可忽略
        yield return new WaitForSeconds(1f);

        MovieTexture mov = (MovieTexture)GetComponent().material.mainTexture;

        mov.Play();
    }

这样运行后的效果如图:

2.从模型发面解决

上面这种方法是基于Untiy原生的改变解决问题,如果你觉得太麻烦的话就不需要如此做,找模型制作的同事帮忙制作了一个比较规则的球,它的uv贴图展开的特别均匀,如图所示:

直接把场景中的UntiySphere替换成模型的ball,其它的一样,这样运行的结果如图:

这样也能达到一样的效果,性能上还省了我们Untiy创建球的时间,空间上这个模型也不大才69kb

与第一种比起来第二种更好,但是mesh的底层研究知道肯定比不知道好。

3.替换MeshFilter

楼主研究了下AVPRo插件里的全景视频的播放,发现它播放的不但很清楚,而且也没有twist的问题,一开始以为是它自己写的shader也能解决这个问题,于是把Untiy自带的Sphere赋予插件里的shader,发现问题依然存在,后来仔细研究一下,发现原来它替换了一个MeshFilter,它的MeshFilter是一个Octahedron的球,跟我们Mesh建立球的思路一样,但是它不是Untiy创建的,而是一个创建好了的片,这样比第二种方法的模型还要方便。
这个片如图所示:


我们把UnitySphere的MeshFilter替换成这个片运行后如图所示:

同样解决了哈,方法三比前面两种似乎更加方便呢。