zoukankan      html  css  js  c++  java
  • unity 3d 之合并网格和贴图(combine mesh and texture)

      本人是个小白,但是有个做技术的理想。

      关于合并网格和贴图这个问题困扰了我好久,问群友,逛论坛,翻帖子,或者说是我的愚笨吧,不过经过努力还是我解决了,测试通过,一个8drawcall的模型,合并后降到2drawcall,当然现在移动设备的性能都比较高了,不必过多纠结于drawcall,如果没这需要请路过吧。。。

      好的,废话不多说,我把代码贴出来。

      1 using UnityEngine;
      2 using System.Collections;
      3 using System.Collections.Generic;
      4 using System.IO;
      5 
      6 public class CombineMesher : MonoBehaviour
      7 {
      8     // Use this for initialization
      9     void Start()
     10     {
     11         Combine(transform);
     12     }
     13 
     14     // Update is called once per frame
     15     void Update()
     16     {
     17 
     18     }
     19 
     20 
     21     public Transform Combine(Transform root)
     22     {
     23         float startTime = Time.realtimeSinceStartup;
     24 
     25         // The SkinnedMeshRenderers that will make up a character will be
     26         // combined into one SkinnedMeshRenderers using one material.
     27         // This will speed up rendering the resulting character.
     28         // note:each SkinnedMeshRenderer must share a same material
     29         List<CombineInstance> combineInstances = new List<CombineInstance>();
     30         List<Material> materials = new List<Material>();
     31         Material material = null;
     32         List<Transform> bones = new List<Transform>();
     33         Transform[] transforms = root.GetComponentsInChildren<Transform>();
     34         List<Texture2D> textures = new List<Texture2D>();
     35         int width = 0;
     36         int height = 0;
     37 
     38         int uvCount = 0;
     39 
     40         List<Vector2[]> uvList = new List<Vector2[]>();
     41 
     42         foreach (SkinnedMeshRenderer smr in root.GetComponentsInChildren<SkinnedMeshRenderer>())
     43         {
     44             if (material == null)
     45                 material = Instantiate(smr.sharedMaterial) as Material;
     46             for (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++)
     47             {
     48                 CombineInstance ci = new CombineInstance();
     49                 ci.mesh = smr.sharedMesh;
     50                 ci.subMeshIndex = sub;
     51                 combineInstances.Add(ci);
     52             }
     53 
     54             uvList.Add(smr.sharedMesh.uv);
     55             uvCount += smr.sharedMesh.uv.Length;
     56 
     57             if (smr.material.mainTexture != null)
     58             {
     59                 textures.Add(smr.renderer.material.mainTexture as Texture2D);
     60                 width += smr.renderer.material.mainTexture.width;
     61                 height += smr.renderer.material.mainTexture.height;
     62             }
     63 
     64             // we need to recollect references to the bones we are using
     65             foreach (Transform bone in smr.bones)
     66             {
     67                 foreach (Transform transform in transforms)
     68                 {
     69                     if (transform.name != bone.name) continue;
     70                     bones.Add(transform);
     71                     break;
     72                 }
     73             }
     74             Object.Destroy(smr.gameObject);
     75         }
     76 
     77         // Obtain and configure the SkinnedMeshRenderer attached to
     78         // the character base.
     79         SkinnedMeshRenderer r = root.gameObject.GetComponent<SkinnedMeshRenderer>();
     80         if (!r)
     81             r = root.gameObject.AddComponent<SkinnedMeshRenderer>();
     82         
     83         r.sharedMesh = new Mesh();
     84 
     85         //only set mergeSubMeshes true will combine meshs into single submesh
     86         r.sharedMesh.CombineMeshes(combineInstances.ToArray(), true, false);
     87         r.bones = bones.ToArray();
     88         r.material = material;
     89 
     90         Texture2D skinnedMeshAtlas = new Texture2D(1024, 512);
     91         Rect[] packingResult = skinnedMeshAtlas.PackTextures(textures.ToArray(), 0);
     92         Vector2[] atlasUVs = new Vector2[uvCount];
     93 
     94         //as combine textures into single texture,so need recalculate uvs
     95 
     96         int j = 0;        
     97         for (int i = 0; i < uvList.Count; i++)
     98         {
     99             foreach (Vector2 uv in uvList[i])
    100             {
    101                 atlasUVs[j].x = Mathf.Lerp(packingResult[i].xMin, packingResult[i].xMax, uv.x);
    102                 atlasUVs[j].y = Mathf.Lerp(packingResult[i].yMin, packingResult[i].yMax, uv.y);
    103                 j++;
    104             }
    105         }
    106         
    107         r.material.mainTexture = skinnedMeshAtlas;
    108         r.sharedMesh.uv = atlasUVs;
    109 
    110         Debug.Log("combine meshes takes : " + (Time.realtimeSinceStartup - startTime) * 1000 + " ms");
    111         return root;
    112     }
    113 }
  • 相关阅读:
    SpringBoot项目部署与服务配置
    JDBC链接oracle已经mysql的测试
    Jedis工具类
    jsp&Sevelet基础详解
    Mysql和Oracle数据库concat()函数
    如何在maven工程中加载oracle驱动
    获取日期的相关方法
    SpringBoot配置Email发送功能
    spring中schedule注解的使用
    新建一个新的spring boot项目
  • 原文地址:https://www.cnblogs.com/eangulee/p/3877824.html
Copyright © 2011-2022 走看看