- 0
- 0
- 0
分享
- URP系列教程 | URP Enlighten Realtime GI的介绍与实战 - 室内场景案例(上)
-
2022-02-09
节后第一篇技术分享,来自鹏鹏老师的《URP Enlighten Realtime GI 的介绍与实践 - 室内场景案例(上)》。点击“阅读原文”,即可免费解锁完整教程。
全局光照(Global Illumination, GI)
Unity 场景中的光照信息大致可以分成两类:直接光照和间接光照。光线直接照射物体表面,而没有经过反弹,称之为直接光照。光线经过一次或者多次物体表面的反弹,称之为间接光照。如下图所示:同一个场景下,最左边这幅图是没有光照,中间这幅图是只有直接光照而没有间接光照,最右边是有直接光照和间接光照。
从中间这副图中我们也可以清楚的发现如果只考虑直接光而没有间接光照的影响,场景中的阴影是全黑的,只有落在光线下的球体表面受到了影响。整个场景缺乏很多光影细节而没有真实性可言。
如第三张图所示光线照射到红色墙壁,会产生红色的间接光反射到球体的表面,从而使得球体的表面表现出红色的效果。间接光照会使得场景中的物体会影响彼此的外观,这就是典型的渗色现象。
而全局光照(GlobalIllumination,GI)就是这样的一套模拟系统。不仅模拟光线如何直接照射到物体表面(直接光照),还可以模拟光线如何从一个物体表面弹射到其他物体的表面(间接光照)。直接光照加上间接光照的模拟可以使得我们构建的虚拟世界看起来更加具有真实性和连贯性。
实时光照(Realtime Lighting)
默认情况下,在 Unity 中创建的灯光-平行光、聚光灯和点光源是实时的。这意味着它们为场景在每帧提供直接光照。当灯光或游戏对象在场景中移动时,光照信息将立即进行更新。
实时照明是场景中照明对象的最基本方式。但是 Unity 实时光源在默认情况下仅为场景提供直接光照,如果不在场景中启用实时全局光照(Realtime GI),实时光源就不会产生反弹(产生间接光照),只有在场景中开启实时全局光照,实时光源才会为场景提供间接光照从而实现全局光照的效果。
如下图所示:下面场景中均为实时光源,左边为没有开启实时 GI,右边开启实时 GI 效果。
因为间接光照的实时计算在目前的硬件条件下,只有支持实时光线追踪的硬件才能实现。在普通的计算设备上,特别是移动端设备上目前还没有成熟实时光线追踪的解决方案出现。所以为了使用全局照明等技术创建更逼真的场景,我们必须依赖预先计算好的光照贴图来提供这些间接光照信息。这就是后面要提到的 Unity 的预计算光照解决方案。
两种预计算光照解决方案
(Precomputed Lighting Solutions)
Unity 预计算光照解决方案有两种:Baked GI(烘焙全局光照)和 Precomputed Realtime GI(预计算的实时全局光照)。
Baked GI 会计算光照对场景中静态物体的影响从而计算出(我们称其为烘焙)一张光照贴图 Lightmap,叠加在场景对象之上建立照明效果。
我们来看下图左:这是一个简单的应用光照贴图的场景,右:由烘焙产生的一张光照贴图 Lightmap(阴影和光源信息都被纳入计算)
这些光照纹理(光照贴图)在游戏运行过程中不会改变,因此被定义为“静态”。虽然实时灯光可以在光照贴图上继续迭加光源计算,但不能以交互方式更改光照贴图本身。
使用这种方法,在游戏运行时的光影信息通过一张或多张光照贴图直接读取,除了贴图占用的内存外,几乎不产生其他的计算资源消耗,这是一种用空间换时间的技术,在保证场景图形效果的基础上,还能有非常棒的运行效率,非常适合移动平台等计算功能较弱的硬件。但是 Baked GI,并不是我们本篇文章要讨论的重点,我们要讨论的是预计算的实时全局光照(Precomputed Realtime GI)。
预计算实时全局照明 (Precomputed Realtime GI) 是一种允许交互式更新场景照明的技术。这与静态光照贴图不同,静态光照贴图无法适应场景中变化的光照条件。无法在游戏运行时改变场景光照,预计算的实时全局光照系统能帮我们实时运算复杂的场景光源互动,使用这种方法,能实现昏暗的环境带有丰富的全局光照反射,并实时反映光源的改变。如下图所示:
Enlighten Realtime GI for URP
Unity 采用备受开发者欢迎的 Enlighten 作为内置渲染管线(BiRP)中的预计算实时全局光照的解决方案。
在 Unity 中使用 Enlighten 的优点有哪些呢?
高效区域光:自发光表面的 CPU 开销非常低。
本着减少用户升级到通用渲染管线的难度,让更多用户使用通用渲染管道 (URP)。Unity 在 URP 12.0 中添加支持 Enlighten Realtime GI。如下图所示我们可以在 2021.2 及以上版本在三大管线中使用 Enlighten Realtime GI。但是在 2021.1 或者更早的版本中暂不支持在可编程渲染管线(SRP)中使用 Enlighten Realtime GI。
Enlighten Realtime GI 适用于变化缓慢且对场景具有高度视觉影响的灯光,例如在天空中移动的太阳或封闭走廊中缓慢闪烁的灯光。由于性能成本和延迟,实时 GI 不适用于快速变化的灯光或者一些特殊效果。
Enlighten Realtime GI 适用于针对中高端 PC 系统和游戏机的游戏。虽然在一些高端移动设备也以使用此功能,但我们应该保持场景较小,降低实时光照贴图的分辨率以节省宝贵的系统资源。
Unity 中所使用的 Enlighten 采用的是辐射度算法的近似方法。即假设有一组有限的静态元素,并且只传递漫反射来简化渲染方程来进行计算。结果如下:
我们来看下参数,这对我们后面对 Enlighten 参数的理解和配置很有帮助。其中:
Lj 是从 cluster j 当中释放出的光(上一帧,这个算法是逐帧迭代的)
上面的公式中频繁提到 cluster(簇),那么什么是 cluster(簇)?Enlighten 在计算全局光照时,会将场景分组到便于并行处理的 system 中。接下来,每个 system 被切割成离散的 cluster(簇)。Enlighten 就是使用这些 clusters(簇)计算间接光的,因为每一帧需要进行积分,所以 cluster(簇)数量越多,计算开销越大。
在计算每个像素的间接照明时,会预先计算像素可以看到的 cluster(簇),(从上面这个例子中我们也可以看到像素 X 可以影响到的 cluster(簇)有A、B、C、D四个)然后在运行时将所有 cluster(簇)颜色相加(加权和)。所以我们可以看到下面最左边这幅图中,一个红色的 cluster(簇)和三个黑色的 cluster(簇)会产生一个略带红色的结果。中间这幅图四个略带红色的 cluster(簇)将产生相同的略带红色的输出。最右边这幅图是使用黑色、红色、蓝色和绿色输入 cluster(簇)的示例,产生深绿色输出。
Scene视图的几种光照绘制模式
接下来我们来了解下 Scene 视图的几种光照绘制模式,这可以帮助我们快速的了解和调试场景中得到光照。这里我重点介绍几种模式。想要了解更多的信息的话,大家可以了解 Scene 视图的光照绘制模式 Unity 文档:
https://docs.unity3d.com/cn/current/Manual/GIVis.html
下图一是案例场景的 System Scene View:光照预计算阶段将基于相似度和光照贴图参数自动将场景细分为 System(即,共享相同实时光照贴图的对象组)。这样做是为了在更新间接光照时允许多线程和进行相应的优化。
下图二是案例场景的 Clustering Scene View:Clustering Scene 视图模式可以帮助识别需要调整 UV 或实时分辨率 (Realtime Resolution) 的几何体。
下图三是 Lit Clustering Scene View,图中 Clustering 与 Clustering Scene View 中是一致的,区别就是应用了全局光照。
Enlighten Realtime GI的参数设置
关于 Unity 的 Enlighten 的光照贴图相关的设置有三处,分别是全场景设置、模型设置以及光照贴图参数设置;Enlighten 需要进行合理的设置才能够达到高效和高质量,如果使用默认设置几乎不能达到要求。所以了解 Enlighten 这些参数设置的含义是至关重要的。
使用 Enlighten Realtime GI 给我们的场景进行照明时,需要做出的首要决定之一是确定场景的默认间接分辨率(Indirect Resolution)。使用间接分辨率(Indirect Resolution)来指定光照贴图用于间接光照计算的样本数(或者你也可以这样理解间接分辨率代表一个 unit 有多少个 Cluster 簇)。而光照贴图分辨率(Lightmap Resolution):是用来指定每个 unit 用于光照贴图的纹素数。增加此值可提高光照贴图质量,但也会增加烘焙时间。
那么如何选择一个合适的间接分辨率(Indirect Resolution)?
通常,场景的间接分辨率(Indirect Resolution)可以根据您的游戏世界的规模来确定。例如,我的场景是否是一个小而人口稠密的室内环境,反射光照变化是不是很大?在这种情况下,更高的光照贴图分辨率(Lightmap Resolutions)可以捕获这种更详细或“高频”的光照信息。
如果您的场景是一个大型户外环境,反射光的颜色几乎看不出来有没有变化。在此类情况下,如果把适合捕捉室内场景中存在的复杂照明细节的分辨率应用于大片且特征较少的室外环境的时将是很大的浪费。因为我们必须存储和更新哪些对场景的整体外观贡献不大的光照贴图纹素,这无疑将浪费宝贵的 CPU 时间和可用内存。
我们可以在“Lighjting”窗口中设置间接分辨率(Indirect Resolution):
01 打开 Lighting 窗口(Window > Rendering > Lighting Settings ),然后选择 Scene 选项卡。
我们发现在 Lightmapping Settings 当中有些参数是灰色的未激活状态。为了激活这里的所有参数,我们点击 Lighting 窗口的右上角的设计按钮,选择Reset。
02 通过选中Realtime Global Illumination复选框,确保启用了 Precomputed Realtime GI(Enlighten Realtime GI),接着将 Lightmapping Settings 下的 Lightmapper 设置为 Enlighten。最后取消勾选 Mixed Lighting 复选框,因为我们的这个案例不涉及混合模式的灯光。
03 展开 Lightmapping Settings 折页并找到 Indirect Resolution 属性。这里我们先将间接分辨率(Indirect Resolution)值设置为 5 。
我们打开 Clustering Scene 视图模式,当我们把间接分辨率(Indirect Resolution)值从 5 设置为 10 的时候,我们发现场景中的 cluster(簇)的数量也是相应成倍的增加。
鹏鹏老师还详细分享了如何将游戏对象标记为 Contribute GI 并开始预计算、选择用灯光探针照亮哪些物体、如何使用灯光探针以及位置的优化注意事项,点击“阅读原文”即可免费解锁。
本教程的下篇,将带大家了解 URP Enlighten Realtime GI 的其他设置参数,对参数进行微调以实现优化实时光照贴图。敬请期待。
长按关注
第一时间了解Unity引擎动向,学习最新开发技巧
点击“阅读原文”,跳转Unity中文课堂
-
阅读原文
* 文章为作者独立观点,不代表数艺网立场转载须知
- 本文内容由数艺网收录采集自微信公众号Unity官方平台 ,并经数艺网进行了排版优化。转载此文章请在文章开头和结尾标注“作者”、“来源:数艺网” 并附上本页链接: 如您不希望被数艺网所收录,感觉到侵犯到了您的权益,请及时告知数艺网,我们表示诚挚的歉意,并及时处理或删除。