作者:杨栋
随着各大计算平台的算力稳步增长,特别是GPU技术的不断进化,原先可望而不可及的技术比如实时光线追踪技术开始逐步走入玩家的视野。一些先锋厂商甚至已经超出Demo的范畴,开始正式推出支持实时光追的游戏。
不过目前的实时光追技术还只能在配备了最新Nvidia RTX 20系列显卡的PC机上才能实现(前一代Nvidia 10系列显卡,比如GeForce 1080,1070,甚至1060也可以用软件实现实时光追,但是总体效果不佳)。
大多数玩家所在的移动平台上,目前并没有实时光追技术被正式推出。虽然有厂商如Imagination Technologies推出了移动端实时光追的架构设计和演示Demo(可查看Imagination官网:https://www.imgtec.com/powervr-ray-tracing/),但是这些技术要在主流手机厂商如华为,苹果,三星,小米等那里得到实际应用,还有一段不短的路程要走。
因此我们今天来聊一下一项“老”技术:光照贴图烘焙。虽然实时光追非常诱人非常好,目前来说要想实现好的光照效果,我们还是要依赖光照贴图烘焙技术来实现。
本文将以问答的方式来讲解Unity 2019.4版本中的Progressive Lightmapper(Unity 2018等之前版本中的Enlighten已在2019.4中正式弃用)。之所以选择问答的形式原因如下:
- 大家阅读时可以看完一个问题的解答随时停下来。
- 便于大家事后查找相关内容。
- 如果本文中遗漏了什么问题,大家可以在留言区留言,我们可以下次通过文章或者B站视频(B站搜索“Unity官方”)的方式集中回答。
一、什么是光照贴图(Lightmap)?为什么要用光照贴图?
场景中的光照信息大致可以分成两类:直接光照和间接光照。
如果没有间接光照,那么整个场景就没有真实性可言。但是间接光照的实时计算在目前的硬件条件下,只有支持实时光线追踪的硬件才能实现,比如Nvidia的RTX系列显卡。在普通的计算设备上,特别是移动端设备上目前还没有实时光线追踪的解决方案出现。因此我们必须依赖预先计算好的光照贴图来提供这些间接光照信息。
光照贴图本质上就是一张或者多张应用在场景模型上的贴图。它们包含的是通过光照贴图烘焙方式进行预计算所获得的间接光照,阴影等信息(可以在烘焙时选择只烘焙间接光照,不烘焙阴影)。使用光照贴图可以避免在游戏运行时进行实时的光照和阴影计算,提高游戏的运行性能,特别适合用于性能较弱的计算平台比如移动平台上。
要在Unity中预计算(或者说烘焙)获得光照贴图,我们使用的是Unity官方研发的Progressive Lightmapper(渐进式光照贴图烘焙)。在Unity 2018版本之前,Unity中集成的光照烘焙模块是一套第三方解决方案Enlighten。由于第三方厂商Geomerics不再维护Englighten,所以从Unity 2019版本开始Enlighten被标记为弃用状态(Deprecated)。Unity 2021.1版本开始将完全移除Englighten模块。
ProgressiveLightmapper基于AMD的Radeon Rays技术(https://gpuopen.com/radeon-rays/)开发。RadeonRays是一套支持跨平台的ray intersection库(如大家对Radeon Rays技术感兴趣,可以参考网址:https://gpuopen.com/radeon-rays/)。
二、渐进式光照贴图烘焙对场景中模型的要求是什么?
使用渐进式光照烘焙对模型有以下几个要求:
1. 模型上不能有重叠的UV。
2. UV之间要有足够的间距以避免“渗色”现象的发生。
3. 因为光照贴图只能烘焙静态物体,所以我们要把需要参与烘焙的物体标记为Static。
以下为具体说明:
1. 模型上不能有重叠的UV。我们可以尝试使用Unity的ImportSettings窗口中的Generate Lightmap UVs来生成第二套UV(记得在勾选复选框以后点击Apply按钮):
但是通常建议大家在建模软件中制作第二套UV,因为光照贴图烘焙用的UV与普通纹理贴图的UV有所不同。
Unity中并没有内置的模型UV查看功能,这里介绍一个Unity资源商店中的小工具UV Inspector,如下图所示:
下面两张图是在Unity中使用UV Inspector的界面。在Scene窗口选中模型以后,UV Inspector界面就会显示当前模型包含的所有UV。图一为第一套UV用于纹理贴图;图二为第二套UV用于光照贴图烘焙:
2. UV之间要有足够的间距以避免“渗色”现象的发生。“渗色”的发生因为两块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 GlobalIllumination(接受全局光照)则会被设置为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 Indir