2016-10-11 44 views
0

我試圖在運行時創建UVs,我使用BOX類型的UV(類似於3ds max中的BOX UVW),並基於我的面部方向計算。運行時優化的UV展開

我知道這不是一個很好的選擇,以創建一個運行時間,但我別無選擇:(它的計算後保存的,所以我做了一次。

但我需要40秒,一個30000點的頂點......太長

有沒有在我的代碼任何優化,可以進行

這裏是我的代碼隨意使用,如果你有< 5000頂點網:?

public static void CreateUV(ref Mesh mesh) 
{ 

    int i = 0; 
    Vector3 p = Vector3.up; 
    Vector3 u = Vector3.Cross(p, Vector3.forward); 
    if (Vector3.Dot(u, u) < 0.001f) 
    { 
     u = Vector3.right; 
    } 
    else 
    { 
     u = Vector3.Normalize(u); 
    } 

    Vector3 v = Vector3.Normalize(Vector3.Cross(p, u)); 

    Vector2[] uvs = new Vector2[mesh.vertices.Length]; 

    for (i = 0; i < mesh.triangles.Length; i += 3) 
    { 

     Vector3 a = mesh.vertices[mesh.triangles[i]]; 
     Vector3 b = mesh.vertices[mesh.triangles[i + 1]]; 
     Vector3 c = mesh.vertices[mesh.triangles[i + 2]]; 
     Vector3 side1 = b - a; 
     Vector3 side2 = c - a; 
     Vector3 N = Vector3.Cross(side1, side2); 

     N = new Vector3(Mathf.Abs(N.normalized.x), Mathf.Abs(N.normalized.y), Mathf.Abs(N.normalized.z)); 



     if (N.x > N.y && N.x > N.z) 
     { 
      uvs[mesh.triangles[i]] = new Vector2(mesh.vertices[mesh.triangles[i]].z, mesh.vertices[mesh.triangles[i]].y); 
      uvs[mesh.triangles[i + 1]] = new Vector2(mesh.vertices[mesh.triangles[i + 1]].z, mesh.vertices[mesh.triangles[i + 1]].y); 
      uvs[mesh.triangles[i + 2]] = new Vector2(mesh.vertices[mesh.triangles[i + 2]].z, mesh.vertices[mesh.triangles[i + 2]].y); 
     } 
     else if (N.y > N.x && N.y > N.z) 
     { 
      uvs[mesh.triangles[i]] = new Vector2(mesh.vertices[mesh.triangles[i]].x, mesh.vertices[mesh.triangles[i]].z); 
      uvs[mesh.triangles[i + 1]] = new Vector2(mesh.vertices[mesh.triangles[i + 1]].x, mesh.vertices[mesh.triangles[i + 1]].z); 
      uvs[mesh.triangles[i + 2]] = new Vector2(mesh.vertices[mesh.triangles[i + 2]].x, mesh.vertices[mesh.triangles[i + 2]].z); 
     } 
     else if (N.z > N.x && N.z > N.y) 
     { 
      uvs[mesh.triangles[i]] = new Vector2(mesh.vertices[mesh.triangles[i]].x, mesh.vertices[mesh.triangles[i]].y); 
      uvs[mesh.triangles[i + 1]] = new Vector2(mesh.vertices[mesh.triangles[i + 1]].x, mesh.vertices[mesh.triangles[i + 1]].y); 
      uvs[mesh.triangles[i + 2]] = new Vector2(mesh.vertices[mesh.triangles[i + 2]].x, mesh.vertices[mesh.triangles[i + 2]].y); 
     } 

    } 

    mesh.uv = uvs; 
    Debug.Log("Finish"); 
} 

回答

1

我強烈建議緩存mesh.vertices的副本。

部分爲vertices屬性狀態的文檔:

返回頂點位置的副本或分配新的頂點位置陣列。

注「返回副本」 - 你訪問這個屬性22倍的循環中,所以這將創建數組的大致22n/3副本。對於具有30,000個頂點的網格,這是在後臺進行的超過200,000次不必要的複製操作。

如果您創建一個臨時數組來保存頂點數據(就像您已經在使用mesh.uvs一樣),您應該看到顯着的性能提升。

您可能還會檢查mesh.triangles是否是複製操作。我預計它可能是,但文件沒有具體說明。

+0

謝謝你這麼玉米粥!!!! –

+0

mesh.vertices AND mesh.triangles是複製操作! –

0

這裏是我的代碼優化感謝@rutter

public static Vector2[] CreateUV(ref Mesh mesh) 
{ 

    int i = 0; 
    Vector3 p = Vector3.up; 
    Vector3 u = Vector3.Cross(p, Vector3.forward); 
    if (Vector3.Dot(u, u) < 0.001f) 
    { 
     u = Vector3.right; 
    } 
    else 
    { 
     u = Vector3.Normalize(u); 
    } 

    Vector3 v = Vector3.Normalize(Vector3.Cross(p, u)); 
    Vector3[] vertexs = mesh.vertices; 
    int[] tris = mesh.triangles; 
    Vector2[] uvs = new Vector2[vertexs.Length]; 

    for (i = 0; i < tris.Length; i += 3) 
    { 

     Vector3 a = vertexs[tris[i]]; 
     Vector3 b = vertexs[tris[i + 1]]; 
     Vector3 c = vertexs[tris[i + 2]]; 
     Vector3 side1 = b - a; 
     Vector3 side2 = c - a; 
     Vector3 N = Vector3.Cross(side1, side2); 

     N = new Vector3(Mathf.Abs(N.normalized.x), Mathf.Abs(N.normalized.y), Mathf.Abs(N.normalized.z)); 



     if (N.x > N.y && N.x > N.z) 
     { 
      uvs[tris[i]] = new Vector2(vertexs[tris[i]].z, vertexs[tris[i]].y); 
      uvs[tris[i + 1]] = new Vector2(vertexs[tris[i + 1]].z, vertexs[tris[i + 1]].y); 
      uvs[tris[i + 2]] = new Vector2(vertexs[tris[i + 2]].z, vertexs[tris[i + 2]].y); 
     } 
     else if (N.y > N.x && N.y > N.z) 
     { 
      uvs[tris[i]] = new Vector2(vertexs[tris[i]].x, vertexs[tris[i]].z); 
      uvs[tris[i + 1]] = new Vector2(vertexs[tris[i + 1]].x, vertexs[tris[i + 1]].z); 
      uvs[tris[i + 2]] = new Vector2(vertexs[tris[i + 2]].x, vertexs[tris[i + 2]].z); 
     } 
     else if (N.z > N.x && N.z > N.y) 
     { 
      uvs[tris[i]] = new Vector2(vertexs[tris[i]].x, vertexs[tris[i]].y); 
      uvs[tris[i + 1]] = new Vector2(vertexs[tris[i + 1]].x, vertexs[tris[i + 1]].y); 
      uvs[tris[i + 2]] = new Vector2(vertexs[tris[i + 2]].x, vertexs[tris[i + 2]].y); 
     } 

    } 

    mesh.uv = uvs; 
    return uvs; 
}