Unity 移动平台下的光照烘焙及优化

前言

移动平台下场景制作的规模越来越大,开放视角的3D大世界场景,对地图大小、可视距离的要求越来越高,随之带来了地形尺寸变大、场景物件种类变多、物件的模型面数和数量增长,对美术效果上的要求也趋近于主机和PC端游戏。Realtime Global Illumination 在移动平台下还不能随意使用,美术场景的光照主要还是以 Baked GI 为主,随着Unity版本的升级,场景烘焙流程也迭代过几个版本,但是仍然暴露出了越来越多的问题。在Unity官方的技术支持下我们发现在烘焙流程中疏忽了一些很重要的环节,加上升级Unity2017.4后更换了烘焙模式,因此而整理此文。

大纲

一、Unity光照烘焙系统

以Unity5.6版本前后这个时间节点介绍一下光照烘焙系统,旧的历史版本就不做回顾了。


Unity5.6版本前后光照烘焙系统对比

1、基于Enlighten的GI和Lightmapping Workflow

Unity5.0版本升级了基于Enlighten的real-time GI,以及升级了烘焙光照图的工作流程。“Auto”模式下会生成预计算的实时GI、静态光照图Lightmaps、灯光探针Light Probes、反射探针Reflection Probes等数据。主要升级内容:

1)实时GI支持的Lights及Skylight的修改,支持自发光的表面作为实时光源,发光的颜色可以实时影响动态物体,并可以动态修改。

2)光照图Lightmap有三种模式:

“Non-directional” 模式开销最小,得到一个普通的漫反射效果。

“directional” 模式会计算法线,所以Lightmap带有漫反射和法线的效果。

“directional specular” 模式还会保留高光效果。


三种烘焙的直接光模式

3)Reflection probes支持hdr格式,且支持实时渲染或者烘焙存储为cube资源。


使用Reflection Probes的效果对比

4)Skybox支持hdr格式,Skybox可以作为环境光的一种。


Skybox作为环境光可以参与烘焙

从Unity5开始,烘焙系统就不仅仅依赖灯光来营造烘焙效果了,在烘焙流程中还应该考虑环境光、反射环境、使用发光Shader的材质等。

2、Mixed Lighting

Unity5.6版本开始Baked GI变更为混合光照Mixed Lighting,Light Mode设置为Mixed不仅是指灯光对静态物件和动态物件共同作用,而是真正的去混合间接光照与直接光照、烘焙阴影与实时阴影。

基于Mixed Lighting增加了新的Shadowmask烘焙方式,支持烘焙阴影与实时阴影进行融合。建议使用Unity2017以上版本,在Unity2017.1版本中,Shadowmask和Distance Shadowmask两种模式的切换移到了QualitySetting中,通过QualitySettings.shadowmaskMode进行修改。


Mixed Lighting的Shadowmask Lighting Mode

画面左侧shadowmask模式下是完全烘焙的shadowmap效果,画面右侧Distance Shadowmask是实时阴影与烘焙shadowmap按照设置距离融合的效果。

3、Progressive Lightmapper

Unity5.6版本增加了新的特性Progressive Lightmapper,一种与Enlighten完全不同的一种渐进光照贴图技术,随之改进了烘焙工作流程。

Progressive Lightmapper基于路径追踪渐进的生成光照图,可以快速预览场景的烘焙光照,快速烘焙出lightmaps和Light Probes,然后逐渐迭代显示为最终版本。


Progressive Lightmapper渐进光照烘焙的特性

基于Enlighten的烘焙依赖precomputed realtime GI来生成间接光照,它的优势是,只修改灯光的情况下可以快速生成新的光照贴图,但是在地图的制作阶段会由各种因素涉及到场景物件的改动,Lightmap UVs布局会重新发生变化。在Enlighten特性下,还是需要频繁的进行烘焙生成光照图,而在Progressive Lightmapper这种特性下,”Auto Generate”才能真正变得可用于大型场景的制作。

Enlighten无法完全避免因为UV引起的效果上的缺陷,而Progressive Lightmapper对UV的要求比较正常:没有重叠的UV、较小的面积和角度的误差、charts之间有足够的填充间距。随着Unity的版本升级,Progressive Lightmapper能提供更好的解决方案和烘焙效果,比如在Unity2017.2版本中增加的Stitch Seams功能可以修复接缝处的光照。


Progressive Lightmapper的Stitch Seams功能

而Progressive Lightmapper在Unity2017所有的版本中还只支持预览,在Unity2018中才支持烘焙使用。如果没有升级到Unity2018,还是需要继续使用Enlighten的烘焙系统。不过,随着Progressive Lightmapper的出现,Unity的烘焙流程也在往更好的方向调整。

Unity5.6版本开始,UV Control和Lightmap Settings从Lighting-Object面板移到了Inspector面板的物件属性中,由Mesh Renderer统一管理,我们在Mesh导入阶段就应该注意和重视光照相关的2号UV设置以及Lightmap设置


Lightmap Settings面板的改动

二、Mixed Lighting烘焙模式

1、Mixed Lighting的三种模式

Window > Lighting > Scene 面板中对 Mixed Lighting 中的 Lighting Mode 进行选择。

Mixed Lighting有三种模式:


Mixed Lighting的三种模式

Baked Indirect :图左,只烘焙间接光照。

Shadowmask :图中,烘焙间接光照和阴影。

Subtractive :图右,烘焙直接光照、间接光照和阴影。

使用混合光照可以理解为间接光照、直接光照、阴影之间进行混合。三种模式下得到的烘焙光照图不一样,混合灯光的计算也不一样。


三种模式下烘焙得到的光照图

Baked Indirect 与Shadowmask模式下,混合灯光的直接光照是实时计算的,间接光照被烘焙在光照图中。Shadowmask模式下会多一张阴影光照图,会有额外的内存开销,当Shadowmask的类型为Distance Shadowmask时,阴影光照图可以与实时阴影按照Shadow Distance设置的距离进行混合。Baked Indirect模式下的静态物体只可能有实时阴影,按照Shadow Distance设置的距离过渡到无阴影。

Subtractive模式类似于旧版本的Baked GI,它的直接光照也被烘焙在光照图中,作为Mixed Lighting的一种备用解决方案,用于低端手机设备。Subtractive模式下,参与实时计算的只有动态物体的实时光照和动态物体对静态物体的投影。

2、Shadowmask烘焙模式

1)Mixed灯光的作用

Mixed灯光对静态物体产生的间接光照记录在光照图Lightmap_light上,对静态物体产生的阴影记录在光照图Lightmap_shadowmask上。Mixed灯光产生实时的Direct Lighting与Lightmap_light上的Indirect Lighting一起计算静态物件的光照;Mixed灯光产生的实时阴影与光照图Lightmap_shadowmask上的阴影信息一起计算静态物件的阴影;对动态物件计算实时阴影。

烘焙好的光照信息存储在两组光照图上,不能在运行时修改,但是Mixed灯光的参数(比如Directional Light的参数Transform、Color、Intensity)可以在运行时修改。

2)Shadowmask的两种模式

在 Edit > Project Settings > Quality > Shadows的设置中,可以设置Shadowmask ModeShadow Distance的参数。


Shadow Distance和Shadowmask Mode的设置

Shadowmask Mode为Shadowmask时,使用Lightmap_shadowmask上的烘焙阴影。

Shadowmask Mode为Distance Shadowmask时,根据设置的Shadow Distance参数值对实时阴影和烘焙阴影进行融合。在距离以内使用Realtime Shadowmap,分辨率为Shadow Resolution所设置的阴影分辨率;在设置的距离外使用Lightmap_shadowmask上的烘焙阴影。

Distance Shadowmask的开销更高,因为静态物件也在Shadowmap中实时渲染了。对于一个太阳位置固定的大世界场景,推荐使用Distance Shadowmask模式,阴影的效果可以一直延伸到地平线。

3、Shadowmask烘焙示例

1)旧的烘焙模式下实现实时阴影与烘焙阴影切换

Shadowmask这种烘焙模式出现之前,我们使用Unity5.5版本实现实时阴影和烘焙阴影的切换方案是这样的:


Untiy5.5版本实现实时阴影和烘焙阴影的切换方案

画面左侧为烘焙光照;画面右侧为烘焙AO与实时光照混合。

烘焙光照:使用一组烘焙灯光组 Bake_lights_Group 按照Baked GI的流程烘焙得到光照图,烘焙灯光组中包含一盏产生阴影的灯光。实时光Sunlight的强度只有0.1,用于绘制静态场景接收的动态角色阴影,角色的光照也由Sunlight决定,因此在角色Shader中需要补偿10倍Sunlight的强度。

烘焙AO:使用另一组烘焙灯光组 BakeAO_lights_Group 烘焙得到带有AO信息的光照图,灯光组中没有产生阴影的灯光,只烘焙出灯光的颜色、AO。Sunlight作为实时光开启阴影,另外增加了一个全局颜色来与烘焙光照的效果校正。

这种做法的目的只是为了将烘焙的光照图中的阴影独立出来,却涉及到需要烘焙两套光照图、修改实时光与烘焙光照图的混合计算、修正实时灯光的强弱和两种效果之间的光照差异等制作流程相关的改动。

2)Shadowmask模式的优势

Unity5.6版本提供的Shadowmask烘焙模式,只需要烘焙一套光照图就能满足实时阴影与烘焙阴影切换的需求,切换Distance Shadowmask和Shadowmask就可以实现实时阴影与烘焙阴影的切换。


Shadowmask和Distance Shadowmask的切换

画面左侧为ShadowMask模式,画面右侧为Distance ShadowMask模式。

Distance Shadowmask模式下设置Shadow Distance,可控制场景实时阴影的范围,比使用全场景实时阴影的开销更低。


Distance ShadowMask模式下Shadow Distance为35和70的效果对比

画面左侧为Distance ShadowMask模式下Shadow Distance为35的效果,画面右侧为Distance ShadowMask模式下Shadow Distance为70的效果。

4、实时阴影优化策略

理解Shadowmask这种烘焙模式后, 同时需要对Edit > Project Settings > Quality > Shadows的阴影设置有更深的理解,才能利用这些参数更好的控制实时阴影的开销。

1)合理设置Shadow Resolution

根据实际情况合理设置Shadow Resolution的值。设置的阴影分辨率值越大,shadowmap带宽占用越大;阴影精度提升后,计算的开销也会变大,对性能和发热都有很大的影响。

通常情况下建议设置为Medium Resolution或High Resolutin,阴影分辨率分别为20482048和40964096。Very High Resolutin会使用硬件提供的最大分辨率,开销太大不建议在移动平台使用。

2)合理设置Shadow Distance

根据实际情况合理设置Shadow Distance的值。当实时阴影距离变大时,场景中参与阴影绘制的静态物件变多,会引起DrawCall增长,同屏绘制的三角面增多。同时,实时阴影距离越大并不代表阴影效果越好,在Shadow Resolution阴影分辨率不变的情况下,设置的Shadow Distance越大,阴影显示质量反而降低。

3)注意Shadow Cascades的使用

使用Shadow Cascades可以让阴影的分辨率按照距离分布更加合理,但是有额外的阴影计算开销。按照Shadow Cascades的设置可以将阴影的渲染划分成对应的几块区域,提升近处阴影的分辨率占用,减轻近处阴影的锯齿感。如果追求更高的阴影效果可以使用Shadow Cascades,注意需要同时开启QualitySetting和GraphicSetting中的设置才会生效。一般不建议在移动平台使用Shadow Cascades。


使用Shadow Cascades可以减轻近处阴影的锯齿感

4)Shadow Projection使用Stable Fit

在整体阴影分辨率不变的情况下,使用Shadow Projection的Close Fit可以进一步的提高近处物件的阴影分辨率,同时也有更高的开销。移动平台建议使用Stable Fit,阴影效果更稳定。

5)制定不同画质等级下不同的阴影配置

根据实际情况,提供不同的阴影配置给不同的画质。


制定不同画质等级下不同的阴影配置

三、烘焙效率和效果的优化

随着场景制作的规模变大,带来对烘焙工作流程的主要影响:

1)烘焙工作量增加

2)单个地图的烘焙时间越来越长,还可能出现烘焙卡在进度条

3)光照图分辨率精度不变的情况下,光照图数量变多,内存占用过高

这三个问题都与Generate Lighting的流程相关,所以我们需要理解Unity在生成光照数据时的计算过程。

1、Generate Lighting Process

Generate Lighting时,编辑器右下角会显示Precompute Process在后台的处理进度。

官网介绍的计算光照的流程:


计算光照的流程

在单场景烘焙时,耗时较高的是映射光照信息(5/11)和光照计算(7/11),所以影响烘焙速度的主要在于UV的合理性和光照的计算精度。

Unity官方提供了优化Precomputed Realtime GI的资源和详细教程,建议阅读原文。

https://learn.unity.com/tutorial/precomputed-realtime-gi-global-illumination


优化Precomputed Realtime GI的教程

这份教程划出了优化烘焙速度的重点。

Over the course of the document we will cover:

l How to determine an appropriate lighting resolution for our Scenes.

l What Charts are and how they affect our precompute times.

l How to start the precompute process.

l Using probe lighting to reduce the complexity of our lighting solution.

l Improving auto-unwrapped UVs generated by Unity’s Precomputed Realtime GI.

l What Clusters are and how they are used to generate globally illuminated lighting.

l Using Lightmap Parameters to fine-tune our lighting on a per-object basis.

2、UV Charts、Lightmap UVs和Clusters的理解

在计算静态物体的光照时,Precomputed Realtime GI会先计算一部分光照数据存储在Lighting Data Asset中,这些数据在运行时生成一组低分辨率的光照图;Baked GI会将光照数据离线生成光照图。实时的Lightmap与烘焙Lightmap没有直接对应关系,两个物件可以在同一张realtime Lightmap上,同时在两张不同的baked Lightmap上,baked UVs与precomputed realtime UVs是不一样的。从预览窗口可以看到UV Charting和Lightmap。

1)理解UV Charts

UV Chart是静态物件在光照图上的UV对应在光照图上的区域,在预计算实时GI时,每个Chart上的像素都会计算灯光,预计算的时间跟Chart的数量有很大关系,所以了解Charts是怎样工作的可以帮助我们优化光照的计算时间。

每个物件的UV Charts是由一组UV Chart组成,每个UV Chart为一段连续的UV片段,UV Chain之间预留了0.5个像素的边缘来防止纹理的溢出,最小的单位是44,每个Chart最少会占用16个像素。举例来说,一个11米大小的物体,Lightmap Resolution分辨率设置为1时,一个Chart在光照图上占用16个像素,如果它有50个Charts,那么在光照图上占用的像素是800。

上图左侧为6个UV Charts,至少占用96个像素,上图右侧优化为1个UV Chart。

2)UV Charting Control

静态物件的光照图参数中可以调整UV Chart的参数。Unity的UV映射方式是正交的,Unwrapping算法主要通过找到UV片段共享的边与邻近的边进行缝合来简化Lightmap UVs。


Optimize Realtime UVs调整UV Chart的参数

可以通过修改Max Distance(默认值0.5)和Max Angle(默认值 89)参数减少UV Chart的数量。

Max Distance代表在设置的距离内连接连接和缝合UV shell,UV的边缘如果在设置的Max Distance距离以内会被考虑缝合。Unity系统的默认值为0.5个单位(单位是Unity的系统单位,比如1米),比较大的物件可以将参数值设置大一些。数值越大,UV片段将会减少,但是也要根据实际情况考虑,对于一些需要在光照图上占用更多的像素的物件,需要更多的UV片段。

Max Angle代表在设置的角度范围内连接连接和缝合UV shell,UV边缘缝合与邻近面之间的角度也有关系,共享同一个边的两个面之间的角度在设置的Max Angle角度以内会被考虑缝合。数值越大,UV片段将会减少,但是有些情况下太大的数值会引起UV拉伸,也需要合理的设置。

如果导入的mesh因为过高的三角形面数被拆分为子mesh,在拆分处的三角面会有不同角度的法线,Charts的分布也会受到影响。勾选Ignore Normals时(只有Precomputed Realtime GI会受这个选项的影响),Charts不会被拆分,大多数情况下拆分mesh是不需要拆分Charts的,需要注意勾选Ignore Normals选项

通过Window > Lighting的Object选项卡,选择Charting预览项,可以看到选择的物体的Chart分布情况。

通过Scene视窗中的UV Charts可视化预览模式,我们很容易的看出单个物体的UV Charts数量,评估使用是否合理,找到一个平衡点


UV Charts可视化预览模式

对于一些UV Charts无法合并的情况,比如树叶的叶片、灌木小植物等,这些物件可以使用Light Probe。

3)理解Clusters

为了简化计算,Unity先将静态场景体素化为Clusters,在场景中通过格子映射到静态几何体的表面,用于光照计算。Clusters与UV Charts的光照映射方式类似,但是它们是独立的功能。

通过Scene视窗中的Clustering可视化预览模式,可以看出Cluster的分布情况。


Clustering可视化预览模式

上图中方形的一个色块就是一个Cluster,Cluster的数量和计算精度与Lightmap Parameters中Cluster Resolution的设置有关。

4)Generate Lightmap UV

大部分的物件我们使用Unity的Generate Lightmap UVs的默认参数计算生成光照图的UV,Hard Angle参数值可以根据物体的角度做手动调整,防止过多的UV断开的情况。

尽量使用Untiy来生成Lightma UVs,手动处理的UV片段在光照图上还是会重新布局,而且比Unity自动UV耗费更多的预处理时间。Unity自动处理UV时,在Lightmap上逐个排布UV片段;不使用Unity的Generate Lightmap UVs的情况下,会使用物件本身的2号UV信息作为光照图的UV信息,还需要从手动处理好的合并的UV布局中找到UV片段进行排布。

有时很难通过自动分UV得到理想的UV分布,这种情况下需要手动处理模型的2号UV,手动处理UV时重点考虑减少UV片段,保持UV没有扭曲。


Unity自动生成UV与在3ds max中手动处理为连续的2号UV的效果对比

在手动处理2号UV时需要注意,如果导出的一个物体有多个子mesh的情况,所有子mesh都需要手动处理2号UV,否则不勾选Generate Lightmap UVs时,获取不到2号UV的数据,会导致烘焙结果为黑色。举例来说,这里的树干和树叶会合并导出为一个物体,不能只在3ds max中单独修改树干的2号UV,树叶也需要unwrap生成2号UV的数据。

3、影响光照图的占用像素的参数

单个物件在光照图上占用的像素受到多个参数影响,在UV Charting Control参数不变的情况下,主要受全局参数Lightmap Resolution和每个物件的Scale In Lightmap参数影响。


单个物件在光照图上占用的像素的主要参数影响

LightmapPadding决定物件之间在光照图上间隔的像素,LightmapSize决定单张光照图的最大尺寸,当一张光照图容纳不下所有的物件对应的光照像素时,会烘焙得到多张光照图。

1)Lightmap Resolution

选择合适的Lightmap Resolution很重要,它是一个控制场景的光照图占用总像素的全局值。官方推荐的Lightmap Resolution值,场景比例与世界单位一致(1unit=1米)的情况下,室外场景0.51,室内23,地形0.10.5。我们以1米为一个单位,对于一个丰富的室内小场景,有很多不同的灯光和反弹照明,那么光照图的分辨率可以设置23像素/单位,可以容纳更多的灯光细节。如果是一个很大的室外场景,游戏世界的比例会更大一些,也许一个物体的表面可以达到上百甚至上千米,单个表面同时受到灯光的种类比较少,这种情况下,对物件可设置光照图的分辨率在0.51像素/单位,对地形可以设置为0.10.5像素/单位。在旧版本的烘焙技术中,因为烘焙阴影需要较高的精度,Realtime Resolution可能设置到10~30,而Mixed Lighting烘焙模式推荐使用间接光照与实时阴影,对烘焙阴影的要求降低了很多。因此,需要根据实际场景的规模、使用的烘焙模式、烘焙效果的要求等综合考虑,选择一个合适的值。

2)Scale In Lightmap

有一种错误的理解是,面积大的物件就应该设置更高的光照图精度和光照计算精度。实际上,光照图分辨率不变的情况下,物体在光照图上占用的像素也会随物体的大小发生变化。精细的小物件可能需要设置更高的精度。

画面左侧为旧的调整方式,将大物件的Scale In Lightmap的参数调高到3甚至5,将小物件的参数调低到0.5甚至0.1,手动修改物件的参数且不合理。

画面右侧为新的流程,提前将Scale In Lightmap和Lightmap Parameters配置存储到Prefab中,场景搭建好后光照精度比例已经成型,只需要根据最后的烘焙结果调整场景中的特殊情况,大部分细碎的物件不用一一调整,大大减少了手动调整参数的工作量

在全局Lightmap Resolution的基础上,通用物件的Scale In Lightmap为1,为需要特别设置精度的物件按照分类制定规范,设置不同的精度比例。比如建筑物的墙面结构简单,受光主要是低频光,参数可调低到0.5;城市街道需要更高的阴影精度,参数可调高到3;野外大面积的地形和大量的植物,参数可调低到0.5;细节较多的主体物件,参数可调高到2。


Scale In Lightmap调整前后的物件光照精度对比

调整后光照图的像素占用分布更合理。

4、影响光照精度计算的参数

影响烘焙时长的主要因素在于光照精度的计算,主要是Lightmapping Settings上的参数配置。


烘焙时长的主要参数影响

1)Indirect Resolution

光照计算是以Cluster为单位发射光线收集光照信息的,Indirect Resolution会影响Cluster数量,修改它会对烘焙速度有提升。通常在光照效果调试阶段建议降低精度,确定最终光照参数后再调高来得到最终的烘焙效果。

2)Ambient Occlusion

勾选Ambient Occlusion时,会计算物件之间的遮挡关系,在场景物件数量级较大的情况下,关闭AO计算对烘焙速度有提升。通常在光照效果调试阶段建议关掉,确定最终光照参数后再开启来得到最终的烘焙效果。

3)Final Gather

勾选Final Gather时,会按照Lightmap的分辨率用光线追踪算法计算光照反弹,RayCount决定了采样光照计算的射线数量,默认为256,数值越大,烘焙过程中的计算耗时越长。通常在光照效果调试阶段建议关掉,确定最终光照参数后再开启来得到最终的烘焙效果。

4)Lightmap Parameters

Lightmap Parameters是一组Precomputed Realtime GI的参数集合,可以设定多套参数配置给不同的静态场景物件使用。对烘焙速度的影响主要体现在Resolution和Cluster Resolution参数。Resolution直接影响了光照计算的精度,一般建议在0.1~2;Cluster Resolution影响Cluster数量,一般建议设为0.3-0.6;数值越大,烘焙耗时越长。Resolution和Cluster Resolution代表光照计算的精度,不同于Scale In Lightmap,并不影响Lightmap Resolution光照图的分辨率和最终尺寸。

调整Baked GI的Blur Radius模糊半径参数可以用来弥补阴影精度不足产生的效果问题。

5、场景光照管理和烘焙调试

移动平台的实时光照需要严格控制,尽量在前期考虑好场景物件的分类和分层,方便后期对灯光和阴影进行控制。在实际的制作中,美术可能习惯了发现问题后再进行分类,不管能否提前制定规范,在烘焙流程中都是很重要的一个不容忽视的步骤。

1)配置物件Prefab上的光照参数

搭建一个标准环境,导入模型创建Prefab时,在标准环境下测试模型的2号UV是否合理,调整模型的UV Control与Lightmap参数,按照通用规则设置Prefab上的Scale in Lightmap值和Lightmap Parameters配置。

存储在Prefab上的光照参数可以认为是一个全局参数,一个经验值。场景调用Prefab后,大部分情况不需要再逐个调节参数,对特殊情况进行微调来适应实际场景。在模型的导入阶段检查模型UV、配置物件的光照参数配置,可以节省后期的大量物件的光照配置工作量。

