Android OpenGLES2.0(十七)——球形天空盒VR效果实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android OpenGLES2.0(十七)——球形天空盒VR效果实现相关的知识,希望对你有一定的参考价值。

参考技术A 在3D游戏中通常都会用到天空盒,在3D引擎中也一般会存在天空盒组件,让开发者可以直接使用。那么天空盒是什么?天空盒又是如何实现的呢?本篇博客主要介绍如何在android中利用OpenGLES绘制一个天空盒,并实现VR效果。

虽然大多数人知道这些东西是啥,但是我觉得我还是有必要把他们的定义“搬”过来,万一有人不知道呢。

天空盒的实现应该是最简单的,但是效果可能会有些瑕疵,尤其是顶着两面的交点处总能看出点不同。天空穹和天空球效果都差不多,会比天空盒好上很多,但是相对天空盒来说,比较耗性能。

在之前的博客中Android OpenGLES2.0(六)——构建圆锥、圆柱和球体有介绍如何绘制一个球,只不过之前的球是没有贴图的,现在我们绘制一个球,并为它贴上环境的贴图。就像绘制一个地球仪一样。

首先,首先我们需要得到球的顶点坐标和纹理坐标:

相应的顶点着色器和片元着色器分别为:

准备好了顶点坐标、纹理坐标和着色器,从顶点着色器中可以看出,我们还需要几个变换矩阵,变换矩阵求取:

这样,万事俱备,我们就可以编译glprogram,并进行球体的渲染了:

其中纹理图片如下:

渲染的结果如下:

绘制出球体之后,我们需要让球与手机的姿态进行同步,也就是当手机背面超下时,我们看到的应该是地面,手机背面朝上是,我们看到的应该是天空。很明显,这就需要用到手机中的传感器了。

Android中的传感器定义如下:

虽然在API中定义了这么多的传感器,然后实际上绝大多书手机都不会具备所有的传感器。所以当我们在使用某个传感器时,一定要检测这个传感器是否存在。
根据我们的需求,我们需要获得的是手机的姿态,所以上面的传感器中,我们能使用的方案如下:

我们直接使用旋转矢量传感器来获取手机姿态。传感器的使用相对来说比较简单:

然后再监听器中处理数据就可以了:

利用旋转矢量传感器我们很方便的获得了一个旋转矩阵,将这个矩阵传递到顶点着色器我们就可以让球体随着手机的姿态变化而变化了。
修改顶点着色器中顶点的计算为:

然后获取旋转矩阵的句柄并将旋转矩阵传递进来:

这样,球的旋转就和手机姿态同步了

然而我们需要的,并不是这样的结果,仔细想想,天空球模式的话,相机应该是在球的内部,我们看天空看大地,左看右看的时候,应该是人相机在动,而不是球在动。而我们现在看到的却是球自己转动。问题出在哪儿呢?
从 gl_Position=uProjMatrix*uViewMatrix*uRotateMatrix*uModelMatrix*vec4(aPosition,1) ;中可以看到,顶点的坐标计算中,我们是用从传感器获得的旋转矩阵在模型矩阵前,这样我们的旋转操作的就是球体,修改为:

这样,我们操作的就是相机了,得到的渲染结果如下,当摄像头对的方向变话,球在屏幕上的位置也会发生变换,就像我们头转动时,看到的东西在我们眼睛中成像的位置也会发生变化。

完成上述操作,我们里成功就剩下一步之遥了。上面的操作,我们始终在球的外面看球,就如同我们在外太空看地球一样。现在我们需要回到球的内部来看球。在获取矩阵时,我们的视图矩阵求法如下:

根据上面矩阵可以看到,很简单,我们只需要将相机位置改为球的圆心就可以了,当然也可以是球内的其他位置,但是效果上肯定是不如让相机和球心重合。

以上是关于Android OpenGLES2.0(十七)——球形天空盒VR效果实现的主要内容,如果未能解决你的问题,请参考以下文章

Android OpenGLES2.0——了解OpenGLES2.0

OpenglES2.0 for Android:来画个立方体吧

Android OpenGLES2.0(十八)——轻松搞定Blend颜色混合

Android OpenGLES2.0(十八)——轻松搞定Blend颜色混合

OpenglES2.0 for Android:各种变换来一波

Android OpenGLES2.0——纹理贴图之显示图片