【转载】使用光照探针实现静态光照
手机游戏引擎手游引擎Unity3D技术地编场景制作3D场景
显示全部 9
5938 0
实名

通过了实名认证的内容创造者

发布于 2019-11-27 16:29:01

您需要 登录 才可以下载或查看,没有账号?注册

x
作者:Tobias Alexander Franke和David Llewelyn,2019年8月28日

image.png





在2019.2版本中,我们移除了光照贴图静态标识,用“Contribute to GI”(帮助全局光照)设置取而代之。同时,全局光照的光源现在可以在光照贴图和光照探针之间选择。这个看上去很小的改动会给场景光照性能与质量上的烘焙造成巨大影响。我们来一探究竟吧。



光照贴图和光照探针

全局光照通过一系列复杂的计算,来算出光从光源射出后在表面间的弹射。要达到精确的计算,一般需要在运行时中加入大量繁重的计算。为了达到最佳光照效果,常见的解决方案是将这些繁重的计算转移到编辑模式的预计算步骤中去。

要实现此种方法,首先得确保场景中的部分对象和光源位置相对固定,不会变形、旋转或改变表面属性。有了这些前提条件,光线便能以光照贴图技术来完成了。

为了标记这些对象,Unity使用了Lightmap Static标识,说明了只有静态对象会使用光照贴图。但静态贴图只是在场景储存全局光照的许多方法中的一种,且有一定的缺陷,我们稍后会继续讨论。

当使用光照贴图来实现全局光照时,非静态(或动态)对象无法对全局光照起作用,因为它们违背了静态这个前提。如果为移动对象添加全局光照,光照只会在起始位置上生效。这是传统光照贴图的主要局限。

动态对象仍能从光照探针接收到来自其他静态对象生成的全局光照。光照探针是空间中的一个个位置点,它能储存各个方向射来的光线采样。此种光照数据被编成叫做“球谐函数”的特殊值。在运行时,动态对象在世界中移动时便能从光照探针周围接收到光照数据。这项功能使动态对象能正确接收到局部光照,融入四周环境的光照条件。

技术上来说,静态对象完全能用光照探针取代光照贴图,所以为什么还要用光照贴图呢?

纹素成本

需要光照的对象必须先展开,并在光照贴图中预留部分空间。根据分辨率,每个投射进光照贴图的对象会保留不同大小的纹素。

比如,在每空间单元一纹素的光照贴图分辨率中,一单元方块(1x1x1)每一面会保留一个纹素,总共会有6纹素。在每个纹素上,贴图将计算照射到纹素位置的光照数据。计算过程是先投射出几条射线,让其在场景中弹射,直到发现一处光源。纹素越多,结果的计算量越大。当场景中有许多小型对象时,计算量便会急剧增加。实际上,此类对象的展开、绘制及光照贴图的添加正是烘焙失败或耗时较长的常见原因。



光照贴图分辨率为1时一单元方块正好占据了一纹素。




较小的物体,如石子和小碎片,或细的对象如电线和旗杆很容易产生“无用纹素”。这些纹素并不会对整体外观有太大影响,但仍旧增加了计算时间,占据了不少贴图空间。

较细的对象常出现仅有一两个像素包裹住物体的展开结果,对整体外观影响较小。同样,小型对象(根据其在屏幕上的大小)经常产生许多对最终效果影响不大的纹素。结果就是产生了许多意义不大的纹素,耗费了大量计算时间,增加了所需光照贴图的量。



可轻易用光照探针照亮的小型对象。




针对生成光照贴图时间的优化方法之一是将这些小型对象设置为非静态,将其移出光照贴图计算,以此来减少需要计算的贴图纹素数量。但是,在部分情况下这些对象对场景光照会有很大影响,比如一个非常明亮的彩色对象,或者有发光材质的对象。如果这些对象不属于Lightmap Static,它们将无法为场景的全局光照产生影响,也就不会产生预期的光照效果了。

因此在处理这类对象时,我们便面临两个选择:为它们添加光照贴图,使其能对场景施加效果,而代价是更长的烘焙时间及更多的贴图空间;或者舍弃它们,降低整体和全局光照效果的质量。如何解决这个两难境地呢?

使用光照探针

在2019.2版中,我们添加了一个功能,使得对象能在接收光照探针的全局光照的同时,给为场景施加光照影响。你可以在检视窗口中Mesh Renderer新加的下拉菜单中激活该功能。



新的Contribute和Receive Global Illumination选项。




在Mesh Renderer中,你能在Receive Global Illumination选择从Lightmap(Unity 2019.2之前光照贴图静态对象的唯一选择)接收全局光照;或选择从Light Probes(Unity 2019.2之前光照探针动态对象的唯一选择)接收全局光照。

当Contribute Global Illumination启用时,该对象会被包含在光照贴图的全局光照计算中。虽然前提仍是假定对象静止不动,但现在你可以根据具体的光照保真度要求,指定对象使用光照探针或光照贴图。当勾选Contribute Global Illumination时,同时选择从光照探针接收全局光照,那么该对象仍会对周围环境产生影响。一杆高大的路灯可以投下经由光照贴图计算的阴影,同时路灯上的发光材质也会照亮周围场景。

如何使用

有了这项新功能后,在Unity中优化这些麻烦的细小对象就简单直接了:只需将Mesh Renderer中Receive Global Illumination一栏选为Light Probes。设置完后,指定的对象便不会在光照贴图中占用空间,而相应的纹素也不会再产生不必要的计算。

光照探针另一个较为关键的优点是它不需要合适的UV来工作,能省去许多UV展开时间。如果有一个不会移动、旋转或改变的动态对象,在光照探针下表现较好,可以为它勾选Contribute Global Illumination,该对象便能在不增加烘焙时间的前提下,影响周围添加了光照贴图的对象。如此一来,我们能极大地增加生产力,减少内存的使用量。





结论

有了这次更新,动态(非静态)对象就能用光照探针来接收光照了。在全局光照计算中,你可以决定对象从光照探针或光照贴图中接收间接光照,减少光照贴图中的纹素使用。总之,这次改动将大幅减少光照贴图的计算时间,降低内存使用,提升运行时的性能。





评分

参与人数 1元素币 +10 活跃度 +12 展开 理由
源支始 + 10 + 12

查看全部评分

使用道具 <
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表