鹅厂分享会 | 腾讯视频中的VR带你跨越现实的屏障

导语 | 虚拟现实(virtual reality,vr)技术在过去的几年中从狂热逐渐的趋于冷静,随着技术的发展与积累,越来越多的vr应用出现在人们的视野里,随着王菲演唱会的顺利结束,腾讯视频在移动端也支持了vr视频的播放,本文主要探讨虚拟现实在视频渲染中的解决方案,以及有关虚拟现实视频的未来走向。
vitrual reality was once the dream of science fiction. but the internet was also once a dream, and so were computers and smartphones. the future is coming.-mark zuckerbeg
回顾2016,虚拟现实技术与深度学习技术占据了科技界的各种头条,随着tensorflow,mxnet,openai等深度学习平台的完善以及公开,alphago与master的不断胜利,人们在不断地提升着计算机的思考能力,融入到我们生活的各个角落里,而虚拟现实技术,则是让人们能够沉浸在计算机运算所产生的虚拟世界里,正如美剧西部世界中描述的一样,我们在不断的推进人与机器的距离。
0x01.什么是虚拟现实
虚拟现实(virtual reality)并不是一个全新的概念,在上个世纪五十年代,stanley g. weinbaum就在他的小说《pygmalion's spectacles》详细的描述了包括嗅觉、触觉和全息护目镜为基础的虚拟现实系统。
图1.各种虚拟现实设备从根本上来说,vr是利用外部设备模拟产生一个虚拟的具有三维空间的世界,让使用者有着身临其境的感觉。这里的外部设备既包括了计算机本身,也包括了为了增强沉浸感所使用的各类传感器,例如眼镜,手套等设备。
在技术角度来看,虚拟现实技术就是人机交互的最后一道屏障,在计算机发明之初,我们利用打孔的方式与计算机进行交流,到现在我们可以灵活的用鼠标,键盘,耳机,或者手指去控制计算机,而在虚拟现实的世界里,这些交流的屏障,将不复存在,我们可以用语言,肢体动作,甚至一个眼神就可以实现与计算机的交流。
虚拟现实技术具有着一下三个特征”immersion-interaction-imagination”(沉浸-交互-构想),这些特征都是围绕着用户去考虑的,将用户从鼠标键盘耳机屏幕中解放出来,彻底的激发想象力,跨越人机交互的屏障。
0x02.嗅觉敏锐的游戏厂商
限制人们想象力的永远是硬件的不足,虚拟现实也受到硬件的限制一致无法取得大的突破,从video game到pc game,游戏永远是人类的天性,精明的游戏厂商们发现,虚拟现实技术的应用对于传统的需要键盘鼠标键盘来操控的游戏会有着巨大的颠覆,尽管硬件的发展还远远满足不了vr所需要的计算能力,在90年代,sega就已经发行了可以追踪并反应的用户头部运动的街机游戏,并且虚拟现实技术也在军事领域有着广泛的应用,例如跳伞,军事模拟训练等,但那个时候虚拟现实技术并没有激起多大的浪花,但这个种子随着硬件计算能力的发展,逐渐发展壮大,2007年谷歌推出全景街景地图,人们可通过浏览器便可以近距离的感受千里之外的真实世界,但全景图片仍然是某种意义上的对硬件的妥协,随着oculus的创办,次世代游戏技术的发展,vr技术得以真正的出现在了人们的视野里,并且游戏平台steam上已经上架了大量的具备可玩性的vr游戏,在戴上设备的那一瞬间,相信大多数人们都会被眼前的场景所惊叹。图2.oculus vr设备
0x03.戴着镣铐起舞-移动端中的vr渲染技术
不愿被束缚,是我们的天性,为了获得更好的沉浸体验,各种各样的传感器将人与主机进行连接,这也导致了用户的活动空间是非常有限的,并不能随心所欲的移动。而移动端设备则挣脱了这些束缚,使人们可以随时随地的使用vr设备,但不可否认的是,虽然移动端的计算能力日益强大,但面对场景十分复杂的虚拟现实渲染仍然捉襟见肘。尽管如此,各大厂商们仍然发布了移动端的vr设备以及开发组件:
移动端的虚拟现实设备一般分为两类,一类仅仅提供一组镜片,或者是简单的控制传感器,将计算任务交至手机,例如cardboard设备,这应当是目前离消费者最近的vr设备了,另一类则是将其进行整合,提供vr专用的一体机。
在移动端,随着网络质量的提高,看视频逐渐成为人们消磨空闲的方式之一,虚拟现实视频也是一个非常重要的分支,3d电影早已被人们所接受,而虚拟现实视频则在3d的基础上,更近一步的提升了用户沉浸体验,相对于vr游戏需要各种实时复杂的场景建模,虚拟现实视频则在视频制作时就以完成,vr设备仅需要对视频进行解码,并将其正确的渲染至对应的显示设备上。目前移动端的虚拟现实频按照观看方式的不同,可以分为两类360全景视频,以及双目立体视频。本文将会分析这两种模式的区别,以及腾讯视频的解决方案:从技术上来说,vr视频渲染与游戏渲染并无差异,因此很多游戏引擎都提供了vr渲染的支持,例如unity,unreal等游戏引擎,并且google也提供了相应的开发插件,但是在很多场景下,我们不希望引入繁重的游戏引擎,希望能够简单轻量的实现虚拟现实视频的渲染,在腾讯视频中,我们主要使用opengl实现虚拟现实视频的渲染,减少第三方的依赖,以获得更好的适配性。
腾讯视频vr sdk拥有产品特性多平台支持,支持ios,android端的全景视频的播放机型兼容性强:结合腾讯视频播放器sdk的使用,支持硬解码以及软解码模式,适配性强具备lens-distortation(镜头矫正)模式,为佩戴vr眼镜的用户提供更好的观看体验轻量快速,纯opengl调用,无需第三方组件即可轻松实现vr视频播放可交互性,简单可控头部追踪以及触摸模式。
360度全景视频:1)普通视频与全景视频的移动端渲染方案对比:android端的视频渲染:
图3.普通视频的渲染流程
android端视频的渲染的模式如图3所示,视频的解码一般可以分为硬解码模式与软解码两种渲染流程,在硬解码的模式的渲染中,通过将surface设置给播放器使用gpu接管视频的解码以及渲染播放。如图3中蓝色标记的序号所示;而软解码则需要播放器输出yuv的数据,交由opengl渲染至texture,最终显示到终端屏幕上,一般情况下,硬解码需要硬件厂商的支持,不同硬件厂商在实现上可能有着差别,而软解码模式则相对比较可控,但占用了cpu的计算资源。
全景360视频全景视频在拍摄时,利用多个摄像头对周围环境的影像进行捕捉,并采用图像拼接技术将多张图片拼接成一幅全景图像,在显示时,则与捕捉的过程相反,通过前端设备采集运动数据,依据计算出的可视角度,实时的更新显示数据,最大限度的还原拍摄的现场。
全景视频通过提供任意的观看视角以达到沉浸式的观看体验。在视频渲染时,我们将视频帧映射与球形渲染体进行映射以达到全景视角的目的,通过将用户的观看视角置于球体的中央以还原原始的拍摄场景。全景视频的采集以及播放渲染的整体流程如下图所示:图4.全景视频的采集与渲染流程
全景视频数据的获取在全景视频渲染播放中,渲染数据是必不可少的,在现有的技术框架下,全景视频与普通视频在文件的格式以及存储上是一致的,换言之,采用普通视频的播放以及渲染方式对于全景视频是完全可行的,当然,用户看到是整幅没有经过处理过的图像(如上图中的全景图片),所谓全景感也并不存在了。因此,为了达到全景渲染的目的,在解码端我们可以采用普通视频的解码方式,但由于全景视频的渲染的特殊性,解码后的数据需要进一步处理后,再驱动opengl进行渲染,从而达到“全景”的目的,因此全景视频的播放经历了解码,渲染数据获取与处理,opengl渲染这三个环节。下面我们将分别阐述android端与ios端的数据获取方式。
android端的渲染数据获取在上个小节中,我们简要介绍了android端的两种播放渲染思路:gpu等专用芯片主导的硬件解码以及cpu主导的软件解码,在全景视频的渲染中,针对以上两种不同的模式也有着不同的处理思路:
硬解码:在普通视频的播放中,正如图3中的流程所示,需要应用层做的工作主要包含了初始化一个与opengl相关的surfaceview以及对应的回四平播放地址,便可以实现播放功能,但对于全景视频来说,android系统并没有直接支持全景模式的播放,因此我们需要另辟蹊径,在采用硬解码模式时截获播放器的渲染数据,从而进行全景模式的渲染。获取数据时主要利用了surfacetexture中的updateteximage方法:
void updateteximage ()update the texture image to the most recent frame from the image stream. this may only be called while the opengl es context that owns the texture is current on the calling thread. it will implicitly bind its texture to the gl_texture_external_oes texture target.
通过调用updateteximage方法,我们可以将解码后的数据绑定至opengl的texture中,从而可以使用opengl自定义渲染。具体的使用方法如下(省略了一些无关的代码)
图5.使用surfacetexure获取解码数据
在实现中,我们利用onframeavailable接口回调通知opengl更新texture,但在实际的应用中,这个接口有时不能及时的回调刷新,因此我们采用了保持一个固定的频率去主动更新texture,而onframeavailable这个接口仅起到了辅助通知的作用。
软解码:在软解码的模式下,我们可以直接的获取到视频帧的yuv数据,因此可以直接去驱动opengl进行渲染,与硬解码使用texture进行渲染不同,软解码直接使用yuv数据进行渲染(相当于渲染一帧bitmap),因此两者对应的fragmentshader也有所区别。
ios端解决方案ios中获取数据的方式比较简单,主要通过avplayeritemvideooutput中的copypixelbufferfromitemtime这个接口获取播放器解码后的视频帧数据再进行opengl渲染,与andorid端的软解码模式比较相似,但这里在数据处理上主要需要注意一下几点:
长时间获取不到pixelbuffer时需要重新初始化output防止黑屏pixelbuffer中的数据格式在初始化时需要配置,在渲染时需要注意yuv的数据格式全景视频的渲染可能会使得上层ui卡顿,因此需要异步的渲染保证ui的流畅性。
沉浸式体验:360度全景视频给予了用户更高的自由度以及与视频内容进行交互便利,极大丰富了观看体验,但离上文所述的虚拟现实情景依然有着不小的距离,而沉浸式的观看体验可以更快速的带领用户进入虚拟现实世界的是,但相应的用户需要佩戴vr眼镜(例如cardboard眼镜)将视频分为左眼与右眼两个显示区域以配合虚拟现实的要求,vr眼镜中一般包含了两组镜片,通过镜片增大用户的可视区域(field of view,fov),增强虚拟现实感,但同时也带来了图像畸变的代价。在双目的vr视频中,其中单个眼睛的显示区域与360全景视频并无差异,因此一个最简单的想法是将原先的全景视频简单的复制一份,将屏幕分为两个相同的区域,对两个区域执行相同的渲染即可。利用opengl中的glscissor功能可以将glviewport分割为不同的渲染区域,用于执行不同的渲染指令,具体的渲染流程如下:
图6.多窗口的实现
更真实的双目视频:由于vr眼镜中镜片的使用,导致用户眼中的成像会发生枕型畸变(pincushion distortion),如图7所示
图7.枕型畸变与桶形畸变
若在视频渲染中不对视频帧预处理,用户所观察到的图像将由于物理镜头的原因产生形变,进而影响vr视频的观看体验。因此,为了减少镜头畸变产生的不良影响,我们在对视频帧渲染前,使用反畸变(anti-distortation)技术对视频帧进行预处理,反向抵消镜头的物理枕形畸变带来的影响,其可视化的效果如下图中a所示,图中b则是没有增加数字反畸变后的效果。
图8.反畸变示意图
反畸变技术在图像处理领域,反畸变算法有着成熟的研究以及应用体系,其相关的数学计算公式也非常明确,但在具体的应用实现中,有着不同的实现方法,并且其运行效率也有着显著的差别:
fragment based solution:算法对整幅视频帧的数据利用opengl中的shader对每个像素进行反畸变处理,即类似于图像处理的原理,这种方式在实现上较为简单,但是由于在每次渲染前需要对整幅图像进行处理,将会严重的影响渲染的效率,用户可能会明显的感受到滞后与卡顿感。
mesh based solution(我们使用的方式):这种算法通过使用额外的一个texture作为渲染的中间层,存储渲染数据,并通过已经计算好固定的mesh面对中间数据进行反畸变处理,例如当我们需要渲染一帧大小为1920*1080大小的视频帧时,采用第一种方法每帧将要处理百万级别的顶点数量,而采用mesh based的方法,若我们将mesh定为10*10大小,则处理的顶点将由上百万降至一百,并且大多数vr视频的分辨率远远不止1080p,因此使用临时的中间存储所带来的收益大于其相应的技术代价,因此在腾讯视频的vr模块中采用了这种技术
vertex displacement based solution:这种方式是目前最有效也是最简便的一种方式,利用了geometry vertex displace方法,直接利用vertexshader进行反畸变处理,但遗憾的是opengles对这种支持并不完善,因此不是本文的讨论重点。图9.腾讯视频中全景渲染mesh面图10.反畸变后的全景渲染mesh面
图11使用反畸变后的视频变换
虚拟现实中的矩阵变换:头部运动追踪全景渲染以及双目渲染技术已经在视觉效果上达到了虚拟现实的标准,但仍然需配合头部追踪技术以定位用户的空间位置,已达到实时显示的目的。
移动端的头部追踪技术在硬件上主要传感器实现,手机类的虚拟�...