Unity的GPU Instancing技术
首先新建一个场景,添加一个相机,并创建一个Render Texture给相机。
然后在相机上挂载以下脚本TestBatches ,同时脚本的Inspector面板的Mesh中选择Cube,另外创建一个新的材质拖动给mat:
public class TestBatches : MonoBehaviour
{
public Mesh mesh;
public Material mat;
private void OnRenderObject()
{
Graphics.DrawMesh(mesh,Vector3.zero,Quaternion.identity,mat,0);
}
}
运行Unity则可以看到一个Cube:
这里可以看到DrawCall数量为36个,以为相机本身有10个DrawCall,所以等于这个Cube的绘制有16个DrawCall。
然后我们修改代码为,就会发现DrawCall数量增加到了52个,因为36+16=52
private void OnRenderObject()
{
Graphics.DrawMesh(mesh,Vector3.zero,Quaternion.identity,mat,0);
Graphics.DrawMesh(mesh,Vector3.zero,Quaternion.identity,mat,0);
}
那么我们如何可以通过其他方式绘制出同样的两个Cube,而不增加DrawCall数量呢,接下来我们使用Gpu Instancing的方式,首先开启材质的Instancing开关:
然后修改代码,使用Graphics.DrawMeshInstanced接口绘制:
public class TestBatches : MonoBehaviour
{
public Mesh mesh;
public Material mat;
private Matrix4x4[] m_atrix4x4s = new Matrix4x4[2];
private void Start()
{
// 初始化两个矩阵以定义两个物体的位置、旋转和缩放
m_atrix4x4s[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one); // 第一个物体位置
m_atrix4x4s[1] = Matrix4x4.TRS(new Vector3(2, 0, 0), Quaternion.identity, Vector3.one); // 第二个物体位置,相对于第一个物体偏移
}
private void OnRenderObject()
{
//Graphics.DrawMesh(mesh,Vector3.zero,Quaternion.identity,mat,0);
// 使用 DrawMeshInstanced 绘制两个物体
Graphics.DrawMeshInstanced(mesh, 0, mat, m_atrix4x4s);
}
}
可以看到绘制了两个同样的Cube但DrawCall数量没有增加: