本文主要讲解光照贴图对于动态加载的模型预设体的使用教程
一、添加光照贴图数据脚本,用于存储灯光烘焙后的光照贴图信息,以及设置光照贴图信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEngine.SceneManagement; public class PrefabLightmapData : MonoBehaviour { [System.Serializable] public struct RendererInfo { public Renderer renderer; public int lightmapIndex; public Vector4 lightmapOffsetScale; } public RendererInfo[] m_RendererInfo; public Texture2D[] m_Lightmaps; void Awake() { Init(); } void Init() { if (m_RendererInfo == null || m_RendererInfo.Length == 0) return; var lightmaps = LightmapSettings.lightmaps; int[] offsetsindexes = new int[m_Lightmaps.Length]; int counttotal = lightmaps.Length; List<LightmapData> combinedLightmaps = new List<LightmapData>(); for (int i = 0; i < m_Lightmaps.Length; i++) { bool exists = false; for (int j = 0; j < lightmaps.Length; j++) { if (m_Lightmaps[i] == lightmaps[j].lightmapColor) { exists = true; offsetsindexes[i] = j; } } if (!exists) { offsetsindexes[i] = counttotal; var newlightmapdata = new LightmapData(); newlightmapdata.lightmapColor = m_Lightmaps[i]; combinedLightmaps.Add(newlightmapdata); counttotal += 1; } } var combinedLightmaps2 = new LightmapData[counttotal]; lightmaps.CopyTo(combinedLightmaps2, 0); combinedLightmaps.ToArray().CopyTo(combinedLightmaps2, lightmaps.Length); LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional; ApplyRendererInfo(m_RendererInfo, offsetsindexes); LightmapSettings.lightmaps = combinedLightmaps2; } void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } // called second void OnSceneLoaded(Scene scene, LoadSceneMode mode) { Init(); } // called when the game is terminated void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } static void ApplyRendererInfo(RendererInfo[] infos, int[] lightmapOffsetIndex) { for (int i = 0; i < infos.Length; i++) { var info = infos[i]; info.renderer.lightmapIndex = lightmapOffsetIndex[info.lightmapIndex]; info.renderer.lightmapScaleOffset = info.lightmapOffsetScale; // You have to release shaders. Material[] mat = info.renderer.sharedMaterials; for (int j = 0; j < mat.Length; j++) { if (mat[j] != null && Shader.Find(mat[j].shader.name) != null) { mat[j].shader = Shader.Find(mat[j].shader.name); } } } } } |
二、添加灯光烘焙编辑器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; public class BakePrefabLightMaps { [MenuItem("Assets/Bake Prefab Lightmaps")] static void GenerateLightmapInfo() { if (Lightmapping.giWorkflowMode != Lightmapping.GIWorkflowMode.OnDemand) { Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled."); return; } Lightmapping.Bake(); PrefabLightmapData[] prefabs = GameObject.FindObjectsOfType<PrefabLightmapData>(); foreach (var instance in prefabs) { var gameObject = instance.gameObject; var rendererInfos = new List<PrefabLightmapData.RendererInfo>(); var lightmaps = new List<Texture2D>(); GenerateLightmapInfo(gameObject, rendererInfos, lightmaps); instance.m_RendererInfo = rendererInfos.ToArray(); instance.m_Lightmaps = lightmaps.ToArray(); //var targetPrefab = UnityEditor.PrefabUtility.GetPrefabParent(gameObject) as GameObject; var targetPrefab = PrefabUtility.GetCorrespondingObjectFromSource(gameObject) as GameObject; if (targetPrefab != null) { //UnityEditor.Prefab PrefabUtility.ReplacePrefab(gameObject, targetPrefab); } } } static void GenerateLightmapInfo(GameObject root, List<PrefabLightmapData.RendererInfo> rendererInfos, List<Texture2D> lightmaps) { var renderers = root.GetComponentsInChildren<MeshRenderer>(); foreach (MeshRenderer renderer in renderers) { if (renderer.lightmapIndex != -1) { PrefabLightmapData.RendererInfo info = new PrefabLightmapData.RendererInfo(); info.renderer = renderer; info.lightmapOffsetScale = renderer.lightmapScaleOffset; Texture2D lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapColor; info.lightmapIndex = lightmaps.IndexOf(lightmap); if (info.lightmapIndex == -1) { info.lightmapIndex = lightmaps.Count; lightmaps.Add(lightmap); } rendererInfos.Add(info); } } } } |
三、将“PrefabLightmapData.cs”挂在到预设体上,并将预设体放在场景里,执行“Assets/Bake Prefab Lightmaps”。
四、等待烘焙完成,查看“PrefabLightmapData.cs”属性已经有了光照贴图信息了
五、移除灯光,测试烘焙效果即可
以上步骤在Editor下运行,可查看到烘焙效果。但打包PC或移动端,光照贴图会丢失,就需要按下面方法来解决丢失问题。
在Graphics设置界面添加模型材质使用的shader,并调整Lightmap Modes为“Custom”
至此,教程结束,希望对大家有用~
Demo下载地址:
https://github.com/654306663/LightmapForPrefab
- 本文固定链接: http://www.u3d8.com/?p=1951
- 转载请注明: 网虫虫 在 u3d8.com 发表过