官方教程 | 使用HDRP基于物理的光照系统实现白天和夜晚光照效果
Unity官方
编辑于 2021年07月10日 20:41
收录于文集
共53篇

在另外一篇教程中,Unity 大中华区平台技术总监杨栋详细讲解了如何设置本教程需要用到的场景素材,感兴趣的同学可以前往 Unity 中文课堂阅读:

Unity HDRP 室外场景打光流程分享(上篇): https://learn.u3d.cn/tutorial/unity-hdrp-outdoor-lighting-part1

本教程将会详细讲解如何使用 Unity HDRP 中基于物理的光照系统来为上述室外场景打光,我们会通过一系列步骤来完成同一个场景白天和夜晚两种光照条件的打光操作,并讲解光照相关的知识。最终完成的两个场景光照效果如图 1 和图 2 所示。

图 1 白天光照条件

图 2 夜晚光照条件

HDRP打光步骤和功能总览

因为 HDRP 的光照系统有别于内置渲染管线和通用渲染管线,所以为了正确讲解 HDRP 基于物理的光照系统,我专门画了如图 3 所示的总览图,来帮助大家理解在 HDRP 中打光的基本组成元素和每个元素相关的技术。

图 3 Unity HDRP 打光总览

上述高清流程图可以在此下载:

链接:https://pan.baidu.com/s/1RpYm3XHW2abCoRmduth06g 

提取码:2021 

针对图 3 的说明如下:

  •  因为 HDRP 的光照系统模拟的是真实物理世界光照的行为,我们就要为 HDRP 场景中的灯光设置正确的光照强度和色温数值。正是因为可以在 HDRP 的光照系统中使用真实世界的光照单位和参数数值,这让我们在 HDRP 进行打光变得更容易了。因为只要你按照正确的光照参考值来打光,就可以获得物理正确的光照效果。

  • 除了要为灯光设置正确的光照物理数值之外,我们还要正确设置场景的曝光。我们之所以要设置场景的曝光,是因为人眼既可以适应很暗的环境,也可以适应很亮的环境。人眼可以通过适应和调整场景中对黑色的感知来自动适应多种光照条件。

  • 在为场景打光时,我们可以按照图中桔色方框的箭头次序,自上而下地来为场景添加光照信息:环境光 -> 主光源 + 次光源(如果有次要光源的话)-> 添加反射信息 -> 添加全局光照 -> 调整场景曝光

  • 图 3 为这 5 个不同的打光环节指出了将会用到的具体 HDRP 功能,为大家提供参考。在下面的内容中,我将会为大家逐个讲解每个环节中所用到的各项功能点,帮助大家理解这些具体的技术。

室外场景白天打光

打光时我们肯定要用到 Light(光源)组件,而要正确设置 Light 组件的参数,我们首先要正确理解 HDRP 中所用到的各种光照单位,以及相关的光照强度(Intensity)和色温(Color Temperature)的参考数值。

针对 HDRP 所用的五种来自真实世界的光照单位,HDRP 文档中有详细描述。

以下链接包含 HDRP 10.4 版本的中文文档针对光照单位以及参考数值的具体内容:https://docs.unity3d.com/cn/Packages/com.unity.render-pipelines.high-definition@10.4/manual/Physical-Light-Units.html

如果你使用的是 HDRP 7.x 版本,Unity 也提供了 HDRP 7.4 版本的中文文档:https://docs.unity3d.com/cn/Packages/com.unity.render-pipelines.high-definition@7.4/manual/Physical-Light-Units.html

我们也可以直接通过图 4(色温,光照强度和曝光速查表)来参考常用的光照和色温数值。

图 4 光照强度,色温和曝光参考

现在我们来看一下如何为这个室外场景进行具体的打光操作。

设置环境光

把模型导入场景以后,当前场景中没有任何的光照设置,所以我们在 Scene 和 Game 窗口看到的场景如图 5 所示。

图 5 默认环境光设置下的光照效果

