2016-10-11 13 views
0

Я пытаюсь создать UVs @ runtime, я использую UV-типы BOX (аналогичные BOX UVW в 3ds max) и основываю свои вычисления на ориентации лица.УФ-развертка в оптимизации времени работы

Я знаю, что это не очень хороший вариант, чтобы создать его среды выполнения, но у меня нет выбора :(она сохраняется после расчета, так что я сделал это один раз.

НО я беру 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; 
}