UV unwrap on Runtime optimization

谁说我不能喝 提交于 2020-02-05 03:38:43

问题


I'm trying to create UVs @ runtime, I'm using a BOX type UVs (similar to BOX UVW in 3ds max) and based my calculation on the face orientation.

I know it's not a good option to create it a runtime but I have no choice :( it's saved after calculation, so I made it once.

BUT I take 40 seconds for a 30000 Vertices... too long

Is there any optimization in my code that can be made?

.

Here is my code feel free to use if you have <5000 vertices Mesh:

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:


I would strongly recommend caching a copy of mesh.vertices.

The documentation for the vertices property states in part:

Returns a copy of the vertex positions or assigns a new vertex positions array.

Note "returns a copy" -- you access this property 22 times inside your loop, so this will create roughly 22n / 3 copies of that array. For a mesh with 30,000 vertices, that's over 200,000 unnecessary copy operations going on in the background.

If you create a temporary array to hold vertex data (like you're already doing with mesh.uvs), you should see a dramatic performance improvement.

You might also check if mesh.triangles is a copy operation. I anticipate that it could be, but the docs don't specify.




回答2:


here is my code optimized thanks to @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;
}


来源:https://stackoverflow.com/questions/39980248/uv-unwrap-on-runtime-optimization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!