自动部分:
手动优化部分:
自动部分:
手动优化部分:
编辑 > 项目设置 > 播放器 > 其他设置 > 渲染 > 动态批处理✓
![动态批处理设置示意图]
✅ 条件检查清单:
共享材质:
// 不要这样做
renderer.material = myMaterial; // 创建材质副本
// 正确做法
renderer.sharedMaterial = myMaterial; // 使用共享材质
减少材质数量:
最简单的方法:
![GPU Instancing 设置示意图]
#pragma multi_compile_instancing
// 基础 GPU Instancing 示例
public class SimpleInstancing : MonoBehaviour
{
public Mesh mesh;
public Material material;
public int count = 100;
public float radius = 10f;
private Matrix4x4[] matrices;
void Start()
{
// 确保材质支持实例化
material.enableInstancing = true;
// 准备实例变换矩阵
matrices = new Matrix4x4[count];
for (int i = 0; i < count; i++)
{
float angle = i * Mathf.PI * 2f / count;
Vector3 position = new Vector3(
Mathf.Cos(angle) * radius,
0,
Mathf.Sin(angle) * radius
);
matrices[i] = Matrix4x4.TRS(
position,
Quaternion.Euler(0, angle * Mathf.Rad2Deg, 0),
Vector3.one
);
}
}
void Update()
{
// 一次性绘制所有实例
Graphics.DrawMeshInstanced(mesh, 0, material, matrices, count);
}
}
// 带有属性变化的 GPU Instancing
public class ColoredInstancing : MonoBehaviour
{
public Mesh mesh;
public Material material;
public int count = 100;
public float radius = 10f;
private Matrix4x4[] matrices;
private MaterialPropertyBlock propertyBlock;
void Start()
{
// 确保材质支持实例化
material.enableInstancing = true;
// 准备实例数据
matrices = new Matrix4x4[count];
propertyBlock = new MaterialPropertyBlock();
// 准备颜色数组
Vector4[] colors = new Vector4[count];
for (int i = 0; i < count; i++)
{
float angle = i * Mathf.PI * 2f / count;
Vector3 position = new Vector3(
Mathf.Cos(angle) * radius,
0,
Mathf.Sin(angle) * radius
);
matrices[i] = Matrix4x4.TRS(
position,
Quaternion.Euler(0, angle * Mathf.Rad2Deg, 0),
Vector3.one
);
// 每个实例不同颜色
colors[i] = new Vector4(
Mathf.Abs(Mathf.Cos(angle)),
Mathf.Abs(Mathf.Sin(angle)),
0.5f,
1.0f
);
}
// 设置颜色属性
propertyBlock.SetVectorArray("_Color", colors);
}
void Update()
{
// 使用属性块绘制实例
Graphics.DrawMeshInstanced(mesh, 0, material, matrices, count, propertyBlock);
}
}
使用 Frame Debugger 查看:
选择动态批处理:
选择 GPU Instancing:
问题: 启用了 GPU Instancing 但没有效果?
解决:
问题: 动态批处理没有预期效果?
解决:
在实际项目中,通常混合使用不同优化技术:
对于程序生成的大量物体(如草、树、粒子):
// 高级实例化系统示例
[System.Serializable]
public class InstanceGroup
{
public Mesh mesh;
public Material material;
public Vector3 positionVariance = new Vector3(10f, 0f, 10f);
public Vector3 scaleVariance = new Vector3(0.2f, 0.5f, 0.2f);
public int count = 1000;
}
public class InstanceManager : MonoBehaviour
{
public List<InstanceGroup> instanceGroups = new List<InstanceGroup>();
private Dictionary<InstanceGroup, List<Matrix4x4>> instanceData =
new Dictionary<InstanceGroup, List<Matrix4x4>>();
void Start()
{
foreach (InstanceGroup group in instanceGroups)
{
// 确保启用实例化
group.material.enableInstancing = true;
// 创建和存储实例数据
List<Matrix4x4> matrices = new List<Matrix4x4>();
instanceData[group] = matrices;
// 生成随机位置
for (int i = 0; i < group.count; i++)
{
Vector3 position = new Vector3(
Random.Range(-group.positionVariance.x, group.positionVariance.x),
Random.Range(-group.positionVariance.y, group.positionVariance.y),
Random.Range(-group.positionVariance.z, group.positionVariance.z)
);
Vector3 scale = Vector3.one + new Vector3(
Random.Range(-group.scaleVariance.x, group.scaleVariance.x),
Random.Range(-group.scaleVariance.y, group.scaleVariance.y),
Random.Range(-group.scaleVariance.z, group.scaleVariance.z)
);
Quaternion rotation = Quaternion.Euler(0, Random.Range(0, 360), 0);
matrices.Add(Matrix4x4.TRS(position, rotation, scale));
}
}
}
void Update()
{
// 渲染所有实例组
foreach (InstanceGroup group in instanceGroups)
{
List<Matrix4x4> matrices = instanceData[group];
int batchCount = Mathf.CeilToInt((float)matrices.Count / 1023);
// 支持超过1023个实例(实例化限制)
for (int i = 0; i < batchCount; i++)
{
int batchSize = Mathf.Min(1023, matrices.Count - i * 1023);
Matrix4x4[] batchMatrices = new Matrix4x4[batchSize];
for (int j = 0; j < batchSize; j++)
{
batchMatrices[j] = matrices[i * 1023 + j];
}
// 绘制当前批次
Graphics.DrawMeshInstanced(group.mesh, 0, group.material,
batchMatrices, batchSize);
}
}
}
}
Unity 的动态批处理和 GPU Instancing 既可以自动工作,也可以通过编程优化以获得最佳性能:
动态批处理:
GPU Instancing:
两种技术各有优势,理想情况下应组合使用以获得最佳性能。正确应用这些技术可以显著提高帧率,尤其是在有大量相似物体的复杂场景中。