昼夜交替,目前通用的做饭是动态替换LightMap。
要烘焙LightMap。需要物体带UV2.美术没有做UV2的情况下,Unity导入物体时勾选上“Generate Lightmap UVs ”。就会自动创建UV2
烘焙好的物品,在Render组件上面能查看到LightMap的信息。里面主要存的是用到那张光照贴图以及在光照贴图里面的Index和Scale,如图所示:
影响光照贴图显示的。基本上就是上面几个参数。
在不进行静态批处理的情况下。可以手动设置光照贴图的参数到每个物体。从而改变光照贴图的显示。但是一旦发生了静态批处理合并。就不能手动设置上面的参数。所以要想动态改物体上的Lightmapping参数。就要不勾选静态批处理。
如果场景物体没有移动,没有改变过lightmapScale,光罩面板里的分辨率等参数不变的话,只是灯光位置和参数的变化是不会引起物体的光照index,scale 这两个参数变化的。只要这两个参数不变。整体替换LightMap之后就不会出现偏差
基于上面的原因。可以有两种动态切换LightMap的方式
1、不勾选静态批处理。加载完场景之后手动修改物体的Lightmapping参数和场景的LightmapSettings。这样的好处是可以任意修改烘焙信息。缺点就是不进行静态批处理会影响一部分效率
//手动修改物品的Lightmapping参数, lightmapIndex和lightmapOffsetScale都是在编辑器里面保存下来的
void SetObjLightMap(GameObject a, int lightmapIndex, Vector4 lightmapOffsetScale)
{
var ren = a.GetComponent<Renderer>();
ren.lightmapIndex = lightmapIndex;
ren.lightmapScaleOffset = lightmapOffsetScale;
}
//加载LightMap
void LoadLightMap(string strPath)
{
var aLightMap = Resources.Load<Texture2D>(strPath);
if(strPath.Contains("dir"))
{
lightmapData.lightmapDir = aLightMap;
}
else
{
lightmapData.lightmapColor = aLightMap;
}
}
//设置LightMap,LightMapData可以是一个数组。这里测试就用一个就行
void SetLightMap()
{
lightmapDatas.Clear();
lightmapDatas.Add(lightmapData);
LightmapSettings.lightmaps = lightmapDatas.ToArray();
}
2、在“场景物体没有移动,没有改变过lightmapScale,光罩面板里的分辨率等参数不变”的前提下。修改场景的LightmapSettings就行。有个需要注意的地方。默认的场景需要带一套光照贴图。不然物体上面没有Lightmapping参数信息。这就不可避免的增加了一些内存。优点是简单。不用太多的操作。缺点就是有一些限制前提。如果在移动端的话。这些限制还是能克服的
上面两种方法都是直接切换。会有一些突兀。在有条件的高端机上面。可以在Shader里面,根据时间参数。Lerp两个光照贴图获得一个插值的颜色教给物体使用。插值光照贴图需要给光照贴图解码。解码在UnityGlobalIllumination里面。具体的函数是DecodeLightmap。
上面的代码:
通过LightMapUV获取到当前的光照贴图的颜色和要插值的光照贴图颜色。然后通过DecodeLightmap函数解码出真正能用的颜色。用这个颜色值交付给物体使用
还有一种不替换LightMap的方法。是通过修改材质的参数。达到物体变暗的效果。具体参考:
https://answer.uwa4d.com/question/5aa9d6f4d35eb22c10a0a3cf
https://answer.uwa4d.com/question/5992e3aae85f22ea2dc0c603
Shader读取LightMap的参考: