在游戏开发中,场景的 Mesh 合批优化是提高渲染性能的重要手段。合批(Batching)是指将多个小的 Mesh 合并为一个大的 Mesh,以减少绘制调用(Draw Calls)和提高 GPU 的渲染效率。以下是一些常见的 Mesh 合批优化策略和技术:
1. 静态合批(Static Batching)
概念
静态合批是将场景中不移动的物体(如建筑、地面等)合并为一个或多个大的 Mesh。这样可以减少渲染时的绘制调用。
实现方法
- 使用引擎功能:许多游戏引擎(如 Unity、Unreal Engine)提供了静态合批的功能。开发者只需将需要合批的物体标记为静态,引擎会自动处理合批。
- 合并 Mesh:在建模软件中(如 Blender、Maya)将多个 Mesh 合并为一个 Mesh,然后导入到游戏引擎中。
2. 动态合批(Dynamic Batching)
概念
动态合批是针对移动物体的合批技术。它允许在运行时将多个小的 Mesh 合并为一个大的 Mesh。
实现方法
- 使用相同材质:动态合批通常要求合并的 Mesh 使用相同的材质和着色器。确保在场景中尽量减少材质的种类。
- 小型 Mesh:动态合批通常适用于较小的 Mesh(如小型道具),因为合并过大的 Mesh 可能会导致性能下降。
3. 材质合并
概念
通过合并多个材质为一个材质,减少渲染时的切换次数,从而提高性能。
实现方法
- 纹理图集:将多个小纹理合并为一个大纹理(纹理图集),然后在 Mesh 中使用 UV 映射来引用不同的纹理区域。
- 材质合并工具:使用工具(如 TexturePacker)来创建纹理图集,并在游戏引擎中配置材质。
4. LOD(Level of Detail)
概念
使用不同细节级别的 Mesh,根据相机距离动态切换,以减少远处物体的渲染负担。
实现方法
- 创建 LOD Mesh:为每个物体创建多个细节级别的 Mesh(高、中、低),并在游戏引擎中设置 LOD 级别。
- 自动 LOD 生成:一些引擎提供自动生成 LOD 的功能,可以根据原始 Mesh 自动生成低细节版本。
5. Occlusion Culling(遮挡剔除)
概念
在渲染时剔除被其他物体遮挡的 Mesh,减少不必要的渲染。
实现方法
- 使用引擎的遮挡剔除功能:许多游戏引擎提供内置的遮挡剔除功能,可以自动处理。
- 手动设置遮挡体:在场景中手动设置遮挡体,帮助引擎更好地判断哪些物体需要渲染。
6. 使用实例化渲染(Instancing)
概念
实例化渲染允许在一次绘制调用中渲染多个相同的 Mesh,适用于大量相同物体的场景(如树木、石头等)。
实现方法
- 使用引擎的实例化功能:许多引擎(如 Unity、Unreal Engine)支持实例化渲染,开发者只需使用相应的 API。
- 自定义着色器:在需要时,可以编写自定义着色器来支持实例化渲染。
7. 预计算和场景分割
概念
将场景分割成多个区域,预计算每个区域的 Mesh 和材质,以减少实时计算的负担。
实现方法
- 场景分块:将场景分割成多个小块,按需加载和渲染。
- 光照贴图:使用光照贴图预计算光照信息,减少实时光照计算的开销。
总结
Mesh 合批优化是提高游戏性能的重要手段。通过静态合批、动态合批、材质合并、LOD、遮挡剔除、实例化渲染和预计算等技术,可以显著减少绘制调用,提高渲染效率。在实际开发中,选择合适的优化策略和技术,结合具体的场景需求,可以有效提升游戏的性能和用户体验。
静态合批(Static Batching)
静态合批(Static Batching)是一种在游戏开发中常用的优化技术,旨在减少渲染时的绘制调用(Draw Calls),从而提高性能。它主要适用于那些在场景中不会移动或改变的物体,比如建筑、地面、墙壁等。以下是关于静态合批的详细介绍,包括其原理、优缺点、实现方法以及使用场景。
原理
静态合批的基本原理是将多个静态物体的 Mesh 合并为一个大的 Mesh。在渲染时,GPU 只需处理一个大的 Mesh,而不是多个小的 Mesh,从而减少了绘制调用的数量。每个绘制调用都涉及到 CPU 和 GPU 之间的通信,减少绘制调用可以显著提高渲染性能。
优点
- 减少绘制调用:通过合并多个 Mesh,静态合批可以显著减少绘制调用的数量,从而提高渲染效率。
- 提高性能:在场景中有大量静态物体时,静态合批可以显著提高帧率和整体性能。
- 简单易用:许多游戏引擎(如 Unity、Unreal Engine)提供了内置的静态合批功能,开发者只需简单配置即可使用。
缺点
- 内存占用:合并后的大 Mesh 可能会占用更多的内存,尤其是在场景中有大量静态物体时。
- 灵活性降低:一旦物体被合并为静态 Mesh,就无法在运行时移动或改变它们。如果需要动态改变物体,必须将其从合批中移除。
- 合并开销:在合并 Mesh 的过程中,可能会有一定的计算开销,尤其是在场景加载时。
实现方法
在不同的游戏引擎中,静态合批的实现方法可能会有所不同。以下是一些常见引擎的实现方式:
Unity
- 标记为静态:在 Unity 中,开发者可以通过选中物体并在 Inspector 面板中勾选“Static”选项来标记物体为静态。
- 合批设置:Unity 会自动将标记为静态的物体合并为一个大的 Mesh。开发者可以在项目设置中调整合批的相关参数。
- 使用静态合批工具:Unity 还提供了一些工具和插件,可以帮助开发者更好地管理和优化静态合批。
Unreal Engine
- 使用合并工具:在 Unreal Engine 中,开发者可以使用“Merge Actors”工具将多个静态 Mesh 合并为一个。
- 设置合并选项:在合并过程中,开发者可以选择合并的选项,如是否保留原始 Mesh、是否生成碰撞体等。
- 使用蓝图或 C++:开发者还可以通过蓝图或 C++ 脚本实现更复杂的合并逻辑。
使用场景
静态合批适用于以下场景:
- 建筑物和地形:场景中的建筑物、墙壁、地面等静态物体非常适合使用静态合批。
- 场景装饰:如树木、岩石等不需要移动的装饰物体。
- 大型场景:在大型开放世界游戏中,静态合批可以显著提高性能,减少渲染负担。
总结
静态合批是一种有效的性能优化技术,适用于场景中大量静态物体的渲染。通过减少绘制调用,静态合批可以显著提高游戏的渲染效率和帧率。在实际开发中,合理使用静态合批可以帮助开发者创建更流畅的游戏体验。
静态合批(Static Batching)的逻辑代码实现
静态合批(Static Batching)的实现通常依赖于游戏引擎的内置功能,但如果你想要手动实现静态合批的逻辑,以下是一个简单的示例,展示如何在 Unity 中使用 C# 脚本来合并多个静态 Mesh。
Unity 中的静态合批实现示例
在 Unity 中,你可以通过以下步骤手动实现静态合批:
- 创建一个新的 C# 脚本,命名为
StaticBatcher
。 - 将以下代码粘贴到脚本中:
using UnityEngine;
using System.Collections.Generic;
public class StaticBatcher : MonoBehaviour
{
public GameObject[] objectsToBatch; // 要合并的静态物体
public Material combinedMaterial; // 合并后的材质
void Start()
{
CombineMeshes();
}
void CombineMeshes()
{
// 创建一个新的 GameObject 来存放合并后的 Mesh
GameObject combinedObject = new GameObject("CombinedMesh");
combinedObject.transform.position = Vector3.zero;
// 获取 MeshFilter 和 MeshRenderer 组件
MeshFilter combinedMeshFilter = combinedObject.AddComponent<MeshFilter>();
MeshRenderer combinedMeshRenderer = combinedObject.AddComponent<MeshRenderer>();
combinedMeshRenderer.material = combinedMaterial;
// 创建一个列表来存储所有的 Mesh
List<MeshFilter> meshFilters = new List<MeshFilter>();
// 遍历所有要合并的物体
foreach (GameObject obj in objectsToBatch)
{
if (obj != null)
{
MeshFilter meshFilter = obj.GetComponent<MeshFilter>();
if (meshFilter != null)
{
meshFilters.Add(meshFilter);
}
}
}
// 合并 Mesh
CombineInstance[] combine = new CombineInstance[meshFilters.Count];
for (int i = 0; i < meshFilters.Count; i++)
{
combine[i].mesh = meshFilters[i].sharedMesh;
combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
}
// 创建合并后的 Mesh
Mesh combinedMesh = new Mesh();
combinedMesh.CombineMeshes(combine);
combinedMeshFilter.mesh = combinedMesh;
// 销毁原始物体
foreach (GameObject obj in objectsToBatch)
{
if (obj != null)
{
Destroy(obj);
}
}
}
}
使用说明
- 创建一个空的 GameObject,并将
StaticBatcher
脚本附加到该 GameObject 上。 - 在 Inspector 中设置:
objectsToBatch
:将要合并的静态物体拖放到这个数组中。combinedMaterial
:设置合并后的材质。
- 运行场景:当场景开始时,脚本会自动合并指定的静态物体,并创建一个新的合并 Mesh。
注意事项
- 材质:确保所有要合并的物体使用相同的材质,以便能够成功合并。
- 变换:合并后的 Mesh 的变换是基于原始物体的局部变换,因此在合并后,原始物体会被销毁,合并后的 Mesh 会在原点位置。
- 性能:手动合并 Mesh 可能会在场景加载时产生一定的性能开销,建议在场景初始化时进行合并。
总结
以上代码展示了如何在 Unity 中手动实现静态合批的逻辑。虽然 Unity 提供了内置的静态合批功能,但在某些情况下,手动合并 Mesh 可能会提供更大的灵活性。通过合理使用静态合批,可以显著提高游戏的渲染性能。
静态合批(Static Batching)存在哪些性能限制
静态合批(Static Batching)是一种有效的性能优化技术,但它也存在一些性能限制和潜在问题。以下是静态合批的一些主要限制:
1. 内存占用
- 合并后的 Mesh 大小:合并多个 Mesh 会生成一个较大的 Mesh,这可能会导致内存占用增加,尤其是在场景中有大量静态物体时。
- 内存碎片:合并后的大 Mesh 可能会导致内存碎片,影响整体内存管理和性能。
2. 动态性限制
- 不可移动:一旦物体被标记为静态并合并,它们就不能在运行时移动或改变。如果需要动态改变物体,必须将其从合批中移除并重新合并。
- 场景变化:如果场景中有频繁的变化(如动态生成或销毁物体),静态合批的效果会大打折扣,因为每次变化都需要重新合并。
3. 材质限制
- 相同材质要求:静态合批要求所有合并的物体使用相同的材质和着色器。如果物体使用不同的材质,无法进行合并,这可能会导致材质种类过多,从而影响性能。
- 材质切换:即使在合并后,如果需要在运行时切换材质,仍然会导致性能下降,因为这会增加绘制调用。
4. 合并开销
- 合并过程的开销:在场景加载时,合并多个 Mesh 可能会产生一定的计算开销,尤其是在合并的物体数量较多时。
- 实时合并的复杂性:如果需要在运行时动态合并物体,可能会导致更高的 CPU 开销,影响帧率。
5. 碰撞体和物理
- 碰撞体处理:合并后的 Mesh 可能需要重新设置碰撞体,尤其是在使用物理引擎时。合并后的物体可能无法正确处理碰撞。
- 物理交互:如果合并的物体需要进行物理交互,可能会导致物理计算的复杂性增加。
6. LOD(Level of Detail)管理
- LOD 兼容性:静态合批可能会影响 LOD 的管理,因为合并后的 Mesh 可能不容易与不同细节级别的 Mesh 进行切换。
7. GPU 限制
- 顶点数量限制:每个 Mesh 的顶点数量通常受到 GPU 的限制。如果合并后的 Mesh 超过了 GPU 的顶点限制,可能会导致渲染失败或性能下降。
总结
虽然静态合批是一种有效的性能优化技术,但在使用时需要考虑其限制和潜在问题。开发者应根据具体的场景需求和性能目标,合理选择合批策略,并结合其他优化技术(如动态合批、实例化渲染、LOD 等)来实现最佳的性能效果。
动态合批(Dynamic Batching)
动态合批(Dynamic Batching)是一种在游戏开发中用于优化渲染性能的技术,旨在减少绘制调用(Draw Calls)的数量。与静态合批不同,动态合批主要用于那些在运行时可能会移动或改变的物体。以下是关于动态合批的详细介绍,包括其原理、优缺点、实现方法以及使用场景。
原理
动态合批的基本原理是将多个小的、动态的 Mesh 合并为一个大的 Mesh,在渲染时一次性绘制。通过将多个物体的顶点数据合并到一个绘制调用中,动态合批可以显著减少 CPU 和 GPU 之间的通信,从而提高渲染性能。
优点
- 减少绘制调用:动态合批可以显著减少绘制调用的数量,尤其是在场景中有大量小物体时。
- 适用于动态物体:与静态合批不同,动态合批可以处理在运行时移动或改变的物体,提供更大的灵活性。
- 简单易用:许多游戏引擎(如 Unity)提供了内置的动态合批功能,开发者只需简单配置即可使用。
缺点
- 性能开销:动态合批的合并过程会在每帧进行,可能会导致一定的 CPU 开销,尤其是在合并的物体数量较多时。
- 材质限制:动态合批要求合并的物体使用相同的材质和着色器。如果物体使用不同的材质,无法进行合并。
- 顶点数量限制:每个绘制调用的顶点数量通常受到 GPU 的限制,合并后的 Mesh 可能会超出这个限制,导致渲染失败。
实现方法
在 Unity 中,动态合批的实现通常是自动的,但开发者可以通过以下方式确保动态合批的有效性:
- 使用相同的材质:确保所有需要合并的物体使用相同的材质和着色器。
- 小型 Mesh:动态合批通常适用于小型 Mesh,避免使用过大的 Mesh。
- 标记为可动态合批:在 Unity 中,确保物体的 Mesh Renderer 组件的“Dynamic Batching”选项被启用。
使用场景
动态合批适用于以下场景:
- 小型动态物体:如小型敌人、道具、特效等,这些物体在场景中频繁移动或变化。
- 大量相似物体:在场景中有大量相似的物体(如树木、石头等),使用动态合批可以显著提高性能。
- 实时变化的场景:在需要频繁更新的场景中,动态合批可以帮助减少绘制调用,提高渲染效率。
总结
动态合批是一种有效的性能优化技术,适用于动态物体的渲染。通过减少绘制调用,动态合批可以显著提高游戏的渲染性能。在实际开发中,合理使用动态合批可以帮助开发者创建更流畅的游戏体验。然而,开发者也需要注意其限制,确保合并的物体满足动态合批的条件,以获得最佳的性能效果。
动态合批(Dynamic Batching)通常是由游戏引擎自动处理的,尤其是在 Unity 这样的引擎中,开发者只需确保满足一定的条件,Unity 就会自动进行动态合批。然而,如果你想手动实现动态合批的逻辑,以下是一个简单的示例,展示如何在 Unity 中使用 C# 脚本来合并多个动态 Mesh。
Unity 中的动态合批实现示例
以下是一个简单的动态合批实现示例,使用 Unity 的 Mesh
和 Graphics
类来手动合并多个动态物体的 Mesh。
1. 创建一个新的 C# 脚本
命名为 DynamicBatcher
。
2. 将以下代码粘贴到脚本中
using UnityEngine;
using System.Collections.Generic;
public class DynamicBatcher : MonoBehaviour
{
public GameObject[] objectsToBatch; // 要合并的动态物体
public Material combinedMaterial; // 合并后的材质
private Mesh combinedMesh;
private List<CombineInstance> combineInstances = new List<CombineInstance>();
private MeshFilter meshFilter;
private MeshRenderer meshRenderer;
void Start()
{
// 创建合并后的 Mesh
combinedMesh = new Mesh();
meshFilter = gameObject.AddComponent<MeshFilter>();
meshRenderer = gameObject.AddComponent<MeshRenderer>();
meshRenderer.material = combinedMaterial;
}
void Update()
{
CombineMeshes();
}
void CombineMeshes()
{
combineInstances.Clear();
// 遍历所有要合并的物体
foreach (GameObject obj in objectsToBatch)
{
if (obj != null)
{
MeshFilter meshFilter = obj.GetComponent<MeshFilter>();
if (meshFilter != null)
{
CombineInstance combineInstance = new CombineInstance
{
mesh = meshFilter.sharedMesh,
transform = obj.transform.localToWorldMatrix
};
combineInstances.Add(combineInstance);
}
}
}
// 合并 Mesh
combinedMesh.CombineMeshes(combineInstances.ToArray(), false, true);
meshFilter.mesh = combinedMesh;
}
}
使用说明
- 创建一个空的 GameObject,并将
DynamicBatcher
脚本附加到该 GameObject 上。 - 在 Inspector 中设置:
objectsToBatch
:将要合并的动态物体拖放到这个数组中。combinedMaterial
:设置合并后的材质。
- 运行场景:当场景开始时,脚本会自动合并指定的动态物体,并创建一个新的合并 Mesh。
注意事项
- 材质:确保所有要合并的物体使用相同的材质,以便能够成功合并。
- 动态更新:在每一帧中,
Update
方法会重新合并物体,这可能会导致性能开销,尤其是在物体数量较多时。实际应用中,可能需要根据具体情况优化合并逻辑,例如只在物体位置或状态发生变化时进行合并。 - 碰撞体:合并后的 Mesh 可能需要重新设置碰撞体,尤其是在使用物理引擎时。
- 性能:手动合并 Mesh 可能会在场景加载时产生一定的性能开销,建议在场景初始化时进行合并。
总结
以上代码展示了如何在 Unity 中手动实现动态合批的逻辑。虽然 Unity 提供了内置的动态合批功能,但在某些情况下,手动合并 Mesh 可能会提供更大的灵活性。通过合理使用动态合批,可以显著提高游戏的渲染性能。
动态合批(Dynamic Batching)面临哪些性能问题
动态合批(Dynamic Batching)是一种优化渲染性能的技术,旨在减少绘制调用的数量,尤其是在处理大量小型动态物体时。然而,尽管动态合批可以提高性能,它也面临一些性能问题和限制。以下是动态合批可能遇到的一些主要性能问题:
1. CPU 开销
- 合并过程的开销:动态合批需要在每帧更新时合并多个 Mesh,这会增加 CPU 的计算负担。尤其是在合并的物体数量较多时,合并过程可能会导致显著的性能下降。
- 频繁的内存分配:每次合并时,可能会涉及到内存的分配和释放,这会导致内存碎片和额外的开销。
2. 材质限制
- 相同材质要求:动态合批要求所有合并的物体使用相同的材质和着色器。如果物体使用不同的材质,无法进行合并,这可能会导致材质种类过多,从而影响性能。
- 材质切换:即使在合并后,如果需要在运行时切换材质,仍然会导致性能下降,因为这会增加绘制调用。
3. 顶点数量限制
- 顶点数量限制:每个绘制调用的顶点数量通常受到 GPU 的限制。如果合并后的 Mesh 超过了这个限制,可能会导致渲染失败或性能下降。
- 合并后的 Mesh 大小:合并后的 Mesh 可能会变得非常大,导致 GPU 在处理时的性能下降。
4. 动态物体的复杂性
- 物体移动和变换:动态合批适用于动态物体,但如果物体频繁移动或变换,合并的 Mesh 可能需要频繁更新,这会增加 CPU 的负担。
- 物理交互:如果合并的物体需要进行物理交互,可能会导致物理计算的复杂性增加,影响性能。
5. GPU 性能
- GPU 负载:合并后的 Mesh 可能会导致 GPU 负载增加,尤其是在处理复杂的材质和着色器时,可能会影响渲染性能。
- 渲染状态切换:动态合批可能会导致 GPU 在渲染时频繁切换状态,影响渲染效率。
6. LOD(Level of Detail)管理
- LOD 兼容性:动态合批可能会影响 LOD 的管理,因为合并后的 Mesh 可能不容易与不同细节级别的 Mesh 进行切换。
7. 调试和维护
- 调试复杂性:手动实现动态合批可能会增加调试的复杂性,尤其是在处理多个动态物体时,可能会导致难以追踪的问题。
- 代码维护:自定义的动态合批实现可能需要额外的维护和优化,增加了开发的复杂性。
总结
动态合批是一种有效的性能优化技术,但在使用时需要考虑其潜在的性能问题和限制。开发者应根据具体的场景需求和性能目标,合理选择合批策略,并结合其他优化技术(如静态合批、实例化渲染、LOD 等)来实现最佳的性能效果。在实际开发中,监测性能并进行适当的优化是非常重要的。
动态合批(Dynamic Batching)如何降低因动态带来的CPU性能问题
动态合批(Dynamic Batching)在处理动态物体时,确实可能会引入一些 CPU 性能问题。为了降低这些性能问题,可以采取以下几种策略和优化方法:
1. 减少合并频率
- 条件合并:只在物体的位置、旋转或缩放发生变化时进行合并,而不是在每一帧都进行合并。可以通过设置标志位来跟踪物体的状态变化。
- 合并间隔:设置一个合并间隔,例如每隔几帧进行一次合并,而不是每帧都合并。
2. 限制合并的物体数量
- 分组合并:将物体分成小组进行合并,而不是一次性合并所有物体。这样可以减少每次合并的计算量。
- 优先级合并:根据物体的重要性或可见性来决定是否合并,优先合并那些在视野中频繁出现的物体。
3. 使用对象池
- 对象池技术:使用对象池来管理动态物体的创建和销毁,避免频繁的内存分配和释放,从而减少 CPU 开销。
- 重用 Mesh:对于经常出现的动态物体,考虑重用 Mesh,而不是每次都创建新的 Mesh。
4. 优化 Mesh 数据
- 简化 Mesh:尽量使用简单的 Mesh,减少顶点数量和面数,以降低合并时的计算量。
- 合并相似物体:在场景中,尽量将相似的物体合并为一个 Mesh,减少合并的复杂性。
5. 使用 GPU 实例化
- GPU 实例化:对于大量相似的动态物体,可以使用 GPU 实例化技术,这样可以在 GPU 端进行渲染,减少 CPU 的负担。
- 实例化渲染:通过实例化渲染,多个物体可以共享同一个 Mesh 和材质,从而减少绘制调用。
6. 合理使用材质和着色器
- 减少材质种类:确保合并的物体使用相同的材质和着色器,避免因材质切换而导致的性能损失。
- 优化着色器:使用性能更高的着色器,减少计算复杂度,降低对 CPU 的压力。
7. 使用多线程
- 多线程处理:如果合并过程非常复杂,可以考虑将合并操作放在后台线程中进行,避免阻塞主线程的渲染。
- 任务调度:使用任务调度系统,将合并任务分配到多个线程中,提高 CPU 的利用率。
8. 性能监测和分析
- 性能分析工具:使用性能分析工具(如 Unity Profiler)监测 CPU 的性能瓶颈,找出合并过程中的性能问题。
- 优化迭代:根据性能分析的结果,进行针对性的优化,逐步提高性能。
总结
通过以上策略,可以有效降低动态合批带来的 CPU 性能问题。在实际开发中,合理结合这些优化方法,根据具体的场景需求和性能目标进行调整,能够显著提高渲染性能和游戏体验。
Dynamic Batching:
Build时无额外资源生成,Runtime时生成Vertex Buffer和Index Buffer;
最多900个Vertex Attributes,新项目的模型有Normal,因此最多300个顶点;
模型对应Lightmap的Index,Offset和Scale必须一致。
但因顶点数和光照图的限制,Batching的效果并不理想
Static Batching:
Build时生成额外的数据,把所有共享材质的Mesh合并成一个;
Runtime时直接为合并后的模型生成Vertex Buffer,根据可见性生成Index Buffer进行渲染。
缺陷:无法精细控制Batch的大小,有些距离较远、顶点数较高物件没必要合批。一次性生成Vertex Buffer占用大量内存,视野变化时重构Index Buffer CPU有额外开销。
贴图制作对合批的影响:
因为合批工具不会自动生成新材质,所以要求美术尽量把同种物件的贴图合并到一张纹理上。
考虑到内存和渲染性能,我们最终选择512512作为场景物件的纹理大小。如物件使用的纹理不足512512,将会和其他纹理一起拼合到一张纹理上
批次选择算法:
物件合批是一把双刃剑,一方面可以减少模型的数量,从而减少DrawCalls。另一方面也会有额外的性能开销:
一是生成了新的Mesh,占用额外包量及内存;
二是单个模型渲染Buffer增大,更难以裁剪,可能会造成Overdraw。
因此,选择合适的算法非常重要,需选择合适的物件进行合并,以较小的代价减少更多的DrawCalls。
若合并后增加内存为deltaM,减少的DrawCalls为deltaD,则deltaM/deltaD越小,性价比越高。
合并条件:
1.待合并物件的组合应在以32为半径的圆范围内
2.合并后物件面数不超过8000
3.大于1500顶点或2000面的大物件不合
合并算法
1.把场景中材质相同的物件放入同一队列
2.建立金字塔形的集合,从下到上,每一层代表某合并数量的所有物体组合
3.合并组合中物件最多,且相对中心距离最小的组合
4.剔除已经合并过的物件组合
5.执行3,直到所有剩余的组合全被合并