如果没有间接光照,那么整个场景就没有真实性可言。
但是间接光照的实时计算在目前的硬件条件下,只有支持实时光线追踪的硬件才能实现,比如Nvidia的RTX系列显卡,在普通的计算设备上,特别是移动端设备上目前还没有实时光线追踪的解决方案出现。因此我们必须依赖预先计算好的光照贴图来提供这些间接光照信息。
本质上就是一张或者多张应用在场景模型上的贴图。它们包含的是通过光照贴图烘焙方式进行预计算所获得的间接光照,阴影等信息(可以在烘焙时选择只烘焙间接光照,不烘焙阴影)。使用光照贴图可以避免在游戏运行时进行实时的光照和阴影计算,提高游戏的运行性能,特别适合用于性能较弱的计算平台比如移动平台上。
Progressive Lightmapper基于AMD的Radeon Rays技术(https://gpuopen.com/radeon-rays/)开发。Radeon Rays是一套支持跨平台的ray intersection库(如大家对Radeon Rays技术感兴趣,可以参考网址:https://gpuopen.com/radeon-rays/)
(1) 模型上不能有重叠的UV。我们可以尝试使用Unity的Import Settings窗口中的Generate Lightmap UVs来生成第二套UV(记得在勾选复选框以后点击Apply按钮):
(2) UV之间要有足够的间距以避免“渗色”现象的发生。“渗色”的发生因为两块UV之间的间隔不足,导致一块UV上的颜色“渗透”到了相邻的UV上。 通常建议大家在建模软件中制作第二套UV,因为光照贴图烘焙用的UV与普通纹理贴图的UV有所不同。 Unity中并没有内置的模型UV查看功能,这里介绍一个Unity资源商店中的小工具UV Inspector,下面两张图是在Unity中使用UV Inspector的界面。在Scene窗口选中模型以后,UV Inspector界面就会显示当前模型包含的所有UV。左侧为第一套UV用于纹理贴图;右侧为第二套UV用于光照贴图烘焙:
(3) 因为光照贴图只能烘焙静态物体,所以我们要把需要参与烘焙的物体标记为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)。
渐进式光照贴图烘焙对硬件的要求是什么?支持Unity的哪些渲染管线? 硬件要求: (1) 至少需要一块支持OpenCL 1.2的显卡 (2) 至少2GB的显存 (3) CPU支持SSE4.1指令
(1) 内置渲染管线(Built-in Render Pipeline):支持Baked Indirect,Subtractive和Shadowmask光照模式。 (2) 通用渲染管线(Universal Render Pipeline,简称URP):支持Baked Indirect,Subtractive和Shadowmask光照模式。 (3) 高清渲染管线(High Definition Render Pipeline,简称HDRP):支持Baked Indirect和Shadowmask光照模式。 因为用于烘焙测试的两个场景都是基于HDRP来制作的,所以接下去的讲解我们将会围绕HDRP的光照烘焙模块来进行。 渐进式光照贴图烘焙出来的是什么? 光照贴图烘焙出来的是光照贴图(Lightmaps),光照探针(Light Probes)和反射探针(Reflection Probes)。 按照不同的Lighting Mode(光照模式),光照贴图烘焙出来的结果是不同的。
HDRP下Lighting窗口的光照模式支持Baked Indirect和Shadowmask两种(内置渲染管线和通用渲染管线请参考文档)。
• Baked Indirect模式:
如果场景中的灯光模式设置为Mixed,那么这些灯光会给场景提供直接光照,间接光照信息则被烘焙到光照贴图和光照探针中。此选项适合中高端的平台,比如PC,主机。
• Shadowmask模式:
如果场景中的灯光模式设置为Mixed,灯光会给场景提供直接光照,间接光照烘焙到光照贴图和光照探针中。Shadowmask和光照探针遮挡信息会被烘焙到阴影信息中。你可以在Project Settings > Quality窗口设置Shadowmask的模式(Shadowmask或者Distance Shadowmask两种模式可选)。此选项在游戏运行时比Baked Indirect模式性能更好,因为光照贴图中已经预先烘焙了阴影信息。
• Subtractive模式:(在内置和通用渲染管线中支持)
场景中的直接光照,间接光照和阴影信息都会烘焙到光照贴图中。适合对性能敏感的平台比如移动端平台。
如果场景中光源设置为Mixed模式,在三种光照模式下动态和静态物体的行为可参考以下列表:(总结自Unity文档:https://docs.unity.cn/2019.4/Documentation/Manual/lighting-mode.html)
上述对比中的Shadow Distance在三种不同渲染管线中设置的方式是不一样的。 (1) 内置渲染管线: 打开Edit > Project Settings > Quality > Shadows > Shadow Distance。
(2) URP通用渲染管线: 打开Edit > Project Settings > Graphics中选择UniversalRenderPipelineAsset进行设置。 (3) HDRP高清渲染管线: 通过在场景中使用的Volume进行设置。 界面操作(HDRP示例):打开Window > Rendering > Lighting Settings窗口,在Mixed Lighting区域勾选Baked Global Illumination复选框,然后在Lighting Mode中选择光照模式:
(HDRP中不支持Subtractive光照模式)
渐进式光照贴图烘焙的CPU版本和GPU版本有什么区别?
CPU和GPU两个版本所用的底层技术相同,唯一的区别是:CPU版本使用CPU和内存进行计算;GPU版本使用显卡和显存进行计算。
• 如果使用CPU版本进行烘焙,影响烘焙效率的是CPU的速度和内存的大小。
• 如果使用GPU版本进行烘焙,影响烘焙效率的则是显卡的速度和显存的大小。 界面操作(HDRP示例):打开Window > Rendering > Lighting Settings窗口,在Lightmapping Settings区域可以选择使用哪个版本的Progressive Lightmapper:
Lighting界面上那一堆参数理解一下? 选择好Lighting Mode和Lightmapper,我们来看一下具体的烘焙参数。确保打开Window > Rendering > Lighting Settings窗口。 在HDRP中进行光照烘焙时可以为整个场景指定一个用于烘焙的天空盒作为环境光,如下图所示:
我们可以在这里使用当前HDRP场景中使用的天空盒设置,也可以使用不同的天空盒设置。当然,如果你使用相同的天空盒,那么烘焙所得的光照贴图将会拥有与当前场景一样的环境光。
内置和通用渲染管线的环境光设置参数:
(上图中的设置不在此详细讲解,可以参考中文文档中的具体描述:https://docs.unity.cn/cn/current/Manual/GlobalIllumination.html)
接着我们来看具体的烘焙参数。如下图所示,光照贴图烘焙窗口中Lightmapping Settings区域的这些参数在UI上目前是放在一起的,这么多密集摆放的参数对于新用户来说一眼看上去会有不知所措的感觉:
此数值会被用于分别乘以Direct Samples,Indirect Samples和Environment Samples这三个数值。这三个数值会被应用于Light Probes采样。数值越大效果越好,烘焙时间也越长。 Bounces:此数值用于控制计算光子弹射时的反弹次数,一般2次可以满足普通场景的需求。
无降噪设置烘焙结果:
打开降噪设置:
打开降噪设置烘焙结果:
除了使用Optix,Radeon Pro和Open Image Denoiser这一类具备AI功能的降噪算法之外,我们也可以进一步使用降噪滤镜,比如以下配置:
这里的Guassian(高斯)滤镜会在降噪算法之后在光照贴图上做进一步的模糊处理,以减少光照贴图中的噪点。 (注:内置渲染管线和通用渲染管线还支持A-Trous滤镜。此滤镜会在尽量减少光照贴图中噪点的同时降低模糊的效果,因此通常比高斯滤镜的效果更好。)
像素和纹素最大的区别是:像素其实就是图片数据;但是纹素可以代表很多类型的数据,它可以是纹理贴图,也可以是用于计算阴影的深度图。 光照贴图本质上是纹理贴图,因此Progressive Lightmapper在这里用纹素而不是像素来代表光照贴图的分辨率。 Lightmap Padding(光照贴图间距):数值单位为texel(纹素),默认值为2。烘焙好的光照贴图中包含很多Charts。这些Charts可以理解成对应模型上包含烘焙光照信息的UV色块。在游戏运行时,这些色块会与模型网格进行映射,完成最终效果的计算(在模型原先的纹理上叠加烘焙的光照信息)。但是这些“色块”之间必须保持一定的距离才能确保模型上一个部位的颜色不会“渗色”到另一个部位。 Lightmap Size(光照贴图大小):数值单位为像素,默认值为1024。根据Lightmap Resolution和Lightmap Padding的参数设定,烘焙出来的光照贴图数量会相应的变化。这里的大小其实代表的是每张光照贴图的最大尺寸。按照实际需求,即使设置了2048,某些光照贴图的尺寸也有可能是1024或者512。 接下去我们用一组测试数据来说明上述三个参数的关系(使用的项目是上面的夜间场景):
从上述测试数值可以总结如下: (1) Lightmap Resolution越大,烘焙时间越长,光照贴图越精细。 (2) Lightmap Padding越大,光照贴图的数量越多,但是可能可以减少提示UV重叠的模型数量。 (3) Lightmap Size越大,光照贴图的数量越少,光照贴图越精细。 以下截图是配置-6的烘焙参数和结果:
从上图中可以看到,在提高了Lightmap Resolution,增加了Lightmap Padding数值和Lightmap Size数值以后,从原先的119个UV重叠的物体下降到了94个UV重叠的物体。 那么UV重叠到底是什么意思?是因为我们在制作模型解UV的时候没有做到UV之间保持足够距离吗? 出现这个黄色警告信息的原因有以下几种(我们也列出了可能的解决方法): (1) 模型上用于光照烘焙的UV确实存在重叠: 在Console界面我们可以看到警告UV重叠的信息中包含了具体哪个模型有这个问题。我们可以具体看一下这些模型的UV(这是用于光照贴图烘焙的第二套UV。如果没有这套用于光照烘焙的UV,我们需要手动生成或者用Unity的模型导入界面来生成这套UV)。 如果模型的原始UV确实存在重叠,我们可以通过外部建模工具来修复。 (2) 模型上用于光照烘焙的UV不存在重叠: 如果看下来其实所有模型的原始UV都不存在问题,在实际烘焙好光照贴图的场景中也看不出有什么“渗色”的情况,我们可以忽略这个警告。 当然我们可以尝试提高Lightmap Resolution和增加Lightmap Padding的方式来提高光照贴图的精度,从而减少出现在警告中提示UV重叠的物体数量。不过要注意这会影响烘焙所需的时长,以及增加的光照贴图的大小。
(1) Max Distance(最大距离): 为了计算出一个物体是否被另一个物体挡住从而算出相应的环境光遮蔽效果,系统需要使用射线来做侦测之用。此参数用于控制射线的长度。 射线的长度越长,光照贴图中由环境光遮蔽产生的阴影区域越多,反之越少(只有相邻很近的物体之间才会有环境光遮蔽产生的阴影)。 如果设置为0,意味着此射线为无限长;默认数值为1。 Max Distance设置为0:
Max Distance设置为1:
因为数值0代表射线长度无限长,所以画面中的环境光遮蔽明显暗很多。 (2) Indirect Contribution(间接光贡献):数值在0到10之间,默认数值为1。此参数用于控制间接光强度对环境光遮蔽的影响。 下面三张图比较了不同Indirect Contribution数值对画面整体的环境光遮蔽造成的影响,可以看到Indirect Contribution越大,环境光遮蔽越暗(红色线条标出的区域最明显)。 参数配置一:Max Distance = 1,Indirect Contribution = 0,Direct Contribution = 0:
参数配置二:Max Distance = 1,Indirect Contribution = 1,Direct Contribution = 0:
参数配置三:Max Distance = 1,Indirect Contribution = 10,Direct Contribution = 0:
(3) Direct Contribution(直接光贡献): 数值在0到10之间,默认数值为0。此参数用于控制直接光强度对环境光遮蔽的影响。
CUDA核心越多,显存越大,烘焙时间越短
进行光照贴图烘焙时,GPU版本使用的是显存。就目前的显卡来说,显存总是有限的,我们也无法像添加内存那样可以自行添加(内存也相对便宜很多)。如果当前场景在烘焙时所需的显存空间超出了当前显卡具备的显存大小,那么GPU版本就会停止工作。这时我们就需要一个后退的方法,那就是CPU版本来救场了:在烘焙过程中,如果Unity发现显存耗尽,Unity会把GPU版本自动切换到CPU版本。
GPU版本自动切换到CPU版本的原因是当前系统的可用显存不足,GPU版本无法继续进行正常的烘焙操作。 从GPU版本到CPU版本的切换会发生在准备烘焙阶段。在Unity编辑器的Console窗口可能会出现两段黄色的警报信息(第一段必出),示例图如下
OpenCL报错:后退到CPU光照烘焙。后面一段的意思就是显存不足了。
(可能出现)这一段是说降噪处理失败。请尝试警用降噪处理或者降低光照贴图大小。
我们在使用GPU烘焙的时候,需要注意的是:等待Prepare Baking…这个阶段结束,开始Baking的时候看是否会切换到CPU版本,如下图所示:
如果看到Baking…[ETA: xx:xx:xx],观察到没有切换到CPU版本的话,你可以放心之后会继续用GPU版本进行烘焙了。否则如果这时候你离座去干个别的事情,可能回来一看烘焙时间翻了10倍:因为自动切换到CPU版本。
如何避免GPU烘焙自动切换成CPU烘焙? 因为场景中参与烘焙的资源量大小是不一样的,所以完全避免切换是不可能的。 通过前面不同型号的GPU烘焙测试,可以知道确保能够在场景中使用GPU烘焙的前提条件是当前系统可用显存的大小。因此能否使用GPU烘焙就看我们的系统能否省出足够的显存给渐进式光照烘焙这个模块用。以下是一些节省系统显存的方法: (1) 如下图所示,通过顶部菜单Edit > Project Settings打开项目设置界面,在烘焙开始之前将Texture Quality调整为Eighth Res,意思是在Scene窗口和Game窗口只使用纹理贴图的1/8尺寸进行显示。(默认为Full Res:意思为使用完整尺寸的纹理贴图进行显示)。烘焙结束之后调整回Full Res。具体设置界面如下图所示:
(2) 在烘焙过程中如果不需要查看渐进式的烘焙过程,可以隐藏Scene窗口和Game窗口,比如像下图一样将Project Settings窗口覆盖在最上层:
(3) 将场景切分成多个小场景,使用多场景的方式进行加载。这样可以针对各个小场景进行烘焙。 结语:渐进式光照贴图烘焙系统为我们提供了快速迭代的工作流和整个烘焙时长的预估,完全改变了之前使用Enlighten系统时对所需烘焙时长完全靠猜,以及光照贴图烘焙效果要等到烘焙完成以后才能看到的问题。这大大加快了光照烘焙的速度,也让灯光美术师有了更多的自由度获得自己想要的效果。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有