Unity的光照烘焙技术(下)

2020/01 14 10:01

在Unity的光照烘焙技术(上)中,Unity技术美术李万里介绍了Unity的光照系统。本文将介绍如何使用Unity的Progressive工具去正确的烘焙光照以及设置一些光照。

  演讲内容

  我们谈了很多光照烘培的内容,但也要考虑到烘培的代价是非常高的。

  如果我们烘培一个地图,整个场景不可能都是Box垒起来的,还有大量的物体。如果这些物体全部都要烘培,需要有很强的电脑和集群服务器进行渲染。

  我们还面临一个问题:烘培贴图的数量和体积非常的大,因为它是RGB通道的一些彩色图片,所以是无法改变的。

  我们只能通过格式压缩,但压缩会出现质量下降的情况。贴图加载会占用大量的显存,所以优化整个光照很重要。

  Unity提供了两个非常重要的功能:Light Probe和Light Probe Proxy Volume,二者可以配合使用。Light Probe是球形光照,提供比较简单的间接照明,可以为小物体提供间接光。

  如果游戏场景在室外,像一些植被,草和小型岩石可以不用烘培。因为它们虽然很小,但是整体的数量是很庞大的。尤其是一些小的细节,如果精度不够,烘培的效果会非常差。

  如上图所示,Light Probe Proxy Volume用来给这个小火车进行间接照明,它上面的这些点可以吸取左侧Light Probe上离它最近的值,它会在几个球之间进行颜色的混合,混合出一个符合小火车形状的间接光的体积。尽管本身小火车没有进行光照计算,但它也拥有了间接光。

  Light Probe Proxy Volume目前不支持移动平台,它只支持一些PC或主机平台,之后我们可能改进,支持移动平台。

  大家可以按照项目的情况,正确的使用可以缩减Lightmap的数量和烘焙时间,提高效率。人物和车辆这类动态物体,一定是使用Light Probe进行照明。

  用于结构复杂的小物体,满足下列需求即可:

  结构复杂,单体部件表面起伏过大,UV复杂的物体。尤其在Enlighten中计算的时候,因为复杂性是难以逾越的障碍。

  体积小,不显眼的。例如:镜框和电线杆。

  不重要的,并非游戏场景的重要部件。例如:一块80%埋在地下的岩石。

  树和植被也使用Light Probe照明,因为Enlighten对树和植被也非常的不友好。

  Lightmap优化方面,可以大量使用Light Probe,从而优化掉1/3到1/5的Lightmap数量,加速烘焙时间,使烘焙测试的时候更加流畅,不必等待太长时间。

  如下图所示,这张图是用Enlighten烘焙的。说到Enlighten,不得不提Enlighten最核心的三个概念:Systems、Clustering、UV Charts。

  我们可以把Systems作为Unity让Enlighten把场景中的部件按照光照和它的距离关系来构建出来一个承接光照的最大单元。我们会看到它的颜色不同,代表是不同的System,这种依存关系决定Enlighten构建的复杂度。

  Enlighten会根据使用什么材质,哪个光照对它有影响,它和哪个物体位置比较近,自动构建System。构建得越复杂,计算量也会越多。

  Clustering是最核心的Enlighten概念。Enlighten本身光照进行照明是不需要计算的,它计算的是光照环境。所以构建光照环境时,才可以创造这些Clustering。

  UV Chart是Lightmap光照贴图的UV,而构建光照环境最核心的东西是UV Chart,如果没有UV Chart,它就没有空间可以存储Clustering作为计算单元。

  为什么我们此前说过Enlighten不适合用于植被和树呢?

  因为我们制作了一个树,有多少片树叶,就有多少UV Charts,每个UV Chart都要进行光照计算,光照计算最低代价是4×4,即4个像素乘4个像素的代价去生成整个计算UV Chart的光照空间。

  计算Clustering时,每个至少保留16个像素。如果一棵树还好,如果有500片叶子,还可以接受。如果有一片树林,那就使用Enlighten计算不动了,所以不建议使用Enlighten对树木进行间接光照计算。

  我们需要尽可能的缩减单个物体的Lightmap的UV区块来降低UV Charts,在分Lightmap UV时一定要注意,尽可能将UV连在一起,这样会让Enlighten计算量降低。

  Clustering基本上用每个色块作为一个计算单元,它可以发射低频光对周围进行影响,精度越高,块越小,整体的计算量就会加大,整个计算间接光的时间就会更长一些。

  我们自动生成的一些UV可以使用Unity的功能,在物体上有UV Charting Control,进行动态合并。在合并完成后,我们进行预计算,看看合并上有没有问题。

  合并UV的时候可能会出现扭曲现象,这种扭曲现象在烘焙Lightmap时是非常有问题的。

  上图中的两个示例,UV Charts等于6的情况下,如果Box分成左边是比较合理的,右边这么分在Enlighten的计算量最起码要增加3倍。

  我们来了解一下Unity的光照贴图设置。

  Resolution :控制Clustering的分辨率,会和Lightmapping Settings的Indirect Resolution相乘获得最终的Resolution。

  Cluster Resolution: 控制Clustering,结果会和Resolution相乘。我们可以通过对这些参数进行搭配,调出不同的Resolution。

  Lightmap parameters: 我们可以为关卡中每一类物体都设置不同的Lightmap parameters,来控制不同物体的Clustering Resolution,从而提高lightmap烘焙效率。

  例如:一些不需要计算的植被可以设置一个新的Lightmap parameters组,让它只接受别的物体的间接光,自己不再产生间接光,降低计算时间。

  如上图所示,从左到右依次是Cluster Resolution是3米、1.2米、0.72米的效果。我们可以看出,只有在Cluster Resolution=0.72米的时候,在室内的效果基本才是合格的。

  下面是我们给出的一个计算单元的建议,大家可以根据这个建议来设置游戏中的一些精度。

  常见的物体Cluster Resolution 参考(每单元大小):

  室内墙壁精度为0.5-1米

  室内重要道具精度0.5米

  室外建筑精度1-2米

  室外地面精度2-4米

  室外重要游戏道具精度1-2米

  简单介绍一下Progressive Baking,它的情况非常的暴力,就是你有多少光子,直接光的Samples,有多少间接光的Samples,最终可以获得怎样的精度,最终取决于你的电脑有多强。

  值越高效果就越好,但是不要特别高。我们建议在室外,Direct Samples为50,室内最少要80-100。Indirect Samples在室外大概用400,室内800,不然会出现黑斑问题,弹射次数建议为4次。

  现在提供给大家一些光照经验总结,基本上代表了现在光照技术,使用Unity制作移动平台光照时最重要的建议。

  首选线性空间作为项目的开发环境,Gamma空间适合Opengl3.0之前时代的项目。

  在线性空间下,Direction light(主光源)白天强度在1.5-1.8之间,夜间月光在0.4-0.7之间。

  在Gamma空间下,Direction light(主光源)白天强度在0.5-1之间,夜间月光在0.2-0.5之间。

  光照的Indirect强度不能高过直接光的强度,在线性空间下间接光一般小于1。

  在Englighten渲染模式下,尽可能的降低植被的Cluster Resolution,提高渲染效率。

  静态物体尽可能优化掉不需要烘焙的部分,提高重要物体的Lightmap精度。不参与烘焙的物体使用Light Probe照明。

  优化UV Chart,单个物体UV Chart越少越好。

  优化不同种类的Cluster Resolution,保证不同种类的物体都有合理的计算分辨率。

  混合光照手机平台建议实时阴影距离控制在不超过20米。

  使用Unity提供的Procudral Skybox进行烘焙光照贴图。可以获得更真实的Lightmap。

  不轻易的调整Unity的Albedo boost和Indirect intensity强度。尽可能的保证Albedo boost =1, indirect intensity=1。

  下面是烘培的一些效果,这是可以在移动平台上运行的效果。

  现在我们来进行一个演示。

  如下图所示,这是一个火车的场景,我们刚刚看到它的预览效果。那么场景进行了哪些优化呢?

  我们可以看到,火车和铁轨都是没有烘培的,为什么呢?因为这些东西又小又不显眼,而且扁平化一块一块的,我们不需要对它进行烘培。

  如果把这些内容全部使用Enlighten进行烘培,大概需要花2个小时。如果优化后,大概是3-5分钟就可以烘培完了。

  如下图所示,我们对小火车做了一个Light Probe Proxy Volume,这样就可以控制接受间接光的情况。

  我们可以控制它的精度,然后可以获得更高的纵向的采样值,如果认为它太多了,可以优化掉一部分。如果侧面需要更多的细节,可以通过这种方式对间接光进行采样,但是需要注意这种方式目前不支持移动平台。

  但是如果不使用这种方式,我们可以使用Blend Probes进行融合,切换为Blend Probes时,效果会有一些差异,光照精度上是有一些损失的。

  如下图所示,项目中的整体地面,都是使用的Blend Probes模式的混合。

  这种方式是完全支持移动平台的,比较小或者不显眼的物体,并非游戏重要物体的都可以使用Blend Probes进行照明。

  我们需要勾选Static类型,它们一定在Static批次中,后面把它Lightmap Static去掉就可以了,去掉后就不会生成Lightmap,但是会接收Light Probe的影响。

  在这个项目中像栏杆和一些根本不重要的内部物体,都可以使用Blend Probes进行照明,这些东西烘培下来,整体代价和贴图容量都要大大的超标的。

  我们再来看看另一个场景。

  如上图所示,在整个光照当中,我们加了一些面光源,这是为了提高场景的窗户透光的光亮。如果不加,就没法按窗户形成面光源,向内部进行照明的。

  需要注意,面光源在移动平台上,如果不是HDRP的话,就只支持静态的,只支持烘培,不是烘培的模型它是不支持的。

  下图是场景的光照贴图大概是这样的,比较符合白天的光照效果。

  我们可以看看它的设置。

  首先Procedural Skybox在这里加进来。在Enlighten当中,千万不要使用渐变和颜色进行烘焙,两者烘焙出来的东西会比较风格化,并不写实。有很多人选择用某个颜色烘渐变,但效果会非常不理想,所以一般选择Skybox进行烘焙,而Skybox一般使用Procedural Skybox。

  烘焙完后,再替换为自己场景的风格化Skybox作为最终显示效果。Procedural Skybox是仅用于烘焙的,不是用于制作最终的Skybox效果。

  我们再举一个简单的例子。如果要形成一个特别颓废和压抑的环境,我们可以将大气密度提到很高,然后将染色降一下,或者偏向一个色彩。

  我们可以将整个曝光度调低,把大气密度调高,实现让人很压抑的环境,这种环境烘焙出来的Lightmap比较接近于比较邪恶的地方,从而获得更加压抑的光照效果。

  还有一点,当Atmosphere Thickness提高了以后,它作为偏光的可照明区域会缩减。缩减的意思是:黑色区域基本上不贡献光线了,整个Skybox变为不是半球形了,变得没有原来的光照面积大,所以烘焙出来的图就不那么剔透了。

  因为它的周围存在染色问题,导致它控制在偏红,偏压抑的环境,就能烘托出来。我们可以通过对一些染色以后,对光线的反映来调出适合的视觉效果。

  我们不建议在室内的时候使用Light Probes进行照明,因为它的物体要求精度很高,遮挡关系全靠需要低频光进行影响,没法做出很多变化。

  尤其是一些非常小的物体,如果想要表现出好的效果,一定要对Lightmap大小进行放大。例如:铅笔在Scale In Lightmap里要放大一倍,不然烘出来基本上没效果。但对于有的物体,我们要保证统一性,如果能保证统一性,有的地方会出现一些色斑。

  在示例场景中,我们优化掉了一部分的东西,整个Lightmap的照明还可以,但是你会看到这些东西都浮起来了,靠屏幕空间的AO是控制不住的,效果会产生大量的损失。所以这样的东西只在室外有用,室内的话是不建议这么用。

  Enlighten烘焙在示例场景中的效率,代价是非常大的,因为场景中的物体非常的多,它的UV Charts基本上没办法看到,非常碎,所以烘焙时间也非常长。

  在小火车的场景中,使用Enlighten大概烘焙4分钟。在这个教室场景,因为物体非常多而杂,大概是小火车场景的5倍左右时间,大概20分钟。

  使用Progressive烘培则很稳定,它只看场景有多大的精度,不管场景有多少物体,这就是Progressive和Enlighten之间的差异。

  我的演讲到此结束,谢谢大家。

  小结

  我们希望通过本次演讲内容,让你熟练掌握Unity光照系统以及烘培技术。