全局光照

全局光照(Global Illumination,GI)是一套模拟系统,不仅模拟光线如何直接照射到表面(直接光),还可以模拟光线如何从一个表面弹射到其他表面(间接光)。对间接光的模拟使虚拟世界的效果看起来更加真实和连贯,因为对象彼此之间会相互影响外观。一个典型的例子是『色溢』(颜色溢出),例如,太阳光照射到红色沙发上,红色光将被弹射到后面的墙上。另一个例子是,当太阳光照射到洞穴口的地板上时,光线将在洞穴的内部弹射,所以洞穴的内部也被照亮。

全局光照 - 图1

场景视图中的全局光照。注意微妙的间接光照效果。

GI 概念

传统的视频游戏和其他实时图形应用程序仅限于直接光照,因为间接光照所需的计算太慢了,因此它们只能用于非实时情况,例如电影动画 CG。饶过这个限制的方法是,只为提前就知道不会移动(静态)的对象和表面计算间接光照。这样,慢速计算被提前进行计算,因为这些对象不会移动,所以预计算的间接光照在运行时仍然是正确的。Unity 支持这种技术,称为烘培 GI(也被称为烘培光照贴图),预先计算间接光照并存储的过程称为『烘培』。烘培 GI 利用大量计算时间,可以有效地生成来自区域光和间接光的柔和阴影,并且比通常用实时技术生成的更加逼真。

此外,Unity 5.0 增加了一种名为预计算实时 GI 的新技术。它仍然需要类似上述烘培的预计算阶段,并且仍然仅限于静态对象。不过,它不仅仅预计算光线如何在场景中弹射,而且预计算所有可能的光线弹射,并对这些信息进行编码,以便在运行时使用。所以,对于所有静态对象,它回答了『如果任意光线照射到表面,将向哪里弹射?』这一问题。然后,Unity 保存光线传播路径的信息,供以后使用。在运行时,通过反馈真实存在的灯光到之前计算的光线传播路径中,完成最终的光照。

这意味,灯光的数量、类型、位置、方向和其他属性都可以改变,并且间接照明将相应地改变。类似地,可以改变对象的材质属性,例如颜色、反射光的数量或自发光的数量。

虽然预计算实时 GI 也可以产生柔和阴影,但是通常比烘培 GI 实现的更粗糙,除非场景非常小。还需要注意的是,尽管预计算实时 GI 在运行时完成最终光照,但是它需要在多个桢上迭代地执行,所以,如果光照场景中发生了大量改变,将需要更多的桢才能完全生效。虽然这对于实时应用程序来说已经足够快了,但是如果目标平台的计算资源非常有限,最好使用烘培 GI 来获得更好的运行时性能。

GI 的局限性

烘培 GI 和预计算实时 GI 都有其局限性,即只有静态对象才能被包含在烘培和预计算过程中 —— 因此移动的对象不能弹射光线到其他对象上,反之亦然。不过,移动对象仍然可以接收使用了光照探针的静态对象的弹射光。在烘培和预计算过程中,会测量(探测)探针位置的光照,并且,在运行时的任意时刻,照射到非静态对象的间接光用最靠近它的探针的值近似模拟。因此,一个靠近白色墙壁的红球,不会溢出它的颜色到墙壁上,但是,一个靠近红色墙壁的白球,可以通过光照探针接收墙壁溢出的红光。

译注:球体是运动对象,墙壁是静态对象。

GI 效果示例

  • 通过改变平行光的方向和颜色,以模拟太阳在天空中移动的效果。同时修改天空盒和平行光,可以逼真地创建在运行时更新的昼夜效果。(事实上,内置新增的过程式天空盒很容易做到这种效果。)
  • 随着一天时间的流逝,穿过窗户的阳光在地板上移动,并且光线在房间内和天花板上逼真地弹射。当阳光到达红色沙发时,红光被弹射到它后面的墙壁上。把沙发的颜色从红色改为绿色,将导致它后面的墙壁也从红色变为绿色。
  • 为霓虹灯材质的自发光属性添加动画,这样当它被打开时,将照亮周围的环境。

下面的章节详细介绍了如何使用全局光照功能。