unity3d 补片操作非常慢

lb3vh1jj  于 2022-12-13  发布在  其他
关注(0)|答案(2)|浏览(144)

我的程序在运行时接收到一个网格。网格可以由超过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毫秒以下....
为什么我的日常工作效率这么低?有什么方法可以加快吗?

toiithl6

toiithl61#

也许在每次迭代中获得mesh.normals[i]会使它变慢,请尝试:

Vector3[] newnormals= revMesh.normals;
for (int i=0;i<newnormals.Length;i++)
    newnormals[i] = -newnormals[i];
revMesh.normals = newnormals;

**注意:**要更改法线,从网格中复制法线是很重要的。一旦法线被复制和更改,法线可以重新分配回网格。

https://docs.unity3d.com/ScriptReference/Mesh-normals.html
您还可以执行以下操作:(未测试,但我认为它有效)

using System.Linq;
revMesh.triangles = revMesh.triangles.Reverse().ToArray();
rryofs0p

rryofs0p2#

这里的主要问题是阅读mesh.normals并不直接访问数组。Unity创建了该数组的一个副本并将其传递给您。您在每个循环迭代中读取mesh.normals两次,因此对于一个具有200k法线的网格,您将创建该数组的400k个副本。这可能会运行得非常慢。
如果向Unity请求阵列的一个副本,在上面执行操作,然后在完成后将数据传递回Unity,速度会快得多。
Unity的内部类有一些属性,每次读取时都会返回新的副本。如果你不确定,最好查阅一下手册。

相关问题