我的程序在运行时收到网格。网格可以由超过200k的顶点组成。 我需要将其反转(由内而外)。我反转了索引,但是我还需要反转法线。到目前为止,我使用了以下循环:
Vector3[] newnormals=new Vector3[mesh.normals.Length];
for (int i=0;i<mesh.normals.Length;i++)
{
newnormals[i] = -mesh.normals[i];
}
revMesh.normals = newnormals;
其中“ mesh”是原始的Mesh,当然“ revMesh”是反向的。 我不知道为什么,但是这个循环非常慢。我的i7需要花几秒钟的时间。如果我用
代替revMesh.RecalculateNormals();
执行时间降至100毫秒以下。……
为什么我的例行程序效率低下?有什么办法可以加快速度吗?
答案 0 :(得分:3)
也许每次迭代都获得mesh.normals[i]
会使其变慢,请尝试:
Vector3[] newnormals= revMesh.normals;
for (int i=0;i<newnormals.Length;i++)
newnormals[i] = -newnormals[i];
revMesh.normals = newnormals;
注意:要更改法线,从网格物体复制法线很重要。复制并更改了法线后,可以将法线重新分配回网格。
您也可以这样做:(没有测试,但我认为它可行)
using System.Linq;
revMesh.triangles = revMesh.triangles.Reverse().ToArray();
答案 1 :(得分:2)
这里的主要问题是读取mesh.normals
不能直接访问数组。 Unity创建该数组的副本,然后将副本传递给您。您每次循环迭代都会读取mesh.normals
两次,因此对于具有200k法线的网格,您将创建该数组的400k副本。确实,那可能运行得很慢。
向Unity索要该数组的一个副本,执行该操作,然后将数据传递回Unity会更快。
Unity的内部类具有一些属性,每次读取它们时都会返回新副本。如果不确定,最好检查一下手册。