本文节选自洪流学堂公众号专栏《郑洪智的Unity2018课》,未经允许不可转载。
洪流学堂公众号回复光照探头
,获取本文对应的视频实战教程。
洪流学堂,让你快人几步。你好,我是郑洪智。
Unity的预计算实时GI或者烘焙照明只对静态的物体起作用,对于可移动的物体,需要用一种新的技术来解决光照问题。
为了让动态物体(如交互式场景元素或角色)能够获得静态物体反弹的光线,需要将这些光照信息记录下来,并且在运行时能快速读取和使用。
通过在场景中放置采样点捕捉各个方向的光线来实现动态物体接收间接光的功能。这些采样点记录的光照信息被编码成可以在游戏过程中快速计算值。在Unity中,我们将这些采样点称为“光照探头”。
Light Probe(光照探头)
这个技术是让动态物体从场景接收间接光的有效方法。尽管使用该技术的动态物体不会产生反射光,但通常这没有什么明显的影响。因为探测照明的物体往往是较小的物体,能反射的光很少,对周围环境的影响很有限。
什么是Probe Lighting(探测照明)?
探测照明是一种用于实时渲染的高级照明技术,常用于场景中的角色或非静态(Static)物体的照明。探测照明运行时效率非常高并且预计算也很快。
探测照明通过3D空间中的探头对入射光进行采样并将这些信息通过球谐函数编码处理后保存成文件。这些信息占用的存储空间很少并且在运行时解码非常快。场景中的Shader可以使用这些信息来模拟物体表面的光照。
当然了,有优势也会有相应的劣势。在一定的计算量下,探测照明很难表现变化复杂的照明效果。但是如果增加模拟精度,计算代价也会随之增高。基于性能的考虑,Unity限制了计算的精度。另外一个,由于一个3D位置只用了一个球来进行模拟,在大模型以及较平的模型表面上的光照效果可能会不太好。
除去这些限制,探测照明在小的、凸状的物体上有很好的效果,同时性能很好。
放置Light Probe
非静态物体根据距离最近的探头来接收光照。光照探头会将整个空间划分成一个个四面体,一个物体最终从哪个探头读取光照数据这个物体最终落在哪一个四面体中确定的。为了能够形成这些四面体,探头在摆放时必须形成三维的立体形状或者笼子的形状(不能只在一个平面上摆放)。
探测照明在运行时耗费的资源很少并且预计算也很快。但是,为了尽可能优化性能,在摆放光照探头时也有一些注意事项。
- 以整齐的密集网格排列会减少摆放时的工作量,但是这样会造成很多探头的浪费,因为很多探头在相近的位置接收到的光照都类似,在相似的光照位置,只需要一个或几个探头就足够了。
- 为了提高探头的效率,应该在光照变化比较大的地方多放置探头,在光照变化不大的地方少放探头。比如应该在从明亮到阴影的过渡位置多放探头,在反射光较强烈的表面多放置探头,在大的平面上少放探头。
设置Light Probe的步骤如下:
- 首先从GameObject菜单(GameObject > Light > Light Probe Group)创建一个Light Probe Group。
- 现在我们将开始放置探头。在Hierarchy中选择新创建的Light Probe Group。
- 在Inspector中,在Light Probe Group组件中选择“Edit Light Probes ”。
- 默认创建出来Light Probe Group有8个探头组成了一个立方体,你可以选中一个小黄球,移动重新摆放这些探头,也可以删除所有的探头重新创建。
- 选中一个探头,按Ctrl + D(Mac上的Cmd + D)可以复制一个出来,然后使用Move Tool(W)移动探头。
- 一般来说,放置探头在Y轴至少要放置两层(上文提到了探头需要组成三维立体或笼子形状),接近地面的区域可以多放置一些,空中可以少放置一些
这样的垂直布置光照探头的原因是为了能够从角色的头部高度或更高的空中接收从地面反射的间接光。当我们在场景复制这些光照探头来组成四面体时,确保任何物体都能落入四面体内。探头之间绘制的洋红线可以可视化这些四面体。
可以通过Ctrl+点击多选或框选,选择多个探头进行复制并布置。将复制出来的探头移动到场景中光照“敏感”的区域。
光照“敏感”的区域有哪些呢?
寻找光影变化的区域,或者材质颜色变化较大的区域。记住,我们的目标是在整个场景中采样。为了保证添加的光照探头是合理的,我们需要确保它正在采样的地方照明有明显的变化。如果使用光照探头来采样没有特点或其他探头已采样过的区域,那么当动态物体通过这些探头获取光照信息时,不会看到太多变化,所以这些探头也没什么必要。基于游戏优化方面的考虑,我们应该尽可能让放进去场景的东西发挥一定的作用。
- 重复复制探头并将它们放置在合适的位置,直到所有探头形成的稀疏笼式布局,覆盖玩家可到达的区域。
- 在放置探头时,记住检查最底端的探头是否高于地面(在地面以下可能会造成地面上的物体光照信息错误)。
一个场景中可以创建多个Light Probe Group,比如一个光影复杂的城市中使用一个较密集的Light Probe Group,城市周边使用一个较稀疏的Light Probe Group。场景中有多个Light Probe Group时,Unity在运行时会将这些Group自动合并,并且会移除位置重复的Probe。
预计算完成后,我们才能看见光照探头对场景中物体的作用。如果Lighting窗口中的Auto Generate复选框是选中的,预计算会自动开始;如果没有选中,可以点击右侧的Generate Lighting来启动预计算。
计算完成后,你就能看到场景中的非静态物体上的灯光和整个场景更契合了。
在GI烘焙中,大量的小物体会增加非常多的计算量,但是这些小物体反射的光基本上对场景没有影响。所以如果能将这些小物体排除在外,只接收间接光,不反射光,可以将预计算的时间减少很多。这也是光照探头针对GI的一个优化点。
物体Renderer上的Light Probe
Light Probe与计算完毕后,选中一个非Static的物体,你可以在场景中看到:
如果没有显示成上图那样,Lighting面板的Debug Settings按下图所示设置。
还记得MeshRenderer中关于Light Probe的设置么?(通常保持默认值即可)
- Off 不使用Light Probe,即不会从Probe中获取光照信息
- Blend Probes 默认值。使用混合后的Probe。
- Use Proxy Volume 用到的较少。当大的物体使用Blend Probes光照效果不好时,可以尝试使用。具体用法可以参考官方文档
Custom Provided 用于在Shader中自定义Probe,后面Shader模块会讲到。
总结
今天学习了使用Unity中的光照系统中的Light Probe,希望你能记住以下几点:
- Light Probe能给动态物体提供高质量光照
- 放置Light Probe时尽量放到光影变化多的地方
今日思考题
构建一个简单场景,在烘焙GI的基础上,添加Light Probe和动态物体,看看动态物体的效果如何~
欢迎在留言区分享你的收获,和大家一起讨论。
别忘了分享给你学Unity的朋友,也许能够帮到他。
洪流学堂公众号回复光照探头
,获取本文对应的视频实战教程。
《郑洪智的Unity2018课》,倾尽我8年的开发经验,结合最新的Unity2018,带你从入门到精通。