Vector3 * float非常慢

时间:2019-06-11 18:16:25

标签: c# loops unity3d optimization

我的程序在运行时收到网格。网格可以由超过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毫秒以下。……

为什么我的例行程序效率低下?有什么办法可以加快速度吗?

2 个答案:

答案 0 :(得分:3)

也许每次迭代都获得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();

答案 1 :(得分:2)

这里的主要问题是读取mesh.normals不能直接访问数组。 Unity创建该数组的副本,然后将副本传递给您。您每次循环迭代都会读取mesh.normals两次,因此对于具有200k法线的网格,您将创建该数组的400k副本。确实,那可能运行得很慢。

向Unity索要该数组的一个副本,执行该操作,然后将数据传递回Unity会更快。

Unity的内部类具有一些属性,每次读取它们时都会返回新副本。如果不确定,最好检查一下手册。