Unity 5.6中的混合光照(上)

时间:2021-01-11 07:08:15

https://mp.weixin.qq.com/s/AbWM21sihHw5pFdMzENDPg

在Unity 5中,光照得到了很大的改进。现在,创建高度逼真的游戏已成为可能。但是,出于对性能的考虑,许多Unity开发的游戏仍然依赖烘焙光照。但有时候又必须使用实时和烘焙光照,而这在之前是Unity的短板。如今在5.6中,Unity已解决了这个用户呼声很高的需求。

光照功能对新手来说可能比较神秘,因为编辑器默认不会显示光照UI。而且我们的调查显示,几乎所有新手对于光照贴图都没有概念。因此,我们重构UI使它更显眼,不过,有些概念性的知识还是必须要了解的。在本系列的第一部分中,首先简要介绍实时光照与烘焙光照(光照贴图)之间的区别。之后再对混合光照进行讲解。如果你已熟悉这些概念,可以直接跳过。

预计算实时GI和烘焙GI光照

首先,Unity中新的光照模式没有为预计算实时GI带来任何新的内容,而是为用户提供了可以在场景中同时使用实时与烘焙光照的新方法。实时光照很容易理解,对灯光的任何调整会即时更新场景中的所有光照。唯一的问题是这么做产生的性能消耗。每次主动调整灯光,都会对性能造成很大影响。因此,Unity同时引入光照贴图的概念。可以烘焙光照,并将所有光照数据以光照贴图的形式保存在项目中。这样做代价很低,因为本质上它仅仅是一个纹理。

烘焙光照与实时光照的一个主要区别是:烘焙光照都是静态的,你无法移动光照贴图静态对象,否则就会出现问题。将游戏对象设置为光照贴图静态也很简单。只需在检视窗口中将它们标记为静态(或只是光照贴图静态)。这样可确保Unity会为该对象烘焙光照贴图。如果你希望对象保持动态,就无需这么做,它们默认就是动态的。

预计算GI – 日夜循环

有关这方面概念的详细介绍已超出本文范围,而且Unity官网上已有一个完备的系列教程,由David Llwelyn和光照团队亲自操刀制作,介绍了Unity中使用实时GI光照的优化技巧。

除此之外,我们最近还更新了AssetStore中的Courtyard示例,使之与Unity 5.5兼容。你可以查看下该项目,了解如何在项目中使用实时光照。

直接光照与间接光照

许多新手容易忽略的另一个重要概念是,直接光照与间接光照之间的区别。与实时光照类似,直接光的概念也很容易理解。即从一个光源发射的光子射线直接影响了一个物体。这是你能直接观察到的。

相对难理解的是间接照明这个概念。基本上,间接照明由反弹光照来实现。除了直接光照,我们还可以有反弹的光照。可见光子在一个场景中基于数学公式做简单的反弹。下图展示了间接照明的原理。

Unity 5.6中的混合光照(上)

通过Light组件的“Bounce Intensity”参数,可以设置一个灯光的间接光贡献度。举例来说,如果你希望禁用间接光贡献度,可以把这个参数设置为0。

所以,预计算实时GI很有趣,在Unity中发挥的很完美。但是,它代价很高,而使用Unity的开发者多数以低端设备(移动平台)为目标,为了应对性能问题(VR),需要有优化的场景设置。然后就会选择对所有静态对象进行光照烘焙(例如,环境),对所有动态对象(例如,角色)使用实时光照。所以,这将带我们进入下一个问题。

混合光照

混合光照这个术语本身已经相当的不辨自明了。混合光照让用户可以混合使用实时和烘焙光照。前面我们提到的用例是多数游戏使用的一个典型场景。例如在《Last
of Us》中,环境场景是固定的,因此其对应的所有东西都储存在光照贴图中,而所有移动对象则使用的是实时光照。

可以首先烘焙所有环境,然后对角色们使用实时光照。但这样会引致一个严重问题:所有的已烘焙对象也会接收动态光,而这意味着它们将会被双重曝光,使这些对象过于明亮。当然,也可以对这些烘焙对象进行实时光遮蔽,但这很容易造成亮度值不符。下面的图像就是此问题的一个例子。应用了相同材质的相同几何体,但其中之一是动态的,另一个是静态的:

Unity 5.6中的混合光照(上)

这样可能还可以接受,但在有些情况下这可能就相当辣眼睛了:

Unity 5.6中的混合光照(上)

此时就该混合模式登场了。理想情况下,混合模式会为你料理好一切,照亮相同平衡范围内的动、静态对象(从而保留了视觉逼真度与一致性)。

在Unity 5.5中,你可以在检视面板中将Light Type设置为Mixed,启用混合光照。

现在可以安全地对动态和静态对象使用混合光照了。等等……为什么当使用混合聚光灯或点光源的时候,动态对象没有投射任何阴影?

原来期望聚光灯能同时影响动态与静态的几何体。是我错了而这是默认的行为吗?是我遗漏了什么东西还是这是一个Bug?

Unity 5.6中的混合光照(上)

很多开发者会好奇为何混合聚光灯不会投射任何阴影

导致该问题的原因是,混合光照仅当只有一个定向光时才能正常工作。等等,你说什么?

Subtractive模式

这就是在Unity中引入新光照模式的主要原因,基本上就是为了解决这个问题。在光照窗口中你有四种光照模式可以选择。它们是Baked Indirect, Distance Shadowmask, Shadowmask以及Subtractive。仅有三项新的光照模式加入。其中Subtractive是老的混合模式,与其他模式相比它的性能消耗要小,这在你开发诸如移动应用时,仍然有些用处。

让我们用Unity的技术术语来重新描述下这个模式的工作原理:选择‘Mixed’烘焙模式,标记为静态的游戏对象会把来自混合灯光的信息保存为光照贴图。但是,与标记为‘Baked’的灯光不同,混合灯光还会为场景中的非静态(动态)游戏对象提供直接光(实时)。我们提到过仅有单个定向光时它才能正常工作吧?没错,因为混合点光源和聚光灯不会在对象上投射任何阴影。

此外,Subtractive模式里还有另一个特定的功能。与其他模式不同,直接光也是烘焙的,因此在Subtractive光照模式中,没有镜面反射。

探针遮蔽

在Subtractive模式中,另一个动态对象需要使用的重要组件是光照探针组。没有光照探针,动态对象无法对用于静态对象的光照进行采样,而且更重要的是,它们无法使用遮蔽数据。因此,为了能接收阴影,动态对象需要将来自光照探针的光照进行混合。在下面的图象中,你能看到一个动态对象是如何利用光照探针做遮蔽的:

为了实现更精确的遮蔽,可以为场景中重要的对象(例如,主要角色)指定光照探针代理体(LPPV)。但是注意,这会带来额外的性能消耗。

色彩空间与Subtractive模式中的渲染路径

关于Subtractive模式还有最后一点需要提下。这个模式是为前向渲染路径和Gamma颜色空间设计与保留。不适用于延迟渲染路径和Linear颜色空间。这是因为Subtractive模式与其他模式相比,性能消耗要相对较小,主要用于低端设备,例如移动平台。有关渲染路径和色彩空间的有关详细信息,可以在官方手册中查看。最后,我们介绍了Subtractive模式在Unity
5.6中的实际应用。

在下一篇中,我们将讨论新的光照模式(Distance Shadowmask, Shadowmask 和Baked Indirect),以及如何在项目中使用它们。