光照贴图打包处理

在项目中烘焙好的场景贴图资源比较大,这个时候我们也会去进行打包,我用的方法比较粗暴,但是我自己感觉这样用还能够接受,今天抽空码出来,如果有更好的解决方案,当然这个方案就当铺路了。
我主要是新建一个预置体,将我的这些贴图关联到我的这个预置体上,然后把预置体打包,那么解包之后,光照贴图自然就关联到了我的场景中,现在主要是如何将光照贴图关联起来。
1.新建一个空物体,名字自己随便取都行。
2.新建一个脚本挂载到空物体上,主要是用来关联贴图信息的,里面最后一个方法是专门用来添加的,只要点击AddLightmap那么信息就关联好了。

#if UNITY_EDITOR
using UnityEditor;
using System.IO;
#endif
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PrefabLightmapData : MonoBehaviour {

    // Use this for initialization
    [System.Serializable]
    struct LightMapInfo
    {
        public Texture2D lightmapFar;
        public Texture2D lightmapNear;
    }

    [SerializeField]
    LightMapInfo[] m_LightMapInfo;
    void Awake()
    {
        if(m_LightMapInfo.Length>0)
        {
            List<LightmapData> list = new List<LightmapData>();
            foreach (LightMapInfo info in m_LightMapInfo)
            {
                LightmapData temp = new LightmapData();
                temp.lightmapFar = info.lightmapFar;
                temp.lightmapNear = info.lightmapNear;
                list.Add(temp);
            }
            LightmapSettings.lightmaps = list.ToArray();
            list.Clear();
        }
    }
    #if UNITY_EDITOR
    [MenuItem("Assets/AddInLightmap")]
    static void AddInLightMap()
    {
        PrefabLightmapData temp = FindObjectOfType<PrefabLightmapData>();
        temp.m_LightMapInfo = new LightMapInfo[LightmapSettings.lightmaps.Length];
        for (int item = 0; item < temp.m_LightMapInfo.Length; ++item)
        {
            temp.m_LightMapInfo[item].lightmapFar = LightmapSettings.lightmaps[item].lightmapFar;
            temp.m_LightMapInfo[item].lightmapNear = LightmapSettings.lightmaps[item].lightmapNear;
        }
    }
    #endif
}

3.还有一些物体引用的mesh都不一样,那么光照贴图的信息也需要一个个关联起来,有一些则已经自动生成xml表的时候已经生成了,创建xml表的前面已经介绍过,这里再写一次。

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;

public class CreateSenceElements : EditorWindow
{
    // Use this for initialization
    [MenuItem("Sence/" + "测试")]
    static void CesiElements()
    {
        GameObject obj_Father = Selection.activeGameObject;
        MeshRenderer render = obj_Father.GetComponent<MeshRenderer>();
        Debug.Log(render.lightmapIndex + "  " + render.lightmapScaleOffset.ToString("0.00000"));
    }

    [MenuItem("Sence/"+"生成场景元素XML表")]
    static void SenceElements()
    {
        GameObject obj_Father = Selection.activeGameObject;
        string filepath = Application.dataPath + "/StreamingAssets" + @"/" + obj_Father.name + ".xml";
        //创建XML文档实例
        XmlDocument xmlDoc = new XmlDocument();
        //创建root节点,也就是最上一层节点
        XmlElement root=null;
        XmlElement rootSence = null;
        XmlElement rootPrefab = null;
        if (!File.Exists(filepath))
        {
            //创建root节点,也就是最上一层节点
            root = xmlDoc.CreateElement(obj_Father.name);
            rootSence = xmlDoc.CreateElement("SenceElement");
            rootPrefab = xmlDoc.CreateElement("SencePrefab");
            root.SetAttribute("ID", "ID001");
            Debug.Log("createXml OK!");
        }
        else
        {
            xmlDoc.Load(filepath);
            root = xmlDoc.SelectSingleNode(obj_Father.name) as XmlElement;
            rootSence = xmlDoc.SelectSingleNode("SenceElement") as XmlElement;
            rootPrefab = xmlDoc.SelectSingleNode("SencePrefab") as XmlElement;
            root.RemoveAll();
        }
        //保存场景中元素的名称
        Dictionary<string, int> dicPrefabs = new Dictionary<string, int>();

        FindChild(ref xmlDoc, ref rootSence, dicPrefabs, obj_Father.transform, 0);

        foreach (string key in dicPrefabs.Keys)
        {
            XmlElement _ele = xmlDoc.CreateElement("PrefabNode");
            _ele.SetAttribute("name", key);
            _ele.SetAttribute("num", dicPrefabs[key].ToString());
            rootPrefab.AppendChild(_ele);
        }
        root.AppendChild(rootPrefab);
        root.AppendChild(rootSence);
        xmlDoc.AppendChild(root);
        //把XML文件保存至本地 
        xmlDoc.Save(filepath);
        AssetDatabase.Refresh();
    }
    static void FindChild(ref XmlDocument doc, ref XmlElement node,Dictionary<string,int> dic, Transform tran ,int level)
    {
        ++level;
       foreach (Transform child in tran)
       {           
           XmlElement _ele = doc.CreateElement("SenceNode" + level.ToString());
           _ele.SetAttribute("name", child.name);
           _ele.SetAttribute("Position", child.localPosition.ToString("0.00"));
           _ele.SetAttribute("EulerAngles", child.localEulerAngles.ToString("0.00"));
           _ele.SetAttribute("Scale", child.localScale.ToString("0.00"));
           MeshFilter _mesh = child.GetComponent<MeshFilter>();
           if (_mesh!=null)
           {
               string _str = _mesh.sharedMesh.name;
               _ele.SetAttribute("Prefab", _str);
                MeshRenderer _render = child.gameObject.GetComponent<MeshRenderer>();
                _ele.SetAttribute("LightMapScale", _render.lightmapScaleOffset.ToString("0.000000"));
                _ele.SetAttribute("LightMapIndex", _render.lightmapIndex.ToString());
                if (dic.ContainsKey(_str))
               {
                   dic[_str] = dic[_str] + 1;
               }
               else dic.Add(_str, 1);             
           }
           if (child.childCount >= 1)
           {
               FindChild(ref doc, ref _ele,dic, child, level);
           }
           node.AppendChild(_ele);
       }
    }

}

