Unity利用GPUinstancing实现大面积草地

{

目录
  • 人物移动+相机跟随脚本修改
  • Gpuinstance实现大面积草地
  • 风吹麦浪+人物影响
  • 后处理动态天空实现
  • 动态天空实现
  • 体积光实现的三种方法

}
之前用unity自带的terrain画了一片草,Draw Call高的要命,自带的草根本就没有批合==没法用

Unity利用GPUinstancing实现大面积草地_第1张图片帧数低得吓人,Draw Call现在是9000多,有的时候能上万,这。。。开发者根本就没用心做吧。。。
于是决定用GPUinstancing,官方API链接: GPU instancing.
可以自动实例化也可以用Graphics.DrawMeshInstanced 函数来实例化,都必须勾选Enable Instancing。
Unity利用GPUinstancing实现大面积草地_第2张图片
关于自动实例化:
1.在shader代码中添加#pragma multi_compile_instancing里面那一套,如果用unity再带可以跳过;
2.勾选Enable Instancing,取消transform组件左上角的static(因为unity优先批处理);
3.如果需要改颜色等信息可以通过renderer.SetPropertyBlock(props)来传值。
4.unity会自动进行instancing。
在Transform已经创建好之后,需要更改颜色信息

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特别适合这种面少数量多的。

Unity利用GPUinstancing实现大面积草地_第3张图片Unity利用GPUinstancing实现大面积草地_第4张图片
对比一下Batches Draw Call
还有很大的提升空间,比如通过计算视椎体可见的部分来绘制,或者较远的草不绘制等。
索性连地形都不用自带的了,直接根据高度图生成Mesh地形,可操作性很高,创建草时草的高度也是通过高度图采样计算得来的。
目前还没有给草的shader添加阴影、随风摆动,还可以通过更改Matrix来添加踩草的效果,因为论文和考试的原因可能又要鸽了,不过性能问题解决了剩下的我想很快就能实现了

你可能感兴趣的:(Unity)