微信AR技术探索之(2): Q3D精简AR渲染引擎2.0版本

2017 年 9 月 6 日 微信AI 柴晓杰



3D渲染引擎是什么?

渲染引擎就是把设计做好的模型按要求显示到屏幕上。广义上来说,浏览器就是一个多媒体渲染引擎,office excel是一个图表渲染引擎。而3D渲染引擎就是要把3D动画模型显示到屏幕上。大家玩的3D游戏都是需要实时3D渲染引擎(游戏引擎)驱动的。比如王者荣耀就是使用Unity的游戏引擎。所有的游戏引擎都包含渲染引擎、物理引擎、粒子系统等。

                    照片底图 + 动画前景 = AR效果

先说一个3D动画模型怎么呈现到屏幕上吧。

一个3D动画模型包含组成模型的:

·      几何网格mesh(一般是三角面片),用于描述模型的几何外形;


·      骨骼关joint/bone与mesh关,就是蒙皮数据,用于描述哪些几何点跟哪些关节绑定;


·      动画animation,画由多帧组成,每帧记录所有骨骼关joint的transform转移矩阵,vertex绑定到joint上,所以也跟着一起transform(就是旋,平移,放)。这样这个模型就起来了;


·      material,用于描述面片是由什么材料成的,主要描述材料的光学属性,即漫反射系数,面反射系数,色,以及各种贴图等等。所有几何面片只有予了材,才能在灯光的照射下被看


渲染过程,简单来说就是:CPU加载模型文件,通过这些属性得到每一个时刻所有三角面片的物理位置,法线,切线等几何属性,贴图颜色等材质属性,然后交给GPU中的shader并行计算出应该显示在屏幕上每个像素的RGBA颜色值,然后通知显示器。具体过程比较复杂,此处只用几幅图让大家明白大致过程。

不夸张的说,一个3D动画引擎就是一个物理仿真器,要在计算机中模拟相机拍摄动画的物理过程,主要是光影的交互过程。


  动画模型的组成:mesh,joint,animation,material



 渲染的过程类似摄像机拍照过程




                                       openGL 渲染过程


什么要开3D渲染引擎

目前有很多商业与开源的游戏引擎,比如PC级别的虚幻UNREAL,移动端的Unity。但是这些引擎都是专业的游戏引擎,一个动态库.so大小动辄上M,甚至10M级别。而微信安装包的大小增长受限,无法使用这种引擎。所以为了让AR功能进入微信,就必须开发一款轻量级的3D渲染引擎。


AR需要什么样的引擎

AR需要的渲染引擎与游戏引擎有一些区别。渲染引擎的设计指标如下:

--跨平台 ios/android

--轻量级 <1M

--高效率 FPS>30  CPU<15%

--3D模型兼容性好,文件最小化

--支持骨骼动画

--支持动态阴影

--支持多种贴图

--支持选择交互

--方便易用的AR接口

其中CPU占用率是一个比较高的指标,因为AR本身需要占用CPU做物体识别,SLAM定位等运算,所以渲染不能占用太多CPU。

AR使用的3D模型一般是在线加载的,所以对模型的尺寸与加载方式有要求,需要模型尽量小,加载速度尽量快。

同时AR需要虚实交融,所以对渲染质量与实时性要求都比较高,需要实现动态阴影,支持一些次世代模型特性,比如法线贴图,高光贴图,AO贴图等。

AR还需要交互操作,比如旋转查看模型,点击模型特定部位触发动画等,所以需要实现选择机制。

我们怎么做

首先为了跨平台,我们就需要使用与系统无关的第三方图形接口,openGL ES是目前唯一的选择。编程语言选择C++。第一版的引擎以openGL ES2.0为基础。

1 . 尽量多的使用GPU

一般渲染引擎对CPU占用比较多的是Draw Call。CPU准备数据并通知GPU渲染的过程称为一次Draw Call。尽量减少Draw Call的次数可以有效降低CPU占用率。所以在绘制过程中我们根据mesh的material不同进行拆分subMesh。以subMesh为单位统一绘制,将一次渲染的Draw Call次数降低到最低

一般动画中每一帧的关节位姿计算在CPU中完成,此处涉及大量类似的矩阵乘法运算。我们将此部分移动到shader中实现,进一步降低了CPU的消耗。

一般的选择操作是通过ray casting计算射线与面片的空间关系。这部分涉及到大量运算,在交互过程中耗费CPU。我们使用GPU加速这个过程,将不同区域的mesh通过颜色编码进行绘制,然后直接读取渲染后buffer中的颜色值进行选择判断,加速了交互过程,同时降低了CPU消耗。

2.尽量减小模型加载时间


