官方解释 DrawMeshInstancedIndirect
Graphics.DrawMeshInstancedIndirect


C#层
划分逻辑上的 2D cell

i % cellCountX :计算第几列
i / cellCountX:计算第几行
+0.5将中心移到cell中心
这两行计算确切的世界中心位置,上面只是计算逻辑上的格子位置
centerPosWS.x = Mathf.Lerp(minX, maxX, centerPosWS.x / cellCountX);
centerPosWS.z = Mathf.Lerp(minZ, maxZ, centerPosWS.z / cellCountZ);
这边默认了每个 cell 是正方形的
Vector3 sizeWS = new Vector3(Mathf.Abs(maxX - minX) / cellCountX, 0, Mathf.Abs(maxX - minX) / cellCountX);
正常非正方向的情况应该如下:
Vector3 sizeWS = new Vector3(Mathf.Abs(maxX - minX) / cellCountX, 0, Mathf.Abs(maxZ - minZ) / cellCountZ);
这边对每个 cell 进行视锥体可见性测试,而不是每个草,加快了计算速度,但计算量仍然很多
if (GeometryUtility.TestPlanesAABB(cameraFrustumPlanes, cellBound)) {
visibleCellIDList.Add(i);
}
设置 CumputeShader 读取的起始位置
因为内部每次都是从总共草里面读取的,这边设置一个GPU组读取数据的起始位置


合并连续的 cell
0,1,2,3,4
0,1,5,7
当Id连续,也就 cell 连续时,合并成一个 batch

进行GPU划分并执行
按照每64颗草为一个组,进行 GPU的 x划分组(Group)

每个组划分 x向的64个线程,分别对应于每一颗草
完整代码

调用绘制



ComputeShader 层
将世界坐标转换到裁剪空间,进行裁剪,判断是否保留

Shader 层