现在的 VR 似乎没有之前那么火热了,于是乎我居然开始了 VR 征程。。。
说起 VR,对于没有接受过相关知识的人来说可能看起来比较高大上,但是 VR 的原理却没有想象中那么复杂。总的来说,VR 之所以能够产生立体感,是因为人有两只眼睛。其实现在有很多自称 VR 的视频或者图片严格来讲并不能算是 VR,因为它只是将一平面图变成了 360° 的图,其实和平面图是一样的,并没有深度信息,只是你可以转转小脑袋来全方位观察而已。如下图:
可以看到图片是扭曲的,至于为什么人眼在 VR 眼镜中看到的图像是正常的,是因为这张图片并不是直接看的,它需要把整个图像投影到一个球体的内表面(可以想象一下把地球仪展开成一个平面图并且补充裂开的部分),然后摄像头位于球体内部的中心,这时候从 VR 眼镜中看到的就只是这个球的一小部分,当然,可以转动你的小脑袋来全方位观察,当转动的时候通过陀螺仪的读书来计算相机的转动角度。这种 VR 的原理大概就是如此了,是不是觉得很简单!
真正有深度信息的 VR 图片 / 视频其实是有两部分的,其中比较多的是左右屏和上下屏,这时候就不能把它直接投影到一个球上了,而是投影到两个球上,并且需要有两个摄像机分别来提供左眼和右眼的图像,此时左眼和右眼看到的图像并不是完全一致的,有一定的错位,就跟我们睁开眼看这个世界一样,所以此时看到的图像就是立体的,有深度信息的。如下图:
(图像比较渣,将就看)
上图中上下看起来是差不多的,但是实际上是有差别的,投影的时候会把上半部分投影到左眼,把下半部分投影到右眼,具体如何实现会在后面讲。除了上下分屏其实还有左右分屏的,原理都差不多了。
原理讲得差不多了下面讲开发:
首先你要准备开发环境:Unity#D5.6(最新),安卓 SDK(5.1 以上),JDK,Visualstudio 2017(可选),Andoridstudio(可选)。Unity 插件:EasyMovieTexture3.59(商用就买,个人爱好可以去搜搜其他人的分享)。
首先来看普通的全景图(没有分屏的),这里强行假设你已经搭建好了所有的环境,打开 Unity3D,新建一个 3D Project,这时候你将得到一个 miancamera 和一个平行光,将平行光删掉(喜欢也可以留着)。新建一个球体,然后导入一张全景图,将图片拖到刚刚创建的球体上,可以看到现在的球体已经被你的图片包围了,然后将球的 Scale 属性 xyz 分别设置为 5,5,-5(其它等比例也行,但是要保证比相机要大). 至于为什么 z 轴是 - 5,等会讲到。将相机和该球的位置都设为 0,0,0. 这时点击相机,你将会在预览窗口什么都看不到,因为你的图片是贴在了外表面。需要想办法把图片贴到内表面去,感谢王文刚老铁提供的 Sharder。
- Shader"Unlit/DoubleSided"
- {
- Properties
- {
- _Color("Main Color", Color) = (1,1,1,1)
- _MainTex("Texture", 2D) ="white" {}
- }
- SubShader
- {
- //Ambient pass
- Pass
- {
- Name "BASE"
- Tags {"LightMode"="Always" /* Upgrade NOTE: changed from PixelOrNone to Always */}
- Color[_PPLAmbient]
- SetTexture[_BumpMap]
- {
- constantColor(.5,.5,.5)
- combine constant lerp(texture) previous
- }
- SetTexture[_MainTex]
- {
- constantColor[_Color]
- Combine texture * previous DOUBLE, texture *constant
- }
- }
- //Vertex lights
- Pass{
- Name "BASE"
- Tags {"LightMode"="Vertex"}
- Material
- {
- Diffuse[_Color]
- Emission[_PPLAmbient]
- Shininess[_Shininess]
- Specular[_SpecColor]
- }
- SeparateSpecular On
- Lighting On
- cull off
- SetTexture[_BumpMap]
- {
- constantColor(.5,.5,.5)
- combine constant lerp(texture) previous
- }
- SetTexture[_MainTex]
- {
- Combine texture *previous DOUBLE, texture *primary
- }
- }
- }
- FallBack "Diffuse",1
- }
这个 Shader 的意思其实就是让球两边都贴上纹理。这时候再点击摄像机你就能看到图像了,但是你可能会发现这图像是反的(你可能也会发现不了,但是它确实是反的),所以我们要将球的 Scale.z 值设基本为负数。到这里基本就完成了,接下来就是打包发布了,点击 file-build and setting 选择安卓,点击 player setting,在 other setting 里将 VR surport 选上,选择一个 sdk(建议 Google cardboard),然后 build 就可以了。不出意外的话生成了一个 apk 文件,安装到你的大手机上就可以看到效果了。这时你会发现和想象中不太一样,顶部和底部的形变比较严重,产生这样的原因是因为 Unity 自带的球体模型比较粗糙,这时候你可以在 3dsmax 中自己建一个球,把分段设大一点,建好后还可以将球的法线翻转下,翻转后就可以不用那个 DoubleShader 了。
好了,一个简单而不简约的 VR 图片观察器就完成了,欲知后事如何,且听下回 BB!
来源: http://www.cnblogs.com/Yixin-ran/p/UnityVR.html