【Unity-Graphics】Choosing a Lighting Technique

选择一种光照技术(Lighting Technique)

广义上说,Unity中的光照可以被认为是“实时(Realtime)”或“预先计算(Precomputed)”,这两种技术可以组合使用来创建身临其境的场景光照。

在本节中,我们将简要介绍不同技术提供的机会(Opportunities ),相对优势和个性化特征。

实时光照(Realtime Lighting)

默认情况下,Unity 中的灯光——方向光(Directional Light)、点光(Point Light)、聚光灯(Spotlight)都是实时的。 这意味着它们可以直接向场景做直接光照,并在每一帧中更新。 随着灯光和GameObjects 在场景中移动,光照会立即更新, 这在场景和游戏视图中可以观察到。

【Unity-Graphics】Choosing a Lighting Technique

这是实时灯光( Realtime light )单独作用的效果。 注意,阴影是完全黑色的,因为没有反射过来的光。 只有落在聚光灯(Spotlight)锥体内的表面才会受到影响。

实时光照(Realtime Lighting)是在场景中照明物体的最基本的方法,对于照亮人物或其他可移动几何物体是很有用的。

但不幸的是,Unity 中的实时灯光(Realtime lights)的光线(Light rays)在只有它们自己时是不会反射的。为了使用全局光照等技术创造更逼真的场景,我们需要启用 Unity 的预先计算(Precomputed)的光照解决方案。

烘焙全局光照(Baked GI Lighting)

当“烘焙(Baking)”一个“光照贴图(Lightmap)”时,会计算场景中光线对静态物体的影响,并将结果写入叠加在场景几何顶点上的纹理(Textures),以产生照明效果。

【Unity-Graphics】Choosing a Lighting Technique

左:一个简单的使用光照贴图的场景。 右:Unity 生成的 Lightmap 纹理。 注意如何阴影和光照信息是如何捕获的。

这些“光照贴图”可以包括撞击表面的直接光以及从场景中其他物体或表面反射的“间接”光。这种光照纹理可以通过与物体材质(Material)相关联的“着色器(Shader)”与表面信息如颜色(反照率)和浮雕(法线)一起使用。

使用烘烤光照,这些光照纹理(即光照贴图 Lightmap)在游戏过程中不能改变,因此被称为“静态(static)”。实时灯光可以叠加在一个使用光照贴图的场景之上,而不能自动地交替地改变光照贴图。

通过这种方式,我们可以给予游戏中的灯光效果一个潜在的性能提升,从而适应不那么强大的硬件平台,如移动平台。

预计算实时全局光照(Precomputed Realtime GI Lighting)

虽然传统的静态光照贴图无法对场景内光照条件的变化作出反应,但预计算实时全局光照(也称预计算实时GI)为我们提供了交互式的实时更新复杂场景光照的技术。

通过这种方式,可以创建具有丰富的全局光照的光环境,并具有反射光,实时响应光照变化。一个很好的例子就是 time of day system —— 灯光的位置和颜色随着时间的推移而变化。使用传统的烘烤光照,这是不可能做到的。

【Unity-Graphics】Choosing a Lighting Technique

一个简单的例子,实现了一天中随着时间的变化灯光角度和颜色也在变化,使用了预计算全局光照

为了在可接受的帧速率中提供这些效果,我们需要将一些特大数量的数字计算从实时过程转移到“预计算”。

预计算将计算复杂的光线行为这一负担,从游戏进行时转移到时间不那么重要的时候,我们称之为“离线”。

那么这是如何进行的?

当我们想给场景创造更具真实感的光照时,最常见的是,我们把间接的(反射的)光线存储在我们的光照贴图上。幸运的是,颜色的变化是轻缓的,带有很少的尖锐或“高频”的地方。Unity 的预计算实时GI这一解决方案利用了间接光照的这些“Diffuse”特征,转化为我们的优势。

较亮的光照细节,如清晰的阴影,通常可以通过实时光照实现,而不是将其烘焙成光照贴图。假设我们不需要捕捉这些复杂的细节,我们可以大大降低我们全局光照解决方案的分辨率(Resolution)。

通过在预计算中进行这种简化,我们有效地减少了在游戏过程中更新我们的GI光照所需要的计算次数。 如果我们要改变灯光的属性,例如颜色,旋转或强度,甚至改变场景中的曲面,这一点便很重要。

