使用OVR_multiview优化VR渲染器

在最新发布的一篇文章中,我曾提到维护虚拟现实系统“真实感”的重要性。而高帧率(60、90或120 Hz,取决于头戴式显示器(HMD)的最大刷新率)的渲染应用程序与光子运动低延迟是实现“真实感”的重要部分

在本文中,我将阐述如何使用OVR_multiview扩展减少渲染VR应用程序所需的CPU和GPU功耗。

不使用OVR_multiview的渲染

1

在标准的优化VR应用程序中,场景将在帧缓冲区对象(FBO)中进行两次渲染——一次渲染左眼图像,另一次渲染右眼图像。要进行渲染,应用程序需进行以下操作:

•Left eye 左眼图像
在FBO左边部分设置视口
使用左眼的摄像机投影矩阵在场景中绘制所有对象

•Right eye 右眼图像
在FBO右边部分设置视口
使用右眼的摄像机投影矩阵在场景中绘制所有对象

渲染每个矩阵的场景时,由于HMD透镜,FBO对象会由桶形失真修正至枕形失真。

2

在这个方案中,应用程序必须提交两个几乎相同的GL call数据流,而两次渲染唯一的区别是应用到顶点时要进行矩阵转换。每矩阵都需提交调用实则浪费时间。同时,GPU驱动程序也需要花费时间来验证API调用并且每矩阵均生成GPU命令缓冲区,而一个简单的共享命令缓冲区便可以完成这些工作。

OVR_multiview

有了OVR_multiview扩展(及分层的OVR_multiview2OVR_multiview_multisampled_render_to_texture扩展),应用程序可以绑定一个结构数组至FBO,并对每个元素进行实例绘制。这样,图像驱动程序便会准备一个GPU命令缓冲区,并在每次实例渲染时重新启用该缓冲区。当扩展程序处于激活状态时,则可以在顶点着色器中访问gl_ViewID_OVR内置来确定需要渲染的元素。

由于是基于拼贴的GPU架构,每实例中必须进行拼贴。拼贴过程完成后便执行每元素的像素渲染任务。

OVR_multiview:优化绘图提交过程

3

使用OVR_multiview一个较为简单的例子是创建一个结构数组,该数组由两个分别代表左眼图像和右眼图像的元素组成。对于每一帧,应用程序可以通过以下步骤完成渲染:

•绑定FBO(附上结构数组)
•将变换矩阵数组统一传输至着色器中
数组包含两个元素——两个变换矩阵分别用于左眼图像和右眼图像
•在场景中绘制对象
•在顶点着色程序执行时,使用gl_ViewID_OVR确定哪些矩阵用于转换

通过这个简单的转换,应用程序可以减少一半需要提交给驱动的OpenGL调用。

OVR_multiview:减少片段处理

用于拓宽用户视野的透镜是沉浸式VR系统的重要组成部分。为解决透镜引起的枕形失真,必须在图形显示之前应用桶形失真。

不过,现代GPU设计的初衷并不仅是渲染桶失真图像。VR应用程序必须在第一层时渲染非失真图像,然后在第二层进行桶形失真。但这样,第一层渲染便过多消耗了GPU周期及带宽的纹素色素,而可供桶形图像外部区域使用的则非常少,在第二层渲染中桶形图像外部区域的纹素和像素密度则非常高。

4

如上图中所示,可以使用OVR_multiview将渲染细分为可以更好地表示桶形图像像素密度的区域。实现该方法一个简单的例子是,每矩阵在桶形图像中间渲染一个高分辨率且窄视野的图像,在桶形图像外部区域渲染一个分辨率较低且宽视野的图像。桶形失真传输期间,片段着色器可以在桶形图像内基于像素坐标将高分辨率和低分辨率图像混合在一起。

在视野狭窄的渲染中,全分辨率图像占整个场景的25%,而宽视野渲染的分辨率则为一半(全分辨率的25%),GPU只需要对全分辨率渲染一半的像素进行着色——极大减少了片段着色器的计算量和相关带宽。当然,具体的节省量取决于没有伪影的情况下视野到底有多窄。

总结

通过OVR_multiview扩展及对一些简单的应用程序进行更改,VR应用程序便可以更有效地将处理任务传输至图像驱动器,并通过减少所需渲染的像素从而降低GPU的功耗。想了解更多Imagination如何优化VR渲染的资讯,我强烈推荐克里斯汀·波茨赫所写的有关使用带渲染减少异步时间弯曲延迟的文章

原文链接:
https://imgtec.com/blog/optimizing-vr-renderers-with-ovr_multiview/

声明:
本文为原创文章,转载需注明作者、出处及原文链接,否则,本网站将保留追究其法律责任的权利

--电子创新网--
粤ICP备12070055号