【问题标题】:UV unwrap on Runtime optimization运行时优化的 UV 展开
【发布时间】:2017-02-20 04:07:53
【问题描述】:

我正在尝试在运行时创建 UV,我正在使用 BOX 类型的 UV(类似于 3ds max 中的 BOX UVW)并基于面部方向进行计算。

我知道创建一个运行时不是一个好选择,但我别无选择:(计算后保存,所以我做了一次。

但是 30000 个顶点需要 40 秒...太长了

我的代码有什么可以优化的吗?

.

如果您有

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");
}

【问题讨论】:

    标签: c# optimization unity3d unityscript uv-mapping


    【解决方案1】:

    我强烈建议缓存mesh.vertices 的副本。

    vertices 属性的文档部分说明:

    返回顶点位置的副本或分配一个新的顶点位置数组。

    注意“返回一个副本”——您在循环中访问此属性 22 次,因此这将创建该数组的大致 22n / 3 副本。对于具有 30,000 个顶点的网格,在后台进行了超过 200,000 次不必要的复制操作。

    如果您创建一个临时数组来保存顶点数据(就像您已经在使用 mesh.uvs 一样),您应该会看到显着的性能提升。

    您还可以检查mesh.triangles 是否为复制操作。我预计可能是这样,但文档没有具体说明。

    【讨论】:

      【解决方案2】:

      感谢@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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-18
        • 1970-01-01
        • 1970-01-01
        • 2016-01-28
        • 2020-04-29
        • 2014-08-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多