自定义模型文件格式,从面向模型交互到面向渲染。比如FBX文件中描述蒙皮绑骨是以关节joint为中心,以列表描述每个joint对vertex的影响权重。而渲染是以vertex为中心,所以我们构建了以vertex为中心的蒙皮绑骨数据结构。同时为提高效率,限制一个vertex的相关joint数目为8个以内,通过两个vec4的uniform来实现。为了避免大于8个的相关joint出现问题,我们队joint的weight权重进行排序后,截取前8个。渲染过程中要求先渲染不透明材质的物体,然后渲染半透明材质的物体,我们可以直接在模型文件中排好渲染顺序,不用显示时再分析处理。类似的处理还有几处,目的是保证模型文件加载后可以尽量少解析,直接可以渲染。

因为我们的模型一般是通过网络下载,所以模型文件的大小很重要。一个10M的模型文件一般下载也要3秒以上。所以尽量精简模型文件大小对体验非常重要。模型一般分为几个部分,几何数据 + 动画数据 + 材质数据  + 场景数据。

几何数据主要是顶点的position,normal,tangent,UV,以及三角面片的vertex index与material index,此处可以将一些double类型的数据转为float。

动画数据主要是绑骨信息以及frame的transform矩阵信息,此处转为以vertex为中心的绑骨结构,同时4*4的transform 矩阵精简为3 float的四元数类型。

材质数据主要是一些材质属性(漫反射系数,环境光系数,默认颜色等等)以及贴图数据。其中贴图数据一般比较大,一副2048*2048的非压缩贴图一般也会上10M,所以首先我们将贴图进行压缩。一些游戏使用非压缩的贴图,目的是减少贴图频繁解压的消耗,而AR应用一般不存在这个问题。当然,引入图像编码模块会增大渲染引擎体积,但一般APP都包含图像编解码库,所以不会增大最终APP尺寸。最终我们采用PNG格式,且尽量使用PNG8的索引方式。同时,我们支持将镜面反射高光系数压缩为1个字节写入法线贴图的alpha通道,这样可以将法线贴图与高光/镜面反射贴图合并。

场景数据一般包含模型在场景中的位姿,light信息以及camera信息,这部分数据量很少。

此外,为了可以在下载与加载过程中有更好的用户体验,我们考虑将几何数据,动画数据,材质数据分阶段传输。这样可以让用户先看到形状,动画,最后加上材质贴图。

 

3.尽量增加模型兼容性


虽然我们使用自己定义的wx模型文件进行渲染,但我们支持广泛使用的FBX文件交互格式。我们提供了一个工具可以将FBX模型转换为wx模型。FBX模型中的一些信息我们尽量都予以保留,特别是场景相关信息。一般游戏制作都需要将模型导入到场景中,然后设置材质,设置位置,调节灯光等。而AR中隐含了场景,所以我们尽量利用FBX文件中的场景信息。

理论上,模型的面片数目越多越精细,渲染结果越真实。一个由36个三角形拼接形成的圆形肯定没有一个由360个三角形拼接形成的圆形边缘光滑。但是手机端GPU的资源有限,一般要求全屏幕不要超过10W面片。在面数受限的情况下,现在游戏使用的次世代模型都通过多种贴图来提高模型精细度。比如使用漫反射贴图,高光贴图,法线贴图,AO贴图等。可以说,现在各种渲染引擎最大的不同就在材质与贴图的应用上。

经典的phong光照模型如下:最终的颜色=环境光反射+多个光源的漫反射+多个光源的镜面反射。

                               phong光照模型


