Unity2018照明流程最佳实践(上)

目前 Unity 提供了多种渲染管道,两种全局照明系统,四种照明模式,三种灯光模式,以及两种 Shadowmask 模式,为开发者在创建面向高配PC、主机、移动和XR设备项目的过程中提供了高度灵活性。但是,作为 Unity 新手,如果不熟悉渲染的话,面对这些选择不免感到茫然,本文来自 Unity Spotlight Team 的分享,XR技术研习社对此进行了编译。

定义

首先看几个重要的图形渲染概念的定义。

  • 渲染管线决定对象如何在场景中呈现出来,分以下三个阶段:
    • 第一阶段:剔除(Culling)。在此阶段列出需要被渲染的对象,优先呈现摄像机可见的范围,以及未被其它物体遮挡的对象。
    • 第二阶段:渲染(rendering)。 在此阶段,根据光照设置以及相关的灯光属性,将对象绘制到基于像素的缓冲区中。
    • 第三阶段:后处理(post-processing )。一般在缓冲区上执行操作,比如应用 Color Grading、Bloom、Depth of Field 等效果,将最终输出到每一帧。
  • 着色器(Shader)是在GPU上运行的程序或程序集合的统称。比如,在剔除阶段完成之后,顶点着色器(vertext shader)将可见对象的顶点坐标从对象空间(object space)变换为剪辑空间(clip space),GPU使用新坐标对场景进行光栅化,即将矢量信息转换为实际像素。然后,像素(或片段)着色器将这些像素进行着色,像素颜色由材质属性和光照环境决定。另一种常见的着色器类型被称为计算着色器(compute shader),这种着色器使开发者能够利用GPU强大的并行处理能力进行任何类型的数学运算,比如光剔除、粒子物理、体积模拟等。
  • 直接照明指的是来自光源(比如灯泡)的照明,并非光线从物体表面反射的结果。根据光源的大小及其与被照射物体的距离,这种照明通常会产生清晰且明显的阴影。需要注意以下两点:
    • 不要将直接照明与定向照明(directional lighting)混淆,定向照明是由无限远的光源(例如Unity中的平行光)发出的光,定向光的显着特性是能够使用平行光线覆盖整个场景,并且没有距离衰减(或光衰减),也就是说,随着到光源距离的增加,物体接收的照明强度不会衰减。
    • 在现实世界中,太阳光与任何其他光源一样,光照强度与距离成反比。例如,水星上日光的照射强度几乎是地球的7倍,而火星接收的日光照射是地球的1/2,而冥王星只有地球的0.06%。然而,鉴于地球上有限的海拔高度,相较以上的距离,日光在地球上的衰减是微不足道的。因此,平行光完全能够模拟Unity场景中的阳光,包括大型的,以行星为中心的开放世界。另外,对于其他类型的光源(比如点光源和聚光灯),Unity 在高清渲染管线(HDRP)中能够提供基于物理的衰减。
  • 间接照明是由光线从物体表面反射然后通过介质(比如如大气或半透明材料)传播和散射而产生的照明。在这种情况下,光线通常通过遮挡物形成相对柔和的阴影。
  • 全局照明(GI)用于在场景中产生间接照明,主要作为直接照明的功能。 在业内,目前实现全局照明存在几种技术,比如光照贴图(lightmaps)、Irradiance Volumes、Light Propagation Volumes、光照探头(light probes)、基于体素的GI和基于距离场的GI等,它们被广泛应用在像Unity、UE4、CryEngine、COD 等引擎中,对于Unity来说,使用光照贴图和光照探头来实现。
    • 光照贴图技术通过发射光线计算光线反射,然后将生成的光照效果应用到纹理中,以此来生成光照贴图和光照探头的数据。因此,使用不同的光照贴图技术会呈现不同的照明效果。目前,Unity 使用两种光照贴图技术:Enlighten 和 Progressive Lightmapper。

概述

以下流程图从内容创作者的角度展示了在Unity中设置照明的过程。



在整个流程中,首先需要选择渲染管线,然后决定如何生成间接照明并选择相应的全局照明系统。在确保所有全局照明设置都对项目进行了相应调整后,可以继续在场景中添加灯光、自发光表面、反射探头,光照探头以及Light Probe Proxy Volumes (LPPVs)。详细介绍所有这些照明对象的用法和功能超出了本文的讨论范围,因此建议读者阅读Unity手册中关于光照部分的相关介绍,以了解如何在项目中正确使用它们。

渲染管线

在 Unity 2018 之前,只有一种渲染管线,现在称之为“内置渲染管线(Built-In Render Pipeline)”,该管线提供前向(forward)和延迟(deferred)两种渲染模式供用户选择。

  • 在(多通道)前向渲染模式中,场景中的所有对象按照一个统一的顺序逐个渲染,在多通道渲染过程中,当多个光源照亮对象时,渲染成本会显着增加,具体取决于影响每个对象的光源数量。这种类型的渲染器通常提供多种着色器,并且能够轻松处理透明度。
  • 在延迟渲染模式下,所有(包括不透明)几何体首先渲染到存储有关其材质信息(颜色、反射、平滑度等)的缓冲区中。稍后(在此体现延迟),每个像素被顺序着色,同时,渲染时间主要取决于影响每个像素的光源数量。透明对象和具有复杂着色器的对象仍需要额外的前向渲染通道进行渲染。在处理包含很多动态灯光的场景时,建议使用延迟渲染,例如人工照明的室内场景,或需要室内外组合照明的项目。

在2018年1月,Unity 推出了 Scriptable Render Pipeline(SRP),允许开发者通过C#脚本自定义渲染流程。这实际上是游戏引擎领域的一次变革——用户能够自由控制对象的剔除、绘制和后处理,而无需使用像C ++这样的底层编程语言。

Unity提供了两种SRP,目前为预览版,其设计充分考虑了硬件规格及性能:

  • 高清渲染管线(以下简称 HDRP)是一个综合了Deferred/Forward、Tile/Cluster 渲染方式的渲染器,提供高级渲染和着色功能,适用于需要展示高品质视觉效果的PC和主机项目。Tile渲染和Cluster渲染如下图所示:


其中,一个 Tile 代表帧中一小块二维正方形区域中的像素,一个 Cluster 代表摄像机两个截平面之间的三维空间。Tile 和 Cluster 渲染技术均依赖于影响每个Tile或Cluster的灯光,然后在一个通道中中根据与其相关灯光来计算照明。不透明对象最有可能使用Tile系统进行着色,而透明对象则依靠Cluster系统。与内置渲染管道(延迟模式)相比,HDRP 的主要优势是更快的照明处理和更低的带宽使用。

  • 轻量级渲染管线(LWRP)是一种快速单通道前向渲染器,适用于具有较低实时照明要求的设备,例如智能手机、平板电脑和VR/AR设备。在该渲染管线中,会对灯光进行逐对象剔除,并在一个通道中进行光照计算。与内置渲染管线相比,该管线能够减少绘制调用的次数。

通过使用以下决策树,读者可以使用几个关键条件判断决定使用何种渲染管线。


模板

可以通过 Unity 的 Package Manager (Window > Package Manager) 下载最新版本的 HDRP 和 LWRP应用到项目中。在项目中应用某个 SRP 比较快捷的方式是,在使用Unity Hub创建一个新项目时,选择相应的模板(Template),如下图所示。


手动设置

如果要手动设置HDRP或LWRP项目,请确保已安装所需的 package。以使用HDRP为例,可通过 Create > Rendering > High Definition Render Pipeline Asset 命令在 Project 面板中新建对应的资源,然后将此资源拖到 Graphics Settings 面板的 Scriptable Render Pipeline Settings 属性中,如果此处不指定任何资源,Unity 将默认使用内置渲染管线。如果使用 HDRP,需要确保在 Player Settings 中选择了线性(linear)色彩空间,并使用 Rendering > Scene Settings 命令在场景中添加一个场景设置游戏对象。


可扩展性

对于理解渲染技术并熟悉C#的开发者,如果需要为项目完全定制渲染器,建议尝试使用SRP的相关概念创建自己的渲染管线。鉴于LWRP拥有较小的着色器库且易于注入、移除、切换渲染通道,使得LWRP具有极强的可扩展性。

兼容性

在Unity中将项目中的材质从内置渲染管线切换到HDRP或LWRP比较容易,使用 Edit > Render Pipeline > Upgrade xxx 相关命令即可完成,如下图所示。需要注意的是,此操作不可逆,建议事先做好项目备份。



尽管如此,自定义着色器需要进行手动移植,此过程相对比较耗时,具体取决于自定义着色器的数量。由于LWRP 和 HDRP 在物理表现上比内置渲染管道更加准确,尤其是在光衰减和分布方面,所以切换前后的项目看上去会有一些不同。此外,HDRP和LWRP之间互不兼容,因为它们没有相同的渲染特性,两者可以相互转换,但不是一键操作,需要手动重新设置照明、材质和着色器。

最后需要说明的是,HDRP和LWRP目前仍处于预览中,并非所有功能都已针对两种管线实现。比如,某些照明模式尚未完全适用于LWRP,并且HDRP目前尚不支持VR/AR,但是在未来版本中将逐步实现。

全局光照系统

Unity 提供两种全局照明系统,可在 Window > Rendering > Lighting Settings 中启用它们。

  1. 实时全局光照(以下简称实时GI):该系统完全依赖于第三方照明中间件Enlighten。在Unity的预计算过程中,Enlighten先后经过两个阶段,包括:集群化和光传输。第一阶段将场景分解简化为以“集群”为单位进行组织的集合,在第二阶段计算集群与集群之间的可见性。预计算后的数据在运行时用于交互性地生成场景的间接照明。 Enlighten的优势在于能够实时改变间接照明效果,因为预计算的数据依赖于集群之间的关系。但是,与其他光照贴图技术一样,改变场景中的静态几何体将触发新的预计算。
  2. 烘焙全局光照(以下简称烘焙GI): 照明信息被烘焙到光照贴图和光照探头中,Baked GI 系统可以使用以下两种技术之一:
    1. Progressive Lightmapper
    2. Enlighten

Progressive Lightmapper 优先计算对于摄像机可见物体的照明,并大大提高的照明计算速度,但代价是增加整个场景的总体烘焙时间。 该技术使用CPU通过路径追踪算法计算间接照明。基于GPU加速的 Progressive Lightmapper 能够大幅缩短场景的烘焙时间,目前正在处在研发中,在 Unity 2018.3.05b 中集成了该技术测试版。由于Enlighten 和Progressive Lightmapper 使用了不同的技术计算光照,所以两者产生的光照效果会有不同。

下图列出了各全局光照系统的主要优缺点,可根据决策树选择项目需要使用的全局光照系统。


静态 VS. 动态

无论您使用哪种全局照明系统,Unity 都只会考虑标记为“Lightmap Static”的游戏对象。动态游戏对象需要借助场景中放置的光照探头来接收间接照明。

由于全局光照计算是一个相对缓慢的过程,因此只有具有明显光照变化的大型复杂资源才需要应标记为“Lightmap Static”。接收均匀光照的较小网格可保持为动态设置,然后通过使用 Light Probes 为其提供近似效果的间接照明效果。较大的动态游戏对象可以使用 Light Probe Proxy Volume(LPPV),以便在局部接收更好的间接照明。限制场景中静态游戏对象的数量对于提高烘焙时间同时保持足够照明品质至关重要。

警告

在Unity中可以同时使用烘焙和实时GI技术,但是,必须注意,同时使用会大大增加烘焙时间和程序运行时的内存消耗,因为这两个系统不使用相同的数据。此外,间接照明在运行时的交互式更新将给CPU带来额外的压力,并且在视觉上,烘焙和实时GI提供的间接照明效果会有差异,因为它们使用了不同的技术来模拟间接照明,并且通常在完全不同的分辨率下执行。若同时使用这两种技术,建议将使用范围限制在高端平台或具有可预测性能成本且严格把控场景的项目中,同时,建议由对所有照明设置有很好理解的团队成员负责,因为管理这两个系统相对复杂。

因此,对于大多数项目而言,尽量避免同时使用两种GI技术,选择其一是相对比较稳妥的做法。

你可能感兴趣的:(Unity2018照明流程最佳实践(上))