Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by _lud_ · Apr 11, 2019 at 07:49 AM · meshexportcombinecombinemeshes

Combine meshes result in a larger file size on export (GLTF)

Hi guys, I have a script to combine meshes which share the same material. The obvious goal is to reduce the draw calls count and it works perfectly (from 500 draw calls to about 70).

I need to export the scene in GLTF compressed format (.glb) to use it on web, I am using this open source project by KhronosGroup.

I've noticed that after the combine operation, my exported file has a larger file size: from 2 MB (not combined) to about 5.8 MB (combined). I don't understand the reason , since materials and textures should be the same. Does anyone know why is this happening?

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Apr 11, 2019 at 12:39 PM 0
Share

How "large" are those meshes? $$anonymous$$eep in $$anonymous$$d that Unity by default uses a 16 bit index buffer which limits a single mesh to 65k vertices. However for quite some time now Unity supports 32 bit index buffers. Of course they require twice the space.


I've never used the glTF format. However it seems that usually vertex and index data is stored binary. So it's reasonable that if you combine meshes that the index buffer format might need to change and results in a twice as large index buffer. However since the index buffer usually is only a tiny fraction of the total size this shouldn't have such a large impact.


From what i've seen the "glb" format is a very simple "archive" / concatenation of the involved files with a small 8 byte header (4 byte integer for the file size and a 4 byte type string). So since the major contributing files (usually textures) shouldn't change, the size shouldn't grow that heavily.


I have a script to combine meshes

This is probably the main cause of the issue. $$anonymous$$aybe this script destroys the shared references and somehow each combined mesh now has it's own set of textures. We can't really tell without more information on how you do that "combining".

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by _lud_ · Apr 11, 2019 at 01:04 PM

Hi @Bunny83 , thanks for the answer. The script to combine meshes is almost the same as the one provided by Bunzaga on this thread:

  using UnityEngine;
  using System.Collections;
  
  public class MeshCombiner : MonoBehaviour
  {
      public void Awake()
      {
          ArrayList materials = new ArrayList();
          ArrayList combineInstanceArrays = new ArrayList();
          MeshFilter[] meshFilters = gameObject.GetComponentsInChildren<MeshFilter>();
  
          foreach (MeshFilter meshFilter in meshFilters)
          {
              MeshRenderer meshRenderer = meshFilter.GetComponent<MeshRenderer>();
  
              if (!meshRenderer ||
                  !meshFilter.sharedMesh ||
                  meshRenderer.sharedMaterials.Length != meshFilter.sharedMesh.subMeshCount)
              {
                  continue;
              }
  
              for (int s = 0; s < meshFilter.sharedMesh.subMeshCount; s++)
              {
                  int materialArrayIndex = Contains(materials, meshRenderer.sharedMaterials[s].name);
                  if (materialArrayIndex == -1)
                  {
                      materials.Add(meshRenderer.sharedMaterials[s]);
                      materialArrayIndex = materials.Count - 1;
                  }
                  combineInstanceArrays.Add(new ArrayList());
  
                  CombineInstance combineInstance = new CombineInstance();
                  combineInstance.transform = meshRenderer.transform.localToWorldMatrix;
                  combineInstance.subMeshIndex = s;
                  combineInstance.mesh = meshFilter.sharedMesh;
                  (combineInstanceArrays[materialArrayIndex] as ArrayList).Add(combineInstance);
              }
          }
  
          // Get / Create mesh filter & renderer
          MeshFilter meshFilterCombine = gameObject.GetComponent<MeshFilter>();
          if (meshFilterCombine == null)
          {
              meshFilterCombine = gameObject.AddComponent<MeshFilter>();
          }
          MeshRenderer meshRendererCombine = gameObject.GetComponent<MeshRenderer>();
          if (meshRendererCombine == null)
          {
              meshRendererCombine = gameObject.AddComponent<MeshRenderer>();
          }
  
          // Combine by material index into per-material meshes
          // also, Create CombineInstance array for next step
          Mesh[] meshes = new Mesh[materials.Count];
          CombineInstance[] combineInstances = new CombineInstance[materials.Count];
  
          for (int m = 0; m < materials.Count; m++)
          {
              CombineInstance[] combineInstanceArray = (combineInstanceArrays[m] as ArrayList).ToArray(typeof(CombineInstance)) as CombineInstance[];
              meshes[m] = new Mesh();
              meshes[m].CombineMeshes(combineInstanceArray, true, true);
  
              combineInstances[m] = new CombineInstance();
              combineInstances[m].mesh = meshes[m];
              combineInstances[m].subMeshIndex = 0;
          }
  
          // Combine into one
          meshFilterCombine.sharedMesh = new Mesh();
          meshFilterCombine.sharedMesh.CombineMeshes(combineInstances, false, false);
  
          // Destroy other meshes
          foreach (Mesh oldMesh in meshes)
          {
              oldMesh.Clear();
              DestroyImmediate(oldMesh);
          }
  
          // Assign materials
          Material[] materialsArray = materials.ToArray(typeof(Material)) as Material[];
          meshRendererCombine.materials = materialsArray;
  
          foreach (MeshFilter meshFilter in meshFilters)
          {
              DestroyImmediate(meshFilter.gameObject);
          }
      }
  
      private int Contains(ArrayList searchList, string searchName)
      {
          for (int i = 0; i < searchList.Count; i++)
          {
              if (((Material)searchList[i]).name == searchName)
              {
                  return i;
              }
          }
          return -1;
      }
  }



I've also tried this payed solution from the Asset Store for combine meshes, with the same result on the export.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

115 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

CombineMeshes Error on Run-time Meshes 2 Answers

skinned mesh renderer, combine meshes can't see the result, what am I doing wrong/ missing? 0 Answers

How to combine multiple new meshes without instantiating? 1 Answer

How to merge generated meshes 0 Answers

CombineMeshes() Not Working Properly? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges