目录
相关概念
1.渐进式光照贴图烘焙
1.1 渐进式光照贴图烘焙对模型的要求
1.2 渐进式光照贴图烘焙对硬件的要求
1.3 渐进式光照贴图烘焙支持的Unity渲染管线
1.4 进行渐进式光照贴图烘焙结果
1.5 渐进式光照贴图烘焙的CPU版本和GPU版本
1.6 Lighting窗口Lightmapping Settings参数介绍
1.6.1 采样设置相关
1.6.2 降噪设置相关
1.6.3 光照贴图分辨率
1.6.4 Compress Lightmaps
1.6.5 Ambient Occlusion相关
1.6.6 Directional Mode(方向模式)
1.6.7 Indirect Intensity和Albedo Boost
1.7 渐进式光照贴图烘焙的CPU版本存在的意义
1.8 渐进式光照贴图烘焙节省系统显存的方法:
1.9 解决光照贴图接缝问题
1.10 控制模型在光照贴图中的占比
场景中的光照信息大致可以分成两类:直接光照信息和间接光照信息。
间接光照的实时计算在目前只有支持实时光线追踪的硬件才能实现,比如Nvidia的RTX系列显卡。在普通的计算设备上,特别是移动端设备上目前还没有实时光线追踪的解决方案出现。因此我们必须依赖预先计算好的光照贴图来提供这些间接光照信息。
光照贴图本质上就是一张或者多张应用在场景模型上的贴图。它们包含通过光照贴图烘焙方式进行预计算所获得的间接光照、阴影等信息(可以在烘焙时选择只烘焙间接光照,不烘焙阴影)。使用光照贴图可以避免在游戏应用运行时进行实时光照和阴影的计算,从而提高游戏应用的运行性能,光照贴图特别适合在性能较弱的计算平台比如移动平台上使用。
要在Unity中通过预计算(或者说烘焙)获得光照贴图,我们需要使用Unity官方研发的Progressive Lightmapper(渐进式光照贴图烘焙)模块。Progressive Lightmapper是基于AMD的Radeon Rays技术(https://gpuopen.com/radeon-rays/)开发的。Radeon Rays是一套支持跨平台的ray intersection库。
相关概念
HDRP高清渲染管线下:
- LightingMode:光照模式。Lighting窗口,分为Baked Indirect、Shadowmask两种。
- Lightmapper:光照烘焙。Lighting窗口,Lightmapping Settings,分为GPU和CPU两种。
1.渐进式光照贴图烘焙
1.1 渐进式光照贴图烘焙对模型的要求
- 模型上不能有重叠的UV。
我们可以尝试使用Unity的Import Settings窗口中的Generate Lightmap UVs功能来生成第二套UV(记得在勾选复选框以后单击Apply按钮)供光照贴图烘焙之用。
不过还是建议在建模软件中手工制作第二套UV。因为通常贴图用的UV会导致出现重叠的情况,比如在同一个模型上有两个形状相同的部分,它们可以共用同一个UV区域(这样只需要在上面画一遍纹理)。如果将这一套有重叠的UV用于光照烘焙,就意味着同一模型上不同区域使用相同的光照信息,这显然是不对的。
- UV之间要有足够的间距以避免“渗色”现象的发生。“渗色”现象的发生是因为两块UV之间的间隔不足,导致一块UV上的颜色“渗透”到了相邻的UV上。
- 因为使用光照贴图只能烘焙静态物体,所以要把需要参与烘焙的物体标记为Static。
我们习惯直接勾选Game Object右上角的Static复选框,然后把层级中所有物体标记为Static。不过对于光照贴图烘焙有意义的两个选项是Contribute GI和Reflection Probe Static,因此也可以只勾选这两个选项。
Contribute GI(贡献全局光照)选项和Mesh Renderer中的Contribute Global Illumination(贡献全局光照)选项是联动的。如果右上角的Contribute GI选项被勾选,则Mesh Renderer组件中的Contribute Global Illumination选项也会被勾选。与之相关的Receive Global Illumination(接受全局光照)选项则会被设置为Lightmaps,意指当前Game Object会使用光照贴图获取间接光照。当然,我们也可以把Receive Global Illumination选项设置为Light Probes,这时间接光照信息就来自相关的光照探针(Light Probes)。
1.2 渐进式光照贴图烘焙对硬件的要求
- 至少需要一块支持OpenCL 1.2的显卡
- 至少2GB的显存
- CPU支持SSE4.1指令
1.3 渐进式光照贴图烘焙支持的Unity渲染管线
- 内置渲染管线(Built-in Render Pipeline),支持Baked Indirect、Subtractive和Shadowmask光照模式。
- 通用渲染管线(Universal Render Pipeline,简称URP),支持Baked Indirect、Subtractive和Shadowmask光照模式。
- 高清渲染管线(High Definition Render Pipeline,简称HDRP),支持Baked Indirect和Shadowmask光照模式。
1.4 进行渐进式光照贴图烘焙结果
进行渐进式光照贴图烘焙时烘焙出来的是光照贴图(Lightmaps)、光照探针(Light Probes)和反射探针(Reflection Probes)。光照贴图中会包含间接光照信息,也会包含软阴影和环境光遮蔽(Ambient Occlusion)信息。
按照不同的Lighting Mode(光照模式),烘焙出来的结果是不同的。在HDRP的Lighting窗口中可以选择Baked Indirect和Shadowmask两种光照模式(内置和通用渲染管线还可以选择Subtractive):
- Baked Indirect模式
如果将场景中的光源的模式设置为Mixed,灯光会给场景提供直接光照,间接光照信息则被烘焙到光照贴图和光照探针中。在运行时,由烘焙得到的间接光会和直接光融合在一起。
在此模式下光源会投射实时阴影。不过超过阴影投射距离(Shadow Distance)以后,将不再渲染阴影。
- Shadowmask模式
如果将场景中的光源的模式设置为Mixed,灯光会给场景提供直接光照,间接光照信息则被烘焙到光照贴图和光照探针中。在运行时,由烘焙得到的间接光会和直接光融合在一起。
此模式与Baked Indirect模式的区别是:它能在运行时将烘焙所得的阴影和实时阴影进行融合,并且会在超出阴影投射距离(Shadow Distance)以后,通过使用保存在额外光照贴图中的阴影信息来渲染阴影(这张额外的光照贴图就是Shadowmask,并且在光照探针中也会保存额外的信息)。与其他模式相比,Shadowmask模式可以获得最高质量的阴影,但是它对性能和内存的要求也是最高的。Shadowmask模式适用于远处物体也能看到的开放式场景,适合在中高端硬件上使用。
- Subtractive模式(内置和通用渲染管线支持该模式)
在此模式下,场景中的直接光照、间接光照和阴影信息都会被烘焙到光照贴图中。该模式适合对性能敏感的平台,比如移动端平台。
对于高质量的HDRP场景,通常将光源设置为Mixed(混合)模式,然后Lighting设置界面选择Baked Indirect作为烘焙时用的光照模式。在该组合下,Lightmapper会将间接光照信息烘焙到光照贴图上,直接光照信息和阴影则会实时生成。这非常适合用于制作日夜变化的效果。
1.5 渐进式光照贴图烘焙的CPU版本和GPU版本
Window→Rendering→Lighting窗口,在Lightmapping Settings区域可以选择使用哪个版本的Progressive Lightmapper。(见前文光照贴图烘焙)
Enlighten(HDRP下不支持):烘焙时长靠猜,光照贴图烘焙效果要等到烘焙完成以后才能看到。
CPU和GPU两个版本所用的底层技术相同,唯一的区别是:
- CPU版本使用CPU和内存进行计算;如果使用CPU版本进行烘焙,则影响烘焙效率的是CPU的速度和内存大小。
- GPU版本则使用显卡和显存进行计算;如果使用GPU版本进行烘焙,则影响烘焙效率的是显卡的速度和显存大小。
1.6 Lighting窗口Lightmapping Settings参数介绍
1.6.1 采样设置相关
- Direct Samples:用于设置从每一个纹素(Texel)射出的采样路径数(针对直接光照)。数值越大效果越好,烘焙时间也越长。
- Indirect Samples:用于设置从每一个纹素(Texel)射出的采样路径数(针对间接光照)。数值越大效果越好,烘焙时间也越长。针对户外场景,指导数值为100。对于室内场景(包含自发光物体),可以按需增加采样路径数直到看到效果。
- Environment Samples:针对环境光的采样数。数值越大效果越好,烘焙时间也越长。默认数值为500。
- Light Probe Sample Multiplier:如要使用此功能,必须在Project Settings → Editor → Graphics 中禁用Use legacy Light Probe sample counts功能。此数值会分别与Direct Samples、Indirect Samples和Environment Samples这三个数值相乘。Light Probes在采样时会使用这三个数值。数值越大效果越好,烘焙时间也越长。
- Bounces:此数值用于控制计算光子弹射时的反弹次数,一般两次可以满足普通场景的需求。
1.6.2 降噪设置相关
Filtering区域的设置用于光照贴图的降噪操作。降噪操作本质上是一个针对已经烘焙好的光照贴图做后处理的过程。如果启用Filtering功能,系统会在把光照贴图的Direct、Indirect和Ambient Occlusion这三部分信息融合之前,对它们应用降噪算法进行降噪处理。
- Auto:自动,Progressive Lightmapper会自动选择一个当前机器支持的降噪算法应用到光照贴图上
- Advanced:高级,可以分别为Direct、Indirect和Ambient Occlusion选择降噪算法(Denoiser)或者降噪滤镜(Filter)。
- 降噪算法(Denoiser):如果你有支持Nvidia Optix降噪算法的GPU,则可以选择Optix;如果有支持RadeonPro降噪算法的GPU,则可以选择RadeonPro。在任何情况下,都可以选择基于英特尔CPU的降噪算法OpenImageDenoise。
- 降噪滤镜(Filter):
- Guassian(高斯)滤镜会在执行降噪算法之后在光照贴图上做进一步的模糊处理,以减少光照贴图中的噪点。
- 内置渲染管线和通用渲染管线还支持A-Trous滤镜。此滤镜会在尽量减少光照贴图中噪点的同时减轻模糊的效果,因此通常比高斯滤镜的效果好。
1.6.3 光照贴图分辨率
这里有三个参数:Lightmap Resolution、Lightmap Padding和Lightmap Size。
- Lightmap Resolution(光照贴图分辨率):数值单位为texels per unit(每单位面积的纹素)。
Texel(纹素)有别于Pixel(像素)。像素是图片的基本单位,如果我们在图片编辑软件中把图片放大到足够大,可以看到这些图片由许多正方形的像素组成,所以像素是屏幕空间的概念。而纹素则是纹理的基本单位,纹理用在模型上,所以它并不是屏幕空间的概念。在模型被绘制到屏幕上时,纹素会被转换成屏幕上的像素展现出来。
像素和纹素最大的区别是:像素其实就是图片数据;但是纹素可以代表很多类型的数据,它可以是纹理,也可以是用于计算阴影的深度图。光照贴图本质上是纹理,因此Progressive Lightmapper在这里用纹素而不是像素来表示光照贴图的分辨率。
- Lightmap Padding(光照贴图间距):数值单位为texel(纹素),默认值为2。烘焙好的光照贴图中包含很多Charts。这些Charts你可以理解成对应模型上包含烘焙所得光照信息的UV色块。在游戏运行时,会将这些色块与模型网格进行映射,完成最终效果的计算(在模型原先的纹理上叠加烘焙所得的光照信息)。但是这些“色块”之间必须保持一定的距离才能确保模型上一个部位的颜色不会“渗色”到另一个部位。
- Lightmap Size(光照贴图大小):数值单位为像素,默认值为1024。根据Lightmap Resolution和Lightmap Padding的参数设定,烘焙出来的光照贴图数量会相应变化。这里的大小其实代表的是每张光照贴图的最大尺寸。按照实际需求,即使将该参数设置为2048,某些光照贴图的尺寸也可能是1024或者512。
- Lightmap Resolution越大,烘焙时间越长,光照贴图越精细。
- Lightmap Padding越大,光照贴图的数量越多,但是可能会减少提示UV重叠的模型数量。
- Lightmap Size越大,光照贴图的数量越少,光照贴图越精细。
1.6.4 Compress Lightmaps
默认启用该功能,即对光照贴图进行压缩。虽然压缩光照贴图可以减少内存占用,但是会导致光照贴图质量下降。
1.6.5 Ambient Occlusion相关
环境光遮蔽用于为场景中的某些区域,比如裂缝、孔洞、墙面的交界处或者任何两个物体相邻的区域添加类似于阴影的效果。它会让这些地方变得比其他地方更暗一些。这些环境光遮蔽信息会被烘焙入光照贴图中。
- Max Distance(最大距离):为了计算出一个物体是否被另一个物体挡住从而算出相应的环境光遮蔽效果,系统需要使用射线来做侦测。此参数用于控制射线的长度。射线的长度越长,光照贴图中由环境光遮蔽产生的阴影区域越多,反之越少(只有距离很近的物体之间才会有环境光遮蔽产生的阴影)。如果设置为0,则意味着此射线为无限长,默认数值为1。
- Indirect Contribution(间接光贡献):参数值在0~10之间,默认值为1。此参数用于控制间接光强度对环境光遮蔽的影响。Indirect Contribution越大,环境光遮蔽越暗。
- Direct Contribution(直接光贡献):参数值在0~10之间,默认值为0。此参数用于控制直接光强度对环境光遮蔽的影响。
1.6.6 Directional Mode(方向模式)
- Directional:在此模式下会生成第二套光照贴图,专门用于保存入射光的主要方向信息。
- Non-Directional:禁止烘焙时生成第二套用于保存入射光主要方向信息的光照贴图。
1.6.7 Indirect Intensity和Albedo Boost
- Indirect Intensity(间接光强度):用于控制光照贴图中保存的间接光强度。数值范围在0~5之间,默认值为1。当数值大于1时会增强间接光强度,小于1时会减弱间接光强度。
- Albedo Boost(反射率增强):用于控制物体表面之间光子弹射的数量,默认值为1。数值范围在1~10之间。数值越大,物体表面的反射率越大。
1.7 渐进式光照贴图烘焙的CPU版本存在的意义
既然GPU版本那么快,为什么还需要CPU版本?
答案是:进行光照贴图烘焙时,GPU版本使用的是显存。就目前的显卡来说,显存总是有限的,我们也无法像添加内存那样自行添加显存(内存也相对便宜很多)。如果当前场景在烘焙时所需的显存空间超出了当前显卡具备的显存大小,那么GPU版本就会停止工作。这时我们就需要使用CPU版本来救场了:在烘焙过程中,如果Unity发现显存耗尽,Unity会自动切换到CPU版本。
1.8 渐进式光照贴图烘焙节省系统显存的方法:
- 通过顶部菜单Edit→Project Settings打开项目设置界面,在烘焙开始之前将Texture Quality调整为Eighth Res,意思是在Scene窗口和Game窗口中只使用1/8尺寸的纹理进行显示(默认为Full Res,意思为使用完整尺寸的纹理进行显示)。在烘焙结束之后调整回Full Res。
- 在烘焙过程中如果不需要查看渐进式的烘焙过程,则可以隐藏Scene窗口和Game窗口。(让Project Settings窗口覆盖在最上层)
- 将场景切分成多个小场景,进行多场景加载。这样可以针对各个小场景进行烘焙。
1.9 解决光照贴图接缝问题
渐进式光照贴图烘焙支持自动接缝缝合。选择场景中需要接缝缝合的模型,然后勾选Mesh Renderer组件中的Stitch Seams选项。
1.10 控制模型在光照贴图中的占比
选择模型,可以使用Mesh Renderer组件中Scale in Lightmap属性来控制模型在光照贴图中的占比。若数值为0,则物体不会参与光照贴图烘焙;数值大于1会增加该物体在光照贴图中的像素占比;数值小于1会减少该物体在光照贴图中的像素占比。