unity 3d 之合并网格和贴图(combine mesh and texture)
2014-07-30 13:34
585 查看
本人是个小白,但是有个做技术的理想。
关于合并网格和贴图这个问题困扰了我好久,问群友,逛论坛,翻帖子,或者说是我的愚笨吧,不过经过努力还是我解决了,测试通过,一个8drawcall的模型,合并后降到2drawcall,当然现在移动设备的性能都比较高了,不必过多纠结于drawcall,如果没这需要请路过吧。。。
好的,废话不多说,我把代码贴出来。
关于合并网格和贴图这个问题困扰了我好久,问群友,逛论坛,翻帖子,或者说是我的愚笨吧,不过经过努力还是我解决了,测试通过,一个8drawcall的模型,合并后降到2drawcall,当然现在移动设备的性能都比较高了,不必过多纠结于drawcall,如果没这需要请路过吧。。。
好的,废话不多说,我把代码贴出来。
using UnityEngine; using System.Collections; using System.Collections.Generic; using System.IO; public class CombineMesher : MonoBehaviour { // Use this for initialization void Start() { Combine(transform); } // Update is called once per frame void Update() { } public Transform Combine(Transform root) { float startTime = Time.realtimeSinceStartup; // The SkinnedMeshRenderers that will make up a character will be // combined into one SkinnedMeshRenderers using one material. // This will speed up rendering the resulting character. // note:each SkinnedMeshRenderer must share a same material List<CombineInstance> combineInstances = new List<CombineInstance>(); List<Material> materials = new List<Material>(); Material material = null; List<Transform> bones = new List<Transform>(); Transform[] transforms = root.GetComponentsInChildren<Transform>(); List<Texture2D> textures = new List<Texture2D>(); int width = 0; int height = 0; int uvCount = 0; List<Vector2[]> uvList = new List<Vector2[]>(); foreach (SkinnedMeshRenderer smr in root.GetComponentsInChildren<SkinnedMeshRenderer>()) { if (material == null) material = Instantiate(smr.sharedMaterial) as Material; for (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++) { CombineInstance ci = new CombineInstance(); ci.mesh = smr.sharedMesh; ci.subMeshIndex = sub; combineInstances.Add(ci); } uvList.Add(smr.sharedMesh.uv); uvCount += smr.sharedMesh.uv.Length; if (smr.material.mainTexture != null) { textures.Add(smr.renderer.material.mainTexture as Texture2D); width += smr.renderer.material.mainTexture.width; height += smr.renderer.material.mainTexture.height; } // we need to recollect references to the bones we are using foreach (Transform bone in smr.bones) { foreach (Transform transform in transforms) { if (transform.name != bone.name) continue; bones.Add(transform); break; } } Object.Destroy(smr.gameObject); } // Obtain and configure the SkinnedMeshRenderer attached to // the character base. SkinnedMeshRenderer r = root.gameObject.GetComponent<SkinnedMeshRenderer>(); if (!r) r = root.gameObject.AddComponent<SkinnedMeshRenderer>(); r.sharedMesh = new Mesh(); //only set mergeSubMeshes true will combine meshs into single submesh r.sharedMesh.CombineMeshes(combineInstances.ToArray(), true, false); r.bones = bones.ToArray(); r.material = material; Texture2D skinnedMeshAtlas = new Texture2D(1024, 512); Rect[] packingResult = skinnedMeshAtlas.PackTextures(textures.ToArray(), 0); Vector2[] atlasUVs = new Vector2[uvCount]; //as combine textures into single texture,so need recalculate uvs int j = 0; for (int i = 0; i < uvList.Count; i++) { foreach (Vector2 uv in uvList[i]) { atlasUVs[j].x = Mathf.Lerp(packingResult[i].xMin, packingResult[i].xMax, uv.x); atlasUVs[j].y = Mathf.Lerp(packingResult[i].yMin, packingResult[i].yMax, uv.y); j++; } } r.material.mainTexture = skinnedMeshAtlas; r.sharedMesh.uv = atlasUVs; Debug.Log("combine meshes takes : " + (Time.realtimeSinceStartup - startTime) * 1000 + " ms"); return root; } }
相关文章推荐
- Unity教程之-合并(Combine)引用相同材质球的网格(Mesh)
- Mesh.CombineMeshes 合并网格
- Unity Edior下合并场景 合并网格 合并贴图
- Unity MeshBaker 合并网格和材质
- Unity合并网格和贴图
- Unity MeshBaker 合并网格和材质
- [我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之网格渲染器和过滤器Mesh renderers and filters
- Unity MeshBaker 合并网格和材质
- Unity Shaders and Effects Cookbook (2-4) 压缩和混合纹理贴图:使用灰度图存储插值信息
- Unity 3D 创建Mesh(一)
- Unity 3D mesh制作地形工具
- 【Unity】Mesh网格编程(一)正二十面体
- Unity 网格合并
- Unity Android平台下针对Alpha分离的优化---三张Alpha贴图合并为一张
- Unity 网格合并
- Unity中的网格与材质球合并
- Texture Coordinates and Visuals on 3D surfaces 纹理坐标
- 【Unity】Mesh网格编程(二)流体
- Unity Shaders and Effects Cookbook (1-4) 创建 Ramp Texture(渐变纹理)控制漫反射着色
- Unity换装之合并网格