165 lines
6.5 KiB
C#
165 lines
6.5 KiB
C#
|
using System.Collections.Generic;
|
|||
|
using UnityEngine;
|
|||
|
using UnityEditor;
|
|||
|
using UnityEditor.SceneManagement;
|
|||
|
using Object = UnityEngine.Object;
|
|||
|
|
|||
|
public class LightmapSeperate
|
|||
|
{
|
|||
|
public const string lightmapFormat = "Assets/Res_newMS/LightmapParameters/Lightmap{0}.giparams";
|
|||
|
public const int textureSize = 1024;
|
|||
|
public const float atlasFillRatio = 1f;
|
|||
|
|
|||
|
[MenuItem("Scene/Bake Scene 烘培当前场景", false, 1)]
|
|||
|
public static void SeperateLightmaps()
|
|||
|
{
|
|||
|
var resolution = LightmapEditorSettings.bakeResolution;
|
|||
|
var allMaterials = new List<LightmapSizeData>();
|
|||
|
var meshRenderers = Object.FindObjectsOfType<MeshRenderer>();
|
|||
|
for (var i = 0; i < meshRenderers.Length; i++)
|
|||
|
{
|
|||
|
var meshRenderer = meshRenderers[i];
|
|||
|
if (meshRenderer.gameObject.isStatic)
|
|||
|
{
|
|||
|
var serialized = new SerializedObject(meshRenderer);
|
|||
|
var property = serialized.FindProperty("m_ScaleInLightmap");
|
|||
|
if (property != null && property.floatValue > 0.5f)
|
|||
|
{
|
|||
|
property.floatValue = 0.5f;
|
|||
|
serialized.ApplyModifiedProperties();
|
|||
|
}
|
|||
|
var mainMaterial = meshRenderer.sharedMaterial;
|
|||
|
if (mainMaterial == null)
|
|||
|
Debug.LogError("物体没有材质 " + meshRenderer.transform.GetHierarchyName());
|
|||
|
else
|
|||
|
{
|
|||
|
var lightmapSize = allMaterials.GetItem(mainMaterial, ListGetMode.create);
|
|||
|
lightmapSize.AddMeshRenderer(meshRenderer, resolution);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
for (var i = allMaterials.Count - 1; i >= 0; i--)
|
|||
|
if (!allMaterials[i].IsBakable())
|
|||
|
{
|
|||
|
allMaterials[i].SetLightmapParameters(null);
|
|||
|
allMaterials.RemoveAt(i);
|
|||
|
}
|
|||
|
// 试图合并光照贴图
|
|||
|
allMaterials.Sort((a, b) => -a.totalSize.CompareTo(b.totalSize));
|
|||
|
for (var i = allMaterials.Count - 1; i >= 0; i--)
|
|||
|
{
|
|||
|
var material = allMaterials[i];
|
|||
|
if (material.rendererList.Count < 1)
|
|||
|
{
|
|||
|
allMaterials.RemoveAt(i);
|
|||
|
material.SetLightmapParameters(null);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var lightmapList = new List<LightmapParamData>();
|
|||
|
while (allMaterials.Count > 0)
|
|||
|
{
|
|||
|
var lightmapData = new LightmapParamData();
|
|||
|
lightmapList.Add(lightmapData);
|
|||
|
lightmapData.AddLightmap(allMaterials, 0);
|
|||
|
var index = allMaterials.FindIndex(a => a.totalSize + lightmapData.totalSize < textureSize * textureSize * atlasFillRatio);
|
|||
|
while (index >= 0)
|
|||
|
{
|
|||
|
lightmapData.AddLightmap(allMaterials, index);
|
|||
|
index = allMaterials.FindIndex(a => a.totalSize + lightmapData.totalSize < textureSize * textureSize * atlasFillRatio);
|
|||
|
}
|
|||
|
}
|
|||
|
var source = AssetDatabase.LoadAssetAtPath<LightmapParameters>(string.Format(lightmapFormat, 0));
|
|||
|
for (var i = 0; i < lightmapList.Count; i++)
|
|||
|
{
|
|||
|
LightmapParameters target;
|
|||
|
if (i == 0)
|
|||
|
target = source;
|
|||
|
else
|
|||
|
{
|
|||
|
var path = string.Format(lightmapFormat, i);
|
|||
|
target = AssetDatabase.LoadAssetAtPath<LightmapParameters>(path);
|
|||
|
if (target == null)
|
|||
|
{
|
|||
|
target = Object.Instantiate(source);
|
|||
|
target.bakedLightmapTag = i;
|
|||
|
EditorUtility.SetDirty(target);
|
|||
|
AssetDatabase.CreateAsset(target, path);
|
|||
|
}
|
|||
|
}
|
|||
|
var lightmap = lightmapList[i];
|
|||
|
lightmap.SetLightmapParameters(target);
|
|||
|
}
|
|||
|
EditorSceneManager.MarkAllScenesDirty();
|
|||
|
AssetDatabase.Refresh();
|
|||
|
// 配置标准化烘培参数
|
|||
|
LightmapEditorSettings.maxAtlasHeight = textureSize;
|
|||
|
#if UNITY_2018
|
|||
|
LightmapEditorSettings.maxAtlasSize = textureSize;
|
|||
|
#endif
|
|||
|
Lightmapping.BakeAsync();
|
|||
|
}
|
|||
|
|
|||
|
public class LightmapParamData
|
|||
|
{
|
|||
|
public readonly List<LightmapSizeData> lightmapSizeList = new List<LightmapSizeData>();
|
|||
|
public float totalSize { get; private set; }
|
|||
|
|
|||
|
public void AddLightmap(List<LightmapSizeData> list, int index)
|
|||
|
{
|
|||
|
var item = list[index];
|
|||
|
list.RemoveAt(index);
|
|||
|
totalSize += item.totalSize;
|
|||
|
lightmapSizeList.Add(item);
|
|||
|
}
|
|||
|
|
|||
|
public void SetLightmapParameters(LightmapParameters lightmapParameters)
|
|||
|
{
|
|||
|
for (var i = 0; i < lightmapSizeList.Count; i++)
|
|||
|
{
|
|||
|
var lightmap = lightmapSizeList[i];
|
|||
|
lightmap.SetLightmapParameters(lightmapParameters);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class LightmapSizeData : ListItemBase<Material>
|
|||
|
{
|
|||
|
public readonly List<MeshRenderer> rendererList = new List<MeshRenderer>();
|
|||
|
public float totalSize { get; private set; }
|
|||
|
|
|||
|
public void AddMeshRenderer(MeshRenderer meshRenderer, float resolution)
|
|||
|
{
|
|||
|
var serializedObject = new SerializedObject(meshRenderer);
|
|||
|
var serializedProperty = serializedObject.FindProperty("m_ScaleInLightmap");
|
|||
|
if (serializedProperty != null)
|
|||
|
{
|
|||
|
var bounds = meshRenderer.bounds;
|
|||
|
var size = bounds.size.x * bounds.size.y + bounds.size.y * bounds.size.z +
|
|||
|
bounds.size.z * bounds.size.x;
|
|||
|
rendererList.Add(meshRenderer);
|
|||
|
var scale = resolution * serializedProperty.floatValue;
|
|||
|
totalSize += size * scale * scale;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public bool IsBakable()
|
|||
|
{
|
|||
|
// Unity当前版本无法有效拿到Fallback里面继承的通道
|
|||
|
// 当前条件下,使用Forward通道的,都会参加烘培,所以暂时用这个流程替代
|
|||
|
return id.FindPass("META") > -1 || id.FindPass("FORWARD") > -1;
|
|||
|
}
|
|||
|
|
|||
|
public void SetLightmapParameters(LightmapParameters lightmapParameters)
|
|||
|
{
|
|||
|
for (var i = 0; i < rendererList.Count; i++)
|
|||
|
{
|
|||
|
var meshRenderer = rendererList[i];
|
|||
|
var serializedObject = new SerializedObject(meshRenderer);
|
|||
|
var serializedProperty = serializedObject.FindProperty("m_LightmapParameters");
|
|||
|
serializedProperty.objectReferenceValue = lightmapParameters;
|
|||
|
serializedObject.ApplyModifiedProperties();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|