Unity光照系统的发展
从早期的Enlighten到Progressive CPU ,再到Progressive GPU,从发展轨迹可以看出,大家对光照还是偏向光线追踪算法,认为这是未来的发展方向
Enlighten
Enlighten本身不是光线追踪算法,它是一种非常复杂的数学模型算法,而且对美术制作非常不友好,导致很多人使用Enlighten烘焙都效果不佳。
Enlighten根据官方所讲:2019.4中正式弃用。
Enlighten核心概念
Systems
Clustering
UV Charts
我们可以把Systems作为Unity让Enlighten把场景中的部件按照光照和它的距离关系来构建出来一个承接光照的最大单元。我们会看到它的颜色不同,代表是不同的System,这种依存关系决定Enlighten构建的复杂度。
Enlighten会根据使用什么材质,哪个光照对它有影响,它和哪个物体位置比较近,自动构建System。构建得越复杂,计算量也会越多。
Clustering是最核心的Enlighten概念。Enlighten本身光照进行照明是不需要计算的,它计算的是光照环境。所以构建光照环境时,才可以创造这些Clustering。
UV Chart是Lightmap光照贴图的UV,而构建光照环境最核心的东西是UV Chart,如果没有UV Chart,它就没有空间可以存储Clustering作为计算单元。
- 缺点
Enlighten不适合用于植被和树
一个树,有多少片树叶,就有多少UV Charts,每个UV Chart都要进行光照计算,光照计算最低代价是4x4,即4个像素乘4个像素的代价去生成整个计算UV Chart的光照空间。
计算Clustering时,每个至少保留16个像素。如果一棵树还好,如果有500片叶子,还可以接受。如果有一片树林,那就使用Enlighten计算不动了,所以不建议使用Enlighten对树木进行间接光照计算。
我们需要尽可能的缩减单个物体的Lightmap的UV区块来降低UV Charts,在分Lightmap UV时一定要注意,尽可能将UV连在一起,这样会让Enlighten计算量降低。
Clustering基本上用每个色块作为一个计算单元,它可以发射低频光对周围进行影响,精度越高,块越小,整体的计算量就会加大,整个计算间接光的时间就会更长一些。
Unity光照技术
- Directional Light、
- Area Light、
- Spot Light、
- Point Light
- SkyLight
skyLight是Unity很重要的一个功能,这也是很多人烘焙Unity光照最容易出问题的部分。Unity提供Procedural Skybox,这个Skybox基本上会贡献整体光照烘焙Lightmap的80%左右,所以如果不会使用SkyLight,烘培出来的贴图将效果很差。
- Light Probe
- Reflection Probe,
用来提升一些特殊效果和优化性能的
Unity的光照,必须要讲Unity从Gamma空间过渡到线性空间,以及现在一直保留的Gamma空间的支持
线性空间的优点是能够容纳更多亮度细节,不需要压缩亮部来提高暗部的效果,亮部的表现力更强,更接近真实的光照效果。
Procedural Skybox,它重要在哪儿呢?
因为它提供了光照。我们自然界中光照有两个非常重要的概念,一个概念是它有大气的厚度,大气厚度决定色散的情况,对光线的反映。
Sky Tint主要用来计算天空的染色情况,如果空气密度很高,整个天空又染上一些色,它对光线的反应情况。正常情况下,对地球的Sky Tint,只有沙尘暴时才会出现比较奇怪的效果,如果没有沙尘暴的情况下,地球的Sky Tint值比较接近灰度的颜色。
如果在制作异星题材的游戏的话,情况就不太一样,你可能要根据颜色的调整,让大气做一些吸收,这样折算出来的Sky Light会发生一些改变。
Ground基本上是Skybox在模拟地面对物体的影响,如果值很强会让地面失去立体感,计算时底部的光照会很强,导致天花板的区域变亮。所以这个值不要调得特别的高,基本上以灰度为主。
Exposure曝光度的值非常重要,它是天光的强度,基本上可以达到8或更高的倍数,它可以让整个天光变得更强,更强的结果是整个Skybox会非常强。好处是带来更多间接光的强度,但也会带来让受光比较多的地方产生过曝的问题,这是大家需要控制的。
关于Exposure曝光度,建议大家可以跟Atmosphere厚度的值一起调整。如果曝光度增强的时候,可以将大气密度提高,它会形成比较奇怪的现象。在大气足够密的情况下,曝光度很强,大气密度底部会对光线的吸收特别的强,会发生右侧图片发红的情况,这样会计算出一些接近于早晨、晚上的效果。
像左侧这张图,基本上它的大气密度值在1,Exposure值在3,而值在2是另一种效果,它的厚度值在2时,产生了色彩上的变化,这个变化是在模拟物理的效果。
Directional Light在移动游戏开发中常常用作太阳和月亮的首选光源,因为它能够覆盖整个场景,计算的时候非常节省性能。
直接光强度在线性空间下,我们建议白天为1.5-2.0,夜晚为0.4-1.0。Indirect Multiplier值,白天为0.6-1.0,夜晚为0.3-0.7。白天获得的直接光照比晚上的要强,这样白天会产生更好的间接光亮度。
我们看一看烘焙的效果。如上图所示,在白天的设置下,Intensity是1.8,Indirect Multiplier是1,Atmosphere Thickness是1,Exposure是3,这样我们获得了白天光照很好的房间。
如果设置正确,它应该会出现很好的GI效果,而且不会之前认为,在Unity光照中,有些暗部和间接光不是很好,缺乏全局照明的层次感。
上图就是夜晚的设置效果。在设置中,Intensity是0.4,Indirect Multiplier是0.25,Atmosphere Thickness是1,Exposure是0.1,基本上设置的数值都会往下降。特别是降低曝光度后,我们会得到月光的效果,但是它也有间接照明。
上图是人造光源的效果。Unity提供的除了常用的Point Light、Spot Light,还有一个就是Emissive自照明。Unity支持物体的像素照明,可以将物体的Emissve HDR值提高,提高以后就形成一个光源。
像灯管基本上就是一个Emissve照明的效果,它对房间进行了增强和补亮。为了体现夜晚效果的叠加,上图设置没有调得特别强,如果你希望更亮一些,可以在上面增加Area Light,进行补光。
如下图所示,我们可以看到Area Light关掉和开启的效果对比。
Area Light主要用途是什么呢?
如果大家比较观察细节,可以发现窗户的采光,除了太阳光照,有可能窗户外面世界亮的东西,都会发射光线进入房间。但是在计算机不会这样计算。因此,我们需要在窗户边上做一个同样大小的Area Light,往房间里面补光。
在补光之后,你会看到,尤其是在光照贴图的一侧,Area Light关掉和开启会有明显的视觉效果差异。这是因为右侧的区域没有Area Light,它不是非常仿真物理效果,如果加了Area Light,它会很仿真物理。
光照贴图的一个问题是,它们做的都是间接光,间接光一定不能将光照贴图曝掉,或者曝光度严重不足。所以我们需要一个间接光的空间去存储这些间接光信息。
如上图所示,如果间接光非常的亮,会导致我们看到的最右侧的图像效果。曝光那么多的时候,间接光贴图就损失掉了。
我们建议把Light Intensity设为1.8,HDR Exposure为16,或者Intensity等于3,HDR Exposure为16的曝光度效果。这样既能保证场景的亮度,又能让整体光照没什么问题。
烘焙
- 什么是烘焙
- 该如何烘焙
你设置了很多烘培,但基于性能考虑可能不需要那么多物体需要烘培,不优化会导致场景中很多不需要烘培的物体烘培了光照贴图。
烘培完成后,光照贴图可能会非常大,特别对于一些移动游戏,没办法使用那么多贴图,所以正确的烘培也是非常重要的。
- Enlighten系统
首先说一下Unity的Enlighten系统,它的一个优点是支持实时光GI。在构建过程中,构建光照条件后,我们可以调节光照的强度和方向,还可以移动光源。
但是它不能移动物体。如果静态模型要移动,Enlighten实时GI是不支持的,因为它需要构建光照环境,这就限制了Enlighten不是一个纯实时的GI,它是半实时的。
如果Enlighten使用不好,烘培速度会非常慢,我们通常会发现烘培卡在一个地方不动,慢到都想把电脑砸了,这种情况非常常见。所以大家必须按照Enlighten正确的方法去烘培才会比较快。
Enlighten好处是噪点控制非常好,如上图所示,画面的边缘没有太多的噪点,因为Enlighten的计算方式是不太会出现噪点的,它不是光线追踪算法,也不依赖于光子弹射。
Unity 5开始集成Enlighten,但Unity 2020 LTS版将是在内置渲染器包含Enlighten系统的最后一个版本,Unity 2021.1将完全移除Enlighten。
- Progressive烘焙
Progressive烘焙基于光线追踪,发射的一个光子弹射了多少次,弹射时分裂多少光子,再进行弹射。
Progressive的优点是:真实、GPU烘焙、烘培速度快。在同等的模型数量下,Progressive的计算速度比Enlighten快很多。Progressive的缺点是噪点控制比较差,当光子发射量不够时,它无法充满整个场景,因此无法计算出正确的光照。 -
Progressive和Enlighten区别
Progressive和Enlighten的烘培时间基本上是相等的。Progressive会有一些斑点,Enlighten几乎没有斑点。但Enlighten的问题的缺乏细节,效果过于程序化。如果这是一个深邃的洞穴,过渡到最后面画面会变成黑色,几乎没有了。
我们提高Progressive的计算光子时烘培效果对比。Progressive会更加立体,更真实一些,Enlighten比较轻一些,或者说立体感不是那么足。
这是Progressive和Enlighten烘培后整体的预览效果,差异还是比较明显的
这是一些烘培参数,当Direct Samples=40和Indirect Samples=400,对比Direct Samples=100和Indirect Samples=800,我们可以看到效果差异明显。
Direct Samples和Indirect Samples等同于直接光的采样数量和间接光的采样数量。如果采样越多,光子出现得越多,它就会将整个环境填得更加均匀,更加符合真实的世界。
真实世界的光子是无限的,在计算机模拟的时候是靠光子的数量来模拟的,所以我们尽可能在烘培的时候要把光子数量提高,这样会得到较好的效果。
使用Progressive时最大的问题是:在室内的情况下,要尽可能把整个烘培的精度提高,因为室内低频光比较多,间接光受到的影响比较多,室外可以稍微降低该值,提高烘焙效率。
Unity光照方案
移动游戏方面,建议大家使用混合光照技术,效率更高和更为逼真。近景可以使用动态阴影,远景使用Shadow Mask,这样可以降低Shadow Pass的压力。
例如:5-20米是使用动态阴影,远景全部使用Shadow Mask,这样手机平台上既可以获得动态阴影,又可以获得高的性能,不至于手机玩一会儿就会很烫的情况发生。
我们看一看混合光照的拆分情况。
如上图所示,Baked Lightmap和Shadow Mask在烘培后,一个是RGB通道的图,另一个是单通道。如果大家有能力修改,我们可以将单通道的图变成四通道来进行变化。
我们烘焙一个Lightmap的时候,Shadow Mask可以烘培四个时间段,例如:8点、11点、15点、17点。烘培完成后,我就可以通过Lit的方式把它Lit成变化,使它有间接光照。
Lightmap只使用一套,但我们可以对它进行扩展。Shadow Mask根据昼夜变化的时间,做成四套带有间接光照的,这样便可以根据项目进行深度的改进。