赞
踩
实现合批的必要条件是只有一个material,因此将多texture对象合并成一张texture是必要的。无论是SkinnedMeshRenderer或是MeshRenderer,其合并材质的原理都是一样的。
其调用到的核心API是Texture2D.PackTextures
- // 合并贴图(从收集的各Material中取)
- List<Texture2D> MainTexs = new List<Texture2D>();
- for (int i = 0; i < materials.Count; i++)
- {
- MainTexs.Add(materials[i].GetTexture("_MainTex") as Texture2D);
- }
-
- //所有贴图合并到newDiffuseTex这张大贴图上
- newMainTex = new Texture2D(COMBINE_TEXTURE_MAX, COMBINE_TEXTURE_MAX, TextureFormat.RGBA32, true);
-
- Rect[] uvs = newMainTex.PackTextures(MainTexs.ToArray(), 0);
-
- newMaterial.SetTexture("_MainTex", newMainTex);
- AssetDatabase.CreateAsset(newMainTex, $"Assets/Resources/CombineTexture.asset");
这里先获取到每个material里用到的材质(手动合并可以自己声明一个texture2d数组,之后在editor模式下拖拽),之后直接声明一张1024*1024的texture,我用到的子tex为512*512,因此1024*1024对我已经足够,可视实际情况进行调整。
调用Texture2D.PackTextures接口生成合并贴图,返回合并后的uv,这里的uv对应的是子texture在合并后的大texture的uv,而不是传统意义上片元的uv。
之后将新的材质直接赋值到新的material,也可以调用AssetDatabase.CreateAsset接口,将合并后的材质保存下来。
PS:这里有个问题是执行:newMaterial.SetTexture("_MainTex", newMainTex)后,理论上新的材质应该是合并后的材质,但实际上材质仍然是合并前的子材质,而调用AssetDatabase.CreateAsset创建出来的材质是正常的,在editor模式下拖拽赋值后,才表现正常。目前作者暂不清楚原因,如果有人知道原因务必在评论区告知我,非常感谢。
- // reset uv
- // 计算好uvb赋值到到combineInstances[j].mesh.uv
- oldUV = new List<Vector2[]>();
- Vector2[] uva, uvb;
- for (int j = 0; j < combineInstances.Count; j++)
- {
- //uva = (Vector2[])(combineInstances[j].mesh.uv);
- uva = combineInstances[j].mesh.uv;
- uvb = new Vector2[uva.Length];
- for (int k = 0; k < uva.Length; k++)
- {
- uvb[k] = new Vector2((uva[k].x * uvs[j].width) + uvs[j].x, (uva[k].y * uvs[j].height) + uvs[j].y);
- }
- //oldUV.Add(combineInstances[j].mesh.uv);
- oldUV.Add(uva);
- combineInstances[j].mesh.uv = uvb;
- }
在合并完材质之后,还需要对uv进行处理,根据合并的偏移对每个uv加上对应的偏移值即可,这里不赘述,只得一提的是,这里还需要保存旧的uv,在合并网格之后,将旧的uv重新赋值回去,以免影响到其他使用到同一个Mesh的对象。
- //重新赋值,以免影响其他对象的Mesh
- for (int i = 0; i < combineInstances.Count; i++)
- {
- combineInstances[i].mesh.uv = oldUV[i];
- }
合并网格依旧是调用Mesh.CombineMeshes ,不同的是,第二个参数我们设置为true,因为我们已经将其合并成一个材质,因此不再需要多material。
render.sharedMesh.CombineMeshes(combineInstances.ToArray(), true, false);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。