图 5 中场景中的模型表面呈现一片银色,这是因为当前场景的环境光来自 Project Settings(质量设置)中的 HDRP Default Setting(HDRP默认设置)> Default Volume Profile Asset(默认Volume配置文件)。这些默认的 Volume 设置是为了让新建项目有一个基础的环境光而设的。我们也可以不用这些默认的 Volume 设置,自己在场景中创建这些 Volume 设置。

目前场景模型表面的银色大部分来自反射信息,因为我们场景中不存在任何屏幕空间反射的设置,也不存在任何反射探针可供采样,所以材质系统就默认使用了来自天空的反射信息。

为了更好地理解之后的打光步骤,我们把图 6 中默认 Volume 配置文件里的设置勾选全部去掉。这时可以看到整个场景漆黑一片(除了自发光材质和主相机上设置的天空背景色)。物体表面的银色反射信息也消失了,因为我们把 HDRP 默认 Volume 中的 HDRI Sky 关闭了,所以材质系统也就无法再从天空采样反射信息了。

图 6 移除默认环境光后的效果

然后我们在 Hierarchy 窗口中,通过菜单 GameObject > Volume > Sky and Fog Volume 来创建一个自带环境光设置的 Sky and Fog Volume。新创建的 Sky and Fog Volume 如图 7 所示。此 Volume 的模式自动设置为 Global(全局模式),也就意味着场景中所有的相机都会受到此 Volume 的影响。另外,HDRP 还会自动生成一个名为 Sky and Fog Settings Profile 配置文件,并自动关联到 Volume 组件上的 Profile 参数。

图 7 全局模式Volume中的Visual Environment和物理天空设置

Volume 组件上的 Visual Environment(视觉环境)和 Physically Based Sky(基于物理的天空)两个功能配合使用,将会为场景提供来自程序化生成的基于物理的天空所带来的环境光。基于物理的天空拥有很多不同的参数设置,可以用于模拟很复杂的环境天空,除了地球环境,也可以用于模拟外星球环境。

因为我们要模拟的环境属于写实类的地球环境,所以我们可以使用设置更为简便的 HDRI Sky 来为整个室外场景提供环境光。因此,我们要把 Visual Environment 的 Type(类型)设置为 HDRI Sky,移除 Physically Based Sky 重载,然后通过 Add Override(添加重载)按钮打开重载功能界面,在 Sky(天空)分类中选择 HDRI Sky 添加到 Volume 组件上。具体设置如图 8 所示。

图 8 Visual Environment 关联 HDRI Sky

从图 8 中可以看到,HDRI Sky 的 Intensity Mode(强度模式)默认选择的是 Exposure(曝光),我们也可以选择 Multiplier(乘数)或者 Lux(勒克斯)。目前的曝光数值设置为 0,相当于多云黑夜中的光照强度。因为我们要模拟的是白天中午阳光很好的光照条件,所以我们可以参考图4的“光照强度,色温和曝光速查表”,找到此光照条件下场景的曝光值(Exposure)为 14(单位为EV100),如果我们在 Volume 的 HDRI Sky 中的 Intensity Mode 里选择 Exposure 并输入 14,可以得到如图 9 所示画面:

图 9 HDRI Sky光照强度模式设置为Exposure(曝光)

我们也可以把 Intensity Mode 改为 Lux,然后把 Desired Lux Value 设置为 20000(Lux),画面效果如图 10 所示。

此数值参考自 HDRP 文档中的“自然光强度 - 中午的蓝天“,如图11所示。

HDRP 文档:

https://docs.unity3d.com/cn/Packages/com.unity.render-pipelines.high-definition@10.4/manual/Physical-Light-Units.html

图 10 HDRI Sky光照强度模式设置为Lux(勒克斯)

图 11 参考自HDRP中文文档的蓝天环境光数值

