using System; using UnityEngine; namespace Thousandto.Editor.Test { [Serializable] public class RendererInfo { //网格索引 public int MeshIndex = -1; public int OldLightmapIndex = -1; //原始场景中的uv缩放偏移信息 public Vector4 OldLightmapScaleOffset; //新生成lightmap中uv信息 public Vector4 NewLightmapScaleOffset; public Renderer SourceRenderer; public Vector4 UV2Bound; public void SetRendererDataWhileAwake() { if(SourceRenderer != null) { //lightmapIndex是动态变化的 //SourceRenderer.lightmapIndex = LightmapIndex; SourceRenderer.lightmapScaleOffset = NewLightmapScaleOffset; } } } /// /// 场景烘焙完后,保存lightmap信息 /// [ExecuteInEditMode] public class PrefabLightmapInfo : MonoBehaviour { [SerializeField] public RendererInfo[] RendererInfos; public bool CalcUV2Bound = false; [SerializeField] public int MeshIndex = -1; private int _lastLightmapIndex = -1; void Awake() { if(Application.isPlaying) { for (int i = 0; RendererInfos != null && i < RendererInfos.Length; ++i) { RendererInfos[i].SetRendererDataWhileAwake(); } } } public void OnBakeFinish() { var Renderers = GetComponentsInChildren(); RendererInfos = new RendererInfo[Renderers.Length]; for (int i = 0; i < Renderers.Length; ++i) { RendererInfo rdInfo = new RendererInfo(); rdInfo.OldLightmapScaleOffset = Renderers[i].lightmapScaleOffset; rdInfo.OldLightmapIndex = Renderers[i].lightmapIndex; rdInfo.SourceRenderer = Renderers[i]; RendererInfos[i] = rdInfo; } } public void SetMeshIndex(int meshIndex) { if (RendererInfos == null) return; for (int i = 0; i < RendererInfos.Length; ++i) { RendererInfos[i].MeshIndex = meshIndex; } MeshIndex = meshIndex; } public void SetLightmapScaleOffset(Renderer rd, Vector4 lightmapScaleOffset) { if (RendererInfos == null) return; for(int i =0; i < RendererInfos.Length; ++i) { if(RendererInfos[i].SourceRenderer == rd) { RendererInfos[i].NewLightmapScaleOffset = lightmapScaleOffset; } } } void Update() { if(CalcUV2Bound) { CalcUV2Bound = false; for (int i = 0; i < RendererInfos.Length; ++i) { var mesh = RendererInfos[i].SourceRenderer.gameObject.GetComponent(); if(mesh != null) { var uv2 = GetMeshUV2(mesh.sharedMesh); RendererInfos[i].UV2Bound = GetBounds(uv2, RendererInfos[i].SourceRenderer); } } } int lightmapIndex = Core.Asset.TerrainPrefabManager.Instance.GetLightmapIndexByMeshIndex(MeshIndex); if(lightmapIndex != _lastLightmapIndex) { _lastLightmapIndex = lightmapIndex; for (int i = 0; RendererInfos != null && i < RendererInfos.Length; ++i) { RendererInfos[i].SourceRenderer.lightmapIndex = lightmapIndex; } } } //如果不存在uv2,则使用uv代替 public static Vector2[] GetMeshUV2(Mesh m) { var uv2 = m.uv2; if (uv2 == null || uv2.Length == 0) uv2 = m.uv; return uv2; } /// /// 计算该renderer在lightmap贴图中的包围范围 /// /// uv2光照uv /// /// (minx, miny, maxX, maxY) public static Vector4 GetBounds(Vector2[] uv, Renderer r) { if (uv != null) { var __uv = new Vector2[uv.Length]; Array.Copy(uv, __uv, uv.Length); uv = __uv; var minx = float.MaxValue; var miny = float.MaxValue; var maxx = float.MinValue; var maxy = float.MinValue; for (var _j = 0; _j < uv.Length; ++_j) { var _uv = uv[_j]; if (_uv.x < minx) { minx = _uv.x; } if (_uv.y < miny) { miny = _uv.y; } if (_uv.x > maxx) { maxx = _uv.x; } if (_uv.y > maxy) { maxy = _uv.y; } } var bounds = new Vector4(minx, miny, maxx, maxy); return bounds; } return Vector4.zero; } } }