应很多读者的要求,本文小姐姐将以一个用户的展厅VR场景为例,详细讲解Unity3d的VR开发在美工阶段的模型预处理、UV2拆分、贴图优化、光影烘焙、后处理与特效制作以及最终作品优化的基本方法和流程,其中涉及Build-inRP(Build-inRenderingPipeline-内置渲染管道)、URP(UniversalRenderingPipeline-通用渲染管道)、HDRP(HighDefinitionRenderingPipeline-高清渲染管道)和PBR(PhysicallyBasedRendering-基于物理渲染)材质的应用,希望本文对使用unity3d进行VR开发但没经验及致力于虚拟展厅制作童鞋们理清思路有所帮助。
我们先来看看本案例在内置渲染管道下的效果截图:
需要说明的是,由于一些建模师不熟悉unity3d的美工制作,常常被美工要求反复修改模型,另一方面,由于不合理的模型构建方法,给后续的光影烘焙和场景优化带来很多问题,因此,要做好Unity的美工,就得从建模阶段入手,做好一些模型的预处理。1.场景结构简介
本案例的3dmax模型如下图所示,这个场景的原始模型是另一用户的提供的,由于这个用户对Unity3d的美工的掌握和很多童鞋一样只停留在概念阶段,没有经验,基本也是一边摸索一边推进,结果发现困难重重,尽管他的机器很高端,但是制作的U3d场景苍白暗淡,没有美感,而且非常卡顿,最后做不下去了,向小姐姐求援。当小姐姐打开Unity工程的时候,发现材质、贴图、灯光非常多,很多模型穿插,重面、破面也很多,无奈之下,小姐姐只好放弃他的Unity工程,从3dmax场景开始,重新修改模型,下面的就是小姐姐重新修改后的场景截图。
⑴.材质和贴图优化预处理
前面小姐姐提到过,用户提供的原始模型贴图和材质多达200多个,如此多的贴图和材质,势必会增加机器开销,导致作品实时运行卡顿,尤其是在移动端和3D眼镜中浏览,这肯定是无法接受的,因此必须消减贴图和材质的数量。
从前面的模型截图可以看到,贴图最多的是那些展牌,原始模型之所以材质数量太多,是因为建模师把每张贴图都做成了单独的材质,所以小姐姐考虑将所有的贴图分组合并,具体操作如下图步骤所示,之所以用拼音命名,是因为这些群组的名称会被传递到Unity中,为防止一些插件不支持中文,所以建议最好用拼音或英文。
接下来点击下图所示的图标,让每个展牌的UV1各自独立,图中绿色壳材质线框即刻消失。
另外我们注意到,展牌的贴图比之前的暗了很多,这是因为这张合并了的贴图是通过max的烘焙所得,其中多少会有灯光的因素,所以应该将这张贴用ps打开,将其中的图片用每个展牌贴图合并之前的原始贴图重新逐个替换一遍,保存之后,这张贴图的颜色就正常了。
上面这种方法是在每个展牌各自都贴好了材质和贴图之后为消减材质和贴图的数量的被动之举。我们也可以在开始建模的时候,用手工展UV1的方法来做,也就是先规划好展牌的分类,确定哪些展牌的贴图应该合并在一起,然后用ps将这些展牌需要用的贴图拼在一张大的图片中,假设下图是我们事先拼好的一张大图:
以上讨论了多个物体在不合并的情况下将其材质和贴图合并的两种方法。
接下来将场景中较小的展牌全部分离成单个的物体,如下图所示,然后群组,并命名为“xiao_deng_xiang”,用上述的步骤同法泡制,将材质和贴图合并为一个。
这里特别强调一点,unity3d有自己的材质系统,不兼容建模软件中高级渲染器的材质,因此只需用标准材质贴基本的纹理即可。
⑵.遮挡剔除和视锥剔除优化预处理
Unity3d场景既要控制贴图、材质的数量,也要控制物体的数量和场景中模型的总面数,为此,一些童鞋常常将很多物体在建模软件中合并(Attach),这样一来,物体的数量减少了,但是模型面数却没法消减。Unity3d引入了遮挡剔除和视锥剔除技术来优化相机视图中模型的面数,如果为了减少物体数量而将很多物体合并,反倒不利于Unity3d的遮挡剔除和视锥剔除,例如前面的展牌,如果将所有展牌物体全部合并,相机无论如何移动和旋转,相机会认为这些展牌的面数始终在视野之内,无法将真正处于视野以外的模型面剔除,从而导致运行卡顿。这里说明一点,模型面数对机器造成的负载相对物体的数量来说,要大得多,因此控制模型的面数比控制物体数量要重要的多。
基于上述的概念,对于场景中众多的物体,小姐姐倾向于对其分类群组,不建议随意合并,以方便在unity进行视锥剔除和遮挡剔除优化。
⑶.基于灯光的模型预处理
为加速Unity的相机渲染,可以依据场景的轮廓,构建如下图所示的简版模型作为场景的替身,来接受Unity中碰撞物或称障碍物(Colliders)的实时检测,以防止相机自由下落或穿墙而过。这个简版模型相对带有复杂贴图和光影图的众多场景模型的来说,计算量会小很多,因此会大幅度加速相机的实时渲染,这个简版模型必须在建模软件中预先构建好,而且应与场景模型重合,右下图左上角可见,该模型只有300多个面,远远小于场景的总面数(18万+),这个模型无需贴图,也无需烘焙和渲染,仅用于碰撞检测。
⑸.拆分UV2
拆分UV2之前,得根据后期光影烘焙的需要,对整个场景进行一个规划,也就是先确定哪些物体需要烘焙,哪些不需要烘焙,不需要烘焙的物体就不需要拆分UV2了,需要烘焙的物体还得根据物体的重要性和面的大小进行权衡,并本着节省光影图的原则,尽量将更多的物体拆分在一个UV2里面。需要注意的是,拆分在一个UV2里的物体,与前面拆分在一个UV1里的物体没有任何关系,各管各的事。不同的多个物体可以共享一个纹理,不同的多个物体也可以共享一个光影图,这些都是因为不同的多个物体共享了一个UV1或UV2产生的,具体将哪些物体拆分在一个UV2里面,这需要一些实战经验,如果有条件,可跟着我的视频教程去临摹案例来感悟和积累经验。另外,作为建模师,对后期的光影烘焙和场景优化等美工各阶段必须有足够的了解,否则构建的模型不是需要反复修改,就是相互扯皮。
因为这个场景中的墙体是最大也是最重要的,所以先来拆分墙体,但是如果把所有的墙体拆分在一个UV2里,光影图的分辨率需要设到4096X4096才可能看上去不虚,可是光影图太大,烘焙太费时、同时后期的实时运行负载太大,所以把墙体分为南墙和北墙分别拆分,这样南墙和北墙就可以分别用2048X2048的分辨率来拆分了,一张4096x4096的光影图相当于4张2048x2048的光影图,两张2048x2048的光影图比一张4096x4096的光影图的负载小一半。
如下图所示,选中南墙(将墙体上的展牌(灯箱)和地台及3D文字等物体排除)所有物体,然后群组,并命名为“nan_qiang_2048”,请大家养成用英文或拼音命名的习惯,以防Unity中的某个插件不支持中文出问题,拼音用低划线隔开是为了好识别,因为有的人一看到字母就以为是英文,直接就懵了,模型是要转给美工的和程序的,得让他们好识别。2048是表示这个群组拆分UV2的分辨率,在群组名称里标识,也是为了传递到Unity中给美工烘焙时设定光影图的分辨率时参考。
以此类推,将其他物体根据需要分别群组并拆分UV2,具体过程就不再赘述,有关拆分UV2的方法就讨论到这里。最后强调一点,要分批次烘焙,就得在建模软件中将物体群组拆分UV2,之所以分批次烘焙,一方面是因为整个场景烘焙太费时,一旦某个群组里的物体有问题或者需要修改,只需修改后导入unity重新烘焙这个群组就可以了,已经烘焙好的没有问题的物体是不受影响的,如果不分批次烘焙,每修改一次物体,就得把整个场景烘焙一遍,另一方面,分批次推进烘焙,不至于等的让人心急。3.模型导出