一个人体次世代模型的效果图与4个贴图(右侧4个贴图分别是,漫反射,镜面反射,法线,AO



一个人体次世代模型的效果图与4个贴图(右侧4个贴图分别是,漫反射,镜面反射,法线,AO



各种贴图的效果(从左到右,从上到下:无贴图,漫反射贴图,加光照,带法线贴图的光照,带法线贴图与漫反射贴图的光照,带光照阴影)

4.选择与交互


4.1选择


AR中涉及到用于对模型的选择与交互,而现有的引擎不支持选择操作。

目前游戏引擎一般选择ray casting的射线检测方式实现,即通过选择的成像平面UV坐标与摄像机参数得到一条通过摄像机光心的射线,然后判断这条射线与所有三角面片的交点,最后通过深度判断得到最前方的选择物体。这种方法需要CPU来解算,在面数较多时效率并不高。

所以我们采用另外一种方法即颜色索引法,将需要区分的不同物体或者物体的不同部分根据mesh的ID赋予不同的颜色值,然后进行一次渲染,最后通过读取选择成像平面UV坐标上的像素颜色值来确定物体mesh的ID。比如,在模型创建过程中根据需要将模型的不同部位分割为不同的mesh,一个人头部与身体,左胳膊的mesh ID分别是1,2,3。对应的颜色可以是(32,0,0,),(64,0,0),(128,0,0)。当我们点击头部时,读取点击像素的颜色为(32,0,0),则我们通过反查ID-颜色对应表可以知道选择的是头部。

当模型是绑骨动画模型时,我们也可以将joint关节的ID与颜色对应,这个可以返回选择的joint关节,然后触发相应的动作。实际上RGB有三个通道可以用于索引,可以分别对应meshID,subMeshID以及boneID/jointID。

这种选择机制的好处是完全由GPU实现,不消耗CPU,而且可以直接返回有意义的mesh与joint的ID,而不是面片索引。

                           ray casting 示意图

 动画模型与非动画模型在选择模式下的渲染错误! 未指定文件名。

4.2交互

现有的引擎支持旋转,缩放,平移交互操作,相当于是一个3D动画模型的浏览器操作。但AR中最重要的是模型要出现在“适合”的地方,而且就像环境中的真实物体一样,不随手机运动而移动。我们利用了手机的IMU信息,得到手机的姿态,然后将手机姿态与虚拟相机姿态绑定实现此效果。同时,利用IMU的重力信息还可以使模型始终“站”在地面上。

实现上用户对模型的操作修改ModelMatrix矩阵,手机姿态调整ViewMatrix矩阵,ProjectMatrix与相机内参一致,最后相乘得的MVP矩阵用于坐标变换。

 

手机上下左右渲染时模型的显示位置与实景物体一致

                              几何变换流程

5.动态阴影


动态阴影是中高端3D游戏引擎的必备功能,但在AR的应用中目前还没有普及。目前市面上的一些AR应用都是使用虚假静态阴影,就是把阴影当做模型一部分进行绘制,而不是实时通过解算得到阴影。动态阴影的实现需要多次渲染,所以GPU消耗稍高,但优化后在手机端还是可以实现的。

关于动态阴影的实现方式网上有很多教程,此处就不详解解释了。只简单描述,就是先在光源位置渲染一次,得到深度图,然后在摄像机位置渲染的时候读取深度图判断是否是阴影区域,然后做相应处理。

              动态阴影示意图(左上角小图是光源位置渲染的深度图)

              阴影效果对比(左:虚假静态阴影,右:动态阴影)

6. AR特殊接口

 AR是将虚拟渲染的动画与实景照片结合,所以也要将摄像机拍摄的画面进行渲染。一般来说,照片最为背景,动画作为前景。就是引擎支持2D图像的渲染。同时摄像机的参数还要与真实手机的内参一致。

其次,有时需要渲染曲面视频,比如在一个瓶子上渲染广告宣传片,此时引擎要支持3D曲面视频的渲染。

更进一步,有时AR要求物体不仅出现在前景,而要部分位于实景后面,比如一个小精灵躲在瓶子后面。此时,还需要将实景模型(预先重建或实时重建)进行预渲染,遮挡部分动画,然后再用实景照片替换渲染的实景。


       在实景照片上渲染


        曲面视频渲染

目前进展

目前Q3D引擎处于内部测试中,我们转换了一批教育,游戏,文物,家居类的模型进行测试。

我们此次将Q3D引擎升级到0.2版本,虽然增加了一些功能,但距离完美的AR渲染引擎还有很长的距离。比如真正做到虚实交融,还有估计环境光的位置与强度,实现虚实的光影一致。后续我们会继续努力。

平面 MARK 下 AR 效果

 

曲面 MARK 下 AR 效果大放送~

 







微信ID:WeChatAI
长按左侧二维码关注



登录查看更多
1

相关内容

增强现实(Augmented Reality,简称 AR),是一种实时地计算摄影机影像的位置及角度并加上相应图像的技术,这种技术的目标是在屏幕上把虚拟世界套在现实世界并进行互动。
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
少标签数据学习,54页ppt
专知会员服务
197+阅读 · 2020年5月22日
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
69+阅读 · 2020年1月17日
【斯坦福&Google】面向机器人的机器学习,63页PPT
专知会员服务
24+阅读 · 2019年11月19日
【干货】谷歌Joshua Gordon 《TensorFlow 2.0讲解》,63页PPT
专知会员服务
27+阅读 · 2019年11月2日
TensorFlow 2.0 学习资源汇总
专知会员服务
66+阅读 · 2019年10月9日
【泡泡点云时空】完美配准:具有平滑密度的3D点云配准
泡泡机器人SLAM
61+阅读 · 2019年5月16日
TensorFlow 2.0新特性之Ragged Tensor
深度学习每日摘要
18+阅读 · 2019年4月5日
极客漫画:增强现实(AR) 2.0 | Linux 中国
Linux中国
3+阅读 · 2019年2月10日
Neural Image Captioning
Arxiv
5+阅读 · 2019年7月2日
Mesh R-CNN
Arxiv
4+阅读 · 2019年6月6日
Arxiv
12+阅读 · 2019年1月24日
Arxiv
10+阅读 · 2018年2月17日
VIP会员
相关VIP内容
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
少标签数据学习,54页ppt
专知会员服务
197+阅读 · 2020年5月22日
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
69+阅读 · 2020年1月17日
【斯坦福&Google】面向机器人的机器学习,63页PPT
专知会员服务
24+阅读 · 2019年11月19日
【干货】谷歌Joshua Gordon 《TensorFlow 2.0讲解》,63页PPT
专知会员服务
27+阅读 · 2019年11月2日
TensorFlow 2.0 学习资源汇总
专知会员服务
66+阅读 · 2019年10月9日
Top
微信扫码咨询专知VIP会员