场景中对预设体进行烘焙贴图后,然后删掉场景中的预设体,接着再通过代码实例化这个预设体或者直接拖一个预设体进入一个场景,都会发现场景光照信息丢失
光照信息丢失的主要原因是:
解决这个问题的办法如下:
先准备一个场景,如下:
上面的红色物体全部勾选为静态(static),蓝色物体作为参照不勾选静态
对lighting进行参数设置
经过上面准备工作做好后,开始烘焙
此时 ,我们删掉场景中的Plane预设体,然后再重新向场景中拖入该Plane的预设体,你会发现,没有光照信息,场景很暗
但是此时运行场景,你会发现光照信息又有啦
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PrefabLightmapData : MonoBehaviour
{
[System.Serializable]
struct RendererInfo
{
public Renderer renderer;
public int lightmapIndex;
public Vector4 lightmapOffsetScale;
}
[SerializeField]
RendererInfo[] m_RendererInfo;
[SerializeField]
Texture2D[] m_Lightmaps;
void Awake ()
{
if (m_RendererInfo == null || m_RendererInfo.Length == 0)
return;
var lightmaps = LightmapSettings.lightmaps;
var combinedLightmaps = new LightmapData[lightmaps.Length + m_Lightmaps.Length];
lightmaps.CopyTo(combinedLightmaps, 0);
for (int i = 0; i < m_Lightmaps.Length;i++)
{
combinedLightmaps[i+lightmaps.Length] = new LightmapData();
combinedLightmaps[i+lightmaps.Length].lightmapFar = m_Lightmaps[i];
}
ApplyRendererInfo(m_RendererInfo, lightmaps.Length);
LightmapSettings.lightmaps = combinedLightmaps;
}
static void ApplyRendererInfo (RendererInfo[] infos, int lightmapOffsetIndex)
{
for (int i=0;i<infos.Length;i++)
{
var info = infos[i];
info.renderer.lightmapIndex = info.lightmapIndex + lightmapOffsetIndex;
info.renderer.lightmapScaleOffset = info.lightmapOffsetScale;
}
}
#if UNITY_EDITOR
[UnityEditor.MenuItem("Assets/Bake Prefab Lightmaps")]
static void GenerateLightmapInfo ()
{
if (UnityEditor.Lightmapping.giWorkflowMode != UnityEditor.Lightmapping.GIWorkflowMode.OnDemand)
{
Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled.");
return;
}
UnityEditor.Lightmapping.Bake();
PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
foreach (var instance in prefabs)
{
var gameObject = instance.gameObject;
var rendererInfos = new List<RendererInfo>();
var lightmaps = new List<Texture2D>();
GenerateLightmapInfo(gameObject, rendererInfos, lightmaps);
instance.m_RendererInfo = rendererInfos.ToArray();
instance.m_Lightmaps = lightmaps.ToArray();
var targetPrefab = UnityEditor.PrefabUtility.GetPrefabParent(gameObject) as GameObject;
if (targetPrefab != null)
{
//UnityEditor.Prefab
UnityEditor.PrefabUtility.ReplacePrefab(gameObject, targetPrefab);
}
}
}
static void GenerateLightmapInfo (GameObject root, List<RendererInfo> rendererInfos, List<Texture2D> lightmaps)
{
var renderers = root.GetComponentsInChildren<MeshRenderer>();
foreach (MeshRenderer renderer in renderers)
{
if (renderer.lightmapIndex != -1)
{
RendererInfo info = new RendererInfo();
info.renderer = renderer;
info.lightmapOffsetScale = renderer.lightmapScaleOffset;
Texture2D lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapFar;
info.lightmapIndex = lightmaps.IndexOf(lightmap);
if (info.lightmapIndex == -1)
{
info.lightmapIndex = lightmaps.Count;
lightmaps.Add(lightmap);
}
rendererInfos.Add(info);
}
}
}
#endif
}
注意Directional Mode这个参数要设置成Non-Directional,否则运行场景会是黑的,得不到预期的烘焙效果