Unity利用GPUinstancing实现大面积草地

{html

目录

}
以前用unity自带的terrain画了一片草,Draw Call高的要命,自带的草根本就没有批合==无法用
在这里插入图片描述
在这里插入图片描述帧数低得吓人,Draw Call如今是9000多,有的时候能上万,这。。。开发者根本就没用心作吧。。。
因而决定用GPUinstancing,官方API连接: GPU instancing.
能够自动实例化也能够用Graphics.DrawMeshInstanced 函数来实例化,都必须勾选Enable Instancing。
在这里插入图片描述
关于自动实例化:
1.在shader代码中添加#pragma multi_compile_instancing里面那一套,若是用unity再带能够跳过;
2.勾选Enable Instancing,取消transform组件左上角的static(由于unity优先批处理);
3.若是须要改颜色等信息能够经过renderer.SetPropertyBlock(props)来传值。
4.unity会自动进行instancing。
在Transform已经建立好以后,须要更改颜色信息web

MaterialPropertyBlock props = new MaterialPropertyBlock();
MeshRenderer renderer;
foreach (Transform obj in parentts)
{
    float r = Random.Range(0.086f, 0.535f);
    //float g = Random.Range(0.0f, 1.0f);
    float b = Random.Range(0.18f, 0.535f);
    props.SetColor("_Color", new Color(r, .859f, b));
    renderer = obj.GetComponent<MeshRenderer>();
    renderer.SetPropertyBlock(props);
}

可是有不少未知的因素会致使没法自动实例化,就是按照API的套路改了,Draw Call仍是很高,因此建议不要用自动实例化,直接用DrawMeshinstanced函数。
关于底层API DrawMeshinstanced:
1.自动实例化的1,2
2.经过Matrix4x4.TRS(position, rotation, scale);把全部草的坐标算出来,存入数组中。
3.经过MaterialPropertyBlock给shader传递须要修改的值,通常用SetVectorArray或者SetFloatArray,由于咱们但愿这一批草或其它什么有不一样的属性。
4.经过Graphics.DrawMeshInstanced()来实例化(在update函数中,这个函数是绘制一帧,建议在start中把该算的算好)数组

Graphics.DrawMeshInstanced(Mesh, submeshIndex, Material, matrices, count, properties);
/* Mesh 索要绘制的网格 submeshIndex 要绘制网格的哪一个子集,由多个网格组成的才用获得,通常为0 Material 材质 matrices 在步骤2中计算的矩阵数组 count 数量 properties 步骤3中建立的MaterialPropertyBlock,用来传递属性 还有不少参数,不过画草的话用不到 */

须要注意的是一次最多只能绘制1023个实例,也就是说count<=1023。
若是须要绘制的物体太多的话,须要分批绘制,好比此次我绘制了300*300个草,一共分了88批,帧数提高巨大,GPUinstancing特别适合这种面少数量多的。
在这里插入图片描述
以后以前
对比一下Batches Draw Call
还有很大的提高空间,好比经过计算视椎体可见的部分来绘制,或者较远的草不绘制等。
索性连地形都不用自带的了,直接根据高度图生成Mesh地形,可操做性很高,建立草时草的高度也是经过高度图采样计算得来的。
目前尚未给草的shader添加阴影、随风摆动,还能够经过更改Matrix来添加踩草的效果,由于论文和考试的缘由可能又要鸽了,不过性能问题解决了剩下的我想很快就能实现了dom