比如城内的街道需要足够的精度来支持烘焙得到的阴影细节,所以Scale in Lightmap设置为3,Lightmap Parameters设置为High;墙面部分结构简单受光主要是低频光,Scale in Lightmap可降低到0.5,Lightmap Parameters设置为Low;根据这些特性进行配置。

2)场景物件的规划

对物件进行分类可以更快的为他们分配光照计算,方便我们管理物件,选择重复对象。举个例子,场景的父节点为Environment,包含了所有可见的静态场景物件,子级按照大小和结构类似的物件来分组,方便统一设置Static参数,同时方便后期优化。

3)烘焙灯光的规划

通常我们使用一盏Directional Light作为主光源来表现材质效果和阴影,属性为Mixed。根据场景原画概念图中的场景色调和明度初步确定主光源的颜色和强度。主光源的参数Color和Intensity共同决定了场景整体的明暗,可以将 ColorBrightness*Intensity ≈ 1 作为一个标准参考值,同时也需要考虑环境光的平均亮度、其他辅助灯光的强弱对场景亮度的影响。

根据场景原画概念图中阴影的方向初步确定主光源的角度,避免使用过于极端的灯光角度,比如平行于地面或者垂直于地面的角度不利于烘焙效果。

灯光的CullingMask设置为静态场景物件和动态角色所在的Layer层,养成手动设置CullingMask的习惯,避免使用Everything。

只有一盏主光源的情况下,烘焙会存在很多暗角,整个场景的色调会比较单一。通常为了得到更好的烘焙效果,我们会增加额外的平行光来作为烘焙补光,属性为Baked,确定好平行光的方向、颜色和强度。辅助烘焙的平行光不宜超过两盏,过多的平行光会让光照复杂而不真实,也会导致更严重的溢色问题,所以建议同一方向和同一颜色的平行光只保留一盏,如果烘焙效果的色调不够丰富,建议通过后期校色来弥补,后期ColorGrading和Lut的开销在移动平台还是可以接受的。

增加其他类型的辅助灯光表现细节,在场景中需要光源的位置添加烘焙用的Point Light、Area Light等灯光。

4)预烘焙与最终烘焙方案

场景基本搭建完成后,需要对场景增加细节光照。在Enlighten特性下,如果只修改灯光和灯光参数,可以快速烘焙得到光照图;而增加、删除和修改物件,相当于重新烘焙。当场景物件不完全确定时,需要提高烘焙调试的效率。

选择合适的Realtime Resolution,确定大概的光照图尺寸。这一阶段不需要特别精确,不用过分在意光照图的总数和占用情况,在最后的环节微调。

设定两套全局使用的Lightmap Parameters。

这两套参数的差异主要在Resolution和ClusterResolution的值,影响烘焙的速度。需要注意,场景中已配置的Lightmap Parameters不受这两套全局设置的影响。

上图左侧为预烘焙方案。使用第一套Lightmap Parameters-LightmapPreBake,降低Indirect Resolution,并关闭AO和Final Gather,降低Indirect Resolution间接光照计算的精度。调整这些参数会加快烘焙速度,并保证Lightmap的像素占用不发生变化。

上图右侧为最终烘焙方案。使用第二套Lightmap Parameters-LightmapFinalBake,提高Indirect Resolution,并开启AO和Final Gather,提高Indirect Resolution间接光照计算的精度,使用高配置的烘焙机器,得到高精度的光照计算效果。


预烘焙与最终烘焙方案的效果对比

上图为两种方案的烘焙对比,从烘焙结果来看,使用预烘焙的方案进行光照调试,烘焙效率较高。烘焙效果有问题的物件及时修改(部分错误可以通过修正物件的法线、2号UV来解决),不适合烘焙的物件调整为Light Probe光照。确定了光照效果后,使用最终烘焙方案得到更多的光照细节。需要注意的是Indirect Resolution会对光照图的布局产生影响,在最后的阶段确定合适的Realtime Resolution值,让光照图的像素利用率最大化。

