目标是把多个mesh合并成一个或者几个,降低drawcall,但是又不想标记成static的,也不想进3dmax合并的一个尝试。
首先在Window -> Package Manager里安装FBX Exporter,我的unity版本是2020,2019应该也可以
安装成功后发现右键GameObject,可以导出fbx了。
接下来就是合并多个mesh
假设我有这么100个cube,我想让他合并成1个mesh
首先直接用Fbx Export导出试试
导出后还是很多个cube,和我想要的不一样
我目前的想法是读取每个mesh的顶点 nv 法线信息,然后triangles在新的mesh的时候,每次加上之前点数量,感觉上连面就没有问题了。
然后不同的材质需要分不同的mesh。
首先要获取所有选中物体的mesh,之后我暂时根据material的名字记录在一个Dictionary<string, List> meshByMaterial里(以后应该把string改成 直接的material)
合并之后的mesh放在新创建的物体下
GameObject newObjsRoot = new GameObject(name + "__combine");
newObjsRoot.transform.position = Vector3.zero;
foreach (KeyValuePair<string, List<MeshFilter>> keyPair in meshByMaterial)
{
//材质一样的mesh 放到一个父物体下
currentMaterialParent = new GameObject(keyPair.Key).transform;
currentMaterialParent.transform.SetParent(newObjsRoot.transform);
CombineMeshes(keyPair.Value);
}
在每次创建新mesh时,先清空之前的数据
private static void ClearMeshAttribute()
{
vertices = new List<Vector3>();
uvs = new List<Vector2>();
normals = new List<Vector3>();
indices = new List<int>();
// addMaxIndics = 0;
tangents = new List<Vector4>();
addMaxIndics = 0;
}
获取每个mesh的顶点在世界坐标下的位置
for (int i = 0; i < newVertices.Length; i++)
{
vertices.Add(meshObj.transform.TransformPoint(newVertices[i]));
}
存储一个GameObject缩放方向的V3,Obj要是有负数的缩放,法线和traingle顺序都需要改。
Vector3 fixV3 = new Vector3(
meshObj.transform.localScale.x < 0 ? -1 : 1,
meshObj.transform.localScale.y < 0 ? -1 : 1,
meshObj.transform.localScale.z < 0 ? -1 : 1
);
存储法线
for (int i = 0; i < newNormals.Length; i++)
{
newNormals[i] = new Vector3(
newNormals[i].x * fixV3.x,
newNormals[i].y * fixV3.y,
newNormals[i].z * fixV3.z
);
}
// local scale 是负数 要反转面
if (fixV3.x * fixV3.y * fixV3.z < 0)
{
for (int i = 0; i < newIndices.Length; i += 3)
{
int change = newIndices[i + 1];
newIndices[i + 1] = newIndices[i + 2];
newIndices[i + 2] = change;
}
}
然后每个mesh的Indices中的每个数要加上之前存储mesh的顶点数。完事之后再把当前mesh的顶点数存下来
for (int i = 0; i < newIndices.Length; i++)
{
int index = newIndices[i] + addMaxIndics;
indices.Add(index);
}
addMaxIndics = vertices.Count;
然后发现,顶点数过多的时候,面会有很奇怪的破损,查了下有人说unitymesh有最大顶点限制65535,所以如果超过这个数字,就新建一个mesh存储。
if (newVertices.Length + vertices.Count >= maxVerticesCount)
{
CreateNewMesh(material);
ClearMeshAttribute();
}
最终CreateNewMesh给mesh赋值,生成
点击Window/combineMeshEditor
场景里出现了
FBX Exporter 导出后,可看出是一个mesh
TODO 用unity 的CombineMeshes来完成以上功能文章来源:https://www.toymoban.com/news/detail-409037.html
项目地址 https://gitee.com/go_x/unity-project.git文章来源地址https://www.toymoban.com/news/detail-409037.html
到了这里,关于在unity中结合FBX Exporter合并mesh并导出Fbx的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!