为了进一步加速预计算,Unity 不会直接在 Lightmap 贴图的纹理元素(Texel)上工作,而是在世界中创建了一个称为“簇(Cluster)”的静态几何体的低分辨率近似值。

(texel 是纹理元素的简写,是纹理图形的基本单位,用于定义三维对象的曲面。3D 对象曲面的基本单位是纹理,而 2D 对象由像素组成。)

【Unity-Graphics】Choosing a Lighting Technique

左:将场景视图设置为“反照率(Albedo)”,可以清楚地看到Unity预计算实时GI产生的纹素(Texel)。默认情况下,此视图中的纹素(Texel)大致为簇(Cluster)的大小。右图:光照被计算,其结果被转化为光照贴图应用后的游戏中的场景

传统上,当计算全局光照时,我们会在光线在静态场景反弹时,对光线进行“光线跟踪(Ray trace)”。这种处理是十分复杂的,要求太高,以至于不能够进行实时处理。

因此,Unity 使用光线跟踪来预计算这些表面簇之间的关系 - 在预计算的“光传输(Light Transport)”阶段。

通过将世界简化成一个关系网络,我们在追求性能的游戏运行过程中消除了对昂贵的光线跟踪的需求。

我们已经有效地创建了世界的简化数学模型,它可以在游戏运行过程中接受不同的输入。 这意味着我们可以对场景中的灯光或表面颜色进行修改,并且可以快速查看场景光照更新中GI造成的影响。我们的光照模型产生的输出可以转化为光照贴图纹理,用于在GPU上渲染,与其他光照和表面贴图混合,处理效果,并最终输出到屏幕。

效益和成本(Benefits and Costs)

虽然可以同时使用烘焙GI和预计算实时GI,但要注意的是,同时渲染两个系统的性能成本恰好是它们的总和。 我们不仅必须在视频存储器(Video memory)中存储两套光照贴图,而且还支付在着色器(Shader)中解码的处理成本。

您可能希望选择一种光照方法的情况,取决于您的项目的性质和您的预期硬件的性能。 例如,在视频存储器和处理能力更受限制的移动设备上,可能会使烘焙GI方法更加有效。 在具有专用图形硬件的独立计算机或最新的游戏机上,很可能使用预计算实时GI或甚至同时使用这两个系统。

根据您的特定项目的性质和所期望的目标平台,将对使用哪种方法进行评估。记住,当面对一系列不同的硬件,通常这是最高效的,将决定哪些方法是必需的。

启用烘焙GI或预计算实时GI(Baked GI or Precomputed Realtime GI)

默认情况下,在Unity的 Lighting 面板(Lighting> Scene)中启用了预计算实时GI和烘焙GI。

【Unity-Graphics】Choosing a Lighting Technique

同时启用,使用哪种技术可以由每个灯光单独控制(Inspector> Light> Baking)。

【Unity-Graphics】Choosing a Lighting Technique

在场景中同时使用烘焙GI和预计算实时GI可能会对性能造成不利影响。 一个好的做法是确保一次只能使用一种方案,通过禁用其他方案。 这可以通过取消选中Unity的 Lighting 面板(Lighting> Scene)中预计算实时GI或烘焙GI旁边的框来实现。 现在只有已选中的选项将出现在您的场景中,并且将覆盖每个灯光的设置。

每盏灯光的设置(Per-Light Settings)

每个灯的默认烘焙模式是“Realtime”。 这意味着所选择的灯光仍然可以为您的场景提供直接光照,由Unity的预计算实时GI系统处理间接光照。

【Unity-Graphics】Choosing a Lighting Technique

然而,如果烘焙模式设置为“Baked”,则该灯将仅向 Unity 的烘焙GI系统贡献光照。 所选择的这些灯的直接和间接光照将被“baked”成光照贴图,并且在游戏过程中不能改变。

选择“Mixed”烘焙模式时,标记为静态的 GameObjects 仍将在其烘焙GI光照贴图中包含此灯。 然而,与标记为“Baked”的灯光不同,标记为“Mixed”的灯光仍然会为您的场景中的非静态 GameObjects 提供实时,直接的光照。这在您在静态环境中使用光照贴图,但您仍然希望角色使用这些相同的光线将实时阴影投射到使用光照贴图的几何体上的情况下可能非常有用。