VR项目开发过程中的梳理总结
做VR项目已经有一段时间了,做一下梳理总结
引擎选用UE4,硬件选用Oculus,UE4对Oculus有现成的支持,在editor里就可连接Oculus预览VR效果:
VR原理
大脑使用两眼看到的图像差异来感知视觉深度(不信你用单眼看世界和双眼看到的做个对比)。具体到游戏制作中,就是架设两台相机模拟左右两只眼睛,分别渲染出左右两幅图像。
分辨率
Oculus分辨率为1080P,单眼960 * 1080;song 的project morpheus为1080P;HTC vive的为单眼1200 * 1080;三星的Gear VR为1440P。
仅从参数来讲,四个设备可以说处于同一层次,差距不大。反正都能看出像素颗粒感。
直觉来讲,这样的分辨率好像是够了。但由于眼睛离屏幕太近,而且通过透镜的广角放大(为了更大的FOV),与常规设备相比相同分辨率下颗粒感肯定更强。
而且对于Oculus来讲,其采用的OLED屏的子像素排列方式为PenTile(常说的P屏),而非RGB。
可以说是用低分辨率模拟高分辨率,有点upscale的意思,效果自然要打折扣。
变形复原
上面也说了,为了更大的FOV看到更宽的画面,所有的VR设备都加了透镜,如上图。
中间还好,边缘变形厉害。这种Optical Distortion效果只能通过后期效果来补偿。
Oculus SDK里已经把这种矫正做过了,而且特地强调:使用默认的变形Shader,如果自己做,即便看上去正确也很可能会引起不适。
不过如果自己做渲染,例如为依附于Google Cardboard的各类国产眼镜平台开发内容等,应该特别注意优化这一点。
延迟
延迟为使用者头部移动到新图像显示的时间差(运动到显示),还包括传感器反映、传感器数据融合、渲染、图形传送、显示器刷新的时间总和。
延迟最小化是产生沉浸感并且保持舒适的关键所在,Oculus认定引人入胜的延迟阀值为20ms,当然越小越好。
解决这个问题有两种方法:第一,尽可能降低延迟;
第二真正渲染的时候不使用传入的参数而是预测相机位置来弥补从传感器读数到最后图形显示的延迟时间差。
第一种方式受限于硬件太难,oculus采用的是第二种方法,称作TimeWrap技术。
简单来讲,就是利用depth buffer反向计算出世界空间位置,再根据传感器读数进行“世界空间旋转偏移”来抵消Present GPU的时间。具体原理点击此处,这也是Oculus的核心竞争力之一。
效率优化
Oculus要求帧率至少在75以上且要保持足够稳定。想像一下这么大分辨率加上左右两眼各渲染一遍(不仅仅是double drawcalls),相对于传统游戏来讲,优化压力真是山大!
本以为现有硬件已经足够强大,但VR的出现让人感觉让硬件水平一下子回到了5年前。下图是Oculus消费版CV1的推荐配置:
UE4的PPT里提过一次draw传入两个视口(view matrix),不过要对最底层渲染管线做出修改,难度颇大;
好消息是Nvidia和AMD也看到了VR的巨大潜力,正尝试双卡各画一个视口,相信以后PC机能不再是问题了。
(之前写过一篇关于UE4的优化工具:UE4内置的性能调试方法和工具)
用户界面
VR中界面最好做成3D世界的一部分,不要像传统游戏一样悬浮在平面中。
一方面是这样做更加逼真,另外很重要的原因就是防止用户在hud和远处画面之间切换视觉焦点造成眼睛疲劳和不适。
我们最终的解决方案是用3D模型替代传统HUD,这里面分为两种:
·
o 功能性的HUD(如血条、进度条)。首先利用传统制作UI的方法借助UE4的UMG系统做出UI,然后借助RenderTarget的方式往模型上贴。
o 纯表现型的UI就和传统制作模型无异了。因为hud有Touch(hower)、Click等状态,所以要有材质变化或者动画表现。这里面最需要注意的就是理出制作规范!
考虑到弧面HUD很常用并且完全可以程序化自动生成,所以专门针对UE写了一个可参数化生成弧面的Component;
UE4只支持把UMG 界面渲染到一个Quad上面,后面自己又扩展到能够支持美术提供的任意Mesh以及上面提到的程序化生成的弧面。
交互
同样不同于传统游戏,用户带上VR眼睛之后直面虚拟世界,因此现实世界中的鼠标键盘等需要精准操作的传统输入方式统统歇菜。
Oculus消费版以后会提供Oculus Touch,左右手各一个,不过现在拿不到,据说手感很不错。
索尼的Project Morpheus有PS Move,问题不大
HTC和value合作的Vive也有双手控制器,类似Wii Nunchuck的感觉,不确定是否是最终方案。
移动平台:
·
o 三星的Gear VR在头盔上有几个按钮不过相当鸡肋;
o 国内暴风魔镜能忽悠起来,相信其配套的蓝牙遥控器加分不少,体验下来虽没有位置定位,但也能做很多事。
体验过其他游戏,也发现一些其他的控制方式,比如《神经元》中的头部瞄准:眼睛盯着看2秒来触发设计。
具体到我们项目:
o 尝试过Leap Motion,不过要把手限制于设备上方,不够实用
o 正在尝试razer hydra。有位置追踪和很多按键,继续优化体验中。
o 主打Kinect操作。
关于Kinect操作
这种方式最大的优点是非常自然,最有代入感。游戏中利用Kinect捕获的depth buffer,用点云的方式渲染出自己的虚拟形象,科技感十足。
不过精度不理想,能识别的手势有限;自定义的各种手势之间也会有误操作等,需要各种边界条件来过滤掉。
举例来说,握拳选中控件(控件由近及远有层次分布的概念),选中之后可以:单手左右移动,拽着控件在当前层次上左右移动;单手前后移动,推拉控件切换层次。
里面的误操作有两个:
·
o 握拳一瞬间手的位置会抖,然后控件位置跟着抖动了。这需要加一个握拳有效判定时间来把这个抖动过滤掉。
o 左右和前后本身有冲突:左右移动时会夹带着前后小幅度移动,反过来一样。这就需要根据位移速度筛选出有效运动状态。
类似的条件过滤有很多。需要不断体验,一步步去迭代优化。
其他
o 对于Oculus Touch、razer hydra这类有位置追踪的控制器,估计很多场合下要做手臂IK
o billboard型的面片特效在3D效果下极易穿帮,因此需要制作volume effect,如下图
图来自于unreal著名VR demo: Showdown
o 同样2D屏幕下效果很好的normal map在3D效果下立体感大打折扣,换成复杂点的parallax mapping效果会好很多。
(用normal map虽然两眼的光照计算会根据相机矩阵不同结果不同,但毕竟对于左右眼来说normal一样,凹凸程度一样;
加了bump offset的parallax map因为有UV偏移的存在,导致双眼取得的normal不一样,最终结果差异大,立体感很强)
总结
整体来看,VR游戏相对传统游戏差异没想象中那么大。
VR相关的特定三大块:渲染出左右两幅图像、头部(相机)追踪、变形复原,
常用引擎如UE4、Unity等都有封装,不需要太费心。即便不用通用引擎,再往下走别忘了还有平台提供的SDK。
特别需要操心的是效率优化、玩法以及交互方式。
当前,国内外VR硬件平台如雨后春笋般纷纷冒了出来,本次ChinaJoy上VR的火爆场面也让人浮想联翩。
趋势已经起来了,我们需要做的就是做好积累、守在风口,等待飞起的那一刻!