在上一篇了解了光照以及光照贴图的一些相关属性后,在这篇具体讲讲相关的使用,以及自己预见的一些坑。
首先还是在上一篇的场景基础上,我们隐藏Realtime和Mixed光源,只留Baked的光源用来进行场景的烘焙。在Lighting设置中,只勾选Baked GI选项,Lighting Mode选择Subtractive。取消自动烘焙Auto Generate的勾选,点击Generate Lighting,手动生成Lightmap。同时Unity会在.scene文件同级目录下生成一个和scene名相同名称的文件夹,用于存放lightmap数据。相比自动生成的情况,在Baked Lightmaps中会多出一个Lighting Data Asset的参数,对应的LightingData.asset文件用于存放一些Lighting数据。
生成好之后运行Unity,修改Baked光源发现不影响场景的显示,一切都正常。
但是,当我们把静态场景存为Prefab的时候,就会出现一些问题了。而在实际的开发中,很多情况下会把静态的场景存为Prefab用于动态的加载。
我们将测试场景的物体放在同一个根目录下,然后将其转变为Prefab,点击运行。你会发现动态物体(胶囊体)也受到了baked光源的影响,变成了红色。关闭baked光源你会发现整个场景的物体都变黑了,baked的光源效果变成了realtime。
我们随便点击一个静态物体会发现其MeshRenderer中的Lightmapping属性关联的Lightmap不见了。造成这一现象的原因是,我们生成Lightmap的时候,其对应的信息都是和场景中GameObject的唯一ID相关联。当我们将这些GameObject变为Prefab时(包括后期加载该Prefab到场景中),唯一ID发生了变化,导致信息无法正确的关联起来。
有一个解决方案是,我们创建一个组件,挂载Prefab上。在烘焙完成后,这个组件会遍历该节点下所有静态物体的MeshRenderer,存储对应的Lightmap信息。当加载该Prefab的时候,将对应的Lightmap信息重新关联到对应的MeshRenderer上,代码如下:
注:由于很多时候美术可能会在一个新的场景中设置地图,然后会设置一些环境光,Fog等信息,我们程序在别的场景加载的时候,除了对应的地图Prefab外,这些信息也应该对应的设置,所以同Lightmap一起写在了脚本中。
注:由于Terrain比较特殊,如果地图中用到的话,需要单独读取信息。
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.Rendering;
/// <summary>
/// 渲染信息