unity 烘焙场景的创建、保存和使用(附demo项目)

    技术2023-10-04  100

    这是一个入门教程,demo项目:

    practice4.unitypackagehttps://pan.baidu.com/s/1tnDv3sDUzMlk1YnSmJV29w 密码:1234

    1.打开Unity,新建一个场景

    2.打开Light窗口:

    如下图红框处设置参数:

     

     调整导入的模型参数:

    1.导入本地materials,并apply:

     2.打勾,并apply:

     把模型拖拽到Hierarchy窗口,右键对象,点击下图方框处:

    勾选对象的static属性: 

     

    设置灯光的属性:

     回到Light窗口,点击按钮开始烘焙:

    等待几分钟即可烘焙好:

    原图:

     烘焙后效果图:

     但是这个模型只能放在当前场景使用,要想在别的场景也能使用,就需要制作预设。

    首先拖拽对象到资源窗口创建预设,并给预设附一个PrefabLightmapData脚本,上面的demo项目里有,代码如下:

    using UnityEngine; using System.Collections.Generic; public class PrefabLightmapData : MonoBehaviour { [System.Serializable] struct RendererInfo { public Renderer renderer; public int lightmapIndex; public Vector4 lightmapOffsetScale; } [SerializeField] RendererInfo[] m_RendererInfo; [SerializeField] Texture2D[] m_Lightmaps; void Awake() { if (m_RendererInfo == null || m_RendererInfo.Length == 0) return; var lightmaps = LightmapSettings.lightmaps; var combinedLightmaps = new LightmapData[lightmaps.Length + m_Lightmaps.Length]; lightmaps.CopyTo(combinedLightmaps, 0); for (int i = 0; i < m_Lightmaps.Length; i++) { combinedLightmaps[i + lightmaps.Length] = new LightmapData(); combinedLightmaps[i + lightmaps.Length].lightmapColor = m_Lightmaps[i]; } ApplyRendererInfo(m_RendererInfo, lightmaps.Length); LightmapSettings.lightmaps = combinedLightmaps; } static void ApplyRendererInfo(RendererInfo[] infos, int lightmapOffsetIndex) { for (int i = 0; i < infos.Length; i++) { var info = infos[i]; info.renderer.lightmapIndex = info.lightmapIndex + lightmapOffsetIndex; info.renderer.lightmapScaleOffset = info.lightmapOffsetScale; } } #if UNITY_EDITOR [UnityEditor.MenuItem("Assets/Bake Prefab Lightmaps")] static void GenerateLightmapInfo() { if (UnityEditor.Lightmapping.giWorkflowMode != UnityEditor.Lightmapping.GIWorkflowMode.OnDemand) { Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled."); return; } UnityEditor.Lightmapping.Bake(); PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>(); foreach (var instance in prefabs) { var gameObject = instance.gameObject; var rendererInfos = new List<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; if (targetPrefab != null) { //UnityEditor.Prefab UnityEditor.PrefabUtility.ReplacePrefab(gameObject, targetPrefab); } } } static void GenerateLightmapInfo(GameObject root, List<RendererInfo> rendererInfos, List<Texture2D> lightmaps) { var renderers = root.GetComponentsInChildren<MeshRenderer>(); foreach (MeshRenderer renderer in renderers) { if (renderer.lightmapIndex != -1) { RendererInfo info = new 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); } } } #endif }

     然后点击菜单栏的下图按钮:

     等待几分钟后,烘焙好了,并且这个预设保存了烘焙信息,也可以放到别的场景使用了,但是要注意的是,一个场景只能烘焙一样东西,你要是想烘焙另一个东西,就必须新建一个场景烘焙完得到预设。这是因为每次烘焙场景都生成一张烘焙图,这个图对应了场景的光照,并保存起来:

    重复在一个场景烘焙,会覆盖这张图,那么原本烘焙的东西就白费了。

    另外,把模型的比例调大,可以获得分辨率更加高的烘焙结果。

    另外:

    Lighting窗口中的Bounces的大小代表环境光在场景中的最大漫反射次数,所以这个树枝越大,没有被直接照射的部位就会越亮,阴影的轮廓也会越模糊。

     

    制作完预设后,要想在别的场景使用,还需要拖拽Lighting Data 给该场景:

    Lighting Data 所属文件夹的位置与scene文件在同一个子目录上:

    你会发现烘焙的效果还可以和场景中的光照叠加:

    效果更加逼真啦。 

     

    Processed: 0.014, SQL: 10