- 在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> ();
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) {
for (int i = 0; i < ts.Count; i++) {
if (ns[i] != nn[ts[i]] || us[i] != uv[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.normals = ns;
temp.uvs = us;
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> ();
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) {
for (int i = 0; i < ts.Count; i++) {
if (ns[i] != nn[ts[i]] || us[i] != uv[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.normals = ns;
temp.uvs = us;
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
个顶点。