选中我们的场景,所有的子物体的信息都被保存到了一张表中,现在就要把整体的物体的信息给关联起来,需要在他们身上挂载下面的脚本。

#if UNITY_EDITOR
using UnityEditor;
using System.IO;
#endif
using UnityEngine;
using System.Collections.Generic;
[DisallowMultipleComponent, ExecuteInEditMode]
public class PrefabLightmapDataEditor : MonoBehaviour
{
    [System.Serializable]
    struct RendererInfo
    {
        public Renderer renderer;
        public int lightmapIndex;
        public Vector4 lightmapOffsetScale;
    }

    [SerializeField]
    RendererInfo[] m_RendererInfo;

    const string LIGHTMAP_RESOURCE_PATH = "Assets/Resources/Lightmaps/";

    [System.Serializable]
    struct Texture2D_Remap
    {
        public int originalLightmapIndex;
        public Texture2D originalLightmap;
        public Texture2D lightmap0;
        public Texture2D lightmap1;
    }

    static List<Texture2D_Remap> sceneLightmaps = new List<Texture2D_Remap>();
    void Start()
    {
        ApplyRendererInfo();
    }
    public void ApplyRendererInfo()
    {
        for (int i = 0; i < m_RendererInfo.Length; i++)
        {
            var info = m_RendererInfo[i];
            info.renderer.lightmapIndex = info.lightmapIndex;
            info.renderer.lightmapScaleOffset = info.lightmapOffsetScale;
        }
    }
#if UNITY_EDITOR
    [MenuItem("Assets/Bake Prefab LightmapsEditor")]
    static void GenerateLightmapInfoT()
    {
        Debug.ClearDeveloperConsole();

        if (Lightmapping.giWorkflowMode != Lightmapping.GIWorkflowMode.OnDemand)
        {
            Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled.");
            return;
        }

        //Lightmapping.Bake();   

        sceneLightmaps = new List<Texture2D_Remap>();

        PrefabLightmapDataEditor[] prefabs = FindObjectsOfType<PrefabLightmapDataEditor>();
        foreach (var instance in prefabs)
        {
            Debug.Log(prefabs.Length);
            var gameObject = instance.gameObject;
            var rendererInfos = new List<RendererInfo>();
            var renderers = gameObject.GetComponentsInChildren<MeshRenderer>();
            foreach (MeshRenderer renderer in renderers)
            {
                if (renderer.lightmapIndex != -1)
                {
                    RendererInfo info = new RendererInfo();
                    info.renderer = renderer;
                    info.lightmapOffsetScale = renderer.lightmapScaleOffset;             
                    info.lightmapIndex = renderer.lightmapIndex;
                    rendererInfos.Add(info);
                }
            }

            instance.m_RendererInfo = rendererInfos.ToArray();
            var targetPrefab = PrefabUtility.GetPrefabParent(gameObject) as GameObject;
            if (targetPrefab != null)
            {
                //Prefab
                //PrefabUtility.ReplacePrefab(gameObject, targetPrefab);
            }
        }

        Debug.Log("Update to prefab lightmaps finished");
    }
#endif
}

点击Bake Prefab LightmapsEditor则可以将贴图的信息全部关联起来,需要注意的是必须是烘焙好的物体,而且身上带有mesh不然会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瓜皮肖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值