在理解到当在我们的场景中有大量的光照图表时,这对预计算时间来说是有害的。我们能够从从预计算处理中完全地选择排除一些对象物体去极大地提高光照的表现性能。这将会减少光照图表的数量。来取而代之的是,我们可以在这些对象物体上使用探头光照(probe lighting),对于这些使用探头光照的物体从场景中接受间接光照来说,这是一种比较有效率的方式。尽管探头照亮的物体将不会对场景产生反射光照,但这往往是没有什么明显的影响的。对于适用于采用探头光照的对象物体往往是较小的物体,因为这些较小的物体对反射光的影响不大。
什么是探头光照(probe lighting)?
探头光照是在实时渲染应用中一种快速的近似光照技术。它通常被用于在游戏世界中的角色以及其他非静态(动态)对象物体的光照处理。探头光照在游戏运行时性能很好而它额外的好处是预计算会很快。
探头光照的原理,是通过在3D空间中一个指定的点来采样进来的光照信息,然后用球谐函数(spherical harmonics)的这种数学方法将采样的光照信息编码在一个球体上。这些系数占用很小的存储空间,在游戏运行时被快速地”解包"后,被shader所使用,去近似模拟场景中的表面光照。在Unity中这种功能由光照探头(Light Probes)所提供。
使用光照探头会有一些限制。一个这样的限制是,难以在不增加这些光照探头数量的情况下,在整个球面范围内表示高频或斑驳的光照。不幸的是,随着精度的提高性能开销也会迅速升高,这意味着出于性能原因,我们被限制在低阶球面谐波函数。
实际上,对于世界中的一个3D位置只有一个球形的光照表示,这使得探头光照不适合用于有大量变化的光照投射在大物体表面的情况。另一个限制就是当用球谐函数在一个球体上进行编码时,通常不擅于处理拥有特大平面的物体或是带有很深的凹洞的物体。如果想要将探头光照技术用于大型物体,可以参考Unity手册中提供的另一个光照探头代理体(Light Probe Proxy Volumes, LPPV)技术做进一步了解。
尽管有这些限制,探头光照技术还是很适用于和符合条件的小物体一起搭配使用,以较低的成本消耗发挥出卓越效果。 我们后续将深入探讨如何设置及摆放光照探头(Light Probes),现在我们只需要理解,通过选择在场景合适的地方使用探头光照,我们就能减少光照图表的数量。
选择用探头光照的对象物体
尽管通常我们为了进行光照计算,将在Environment组下的游戏对象物体都设为静态物体,但是在这个Environment父物体对象下的很多对象都更适合用探头光照技术进行处理。清除这些对象的静态标签将意味着他们不会被Unity的PRGI系统进行光照计算,因此将会减少光照图表的数量。请记住加快预计算的时间的关键就是要减少我们场景中光照图表的数量。
从Unity编辑器的层级视图(Hierarchy)检查Environment下的子对象,会发现Props对象物体下的子对象物体几乎都是小的,碎片化的点缀场景用的小物体,例如:石头、水桶或木板。 这些物体非常多,并且展开它们的UV将会相对比较复杂。获取不失真的光照贴图UV可能会产生很多UV Shell,一旦UV Shell过多就会需要额外的光照图表,更多的光照图表意味着更多的光照贴图的纹素需要被计算,等等.
假设这些对象物体如此之小,它们对场景中不太可能产生很多间接的光照。同时,它们的大小尺寸意味着它们表面能显示的光照细节也有限。所以这样的物体非常适合用探头光照技术,由于减少了需要加载到内存中以及在shader中解码的光照贴图的数量,不但加快了预计算时间,而且改善了游戏运行时的性能。具体操作如下:
* 从层级视图(Hierarchy)选择Props对象。
* 在检视面板(Inspector)中取消勾选最右上角的Static。
* 在弹出的提示框中,选择"Yes, change children。
对于这种情况,如果我们留给预计算的时间足够长的话,我们最终将会在场景视图中看到我们想要的光照结果。我们将可能会注意到我们的probe-lit, non-Static 对象物体会和它们周围的物体有明显的不同,并且和场景中的光照不匹配。这是因为我们还没有安装我们的光照探头,因此这些对象物体还是在使用场景中的环境探头(Ambient Probe)。Ambient Probe本质上是一个在场景中隐藏的探头,它对用户来说是不可见的,它只对在Lighing window中设置的Ambient Source进行采样。
为了让静态物体在它们照亮的环境获得更令人满意的效果,我们需要花点时间在场景周围放置光照探头,以便对世界中的间接光照进行采样。
放置光照探头
非静态物体会通过附近的光照探头接受光照信息。将光照探头之间的空间划为为四面体,然后检查看给定的对象物体落在了哪个四面体中,这样来决定一个对象物体从哪个光照探头去读取光照信息。为了生成这些四面体,光照探头因此必须被放置成一个3D立体的形状,或者是笼子的形状。
探头光照技术在游戏运行时性能开销比较小而且它可以很快地预计算。然而为了性能最优化,需要注意的是何时放置光照探头。尽管设置更加快速,但稠密网格状放置的探头可能会浪费资源,因为这些光照探头中的许多在局部光照条件下将不会采样很多变化。为了效率,更好的做法是在光照变化明显的区域放置密度更高的探头,例如那些由亮变暗的区域,或者那些由反射光照造成的浓重颜色的区域。设置光照探头的具体方法如下:
* 从GameObject 菜单新建一个光照探头群组(GameObject > Light > Light Probe Group).
* 现在我们将会开始放置我们的探头。在Hierarchy视图选择新建Light Probe Group。
* 在 Inspector 面板中,从 Light Probe Group 组件选择Edit Light Probes开始编辑。
* 你可以在Scene视图选择探头,除了创建的默认立方体其中一角上的探头以外,删除所有其它的探头。
* .将环境中剩余的探头移动刚好到Terrain的上方,然后通过按下Ctrl+D来复制它(在Mac中按下Cmd+D)
* 通过使用Translate工具,沿着Y轴移动这个第二个探头到第一个探头上方的2米处。
* 现在再一次的复制探头并且沿着Y轴移动新复制出来的探头到更远的地方,比如5米。
这样创建一个垂直的布局的原因是我们能够从地面,从头顶附近的高度以及从空中来采样间接光照。当我们为了创建立体的探头布局而在场景附近复制这些光照探头时,我们想确保这些对象物体在可玩区域的任何地方都会落在由探头之间生成的立方体中。可以看到光照探头之间会以品红色的线来绘制这些立方体区域。
* 通过按住Shift键并且分别点击每一个或通过拖拽一个框选来全选三个你刚刚创建的探头
* 复制整个我们已经创建好的垂直链并且移动它到场景中一个需要光照采样的区域附近
需要采样的地方不外乎是有阴影的区域或是地形材质色调会变化的地方。请记住,我们的目的是对场景里的间接或反射光照进行采样。 为了让每个光照探头的性能都用在刀刃上,尽量确保它们对一些光照变化明显的地方进行采样,如果光照探头被放在一致性很高的光照区域,那么当接受光照信息的对象物体通过这些光照探头时我们不太可能看到很多变化。 如同游戏优化的许多方面一样,我们必须确保包含进我们场景中的每一个光照探头都有它存在的价值。
* 继续重复这个过程,将光照探头更多地放置在光照变化的区域,直到创造一个罩住可玩区域的笼子一样的布局。
* 当放置我们的光照探头时,时刻记住去检查最底部的光照探头,让它要刚刚好地离开地表一段距离。
在我们的例子场景LightingTutorialOptimal中:我们已经创建了两组光照探头组。VillageLightProbeGroup比较密集、用于村庄区域,ExtentsLightProbeGroup比较稀疏、用于村庄外无法到达的区域。这第二组覆盖了游戏世界的范围以防止任何非静态物体离开可玩区域。我们在这些场景不可到达的部分不需要有相同的保真度,因此第二组不需要像第一组那么稠密,在垂直的轴向上有两个探头就足够用了。
将光照探头组拆分成两个GameObject可以使放置探头更加的容易。为了在场景中工作时呈现一个更清晰的视图,每个光照探头组都可以独立开启或关闭,.些光照探头在运行时会自动组合并执行重叠检查(de-duplication pass)以删除所有重叠的探头。
想看到光照探头的照明结果,必须等到预计算完成,如果勾选Lighting视图(Window > Lighting)下的Auto选项,就会自动进行计算,如果未勾选,则需要按下旁边的Build按钮来手动计算。
一旦这个过程处理完成后,你会发现场景里面的非静态物体会开始从光照探头读取光照信息,而且看起来和场景光源会更匹配。如果要查看照明状态下的光照探头,可以从层级视图(Hierarchy)取消选择光照探头组。
现在场景里有了光照探头组,我们就能为场景中的小物体取得间接光照信息,而不需要从PRGI的流程中为这些物体生成额外的光照图表。