private Mesh GenerateLod(LODTopologyOptions lod, int index)
        {
            var mesh = new Mesh {
                name = "Procedural Grass " + index
            };

            int numVerticesPerPlane = (lod.verticesX + 1) * (lod.verticesY + 1);

            Vector3[] vertices  = new Vector3[numVerticesPerPlane * lod.planeCount];
            Vector3[] normals   = new Vector3[vertices.Length];
            Vector2[] uv        = new Vector2[vertices.Length];
            Vector4[] tangents  = new Vector4[vertices.Length];
            int[]     triangles = new int[lod.verticesX * lod.verticesY * lod.planeCount * 6];

            for (int planeIndex = 0; planeIndex < lod.planeCount; ++planeIndex)
            {
                float planeRotation = Mathf.PI / lod.planeCount * planeIndex;
                GeneratePlane(lod, vertices, normals, uv, tangents, triangles, planeIndex, planeRotation);
            }

            mesh.vertices  = vertices;
            mesh.normals   = normals;
            mesh.uv        = uv;
            mesh.tangents  = tangents;
            mesh.triangles = triangles;

            return(mesh);
        }
        private void GeneratePlane(LODTopologyOptions lod, Vector3[] vertices, Vector3[] normals, Vector2[] uv,
                                   Vector4[] tangents, int[] triangles, int planeIndex, float planeRotation)
        {
            int vertexStartIndex = (lod.verticesX + 1) * (lod.verticesY + 1) * planeIndex;

            for (int i = vertexStartIndex, y = 0; y <= lod.verticesY; y++)
            {
                for (int x = 0; x <= lod.verticesX; x++, i++)
                {
                    float xRatio = (float)x / lod.verticesX;
                    float yRatio = (float)y / lod.verticesY;

                    float horizontalCornerCoord = patchSize.x * (xRatio - 0.5f);
                    float vertexX = horizontalCornerCoord * Mathf.Sin(planeRotation);
                    float vertexY = patchSize.y * yRatio;
                    float vertexZ = horizontalCornerCoord * Mathf.Cos(planeRotation);

                    vertices[i] = new Vector3(vertexX, vertexY, vertexZ);
                    uv[i]       = new Vector2(xRatio, yRatio);
                    normals[i]  = Vector3.up;
                    tangents[i] = new Vector4(1f, 0f, 0f, -1f);
                }
            }

            int triangleStartIndex = lod.verticesX * lod.verticesY * 6 * planeIndex;

            for (int ti = triangleStartIndex, vi = vertexStartIndex, y = 0; y < lod.verticesY; y++, vi++)
            {
                for (int x = 0; x < lod.verticesX; x++, ti += 6, vi++)
                {
                    triangles[ti]     = vi;
                    triangles[ti + 3] = triangles[ti + 2] = vi + 1;
                    triangles[ti + 4] = triangles[ti + 1] = vi + lod.verticesX + 1;
                    triangles[ti + 5] = vi + lod.verticesX + 2;
                }
            }
        }