光照是游戏中最重要的元素之一,它能起到营造气氛、指引玩家、标记等作用。可以这么说光照可以左右游戏视觉效果的成败。
光照模式
根据光源在场景中的移动方式或使用方式使用不同的光照模式。不同类型的光照模式具有不同的性能特征。在实现光源时,请考虑以下几点:
1、对静态光照使用烘焙。
对于在运行时光照不会改变的对象而言,烘焙是最理想的选择。烘焙光照是指预先计算光照数据并将其存储在称为光照贴图的纹理贴图中的过程。
烘焙出的光照不能在运行时进行修改。光照贴图中的光源和阴影是静态的。由于所有光照均在Unity中预处理,因此不存在任何影响性能的运行时光照计算。
动态阴影无法使用烘焙光照创建。对于动态或移动对象而言,烘焙光照的效果看起来可能比较违和。
2、对于打算与移动对象相互作用的静止光源,请使用混合光照。
例如,火炬将光线投射到玩家身上,并随着玩家经过而产生阴影。混合光照会产生动态直射光和阴影。可以在静态对象的光照贴图计算中包含混合光照。可以在运行时更改强度。仅直射光会更新。
3、对于动态或可移动光源,请使用实时光照。
例如从地面升起然后爆炸的火球所投射的光线,动态光源和阴影属性可以在运行时进行修改。实时光源不会被烘焙到光照贴图中。
开销非常高。
尽可能使用静态光源而避免使用动态光源
动态或实时光照需要在每一帧进行计算和更新。这非常适合移动对象,也适用于互动和表现情绪。
与之相反,静态光源信息被烘焙到光照贴图中。使用光照贴图纹理可以让对象避免开销极高的逐顶点或逐像素光照计算。光照贴图纹理的渲染开销始终远远低于动态光照的渲染开销。因此,我们建议在移动游戏中优先实现烘焙光照。
光照贴图烘焙
预先计算光照效果称为光照贴图烘焙。光照效果存储在名为光照贴图的单独纹理中。光照贴图可用于增强对象的外观。每次场景迭代只需要进行一次光照贴图烘焙。如果更改了场景的几何体或更改了烘焙光照的参数,需要重新烘焙光照贴图。除了光照贴图纹理的开销之外,在运行时不会产生任何额外的性能开销。这是最适用于移动平台的初步光照方法。
烘焙光照不受场景中任何动态元素或移动元素的影响。烘焙光照包括所有静态元素的烘焙全局光照。这意味着光照贴图计算包括由其他静态对象反射的间接光以及直接照射对象的烘焙光。
烘焙光照的三个步骤
第1步:将光照模式设为混合或烘焙模式
将光照的Mode设为“Mixed”或“Baked”。对于移动游戏,最好优先使用烘焙光照,混合模式次之。烘焙是开销最低的光照渲染方式。
第2步:将对象设为静态
将任何受烘焙光照影响的对象设为Static。虽然有许多针对被标记为静态的对象的优化,但一般情况下最好在Static下拉列表中选择Everything。将对象标记为Static之后,Unity就知道应将其包含在光照烘焙中。
第3步:烘焙光照
您可以依次选择Window>Rendering>Lighting Settings,使用其中的Lighting菜单来烘焙光照。
烘烤光照时,保存的数据根据启动烘焙时处于活跃状态的场景而定。系统会生成一个与烘焙的场景同名的文件夹。此文件夹用于存储光照数据的所有组成部分。如果您的项目一次加载多个场景,您必须为每个场景烘焙光照。在调整场景后,您也必须重新烘焙光照。
优化光照贴图
设置好要烘焙的光照后,请确保烘焙出的贴图经过优化。光照贴图的大小因其烘焙时的设置而异。在移动设备上,您必须尽量减少内存用量,因此必须监控光照贴图大小。
光照贴图程序
Unity提供以下三种方法在场景中烘焙光照:
Enlighten:仅在2020年长期支持(LTS)版本之前的版本中受到支持。请勿在新项目中使用此方法。
Progressive CPU:可以节省大量时间,因为此方法逐步创建光照贴图。如果选择了Prioritize View,就会优先处理“Scene”视图中的区域。这可以缩短用于设置场景光照的迭代时间。
Progressive GPU:与Progressive CPU的工作方式相同,但在GPU上而不是CPU上生成光照贴图。在受支持的硬件上,与使用CPU相比,此方法可大幅缩短烘焙时间。
纹素
纹素即纹理像素,是纹理贴图中的单个像素。纹素将照射到对象上的每个光点的光照信息存储在光照贴图中。如果每单位空间使用的纹素较多,就会影响光照质量、烘焙计算时间、磁盘存储开销以及光照贴图的VRAM开销。
如需减少所需的光照贴图数据量,请在Lightmapping Settings中调整每个烘焙单位的纹素数量。
请尽量避免将纹素用于以下对象:
玩家看不到的表面和对象。这可以防止在光照贴图上为屏幕上看不到的细节浪费内存。
光线变化不大的表面。例如,阴影中的对象或受到单一光源照射的对象。
小或薄的对象。这些对象受到的光照量对场景的最终渲染效果增色不多。
尽可能多使用假光照
为减少需要处理的对象,您可以伪造某些元素。这会使您的内容看似使用了光照,其实使用的是更高效的方法。
假阴影
实时阴影开销很高。它们通过一种称为阴影贴图的技术生成。将场景的几何体渲染到阴影贴图的开销与启用阴影的情况下绘制的顶点数量成正比。我们建议您限制投射阴影的几何体数量和实时投射阴影的光源数量。
针对没有动态光源的动态对象的阴影,您可以实现假阴影。这种做法既可以降低渲染开销,又能实现与动态阴影类似的效果。以下是实现假阴影的一些方式:
将3D网格(例如平面或四边形)放置在角色之下,并对其应用模糊纹理。
您可以自行编写自定义着色器,实现更复杂的模糊阴影。
如果将部分阴影绘制到纹理中,就可以减少额外的光照所需的计算量。这种做法可以在烘焙场景的光照时节约内存,因为它需要的光照贴图数据更少。
光照探针
当您使用的动态对象采用烘焙光照时,这些对象不会受光照贴图影响。这可能会使人觉得它们不太像场景的一部分。
您可以用光照探针来解决这个问题。光照探针具有与光照贴图类似的优势。它们也能存储可提前计算和保存的光照数据,以便在运行时使用。这样就可以将大量计算开销转移到编辑时。
光照贴图对表面纹素中接收到的光线进行编码,而光照探针则存储穿过空白空间的光线。您可以使用此数据对移动对象提供光照。光照探针可将整个场景中的动态对象与光照贴图对象在视觉上融为一体。
光照探针最适用于为场景中移动的对象提供光照。探针利用的是烘焙出的光照,这能使移动的对象与场景具有相同的光照。使用光照探针为动态对象提供光照的成本要低于使用实时光照。
Mesh Renderer设置
无论您的场景使用哪种类型的光源,Mesh Renderer设置都必须正确无误。
请关闭所有不使用的功能。在渲染场景时,即使不为对象提供光照,Cast Shadows等设置也会增加开销。以下示例是图13中显示的某个角色的Mesh Renderer设置。该角色使用了光照探针数据,但未使用反射探针。
光照探针的Blend Probes设置可将距离最近的光照探针的光照信息混合到角色中。当角色在场景中移动时,影响该角色的光照探针会随之改变。由于渲染程序使用了模糊阴影方法,因此关闭了Cast Shadows。此外,由于场景是烘焙的,没有实时阴影,因此也关闭了Receive Shadows。
鉴于态光源开销极高,我们建议不要在所有移动游戏中都使用动态光源。
实时光源与光源类型
建议您使用烘焙光照、光照探针和假光照技术(例如绘制的光照纹理或着色器材质效果)来处理光源。但是,如果您需要实时光源,那么您必须考虑要使用的光源类型。
每种光源类型的光照计算开销各不相同。下面列出了每种光源类型的详情:
方向光:这种光源具有一致的方向,且不会减弱。方向光是开销最低的实时光源。每个场景通常只需要一个方向光。采用前向渲染(建议针对移动平台采用的渲染路径)时,如果场景中没有方向光,Unity会添加默认的方向光。
聚光灯:聚光灯会剔除锥体以外的对象,不会为其提供光照。因此,聚光灯的计算开销低于球面点光源的计算开销。为了获得最佳性能,请严格限制锥体宽度,仅照射预定对象。
点光源:这种光源在所有方向上投射光线。在所有方向上投射光线很有用,但开销非常高。在广阔区域内大面积使用点光源的开销极高。此外,阴影计算可能会成为光照计算中开销最高的部分。如果在所有方向上投射光线,阴影就会增加,进而增加计算量。
注意:支持的动态光源数量可能有限制,具体要看目标平台和图形API。