首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >运行时优化的UV解包

运行时优化的UV解包
EN

Stack Overflow用户
提问于 2016-10-11 14:56:39
回答 2查看 1.7K关注 0票数 1

我试图创建UVs @ runtime,我使用的是一个盒子类型的UVs (类似于3ds max中的BOX UVW ),并根据脸的方向进行计算。

我知道创建它不是一个好的选择,但是我没有选择:(它是在计算后保存的,所以我做了一次。

但我花了40秒才有30000个顶点.太长了

我的代码中有任何可以进行的优化吗?

下面是我的代码,如果您有<5000顶点网格,可以随意使用:

代码语言:javascript
复制
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");
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-11 16:28:55

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

vertices属性的文档部分说明如下:

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

注:“返回副本”--在循环中访问该属性22次,因此这将大致创建该数组的22n / 3副本。对于一个有30,000个顶点的网格来说,在后台进行的拷贝操作超过20万次。

如果您创建一个临时数组来保存顶点数据(就像您已经在使用mesh.uvs一样),那么您将看到性能的显著提高。

还可以检查mesh.triangles是否是复制操作。我预计可能是这样,但文档没有指定。

票数 2
EN

Stack Overflow用户

发布于 2016-10-12 15:22:48

这是我的代码经过了优化,这要归功于@rutter

代码语言:javascript
复制
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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39980248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档