不管将 Intensity Mode 设置为 Exposure 还是 Lux,虽然我们应用了正确的数值,但是整个画面都几乎变成了白色。这是因为我们还没有为画面应用正确的曝光控制(注:这里的曝光控制和 HDRI Sky 中的曝光数值是两回事。HDRI Sky 中的曝光数值是用来控制环境光强度的)。

接着我们勾选 Volume 组件上的 Exposure(曝光控制)。

这里说明一下:为了便于演示,我已经在场景中的 Sky and Fog Volume 上添加了所有需要用到的 Volume Override(重载)。如果你新建了一个 Volume,你可以通过 Volume 组件中的 Add Override(添加重载)按钮为 Volume 组件添加所需的重载。这些 Override(重载)可以理解成为 Volume 组件提供的具体功能。

如图 12 所示,我们先把 Exposure(曝光控制)的 Mode(模式)设置为 Fixed(固定),数值设置为 12(EV100),这意味着不管相机对准的是场景中哪个部分,整个画面的曝光值将会是固定的。之后我们将会应用自动曝光,因为在我们场景中有的地方在屋檐下,曝光值与阳光下的部分有所区别。在图中也可以看到,Fixed Exposure(固定曝光值)界面右侧还贴心地提供了一个滑块,可以非常直观地看到哪个数值区间适合什么样的光照条件。

图 12 固定曝光模式

到目前为止,其实我们还没有正确设置整个场景的环境光,因为在 Visual Environment 中的 Ambient Mode 默认设置为 Static(静态),所以环境光会采样自 Lighting 窗口 Environment(环境光)界面中的天空。如图 13 所示,因为我们还没有在 Lighting 窗口中设置任何的环境光来源,因此目前场景中并没有使用我们设置的 HDRI Sky 来提供环境光。现在模型表面上看到的只不过是反射 HDRI Sky 的效果。

图 13 Lighting窗口环境光设置

如图 14 所示,Ambient Mode 为 Static 时场景中没有来自天空的环境光 [后在光照烘焙环节,我们会讲解如何设置 Static(静态)环境光]。

图 14 Visual Environment的Ambient Mode设置为静态

要让 Volume 组件上的 HDRI Sky 为场景提供环境光,我们需要把 Visual Environment 中 Ambient Mode(环境光模式)设置为 Dynamic(动态)。如图 15 所示,如果把 Ambient Mode 设置为 Dynamic,场景中就有了来自 Volume 组件上所关联的 HDRI Sky 的环境光。

图 15 Visual Environment的Ambient Mode设置为动态

通过上述步骤,我们就为场景完成了基础环境光的设置。针对现在场景中已设置完成的环境光,我们可以做出如下总结

  • 通过为 Volume 组件添加 Visual Environment 重载,我们选择了 HDRI Sky 作为我们室外场景的天空。

  • 通过添加 HDRI Sky 重载,然后关联一个 HDRI Sky 天空盒(类型为Cubemap),我们正确设置了环境光强度数值。环境光影响整个场景。

  • 通过添加 Exposure 重载,我们为整个画面设置了一个固定的曝光数值,从而近似地模拟了人眼的曝光控制功能。

创建主光源

要模拟白天中午大太阳室外场景,主光源当然是太阳。我们可以在场景中添加一盏 Directional Light(平行光)来模拟太阳。此平行光的 Light 组件参数设置如图 16 所示。

图 16 设置平行光参数模拟太阳

以下是平行光的主要参数说明:

  • Mode(模式):选择 Mixed(混合模式)是因为我们想让这盏平行光参与之后的光照贴图烘焙,并提供效果更好的实时阴影。

  • Light appearance(光照外观):默认设置为 Color(颜色),也就是为灯光选择一个指定的颜色。如果我们要准确控制灯光的颜色,就要选择 Filter and Temperature(滤光器和温度)模式。在滤光器和温度模式下,我们可以通过选择一个颜色和色温值,组合起来精确控制灯光的颜色。 如果我们想要制作写实类的灯光,可以选择 Filter(滤光器)的颜色为纯白色,然后输入一个色温数值(单位为Kelvin开尔文)。此处我们模拟的是白天中午的阳光,从图 4 的“色温    ,光照强度和曝光速查表“中,我们可以找到相关的色温参考数值为 5500K,这里我们设置成 5800K。

  • Intensity(光照强度):太阳的光照强度设置为 120000 Lux。此数值也可以从“色温,光照强度和曝光速查表“中查找到。

  • Shadows(阴影):如果不打开阴影的话,整个场景没有任何真实性可言。我们需要通过当前项目所用的 HDRP Asset(HDRP配置文件),来控制渲染阴影时所用的算法以及 Shadow Map 的分辨率,具体参数如图 17 所示。

图 17 HDRP配置文件中设置阴影质量

如图 17 所示,HDRP Asset 中的 Filtering Quality(过滤器质量)可以控制计算阴影时所用的具体算法。

对于平行光来说,如果选择 Filtering Quality 为 Low(低质量)或者 Medium(中等质量)时,HDRP 会使用 PCF(Percentage-CloserFiltering)算法,生成的阴影质量不高,边缘较硬。

如果切换到 High(高质量),HDRP 会使用 PCSS(Percentage-Closer Soft Shadows)算法生成高质量的软阴影。当然我们也需要付出一定的性能消耗作为代价。我们可以通过控制 Light 组件上的 Angular Diameter 大小来控制 PCSS 算法所生成阴影的软硬程度。图 18 和图 19 分别在 Filtering Quality 设置为高质量时使用了不同的 Angular Diameter 数值,分别获得了硬边阴影和软边阴影。

图 18 高质量阴影模式下使用Angular Diameter参数生成硬边阴影

图 19 高质量阴影模式下使用Angular Diameter参数生成软阴影

添加反射信息

因为场景中没有设置任何 Reflection Probe(反射探针),所以当前场景的物体表面只有来自天空的反射信息。如图 20 所示,即使在画面右侧屋檐下的部分,物体表面的反射信息也是来自天空的蓝色。

图 20 屋檐下的场景采样天空盒获得反射信息

我们需要在场景中的关键位置放置反射探针。如图 21 所示,黑色的圆球代表的就是放置完成的反射探针。因为我们还未烘焙这些反射探针,所以 Scene 窗口中的反射探针呈现黑色。

图 21 场景中关键位置摆放反射探针

我们可以在 Hierarchy 层级窗口选中所有反射探针,然后点击 Inspector 窗口中如图 22 所示的 Bake(烘焙)按钮。

图 22 反射探针组件上的烘焙按钮

烘焙完所有反射探针以后,Scene 窗口中的显示效果如图 23 所示。每个反射探针上都关联了一张 Cubemap。

图 23 完成场景中所有反射探针的烘焙操作

如图 24 所示,虽然现在烘焙获得的反射探针 Cubemap 上并没有保存间接光信息(因为我们还未对场景进行光照贴图烘焙操作),但是场景中的模型表面已经有了正确的来自反射探针的反射信息。

图 24 屋檐下的物体采样反射探针获得物体表面的反射信息

添加全局光照

这一步我们将为场景添加 Light Probe(光照探针)和进行光照贴图烘焙。

01  添加 Light Probe(光照探针)为动态物体提供间接光照

为了给场景中的动态物体提供间接光照,我们需要为场景添加 LightProbe Group(光照探针组)。如图 25 和图 26 所示,我们在场景中动态物体需要经过的区域都放置了光照探针组,一共 8 组。

图 25 场景中摆放的光照探针组

图 26 场景中摆放的光照探针组

光照探针除了可以给动态物体提供间接光照,也可以为场景中的其他物体提供间接光信息,比如植被,较低等级的 LOD,不值得参与光照烘焙计算的小物体。这样做可以避免烘焙所得的光照贴图过大,导致占用过多内存。

02  光照贴图烘焙

