在Unity3D中使用UniFBX加载模型太慢问题解决方法

  • 在Unity3D中经常使用UniFBX加载FBX模型,但是加载的太慢了,35M的模型需要48秒。我的UniFBX版本是2.2.3.1,问题主要出在UniFBXGeometries.cs文件中的ProcessingByNormals函数中,代码如下:
private UniFBXGeometry.KFbxMesh ProcessingByNormals (List<Vector3> vs, List<int> ts, List<Vector3> ns, List<Vector2> us, List<int> ms) {
        List<Vector3> nn = new List<Vector3> ();
        List<Vector2> uv = new List<Vector2> ();
        //List<int> newVertexIndexes = new List<int> ();
        //List<int> newVertexWeights = new List<int> ();

        int MAX = Mathf.Max (ts.ToArray ());
        int TRIANGLE_SIZE = MAX + 1;

        //效率低下的代码-------------------
        for (int i = 0; i < TRIANGLE_SIZE; i++)
        {
            int j = 0;
            for (int k = 0; k < ts.Count; k++)
            {
                if (ts[k] == i)
                {
                    j = k;
                    break;
                }
            }
            nn.Add(ns[j]);
            uv.Add(us[j]);
        }
        //-------------------------------
        
        if (this.setting.meshes.meshMethode == ImportMethode.Unity) {
            //int MAX_VERTICES = vs.Count - 1;
            //int skip = 1;
            for (int i = 0; i < ts.Count; i++) {
                if (ns[i] != nn[ts[i]] || us[i] != uv[ts[i]]) {
                    //if (vs.Count > (skip * MAX_VERTICES)) skip++;
                    //newVertexIndexes.Add (ts[i] * skip);
                    //newVertexWeights.Add (ts[i]);
                    vs.Add (vs[ts[i]]);
                    nn.Add (ns[i]);
                    uv.Add (us[i]);
                    ns[i] = nn[ts[i]];
                    us[i] = uv[ts[i]];
                    int inc = MAX + 1;
                    ts[i] = inc;
                    MAX = inc;
                    if (vs.Count >= 64000) break;
                }
            }
        }
        ns = nn;
        us = uv;

        UniFBXGeometry.KFbxMesh temp = new UniFBXGeometry.KFbxMesh ();
        temp.vertices = vs;
        //temp.newVeretexIndexes = newVertexIndexes;
        //temp.newVeretexWeights = newVertexWeights;
        temp.normals = ns;
        temp.uvs = us;

        //Debug.Log (vs.Count + " :: " + ns.Count + " :: " + us.Count);
        if (this.setting.textures.normalmaps) {
            if (vs.Count == us.Count) temp.tangents = this.GetTangents (vs, ts, ns, us);
        }
        temp.submeshes = this.GetSubmeshes (ts, ms);
        return temp;
    }
  • 优化后,35M的模型加载只需要4秒(提升10倍),优化后的代码如下:
private UniFBXGeometry.KFbxMesh ProcessingByNormals (List<Vector3> vs, List<int> ts, List<Vector3> ns, List<Vector2> us, List<int> ms) {
        List<Vector3> nn = new List<Vector3> ();
        List<Vector2> uv = new List<Vector2> ();
        //List<int> newVertexIndexes = new List<int> ();
        //List<int> newVertexWeights = new List<int> ();

        int MAX = Mathf.Max (ts.ToArray ());
        int TRIANGLE_SIZE = MAX + 1;

		//优化的代码-------------------
		var tmpNN = new Vector3[TRIANGLE_SIZE];
		var tmpUV = new Vector2[TRIANGLE_SIZE];
		
		var tmpNNFlag = new bool[TRIANGLE_SIZE];
		var tmpUVFlag = new bool[TRIANGLE_SIZE];
		
		for(int i = 0; i < ts.Count; ++i)
		{
		    if (!tmpNNFlag[ts[i]])
		    {
		        tmpNNFlag[ts[i]] = true;
		        tmpNN[ts[i]] = ns[i];
		    }
		    if (!tmpUVFlag[ts[i]])
		    {
		        tmpUVFlag[ts[i]] = true;
		        tmpUV[ts[i]] = us[i];
		    }
		}
		nn.AddRange(tmpNN);
		uv.AddRange(tmpUV);
		//------------------------------
        
        if (this.setting.meshes.meshMethode == ImportMethode.Unity) {
            //int MAX_VERTICES = vs.Count - 1;
            //int skip = 1;
            for (int i = 0; i < ts.Count; i++) {
                if (ns[i] != nn[ts[i]] || us[i] != uv[ts[i]]) {
                    //if (vs.Count > (skip * MAX_VERTICES)) skip++;
                    //newVertexIndexes.Add (ts[i] * skip);
                    //newVertexWeights.Add (ts[i]);
                    vs.Add (vs[ts[i]]);
                    nn.Add (ns[i]);
                    uv.Add (us[i]);
                    ns[i] = nn[ts[i]];
                    us[i] = uv[ts[i]];
                    int inc = MAX + 1;
                    ts[i] = inc;
                    MAX = inc;
                    if (vs.Count >= 64000) break;
                }
            }
        }
        ns = nn;
        us = uv;

        UniFBXGeometry.KFbxMesh temp = new UniFBXGeometry.KFbxMesh ();
        temp.vertices = vs;
        //temp.newVeretexIndexes = newVertexIndexes;
        //temp.newVeretexWeights = newVertexWeights;
        temp.normals = ns;
        temp.uvs = us;

        //Debug.Log (vs.Count + " :: " + ns.Count + " :: " + us.Count);
        if (this.setting.textures.normalmaps) {
            if (vs.Count == us.Count) temp.tangents = this.GetTangents (vs, ts, ns, us);
        }
        temp.submeshes = this.GetSubmeshes (ts, ms);
        return temp;
    }
	   
  • 注意:UniFBX加载模型为文本格式,单个mesh不要超过65000个顶点。
发布了41 篇原创文章 · 获赞 4 · 访问量 3886

猜你喜欢

转载自blog.csdn.net/weixin_42487874/article/details/103413367