# 游戏引擎中的光照与渲染

想要在引擎中得到理想的材质表现,光照是永远绕不开的一个话题。之前在项目中也对光照和渲染这一块花了不少时间去踩坑折腾,这次就来讲讲如何在引擎中去设置光照来得到自己想要的渲染效果。

# 给光照一个分类

以UE5为例,一个材质所接受的光照可以简单分为以下几类

  1. 直接光 Directional Light,在场景中添加一个Directional Light Actor即可得到
  2. 间接光 Indirectional Light,也可以叫做环境光,在场景中添加一个Sky Light即可得到
  3. 点光以及其他光,例如Point Light,Spot Light等

想要更加直观的感受,只需要打开UE引擎,创建一个默认空场景,依次添加上述的Actor即可看到每种光在UE中所展现的效果。

DifferentLights

其中每一个中光照都会产生一个Diffuse分量和一个Specular分量,这个则由材质所使用的光照模型来决定。在不考虑点光和其他因素影响的情况下,通常所说的调整材质的光照,一般来说就是去调整直接光和间接光。制定材质效果,调整光照,这好像听起来是一件非常简单的事情,调整光照,不就引擎里面动动手指给个参数的事吗。确实,刚踏入这个坑的我也是这样一个想法,然而,在执行的过程中却花费了比想象中要多的多的精力去完成这件事情。

那么就让我从头开始梳理这些年所踩过的坑吧

# 第一坑:游戏引擎与DCC之间无法逾越的鸿沟

第一个坑可能无关乎引擎中的光照,但却是在整个制定渲染效果的流程当中定会遇到的问题。

假设这样一个场景,美术同学把刚做好的模型导入引擎里,给材质贴上贴图,给模型贴上材质,结果发现引擎中的效果和自己在DCC软件中看到的效果简直完全不同。于是他把负责引擎渲染的你叫了过去:为什么我同样的贴图,同样的光照,引擎中的效果和和我在DCC中的效果完全不同呢?

你伸出双手开始比划,什么光照模型,什么离线渲染实时渲染,什么纹理色彩空间,什么后处理算法,列举了一系列可能导致两边效果不一样的原因,满脸疑问的美术只蹦出一句,那咋搞嘛。

咋搞,这才是这其中的问题。本质上是希望解决美术在制作模型的过程当中,引擎和DCC表现不一致的问题。表现一致,需要两边拥有相同的贴图,相同的材质,相同的光照模型,以及相同的后处理。DCC软件大多数情况下都不开源,因此无法得知其具体的渲染算法。然而主流DCC软件一般都能够支持自定义的材质和Shader,那么可选的路径似乎只剩下一条,就是在DCC中去尽量还原出引擎的渲染环境。

当然,如果项目组没有足够的人力去解决这个问题,让美术多花点时间来回捣腾反复观看也不是不可。

# 第二坑:建立标准光照环境

现在上面第一个问题已经完美解决,美术成功把模型丢到了引擎里面,效果也和DCC中的一样,然而某一天,细心的美术突然发现,这个模型的材质表现似乎变得有点偏暗了,不知道引擎同学又对引擎搞了什么鬼,还是场景同学调整了整个场景的环境。于是现在所面临的是一个调参的问题。那么问题来了,此时此刻,材质偏暗,该调整哪一个参数。去调整光照强度,可以让材质打到预期表现,但是会不会导致其他材质过曝。调整材质参数,会不会影响光照的其他计算。调整贴图明暗,会不会导致材质在其他光照环境下又出现问题。似乎哪个都可,但是又不完全可。

这时候建立一个标准的光照环境则变成了一件非常有必要的事情,也就是通常所说的Lookdev环境。

标准光照环境的建立是一件非常严谨的事情,意味着将来几乎所有的美术资源的生产都将以这个环境为标准来进行。它不考虑任何艺术效果,只追求一个物理正确的光照。

Lookdev场景的搭建也涉及到非常多的细节,包括整个环境光比的确定,曝光等后处理参数的调整等等。有条件可以使用测光仪来进行各种光照参数的测定,条件差点的可以用相机来大致确定环境参数,啥也没有的,可以在网上找找是否有公开的环境参数来进行参考校准。具体的细节本文就不再展开。

Lookdev的建立会让项目组拥有一套更加统一标准的美术流程,而不至于在美术资源生产时全凭感觉来调整参数。

# 第三坑:材质中的光照计算

好了,现在已经完成了Lookdev场景的搭建,美术终于把模型丢到了Lookdev场景中来观察效果,这时候又出现了新的问题:使用不同光照模型的两个材质A和B,在这个场景当中明暗面的表现都完全不同,放在同一个场景里面简直就是两个不同画风,显得十分违和。这时肯定不能去更改环境的光照了,那么就需要对材质的参数进行一些调整。

那么材质的参数该如何调整,才能使两个不同光照模型的材质在场景中拥有一致的表现呢。上述对光照的分类就派上了用处。光照的分类可以帮助我们针对每一种光的分量进行依次调整,将每种光的diffuse与specluar分别进行调整,直到两个材质的明暗表现都达到一个相近的水平。

不管使用的是什么光照模型,光照的分量是缺一不可的,直接光自不必说,如果缺失了环境光,在白天等强光环境下可能不会轻易看出问题,但是到了夜晚等弱光环境,或者是大面积阴影覆盖的区域,效果差异会变得非常显著。尽管环境光的分量一般在数值上非常之小。

UE的环境光一般来自于实时捕捉的环境球或是已经烘焙好的CubeMap,其中环境光的Diffuse分量引擎会使用球谐函数来进行计算,Specular分量则使用当前环境的IBL来进行计算,计算完成之后与直接光作用于材质光照模型后的结果相加,得到最终的光照结果。

如果是直接使用UE自带的光照模型和材质编辑器来完成材质的制作,其实并不需要操心这么多细节上的问题,编辑器也没有提供这些细粒度的调整手段。但如果项目推进的过程中,人人都是引擎定制家,那么了解其中的计算细节则是必不可少的环节。

# 第四坑:更好的渲染效果

完成了以上几个步骤,理论上已经拥有了一个标准且高效的的美术资源工作流,有了引擎中光照表现正确的材质,但是搭建一个渲染效果好的场景需要做的还有很多。例如场景的布置和打光,例如更好的天空效果和云雾效果,每一个都是需要付出非常多的时间精力去调试折腾。

以上的一些总结,可能并非那么偏向于技术层面,但在实践的过程当中,我反而觉得这些要比一些技术方面的东西更加重要一些,因此一边回忆一边把这些给总结了出来。毕竟再高深的渲染技术可能最终也就是一行Shader代码,而这些东西却是实实在在的经验。