放置完光照探针组以后,我们就可以进行光照烘焙操作了。首先我们来了解用于控制光照烘焙功能的 Lighting 界面。如图 27 所示,Lighting 窗口由三个部分组成:Scene,Environment 和 BakedLightmaps。

图 27 Lighting界面的Lighting Settings设置

通过 Scene 界面,我们可以创建一个 Lighting Settings(光照烘焙设置)。这个配置文件会保存相应的光照烘焙参数。你可以把同一个 Lighting Settings 配置文件应用到多个场景的光照烘焙中。只有创建并关联了相应的 Lighting Settings 配置文件后,Lighting 界面上的 Mixed Lighting 和 Lightmapping Settings 区域才会被激活并允许设置参数。

图 28 中是用于控制环境光的界面。此界面可以关联一个 Volume Profile(Volume配置文件),然后将 Volume 里相关联的天空,比如 HDRI Sky,Physically Based Sky 或 Gradient Sky 关联到 Static Lighting Sky 参数。此处设置的环境光也会被烘焙到光照贴图中,这与之前通过 Volume 组件上的 Visual Environment 和 HDRI Sky 提供的天空环境光是不同的。

图 28 Lighting界面的环境光参数

第三个界面,如图 29 所示,是 Baked Lightmaps(烘焙完成的光照贴图)。你可以在这里查看当前场景所关联的已经烘焙完成的光照贴图,也可以临时把 Lighting Data Asset 的关联移除,查看当前场景没有应用光照贴图时的情况,或者用代码动态关联其他 Lighting Data Asset 以应用其他与当前场景匹配的光照贴图。

图 29 Lighting界面与烘焙完成的光照贴图数据相关联的参数

如图 30 所示,我们在 Environment 界面里关联了当前场景所用的 Volume Profile,并把 HDRI Sky 关联到 Static Lighting Sky 参数上。

图 30 为光照烘焙关联环境光来源

对于 HDRP 中如何进行光照烘焙,大家可以访问此 URL 详细了解:https://developer.unity.cn/projects/progressive-lightmapper

图 31 为白天场景所用的光照烘焙参数。

图 31 白天场景光照烘焙参数

图 32 为完成光照烘焙以后的场景效果。

图 32 光照贴图烘焙完成后的场景

接着如图 33 为场景添加 Fog(雾效),Shadows(平行光阴影控制),Contact Shadow(接触阴影),Indirect Lighting Controller(间接光控制)和 Ambient Occlusion(屏幕空间环境光遮蔽)。

图 33 为场景添加更多Volume重载

获得如图 34 所示画面效果。

图 34 添加更多Volume重载以后的效果

最后添加如图 35 所示的后处理效果。

图 35 为场景添加更多后处理效果

从而获得如图 36 所示最终画面效果。

图 36 白天打光完成以后的光照效果

调整场景曝光

在之前的步骤中我们为整个场景设置了一个固定的曝光值,但是其实这并不符合当前场景的实际情况。我们可以通过以下截图进行比对。

图 37 所示为 Volume 组件中 Exposure 设置为 Fixed(固定曝光)模式,数值为 12(EV100)时的画面表现。可以看到目前的固定曝光数值 12,对于场景的亮部(阳光下的部分)是适用的,但是对于场景的暗部(屋檐下的部分)会导致曝光不足,让屋檐下的暗部几乎漆黑一片(如图38和图39所示)。

图 37 固定曝光模式

图 38 固定曝光模式下从亮部看向暗部

图 39 固定曝光模式下从暗部看向亮部

解决上述问题的一个快速方法是使用自动曝光模式。图 40 所示为 Volume 组件中 Exposure 设置为 AutomaticHistogram(自动曝光直方图)模式,Limit Min 数值设置为 7(EV100),Limit Max 数值设置为 12.5(EV100)时的画面表现。把曝光模式设置成自动模式以后,HDRP 可以为场景的不同部分设置相对正确的曝光值。我们可以通过调节 Limit Min 和 Limit Max 这一对参数的数值,为场景的不同部分找到一个合适的曝光数值区间(如图 41 和图 42 所示)。

