# DynamicLightMap **Repository Path**: andersonunity/DynamicLightMap ## Basic Information - **Project Name**: DynamicLightMap - **Description**: 动态加载烘焙的光照贴图 - **Primary Language**: C# - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 3 - **Created**: 2019-03-13 - **Last Updated**: 2023-05-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # DynamicLightMap ## 介绍 - 动态加载烘焙的光照贴图 - 本例中只有烘焙贴图,没有实时光照贴图 - 加载实时光照贴图没有找到任何资料、方法、API(目前认定不行) ## 步骤 1. 创建原始场景,放置对象(最后变成Prefab),设置烘焙信息 2. 烘焙场景,产生光照贴图 3. 编写保存光照贴图的代码 4. 保存光照贴图 5. 新建动态加载的场景 6. 编写加载光照贴图的代码 7. 运行观察效果 ## 步骤1 > - 创建原始场景,放置对象(最后变成Prefab),设置烘焙信息 > - 没有放置方向光 > - 没有任何实时光源 1. 布置场景,放置对象 - 整体布局 ![](Images/1.1.2.PNG) ![](Images/1.1.1.PNG) - 对象的Static属性 ![](Images/1.1.3.PNG) > 所有对象都设置了Lightmap Static - 对象的Renderer属性 ![](Images/1.1.4.PNG) > - 只有三个Sphere勾选了Stitch Seams > - 放置面与面的过渡过于明显 - 灯光(实际是自发光材质)属性 ![](Images/1.1.5.PNG) > Emission.Color.HDR.intensity = 2 2. Scene的Lighting Setting ![](Images/1.2.1.PNG) > - 环境光为颜色,且纯黑;表示不参与运算 > - 没有勾选实时光照 ## 步骤二 > 烘焙场景,产生光照贴图 1. 烘焙 - 点击Lighting中的Generate Lighting按钮,开始烘焙 2. 查看烘焙文件 - 烘焙结束后,会在场景文件对于的目录下,创建一个文件夹,名称与场景名称相同 - 在该文件夹下,存储了烘焙的光照贴图文件 ![](Images/2.2.1.PNG) 3. 查看效果 - 烘焙前 ![](Images/2.3.1.PNG) - 烘焙后 ![](Images/2.3.2.PNG) 4. 将烘焙的光照贴图修改属性 - 全选所有光照忒图 - 修改Inspector面板中的Advaned.Read/Write Enabled属性 - 勾选该属性 - 点击Apply按钮 > 该步骤的目的是为了后面的代码能够访问这些贴图 ## 步骤3 > 编写保存光照贴图的代码 1. 存储Renderer光照信息用的类 ```C# [Serializable] public class LightmapInfo { public string gameObjectPath; public int lightmapIndex; public Vector4 lightmapScaleOffset; } ``` 2. 存储整个场景光照信息的类 ```C# public class SceneLightmapInfo : ScriptableObject { //Lightmap Color and Dir Texture public Texture2D[] lightmapColorTextures; public Texture2D[] lightmapDirTextures; //Renderer LightmapInfo public LightmapInfo[] lightmapInfos; } ``` 3. Editor.Menu ```C# public class SaveSceneLightmap { [MenuItem("iSane/Utils/Save Scene Lightmap")] public static void SaveLightmapOverride() { string sceneName = EditorSceneManager.GetActiveScene().name; string rootPath = "Assets/SceneLightmap"; string fullPath = rootPath + "/" + sceneName; CreateAssetPath(rootPath, fullPath, sceneName); CreateAsset(fullPath, sceneName); } ... } ``` ## 步骤4 > 保存光照贴图 1. 点击菜单iSane/Utils/Save Scene Lightmap 2. 系统会自动创建相关目录 - Assets/SceneLightmap/场景名称 3. 系统会自动复制场景的光照贴图到上面的目录中 4. 系统会创建SceneLightmapInfo对于的Asset,并自动赋值 5. 查看目录 ![](Images/4.5.1.PNG) 6. 查看Asset属性 ![](Images/4.6.1.PNG) 7. 修改复制的光照贴图的属性 - 将所有复制的光照贴图的压缩属性设置为None,点击Apply按钮 ![](Images/4.7.1.PNG) - 将_light结尾的光照贴图的类型改为Lightmap ![](Images/4.7.2.PNG) ## 步骤5 > 新建动态加载的场景 1. 新建场景 2. 去掉方向光 3. 添加步骤1建立的Prefab - 步骤后的层次结构 ![](Images/5.PNG) ## 步骤6 > 编写加载光照贴图的代码 1. 添加存储场景光照贴图信息的资源 ```C# public SceneLightmapInfo SceneLightmapInfo; ``` 2. 在启动时设置场景的光照贴图和各个Renderer的光照贴图信息 ```C# private void Awake() { LoadLightmapDatas(); LoadRendererInfos(); } ``` 2. 设置场景的光照贴图 ```C# private void LoadLightmapDatas() { int length = SceneLightmapInfo.lightmapColorTextures.Length; LightmapData[] datas = new LightmapData[length]; for (int i = 0; i < length; i++) { datas[i] = new LightmapData(); datas[i].lightmapColor = SceneLightmapInfo.lightmapColorTextures[i]; datas[i].lightmapDir = SceneLightmapInfo.lightmapDirTextures[i]; } LightmapSettings.lightmaps = datas; } ``` 3. 各个Renderer的光照贴图信息 ```C# foreach (LightmapInfo info in SceneLightmapInfo.lightmapInfos) { target = GameObject.Find(info.gameObjectPath); if (null == target) { continue; } r = target.GetComponent(); if (null == r) { continue; } r.lightmapIndex = info.lightmapIndex; r.lightmapScaleOffset = info.lightmapScaleOffset; } ``` ## 步骤7 > 运行观察效果 - 运行前 ![](Images/7.1.PNG) - 运行后 ![](Images/7.2.PNG)