[总结] Unity Lightmap使用总结 |
您所在的位置:网站首页 › unity灯光贴图 › [总结] Unity Lightmap使用总结 |
Unity Lightmap使用总结
一 、动态加载 lightmap 给 Prefab效果操作步骤1. 烘焙光照贴图2. 记录光照信息3. 加载光照信息
遇到的问题(已解决)1. 光照贴图错位问题(已解决)
详细代码LightmapRoot.csLightmapRootEditor.cs
二 、 动态加载 lightmap 给 Scene举个栗子吧
关于“lightmap 动态加载”有两种解释: 一、动态加载 lightmap 给 Prefab : 可用于克隆出多个对象使用同一个光照贴图 二、动态加载 lightmap 给 Scene :可用于不同天气环境的动态切换 一 、动态加载 lightmap 给 Prefab 效果先将预制体对象设置为 Lightmap Static 并放在场景中,如下图,具体操作就不细说了。可以在 MeshRenderer 组件上看到,该对象的 Baked Lightmap 信息: { LightmapIndex = 65535, LightmapScaleOffset = new Vector4 (1,1,0,0) } 然后在Lighting Settings 中勾选 Mixed Lighting ,其他设置自行选择,点击 Generate Lighting 生成光照贴图,再次查看预制体对象的光照贴图信息,与没有烘焙前不一样了,其中: { LightmapIndex = 使用的第几张光照贴图, LightmapScaleOffset = 在光照贴图中使用的 UV 大小和偏移 } 再次选择一个预制体,拖放进场景中,发现的并没有光照效果,查看 Baked Lightmap 信息: { LightmapIndex = 65535, LightmapScaleOffset = new Vector4 (1,1,0,0) } 可以得出结论:烘焙的光照贴图信息(Baked Lightmap)不会保存到预制体上。于是就有了下一步——记录烘焙的光照贴图信息。
这一步主要是编写脚本(详细代码附在最后),用递归获取并保存此对象及所有子对象的烘焙光照贴图信息,包括: { LightmapIndex(int),LightmapScaleOffset(Vector4) } 考虑到运行状态下赋值时多对象 GetComponment() 耗费性能,所以在编辑器状态下记录光照信息时同时保存 MeshRenderer 的引用,所以保存的信息的数据结构可以为: //(详细代码附在最后) [Serializable] public struct CustomLightmapData { public MeshRenderer _renderer; public int _lightmapIndex; public Vector4 _lightmapScaleOffset; } 3. 加载光照信息这一步主要是将上一步保存的烘焙信息重新赋值给相应的 Mesh Renderer 组件(代码附在最后) 遇到的问题(已解决) 1. 光照贴图错位问题(已解决)可以看到 Console 面板提示的警告: 主要意思是:在对象静态批处理后无法再为 Baked Lightmap 赋值,解决办法就是在 Awake() 函数里进行赋值(代码附在最后)或者取消对象的静态批处理(不推荐) 详细代码 LightmapRoot.cs using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class LightmapRoot : MonoBehaviour { public List _datas; void Start() { SetAllLightmapData(); } public void GetAllLightmapData() { _datas = new List(); GetChildData(transform); } public void SetAllLightmapData() { if (_datas == null) return; for (int i = 0; i if (parent.gameObject.isStatic) { var render = parent.GetComponent(); if (render != null) { _datas.Add(new CustomLightmapData(render, render.lightmapIndex, render.lightmapScaleOffset)); } for (int i = 0; i // if (parent.gameObject.isStatic) // { // var render = parent.GetComponent(); // if (render != null) // { // ++index; // var data = _datas[index]; // render.lightmapIndex = data._lightmapIndex; // render.lightmapScaleOffset = data._lightmapScaleOffset; // } // // for (int i = 0; i < parent.childCount; i++) // { // SetChildData(parent.GetChild(i), index); // } // } // } } [Serializable] public struct CustomLightmapData { public MeshRenderer _renderer; public int _lightmapIndex; public Vector4 _lightmapScaleOffset; public CustomLightmapData(MeshRenderer renderer, int lightmapIndex, Vector4 lightmapScaleOffset) { _renderer = renderer; _lightmapIndex = lightmapIndex; _lightmapScaleOffset = lightmapScaleOffset; } } LightmapRootEditor.cs using UnityEditor; using UnityEngine; [CustomEditor(typeof(LightmapRoot))] public class LightmapRootEditor : Editor { private LightmapRoot Root { get { return target as LightmapRoot; } } public override void OnInspectorGUI() { base.OnInspectorGUI(); GUILayout.Space(10); if (GUILayout.Button("SaveLightmapData")) { Root.GetAllLightmapData(); SavePrefab(); } GUILayout.Space(10); if (GUILayout.Button("SetLightmapData")) { Root.SetAllLightmapData(); } } private void SavePrefab() { var prefab = PrefabUtility.GetCorrespondingObjectFromSource(Root); if (prefab != null) { PrefabUtility.ReplacePrefab(Root.gameObject, prefab); } } } 二 、 动态加载 lightmap 给 Scene相当于动态切换场景的 lightmap,实现的核心逻辑是: [SerializeField] private Texture2D _lightmapColor; [SerializeField] private Texture2D _lightmapDir; [SerializeField] private Texture2D _shadowMask; public void ResetLightmapData() { LightmapSettings.lightmaps = new[] {new LightmapData {lightmapColor = _lightmapColor, lightmapDir = _lightmapDir, shadowMask = _shadowMask}}; } 举个栗子吧在王者荣耀中切换查看英雄时,要根据英雄的阵营(背景故事)切换不同的背景,此功能肯定不能通过切换场景实现,那样太慢了,所以根据上面的思路: 将不同的背景做成预制体,烘焙好光照贴图 在 LightmapRoot 中增加字段,保存对光照贴图的引用 (上面的图中两张贴图分别记录了光照信息 lightmapColor 和方向信息 lightmapDir ) 切换英雄时动态加载背景预制体,设置场景的光照贴图 这个栗子同时包含了以上提到的两个 lightmap 动态加载 👍 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |