参考链接:http://www.xuanyusong.com/archives/3807
其它关于Unity5的光照系统神马的,网上很多资源,这几个文章良大本人觉得是很有价值的:
Unity 5 中的全局光照技术详解
http://www.gameres.com/forum.php?mod=viewthread&tid=446301
详解Unity 5 全局光照系统Enlighten问题
http://forum.china.unity3d.com/thread-14559-1-1.html
http://forum.china.unity3d.com/thread-14700-1-1.html
项目内需要对项目进行动态更新或者制作如白天黑夜等,同一场景不同光照渲染的情况。
将场景(.unity)文件转换成(.prefab)文件,能够更加自由的操作场景资源的更换。
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using GOE.Scene;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
using SceneManager = UnityEngine.SceneManagement.SceneManager;
///
/// 描述:动态烘焙场景光照模型,并产生对应的Prefab文件
/// 创建时间:2016-06-15
///
public sealed class LightMapEditor
{
private const string LightMapsDir = "Resources/Lightmaps/";
private static List sceneLightmaps = new List();
public static void UpdateLightmaps()
{
PrefabLightmapData pld = GameObject.FindObjectOfType();
if (pld == null) return;
LightmapSettings.lightmaps = null;
PrefabLightmapData.ApplyLightmaps(pld.mRendererInfos , pld.mLightmapFars , pld.mLightmapNears);
Debug.Log("Prefab Lightmap updated");
}
public static void GenLightmap()
{
genBakeLightmapAndPrefab(false);
EditorSceneManager.SaveOpenScenes();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("----------------Update to Prefab Lightmap Finish -------------------------");
}
///
/// 生成lightmap和prefab资源
///
private static void genBakeLightmapAndPrefab()
{
if (Lightmapping.giWorkflowMode != Lightmapping.GIWorkflowMode.OnDemand)
{
Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled.");
return;
}
Debug.ClearDeveloperConsole();
PrefabLightmapData[] pldArr = GameObject.FindObjectsOfType();
if (pldArr == null || pldArr.Length <= 0)
{
EditorUtility.DisplayDialog("提示", "没有找到必要的脚本PrefabLightmapData,请检查场景", "OK");
return;
}
Lightmapping.Bake();
sceneLightmaps.Clear();
string path = Path.Combine(Application.dataPath, LightMapsDir);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
Scene curScene = EditorSceneManager.GetActiveScene();
string sceneName = Path.GetFileNameWithoutExtension(curScene.name);
string scenePath = Path.GetDirectoryName(curScene.path) + "/" + sceneName + "/";
string resourcesPath = Path.GetDirectoryName(curScene.path) + "/" + sceneName + "_lightmap/" + sceneName;
foreach (PrefabLightmapData pld in pldArr)
{
GameObject gObj = pld.gameObject;
List renderers = new List();
List lightmapFars = new List();
List lightmapNears = new List();
genLightmapInfo(scenePath, resourcesPath, gObj, renderers, lightmapFars, lightmapNears);
pld.mRendererInfos = renderers.ToArray();
pld.mLightmapFars = lightmapFars.ToArray();
pld.mLightmapNears = lightmapNears.ToArray();
GameObject targetPrefab = PrefabUtility.GetPrefabParent(gObj) as GameObject;
if (targetPrefab != null)
{
//自定义存放的路径
PrefabUtility.ReplacePrefab(gObj, targetPrefab);
}
else
{
//默认路径
string prefabPath = Path.GetDirectoryName(curScene.path) + "/" + sceneName + ".prefab";
PrefabUtility.CreatePrefab(prefabPath, gObj, ReplacePrefabOptions.ConnectToPrefab);
}
//改变当前场景中的光照贴图信息
PrefabLightmapData.ApplyLightmaps(pld.mRendererInfos, pld.mLightmapFars, pld.mLightmapNears);
}
}
private static void genLightmapInfo(string scenePath , string resourcePath , GameObject root,
List renderers, List lightmapFars,
List lightmapNears)
{
MeshRenderer[] subRenderers = root.GetComponentsInChildren();
LightmapData[] srcLightData = LightmapSettings.lightmaps;
foreach (MeshRenderer meshRenderer in subRenderers)
{
if(meshRenderer.lightmapIndex == -1) continue;
RendererInfo renderInfo = new RendererInfo();
renderInfo.renderer = meshRenderer;
renderInfo.LightmapIndex = meshRenderer.lightmapIndex;
renderInfo.LightmapOffsetScale = meshRenderer.lightmapScaleOffset;
Texture2D lightmapFar = srcLightData[meshRenderer.lightmapIndex].lightmapFar;
Texture2D lightmapNear = srcLightData[meshRenderer.lightmapIndex].lightmapNear;
int sceneCacheIndex = addLightmap(scenePath, resourcePath, renderInfo.LightmapIndex, lightmapFar,
lightmapNear);
renderInfo.LightmapIndex = lightmapFars.IndexOf(sceneLightmaps[sceneCacheIndex].LightmapFar);
if (renderInfo.LightmapIndex == -1)
{
renderInfo.LightmapIndex = lightmapFars.Count;
lightmapFars.Add(sceneLightmaps[sceneCacheIndex].LightmapFar);
lightmapNears.Add(sceneLightmaps[sceneCacheIndex].LightmapNear);
}
renderers.Add(renderInfo);
}
}
private static int addLightmap(string scenePath, string resourcePath, int originalLightmapIndex,
Texture2D lightmapFar,
Texture2D lightmapNear)
{
for (int i = 0; i < sceneLightmaps.Count; i++)
{
if (sceneLightmaps[i].OriginalLightmapIndex == originalLightmapIndex)
{
return i;
}
}
RemapTexture2D remapTex = new RemapTexture2D();
remapTex.OriginalLightmapIndex = originalLightmapIndex;
remapTex.OrginalLightmap = lightmapFar;
string fileName = scenePath + "Lightmap-" + originalLightmapIndex;
remapTex.LightmapFar = getLightmapAsset(fileName + "_comp_light.exr", resourcePath + "_light",
originalLightmapIndex);
if(lightmapNear != null)
remapTex.LightmapNear = getLightmapAsset(fileName + "_comp_dir.exr", resourcePath + "_dir",
originalLightmapIndex);
sceneLightmaps.Add(remapTex);
return sceneLightmaps.Count - 1;
}
private static Texture2D getLightmapAsset(string fileName, string resourecPath, int originalLightmapIndex)
{
TextureImporter importer = AssetImporter.GetAtPath(fileName) as TextureImporter;
if (importer == null) return null;
importer.isReadable = true;
AssetDatabase.ImportAsset(fileName , ImportAssetOptions.ForceUpdate);
Texture2D assetLightmap = AssetDatabase.LoadAssetAtPath(fileName);
string assetPath = resourecPath + "_" + originalLightmapIndex + ".asset";
Texture2D newLightmap = GameObject.Instantiate(assetLightmap);
string dir = Path.GetDirectoryName(assetPath);
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
// byte[] bytes = newLightmap.EncodeToPNG();
// File.WriteAllBytes(assetPath, bytes);
AssetDatabase.CreateAsset(newLightmap , assetPath);
newLightmap = AssetDatabase.LoadAssetAtPath(assetPath);
importer.isReadable = false;
AssetDatabase.ImportAsset(assetPath , ImportAssetOptions.ForceUpdate);
return newLightmap;
}
}
用于还原和记录光照数据
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace GOE.Scene
{
///
/// 描述:光照模型预设
///
[DisallowMultipleComponent , ExecuteInEditMode]
public class PrefabLightmapData : MonoBehaviour
{
[SerializeField]
public RendererInfo[] mRendererInfos;
[SerializeField]
public Texture2D[] mLightmapFars;
[SerializeField]
public Texture2D[] mLightmapNears;
void Awake()
{
ApplyLightmaps(mRendererInfos , mLightmapFars , mLightmapNears);
//设置原来烘焙时的光照模式,这个不设置正确,默认模式就会只显示光照贴图
LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional;
}
void Start()
{
// StaticBatchingUtility.Combine(this.gameObject);
}
///
/// 应用光照模型,根据指定的渲染信息
///
///
///
///
public static void ApplyLightmaps(RendererInfo[] rendererInfos, Texture2D[] lightmapFars,
Texture2D[] lightmapNears)
{
if (rendererInfos == null || rendererInfos.Length <= 0)
{
Debug.LogWarning("<> renderer info is null !" );
return;
}
LightmapData[] settingLightMaps = LightmapSettings.lightmaps;
int[] lightmapOffsetIndex = new int[lightmapFars.Length];
List combinedLightmaps = new List();
bool existAlready = false;
for (int i = 0; i < lightmapFars.Length; i++)
{
existAlready = false;
for (int j = 0; j < settingLightMaps.Length; j++)
{
if (lightmapFars[i] == settingLightMaps[j].lightmapFar)
{
lightmapOffsetIndex[i] = j;
existAlready = true;
break;
}
}
//如果不存在,则创建新的光照数据
if (!existAlready)
{
lightmapOffsetIndex[i] = settingLightMaps.Length + combinedLightmaps.Count;
LightmapData newLightData = new LightmapData();
newLightData.lightmapFar = lightmapFars[i];
newLightData.lightmapNear = lightmapNears[i];
combinedLightmaps.Add(newLightData);
}
}
//组合数据
LightmapData[] finalCombinedLightData = new LightmapData[combinedLightmaps.Count + settingLightMaps.Length];
settingLightMaps.CopyTo(finalCombinedLightData , 0);
combinedLightmaps.CopyTo(finalCombinedLightData , settingLightMaps.Length);
combinedLightmaps.Clear();
applyRendererInfo(rendererInfos , lightmapOffsetIndex);
//重新绑定
LightmapSettings.lightmaps = finalCombinedLightData;
}
///
/// 应用渲染信息
///
///
///
private static void applyRendererInfo(RendererInfo[] rendererInfos, int[] offsetIndexs)
{
for (int i = 0; i < rendererInfos.Length; i++)
{
RendererInfo info = rendererInfos[i];
info.renderer.lightmapIndex = offsetIndexs[info.LightmapIndex];
info.renderer.lightmapScaleOffset = info.LightmapOffsetScale;
}
}
}
}
using UnityEngine;
namespace GOE.Scene
{
///
/// 渲染信息
///
[System.Serializable]
public struct RendererInfo
{
public Renderer renderer;
public int LightmapIndex;
public Vector4 LightmapOffsetScale; //偏移和缩放
}
///
/// 重渲贴图
///
[System.Serializable]
public struct RemapTexture2D
{
public int OriginalLightmapIndex;
public Texture2D OrginalLightmap;
public Texture2D LightmapFar;
public Texture2D LightmapNear;
}
}