图 40 自动曝光模式

图 41 自动曝光模式下从亮部看向暗部

图 42 自动曝光模式下从暗部看向亮部

另外一个方法为场景的不同部分设置本地模式(Local)的 Volume。使用方式描述如下

  • 为明亮的地方设置一个 Volume 并添加一个模式为 Fixed(固定曝光)的 Exposure(曝光控制),参数设置为 12。

  • 然后为暗部,比如走廊下的部分,设置另一个固定模式的曝光控制,数值设置为 7。然后为这两个本地 Volume 设置长度为 1~2 米的混合距离。

  • 使用本地 Volume 的好处是可以精确控制场景中每个部分的曝光数值。坏处是如果场景比较复杂,就要摆放多个互相嵌套的 Volume,为后期维护和更新带来一些麻烦。

室外场景夜晚打光

完成白天场景打光以后,我们可以通过以下步骤来为夜晚的场景打光。

修改环境光

因为白天和夜晚的环境光相差很大,所以我们首先要改变场景的环境光。

如图 43 所示,首先创建一个新的 Volume Profile 用于保存夜间场景的各项参数。把 Volume 组件中 HDRI Sky 替换成夜晚的天空盒,然后把 Desired Lux Value(期望的勒克斯数值)改为 3,用于模拟夜晚光照条件下的环境光强度。

图 43 替换HDRI Sky为夜间天空盒

接着,如图 44 所示,把 Lighting 窗口 Environment(HDRP)中的 Profile与夜晚的 VolumeProfile 进行关联。这样当我们进行光照烘焙时,光照贴图才会有正确的夜间环境光。

图 44 替换烘焙环境光来源为夜间环境光

修改主光源

如图 45 所示,我们要将 Directional Light(平行光)的色温和强度做相应调整,用于模拟月光。

图 45 修改主光源平行光参数模拟月光

修改次要光源

把场景中预先放置好的所有次要光源,比如街灯,墙下的射灯,汽油桶中模拟火光的点光源,屋檐下的顶灯,以及天空中三盏氛围灯都启用,如图 46 所示。因为我们已经为所有的光源设置了正确的强度(参考物理数值),照射范围和色温,所以我们自然就得到了正确的光照。这也是使用完全基于物理的光照系统的好处所在。

图 46 启用场景中所有次要光源

反射信息和光照探针

我们无需调整 ReflectionProbe(反射探针)和 Light Probe Group(光照探针)的任何设置。在后续的光照贴图烘焙中它们都会获得正确的反射信息和间接光信息。

处理全局光照

因为我们修改了场景环境光和主光源参数,并且添加了更多光源,所以我们要重新烘焙夜间场景的光照贴图。光照烘焙参数如图 47 所示。为了给夜间场景添加一些细节,所以我们将 Lightmap Resolution(光照贴图分辨率)从原先白天场景的 15 提高到夜晚场景的 20。

图 47 夜间场景光照烘焙参数

调整场景曝光

因为夜晚和白天的曝光也是不同的,所以我们也要调整如图 48 所示的曝光数值。

图 48 调整场景自动曝光以适应夜间光照条件

当然我们也需要相应地调整 Fog(雾效),Volume 上的 White Balance(白平衡),Bloom(泛光)等后处理效果也需要做相应的调整。因为后处理调整属于可见即所得的效果,使用也相对简单,这里就不再赘述了。

最后获得的夜间打光效果,如图 49 所示。

图 49 最终完成的夜间打光效果

总结

通过上述内容,我们完整了解了如何为一个 HDRP 场景进行打光,也从中学习到 Unity HDRP 完全基于物理的光照系统为我们带来的好处。

本教程也可以通过以下链接在 Unity 中文课堂上收藏学习:

https://learn.u3d.cn/tutorial/unity-hdrp-outdoor-lighting-part2