最佳实践 | 在多个Unity场景中使用实时全局光照
在Spotlight团队中,我们和优秀的Unity开发人员一起合作,深度挖掘Unity在游戏开发中的潜力。针对复杂图形、性能和设计方面的问题,我们看到了各种具有创新性的优秀解决方案。也看到了同样的问题与解决方案不断的反复出现。
最佳实践系列文章将探讨我们在与客户合作时遇到的一些常见的问题。这些都是我们的合作团队辛苦得出的经验和教训,我们很自豪能够和大家分享他们的智慧。上一次介绍的是如何通过重新组织层级结构改善性能。
这其中的很多问题只有在真正制作主机游戏、手机游戏、或者处理巨量游戏内容时才会出现。如果能在开发早期就将这些问题考虑进去,那么开发过程就会更轻松,而游戏也会更炫酷。
Unity实时光照
在Unity中,实时全局光照由Enlighten实现。简单来说,它所做的就是计算光线被游戏中各种物体阻挡和反射后的信息。它获取这些信息并构建一组纹理和探测器,以便游戏环境能在运行时高效地对光线的变化作出反应。
或者,您可能正在使用我们新开发的Progressive Lightmapper(渐进光照系统)。通过烘焙光照信息实现的全局光照,在游戏运行时是无法重新计算的,所以不能轻易改变日光时间或天气。不过,对于静态光照设置,烘焙光照信息是完美的选择。
关卡太多,光照不足
烘焙的光照看起来很出色。如果游戏中有复杂的表面,丰富的光照,或仅有一个动态手电筒,全局光照都能使游戏看起来比单独使用动态光照更逼真。人类的眼睛非常善于发现事物不对劲的地方,在现实世界中,光会在几乎所有的东西上来回反弹。
使用Enlighten之前和之后的测试关卡
因此,许多最具代表性的客户都在他们的游戏中使用了某种类型的烘焙光照。这些大型团队中,成员众多,各司其职。他们制作的大型游戏,有大量的数据需要放到内存中。所以,他们必须将游戏分成多个不同的场景文件,以便能高效工作,并可在硬件上运行。
这里有个诀窍,所有的光照数据都是烘焙到当前激活的场景中的,同一时间内,只能有一组激活的烘焙光照数据。如果想让场景看起来不错,必须要做提前考虑。
操作顺序
当包含烘焙光照数据的游戏对象被加载时,它们需要配合光照系统,确定自身对反弹光线的应有效果,如果有的话。这需要在运行时对一些光照数据进行重新计算。
如果在每次加载场景时都这样做,会看到加载时间明显更长。但是,如果在最后加载烘焙光照数据,会发现加载时间大大减少。以我们一个客户的游戏《P.A.M.E.L.A.》为例,可以观察到加载时间从大约8分钟降到2分钟以下。
解决方案
幸运的是,依靠非常严格的场景结构和加载顺序,是可以解决烘焙数据的限制问题的。
创建一个新场景,用于储存一组完整场景中所有的烘焙光照数据。最好给场景取个有意义的名字,比如说<有意义的名字>_Lighting。
在新创建的名为XXX_Lighting的场景下,依次叠加加载所有需要光照的场景。
烘焙光照 —— 烘焙诀窍请查阅Unity预计算实时GI。
运行时,叠加加载加载每一个场景,除了XXX_Lighting场景之外。
当加载完所有其他场景后,加载XXX_Lighting场景。你可以切换到另一组光照烘焙完全不同的场景。只需简单的加载你的第一个新关卡,或加载屏幕场景,不必进行叠加载入。这会清除所有探测器数据或其他共享光照数据。
现在可以继续加载另一组新场景,然后加载与之对应的新的XXX_Lighting数据。
后续可以添加更多数据。但这可能会产生一些性能问题,因为部分的光照数据会因为新添加的数据而重新计算。烘焙光照进来后一定要做性能测试。
未来的光照
我们的光照团队了解同时使用烘焙光照和多场景的困难,正努力寻找在运行时将烘焙光照数据融合到一起的各种方法。留意补丁信息和博客文章,了解更多细节。很多修复已经包含在Unity 2017.2中。如果您的产品发布等不到光明来临那刻,那就用这些技巧让全局光照在游戏中发挥作用吧。我们下次将介绍一些技巧,用于避免因碰撞和物理产生的性能问题。
更多Unity光照技术文章
点击“阅读原文”下载示例工程!