在官方教程的例子中,烘焙耗时从7.5hrs优化到2.25mins。

6、其他问题

1)使用Light Probe

Probe lighting是一种近似实时光照的技术,通常用于角色和非静态物体的照明,在运行时有较高的性能。Probe lighting使用球谐函数采样3D空间中的点的入射光,这些系数存储成本低而且能被快速解压,被shader使用。

使用Probe lighting有一个局限性,很难计算高频光,精度不足以计算特殊的可见光辐射范围。受限于低阶球谐函数及性能,Probe lighting不适用于大物件和受光复杂的情况,也不适用于大平面或者表面凹陷的物体;适用于小的、凸面物体。

使用Light Probe的优点:

1、使用Light Probe可以减少Lightmap的像素占用,并提升烘焙速度。场景中有一部分物件是不适合使用Lightmap的,结构复杂的小物件、UV Charts数量不合理的物件、场景中光照单一的物件等。

2、不受Lightmap影响的物件更方便做优化显隐。

3、Light Probe的密集程度影响光照计算效率,根据物件所处环境的光照情况进行探针的布局,需要注意疏密分布。虽然Light Probes的开销不高,放置Probe时也要考虑到降低性能,放置的太密集也会造成浪费,在需要有明显变化或者需要强烈的光线反弹颜色的区域才放置密度更高的探针。同时,可以制作一份简版的Light Probe用于低端画质。

4、Light Probe还可以用于LOD Group中低精度模型的光照。

5、在没有设置Light Probe的情况下,物体会使用Fallback的Ambient Probe照明,Ambient Probe采样灯光面板中设置的环境光,对用户不可见。

2)使用Baked Reflection Probe

对特定的不同区域创建多个不同的ReflectionCube。

移动平台下Reflection Probe的Type一般不使用Realtime而是Baked,设置合适的分辨率,Resolution决定了烘焙得到的Cube的分辨率,一般不超过256。通过Culling Mask设置需要参与反射烘焙的层。

注意设置Box Size的范围,多个不同的ReflectionCube的区域尽量不要重合,区域重合时会根据物件设置进行混合,有额外的开销,可以通过GraphicsSettings禁用Reflection Probes Blending。

建议创建一个全局使用的Reflection Probe,烘焙得到一张Texture Shape为Cube的场景的反射图,配置在Lighting面板上。在优化时可以禁用场景里的ReflectionCube,默认会使用Lighting面板上配置的Cubemap。

3)多场景管理光照图

在光照参数设置合理的情况下,场景的物件越多,烘焙出的光照图数量就越多,同屏绘制的物件可能占用到大量不同的光照图,渲染时内存压力变大。当地图尺寸达到2048尺寸后,建议将大场景按照区域拆分为多个场景,不同区域的物件的光照图会受到场景的管理,拆分后的小场景的光照图数量得到了控制,随着场景的加载和卸载。

4)烘焙硬件配置

烘焙机推荐的硬件配置为32核心256G内存。

参考文献:

Untiy5.0更新日志:https://unity3d.com/cn/unity/whats-new/unity-5.0
Untiy5.6更新日志:https://unity3d.com/cn/unity/whats-new/unity-5.6.0
Pogressive Lightmapper:https://docs.unity3d.com/Manual/ProgressiveLightmapper.html
Mixed Lighting:https://docs.unity3d.com/Manual/LightMode-Mixed.html
Precompute Process:https://docs.unity3d.com/Manual/UsingPrecomputedLighting.html
Unite 2018 | Lightmap烘焙最佳实践:https://connect.unity.com/p/unite-2018-lightmaphong-bei-zui-jia-shi-jian
GI-Enlighten:https://docs.unity3d.com/Manual/GI-Enlighten.html
GI-UVs:https://docs.unity3d.com/Manual/LightingGiUvs.html
Tutorials-Graphics-Precomputed Realtime GI:https://unity3d.com/cn/learn/tutorials/topics/graphics/introduction-precomputed-realtime-gi?playlist=17102

本文来自:https://zhuanlan.zhihu.com/p/68841952