初步介绍
新年假期结束了,想不想掌握一个新技能迎接全新的一年呢?不妨来阅读一下Unity预计算实时GI系列文章。本文是该系列的第一篇。
在Unity中有两种区别很大的技术被用于计算全局光照GI或光源反射,它们就是烘焙全局光照(Baked GI)和预计算实时全局光照(Precomputed Realtime GI)。本文主要介绍预计算实时全局光照(PRGI),学习如何使用Unity全局光照计算系统 — Enlighten系统来优化一个场景,让预计算只需要几分钟而非几小时。
为什么要使用PRGI
当启用PRGI时, 光照预计算指的是计算静态几何对象周围光的反射,并存成数据给Runtime执行使用的过程 。这个过程减少了原本必须在Runtime执行时的光照计算量,可以让项目在保持FPS稳定的同时,还允许使用实时反射光照。
当启用烘焙GI(Baked GI)时,预计算的过程会计算并产生传统的光照贴图(Lightmap),这些贴图会以资源(Assets)的形式存在项目中,但是无法在Runtime执行时被更改。而PRGI则是使用不同的方法生成光照贴图, PRGI计算的结果会被存成光照数据文件(Lighting Data Asset),这些数据可以在Runtime执行时实时产生和更新一组低分辨率的光照图。
不过,除非场景已经为PRGI计算优化过,否则完成这些计算所需的时间可能会很长。下面我们一起来看一下如何针对Enlighten系统来做场景优化,从而把预计算时间从几小时缩小到几分钟。我们将会涵盖以下几个要点:
一旦我们学习并了解了这些技术,我们就可以充分利用PRGI的优点: 快速的光照迭代,以及在打光过程中和在游戏过程中对实时反射光照进行快速试验的能力 。
PRGI优化演示
在下图所示的场景里,用没有优化过的默认设置,在我们的测试机上预计算光照大约花了7.5个小时。显然这是无法接受的!
使用本教学所介绍的技术进行大约30分钟的场景准备后,这个场景的预计算仅仅花了2.25分钟就得到了产品等级的效果。这个技术的好处是显而易见的,因为我们可以在游戏过程中快速迭代场景照明而不需要重新计算GI和改变GI照明。
学习前准备
您可以在 Asset Store资源商店上下载官方光照优化素材包 ,跟着我们进一步学习。本教学所用的是Scenes/Article目录下的范例场景:
Unity预计算实时GI (二)实时分辨率
我们已经在《Unity预计算实时GI (一)介绍》中聊到Unity预计算实时GI的必要性和学习准备,并且了解到实现这个过程需要考虑的问题。本文我们对如何定义一个适合场景的光照分辨率进行了相关介绍,一起来学习一下吧! 如何调整实时分辨率? 当使用PRGI来计算场景照明时,首先要做出的决定之一是确定场景的实时分辨率(Realtime Resolution),因为它决定每个世界单位所使用即时光照的贴图像素数量。Realtime Resolution设定可以在Lighting窗口中找到并调整,方法如下:
Unity的Lighting窗口:主要显示整个场景会用到的光照设定。
但这个分辨率应该如何设置呢? 选择适当的分辨率 在设定场景时,首先要要了解你的项目使用的单位比例,可能在你的项目里一个单位等于现实世界的1米、一英尺或一公分。Unity没有默认真实世界的单位,所以要由开发者自行决定。 在这个范例里我们采用1 unit(单位) = 1 meter(米)。因为这和Unity的物理概念不谋而合。举例来说Unity的重力预设就是以每秒多少单位来计算的,因此设定1单位 = 1米对于一个真实世界的场景来说是恰当的。 Realtime Resolution的值通常可以由游戏世界的规模来制定。例如,你的场景是一个拥有丰富光照变化的室内环境。在这种情况下,高一点的值比如2 - 3,可以捕捉到更详细或"高频"的光照。 如果你的场景是一个规模较大的户外环境,可能覆盖了几百甚至上千单位(平方米)的表面,而这些表面并不会剧烈地改变反射光的颜色。在这样的情况下,把适合计算复杂室内场景的设定用在有大量相同特征的室外环境是很浪费的。我们会浪费宝贵的CPU时间和内存去更新那些对整体外观贡献不大的光照贴图。为了教学目的,我们会提高PRGI计算期间必须考虑的光照贴图的像素数量,这会对预计算的时间造成很大的影响。针对室外环境,可以为场景中尺寸较大的游戏对象设置0.5 - 1的texel,针对地形可以设置0.1- 0.5的texel。 Unity PRGI所需要的Realtime Resolution值比传统光照贴图密度要小好几个等级,这是因为我们只从这些光照图里获取间接光数据,且这些数据通常分辨率都很低。所以使用PRGI时,清晰的阴影通常都是通过实时运算而非高分辨率的光照图来提供的。 在这里使用传统光照惯用的值,例如:30 texels,可能会导致预计算失败或无法计算。室内场景比较适合的值是2 - 3,室外场景则是0.5 - 1。这是我们在使用1单位 = 1米的前提下,如果单位大小不同这些值就需要调整。 具体可以参考以下的场景与Realtime Resolution值对照表(1单位代表1米): 当设定场景实时分辨率时,Unity会指定给场景内的静态对象。新建的带有Mesh Renderer且标记为静态光照(Lightmap Static)的对象,会使用这个值一直到它被其他设置修改。 除了帮场景加上分辨率设定外,我们还能针对每个对象调整光照贴图的分辨率,在需要高分辨率来提供更高真实感的情况下,我们可以选择性的提高这个值。通常是将场景里最多的对象分辨率设为默认值,然后手动调高需要更多照明细节对象的值。 练习一下 如果你想跟着做,打开教学素材包里的LightingTutorialStart场景。 在范例场景里,我们有一个户外环境,具有中等大小的地形与相当一致的色调。所以我们设定Realtime Resolution为0.5像素/单位就足以处理从场景其他对象来的光照反射。然而,场景里也有些贴图细腻的木屋。由于场景里有比地形对象还多的房子,我们应该把默认的分辨率设定为适合房子的数值。然后我们可以单独修改地形对象的分辨率,这样可以降低场景准备的工作量。考虑到这点,我们用1作为我们的默认分辨率,操作步骤如下:
由于我们的世界单位设定为1单位 = 1米,这表示由PRGI所产生的光照图将会是1x1米的大小,或许你看起来很低,那是因为我们只抓取间接光照。还会从场景里的直接光源计算清晰的阴影和反光。
Unity预计算实时GI (三)了解光照图
我们曾经为大家介绍了预计算实时GI的必要性,以及在实现预计算实时GI时,如何定义一个适合场景的光照分辨率。本文我们一起来看看光照图,了解一下它是如何影响计算时间的。
最小的4x4 texel的UV光照图
如上图所示,这是最小的4x4单位的UV光照图,为了防止贴图过滤造成的渗色,UV贴图始终被光照图包住并空出一半texel的宽度。
在预设的情况下,每张光照图最少要有4x4 texel的大小,所以说不管世界中的物体或对应的UV有多大,一张图表至少需要16个texel。因此如果有一个1x1米的对象并带有一个图表,间接分辨率是1,那这个对象就会需要16个texel来表现。最后Unity会将这些图表缝合在一起,作为模型边缘的光线取样参考。Unity需要每张图表的边缘至少有4个texel,方便在缝合不同光照图时有对照的依据。 要注意的是使用实时GI时不需要自己去填这些UV的边,因为Unity在处理网格汇入的流程时,会自动将光照UV图向内挤出一个边框的空间。这样就能让相邻的图表无需做渗色处理,也能保持双线性插值(Bilinearly Interpolated),能节省宝贵的光照贴图空间。 光照图如何影响计算时间? 要弄清楚这个问题,我们可以试想一下: 1x1对象如果带有50张光照图,Unity会为它创建800个texel。尽管这个数字看上去不是很大,但说明了当图表的量一大就会快速拉高texel的量。越多的贴图像素意味着更为繁重的光照运算要处理,更多的光照数据要计算、压缩和储存,这些因素都会提高场景的复杂度,并导致运行时长时间的计算和较低的效率。 不合理的光照图规划一般是导致计算耗时过长或无法完成的主因。也因为如此,我们许多减少计算时间的方向大多都是思考如何降低场景内光照图的数量。
Unity预计算实时GI (四)开始预计算
我们在先前已经为大家介绍了预计算实时GI有关的内容,从初步的介绍,到实时分辨率计算,再到光照图的认识,已经为预计算的实现打下了基础,下面就一起看看如何开始预计算吧!
对场景中的对象进行分类有助于频繁重复选择对象的操作
最好的做法是先从Lighting设置中确定初步大方向,然后边做边调整细节设置: • 选择场景里的"Environment"对象 • 勾选检视面板(Inspector)右上方的Static • 如果系统跳出对话框,提示是否要将该对象下的子对象也一起标记为静态对象,请选择”Yes, change children"。 这样就能确保所有在Environment里的对象都变为静态对象并纳入光照计算。 现在场景内有了一些静态对象之后,我们就可以开始计算GI了,步骤如下: • 打开Lighting界面(Window > Lighting)然后选择Scene标签页 • 确认勾选界面最下方的Auto(最下方Build按钮旁,如果打勾Build按钮会灰掉) • 然后系统就会开始计算光照。 画面的右下角会出现一个蓝色的进度条,显示目前的工作(几分之几)以及需要计算的工作量。 • 如果未勾选Auto,也可以手动点击Build进行计算,系统会先询问是否要存档后开始计算光照。 本次教学建议直接勾选Auto即可。 进度条显示目前进度,并提示等待计算的工作量 Unity预计算实时GI (五)光照探测
|