版本记录
日期 | 版本 | 说明 | 作者 |
---|---|---|---|
2020-1-2 | 0.1 | 文档初始版本 | 李俊 |
目的
- 加速场景加载,减少loading时间
- 提升场景渲染效率
概念
- 动态合批
- 接口
public void CombineMeshes(CombineInstance[] combine, bool mergeSubMeshes, bool useMatrices); - 核心代码
- 接口
foreach (var subItem in itemValue) { CombineInstance combine = new CombineInstance(); ReanderData matReanderData = subItem.Value; combine.mesh = matReanderData._MeshFilter.sharedMesh; combine.transform = matReanderData._MeshFilter.transform.localToWorldMatrix; combines[index] = combine; index++; if (combineData == null) { combineData = matReanderData; } delList.Add(matReanderData._MeshFilter.gameObject); if(maxValue < matReanderData.scaleInLightmap) { maxValue = matReanderData.scaleInLightmap; } } Mesh newMesh = new Mesh(); newMesh.CombineMeshes(combines, true, true); newMesh.name = combineData._Material.name;
- 静态合批
- 接口
static public void Combine (UnityEngine.GameObject staticBatchRoot, bool combineOnlyStatic) - 静态合批源代码 CombineForStaticBatching.cs MeshSubsetCombineUtility.cs
- 核心代码
- 接口
private void CombineObj( GameObject obj ) { Log.Sys("Combine Scene", obj.name); var anis = obj.GetComponentsInChildren<Animator>(); if (anis.Length > 0) { var meshRenders = obj.GetComponentsInChildren<MeshRenderer>(); var gos = new List<GameObject>(); var waterlayer = LayerMask.NameToLayer("Water"); for (int i = 0; i < meshRenders.Length; i++) { var go = meshRenders[i].gameObject; if (go.layer != waterlayer) { var isHaveAniP = go.transform.parent.GetComponent<Animator>(); var isHaveAni = go.transform.GetComponent<Animator>(); if (isHaveAniP == null && isHaveAni == null) gos.Add(go); } } StaticBatchingUtility.Combine(gos.ToArray(), obj); } else StaticBatchingUtility.Combine(obj); }
原理
- 把场景节点分成必需部分和分块
- 必需部分加载完成,即认为场景加载完成
- 必需部分保存成1个prefab,每个块保存成prefab
- 加载场景时,低优先级加载块prefab,只加载不卸载
制作细节
- _min 表示该节点下不再拆分,即所有子节点只会在同一个块prefab下
- 默认都是可以分块的,必需部分需要在always节点下
合批方案
-
无
完全依赖运行时instance合批,- 缺点:
- 默认instance合批,不支持lightmap, 需要额外开发instance合批,并且需要大量修改配套的shader
- 相同材质,不同模型的,无法合批
- 优点:
- 不需要生成额外的模型资源,加载友好
- 跨块的也可以提升性能
- 缺点:
-
动态合批
bake时,把所有材质球一样的模型合并- 缺点:
- 需要重新烘焙,耗时比较长
- 生成新的模型资源,加载不友好
- 烘焙效果可能和原来有差异,因为烘焙参数
- 跨块无法合批
- 优点
- 效率最优
- 可以处理不同模型,相同材质
- 兼容性好
- 开发量相对instance方式小很多
- 缺点:
-
静态合批
bake时,把每个块内静态合批,必需部分静态合批- 缺点:
- 需要生成大的mesh,对加载最不友好
- 无法处理跨块的合批
- 多场景模式下,会有额外的问题
- 优点:
- 不需要重新烘焙
- 可以处理不同模型,相同材质
- 开发量相对instance小很多
- 缺点: