时间:2024-05-04
马万峰,黎娅娟
(四川大学计算机学院,成都 610065)
随着图形学理论的进展和显卡计算能力的提升,使得实时虚拟现实(VR)和增强现实(AR)应用在PC端乃至移动端实现成为可能,尤其是发展到现在AR应用已经被广泛应用于交互游戏和手机自拍中。对于AR应用需要解决两个关键的问题,物理一致性和光照一致性,同时对于透明物体的渲染,还需要考虑融合问题[1]。目前来说很多大的公司都在发力AR,例如谷歌已经正式发布了ARCore,ARKit已经跟新到了2.0版本,已经有超过千万的安装数量。同时,包括三星、小米、华为也在各自手机上开展AR体验,微信、支付宝等也有AR摄影。
目前功能性AR主要集中在各种短视频、特效相机、虚拟全景旅游,用户目前更多的是体验AR所带来的那种新鲜感[2]。2015年左右,AR图书或者AR识图卡[3]特别火,一度带动了图书行业的小高潮,AR+教育成为当时特别火热的话题。通过AR技术,将纸质图文知识以生动酷炫的3D场景/模型呈现,带来全新的阅读体验。AR家居,也是非常典型的应用场景,尤其是结合AR空间深度感知技术,真正为用户解决家居摆放、购买等需求。
国内外互联网巨头目前仍然还在持续不断地对AR进行投入,目前市面上越来越多的产品,我们都能看到在产品上面集成了AR功能。
但是与此同时也带来了一个非常严重的问题,AR渲染不仅仅包括物理场景的探测,还包括周围光照环境的实时探测,特别是当AR与透明物体结合在一起时将会带来更多的挑战。包括预计算和在光照计算上做出一些妥协[5],以及改进渲染算法是一件非常重要的事情,尤其是在目前更多的AR体验来源于移动端,但是移动端GPU和CPU通常计算能力还是不够,如何能够减轻渲染时对硬件带来的负担是一个越来越重要的课题,本文将会聚焦光照一致性算法效率提升和与透明物体渲染结合,能够更好地用于移动端。
本文提出了一种方法,能够将应用于非透明物体的Cook-Torrance光照模型进行改进,利用纹理偏移方法与透明物体背后的场景进行偏移混合,同时利用多种方式改进渲染效率,最终在可接受的渲染时间内实时渲染出了透明眼镜并能够与头部模型混合,随着头部的转动而进行对应的运动,用于自拍体验中。
本文提出的方法,首先通过解析视频或者实时相机拍摄得到的每一帧的含有人头部的图片,通过图像解析算法得到对应的虚拟头部模型的变换矩阵,包括平移、旋转矩阵,每次人的头部发生任何改变,将会对M(Model)、V(View)、P(Projection)矩阵产生影响,并反馈得到。
接下来对眼镜进行渲染,眼睛的光照渲染包括Diffuse光照,Specular光照,透过眼镜之后的折射光照,前面两种光照可以通过IBL(Image Based Lighting)部分进行处理,折射光照可以通过纹理偏移直接对基础人像纹理进行采样并与前面的光照进行混合。然后,再通过对头部模型作用MVP矩阵,从而让头部模型与拍摄或者解析视频得到的真实头部保持一致。
在光照渲染结束之后,需要进行深度一致性的判断,先绘制头部模型,再绘制虚拟眼镜模型。头部模型绘制之后打开深度测试,保证在头部模型外边的眼睛部分片段能够得到显示。
最终,再进行了深度一致性检测和光照一致性渲染之后,得到了最终的AR渲染结果。
另外本算法还对IBL渲染算法中包括切线空间,重要性采样进行了改进,提升了渲染效率。
本节内容主要介绍AR眼镜渲染的IBL算法部分和透明混合部分实现细节。IBL算法部分采用Cook-Torrance BRDF光照模型,但是这种光照模式主要是用来渲染不透明的物体表面的Diffuse光照和Specular光照,并不涉及到透明物体渲染过程中折射光线的问题。本文通过结合IBL算法和纹理偏移算法将两者结合起来,IBL仍然用来实现Diffuse光照和Specular光照,透明物体的后面的折射光照通过光线在顶点法线,折射率,折射放缩因子等共同作用下得到。从而能够得到虚拟眼镜的光照效果。
本文采用的Cook-Torrance BRDF光照模型主要基于三个原理:基于微平面表面模型、能量守恒、应用基于物理的BRDF。用金属度,粗糙度这两个参数来对模型材质进行控制。
所有的PBR技术都是基于微平面理论,任何材质在达到微观尺度下都是由一个个平坦的镜面构成,这样可以用粗糙度来描述这些镜面分布的朝向一致性的概率[6]。对于一束平行入射光线,粗糙度越高,将会产生分布范围更广泛,但是更加暗淡的镜面反射,这是由于能量守恒定律的限制。
另外对于金属材质而言是没有Diffuse光照的,对于铁锈等材质,金属度将会为介于0到1的某个值,用来更好地表现材质的特性。
IBL技术不是通过直接分析光照,而是把周围整个环境作为一个大的光源来照亮物体,可以用一个HDR(High Dynamic Range)天空盒来捕获真实场景光照,并且把天空盒上面的每个像素作为一个光源。用这种方式来对放入其中的虚拟物体进行渲染将会让虚拟物体在光照上与场景有更好的融合感。
解决光照渲染问题最主要的是要解决Cook-Torrance反射率方程的实时积分问题。对此可以将其分为Diffuse光照部分和Specular光照部分分别进行预处理计算[7]来提升渲染的效率,并在最后进行光照的合成。主要目标是解决在所有的分布在法线方向半球入射光线Wi积分。我们需要能够在给定入射光线方向就能够检索环境的辐照度,这个可以根据Cubemap采样进行获取。
(1)IBL中Specular光照
如果把位置p永远当作是环境贴图的中心,那么Diffuse光照积分仅仅依赖于Wi。所以我们就能够预计算一个新的Cubemap存储每个采样方向Wo的Diffuse光照积分结果。
为了计算所有的光线对顶点的影响,需要沿着法线向量方向构造半球,在半球中的所有光线将会对顶点光照产生影响。如图1所示。
图1 半球积分
由于直接对Wi进行积分非常困难,可以将其转换为球面坐标并在上面进行积分,另外由于在越靠近半球下方单位相同角度划分时将会有更大的面积,需要在结果上乘以权重sin(theta)。
图2 计算积分时转化为球面坐标进行计算
输入一张Cubemap环境贴图进行IBL中Diffuse光照计算之后将会得到一张模糊化的Irradiance Cubemap。可以直接根据顶点的法线方向采样Irradiance Cubemap得到最终的Diffuse光照。
图3 环境贴图进行Diffuse光照部分积分后效果图
(2)IBL中Specular光照
Cook-Torrance的Specular光照部分在积分部分上不是常量,积分结果不仅取决于光照入射方向还取决于视线方向。在每所有的入射光线方向,并且包括所有可能的观察实现方向的积分代价过于昂贵不能实时计算出来。本文使用split-sumapproximation方法来解决这个问题。
第一部分叫做pre-filtered environment map,把粗糙度考虑在内,是一个含有不同mipmap等级的Cubemap,当粗糙度越大时,反射现象越模糊[8]。
并且由于我们在做预计算时此时并不知道观察方向,我们可以做进一步妥协,假定观察方向,也就是Specular反射方向总是等于顶点法线方向,用这种方式来去多的观察方向,同时和前面计算Diffuse光照的时候一样,也假定物体的位置均是在Cubemap的中心位置。这样就能直接预计算出含有mipmap等级的Specular光照第一部分。粗糙度等级越高,生成的pre-filtered environment纹理越模糊。
图4 环境贴图进行Specular第一部分光照积分后效果
第二部分是Specualar光照的BRDF积分部分。如果我们假定入射的光线在每个方向是完全的白色,我们就能根据给定的粗糙度和由法线和入射光线构成的角度计算出对应的BRDF积分值[9]。这是一张二维的与输入的环境贴图的无关的纹理。用采样得到的值分别对基础反射率F0进行放缩和偏置,就能够得到最终的材质反射率数值。
图5 BRDF二维图像
对于渲染透明玻璃的材质,折射是光从一种媒介穿到另一种折射率不同的媒介时产生的弯曲现象;
对基本场景生成一副图像,把该图像当作纹理,然后对查找该纹理的坐标进行扰动来模拟折射。
基本步骤:
●第一步是把场景集合渲染到一张纹理上,并忽略折射网格(眼镜模型)。这张纹理可以用来确定哪些物体在折射后方可见的,折射体会在随后渲染,把这张纹理记为S;
●第二步是画折射的网格,用扰动过的纹理坐标从纹理S中查找对应的值来模拟折射效果。这种扰动可以用一个发现图N来完成,用到了法向图的XY通道,用它们乘以一个很小的值作为纹理坐标的偏移量;
●最后用得到的偏移纹理坐标采样场景中的背景图S,就能够得到折射数据。
在渲染眼镜之前,预渲染生成包含Diffuse光照的irradiance贴图,包含Specular光照的prefilter贴图和放缩偏置基础反射率的BRDF二维贴图。同时还需要传入环境贴图已经包含头像的背景贴图。
基本步骤:
●在View空间下进行计算;根据视线方向,法线方向和玻璃材质的折射率分别计算得到反射光线和折射光线;
●在菲涅耳函数中输入法线向量方向,视线方向,基础反射率和粗糙度,便能够得到反射系数,即反射光线占整体反射加Diffuse光照的比率;进而根据求出Specular光照比例为ks=F,Diffuse光照比例为kd=(1-F)*金属度;
●接下来便可得到Diffuse光照为:
vec3 irradiance=texture(irradianceMap,ViewNormal3f).rgb;
vec3 diffuse=irradiance*albedo;
●可得到Specular光照为:
vec3 prefilteredColor=textureLod(prefilterMap,Reflect-View3f,roughness*5).rgb;vec2 brdf=texture(brdfLUT,vec2(max(dot(ViewNormal3f,ViewEyeDirect3f),0.0),roughness)).rg;
vec3 specular=prefilteredColor*(F*brdf.x+brdf.y);
●最终得到IBL部分光照为:vec3 ambient=(kd*diffuse+specular)*ao;
●接下来计算折射光照,需要先通过折射光线方向对纹理xy位置进行偏移,再对包含头像的背景纹理进行采样,就能得到折射的颜色;
tex+=(normalize(RefractView3f).xy*0.12f);
vec3 refractcolor3f=texture(BackColor,tex).rgb;
●进行包含Diffuse光照,Specular光照,折射光照包含一定比例的混合,同时对最终的颜色进行Tonemap色调映射,将其限制为0到1之间。
Vec3 color=ambient*0.5+refractcolor*0.8;
color=vec3(1.0f)-exp(-color.rgb*2.5f);
在渲染眼镜之前,首先需要把得到的每一帧的包含人头部的帧渲染出来,由于需要在折射数据中需要对其采样并混合,需要将其深度设置为1。再渲染头部模型,因为眼睛需要戴在头部模型上面,需要渲染头部模型保留其深度。最后在渲染虚拟眼睛的时候需要执行深度测试,无缝保留在当前视线下所能真正看到的眼镜部分,进入头部模型的眼镜片段由于执行深度测试将会被丢弃掉。
基本步骤:
●绑定帧缓冲,渲染场景的数据将会被渲染到帧缓冲纹理中,以便后续处理。同时开启深度测试,并设置深度测试函数参数为小于等于。
●渲染背景纹理,即解析视频得到的每一帧图像或者拍摄到的视频中每一帧图像。
●设置深度函数参数为小于;渲染头部模型,此时仅仅在shader中渲染深度。在片段着色器中不执行任何内容。
●开始渲染虚拟眼镜,在第一次渲染背景时,背景所在的深度全部设置为1。在接下来渲染头部模型时,由于执行了深度测试,头部模型的深度将会占据屏幕并对其进行赋值。再接下来进行眼镜渲染时,由于原有的头部模型深度已经保存下来,执行深度测试之后,进入头部模型的虚拟眼镜片段将会被丢掉。从而保证眼镜不会出现在人头部里面的情形,保证了在空间深度下的视觉一致性问题。
在这一节中我们将会给出在不同的输入视频,不同的光照环境,不同的角度下,虚拟眼镜戴在头部上的效果。实验环境为 NVIDIA 1060,Win10,VS2013,本文算法的实验输入源为提前准备好的真实环境的全景图,测试的视频。
图6 同一背景在不同头部角度下的渲染结果
图7 不同背景在相似头部角度下的渲染结果
我们所提出的方法,通过将传统的渲染不透明表面物体的Cook-Torrance光照模型与纹理偏移融合起来,IBL光照部分用来作为Diffuse光照和Specular光照,纹理偏移采样到的背景作为折射光照。通过这种方式提供了一种通用折射渲染方式,同时,由于提供的是真实环境的光照环境贴图,并将其用于AR眼镜,将会导致AR眼镜效果看起来更加真实。在实现过程中,做出一些妥协,包括虚拟眼睛的各个顶点位置均位于Cubemap中心,预计算时的视线方向与法线向量保持一致等,使得能够对光照贴图进行预计算,在后期只需要通过方向进行纹理采样并进行混合即可,极大地提高了渲染效率。
在以后的研究中,将会根据相机拍摄的场景得到不完整的环境贴图,并通过诸如最近像素法等恢复出整个场景的其他没有照到的部分,用其进行渲染,做到真正的虚拟眼镜光照效果在不同的环境条件下都能够保持对应的光照正确性。
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!