Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 Exalia · Jan 20, 2014 at 04:54 PM · androidlightmapocclusionmesh manipulationcombinechildren

Combine Mesh, Occlusion Cull, Lightmapping All In One

Hi there,

I'm constantly trying to optimise my project and in doing so I've been looking into Combining Meshes, Occlusion Culling and Light mapping. All work very well on their own, however when it comes to Combining Meshes and Lightmapping I run into issues as the mesh combining seems to generate bad UVs afterwards.

Has anyone had experience with this? I've looked into some old answers on here but there doesn't seem to be a real solution so far.

Thanks in advance for your help

More Info :

I have a scene made of several objects, I combine the meshes in the editor and bake in the occlusion culling. However when I try to bake lightmaps into these newly created meshes the lightmaps are incorrect. I'm guessing this has something to do with the UVs of the new mesh.

Well I followed up on that and generated new UVs for the new meshes using

Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh);

but the results were still incorrect :(

here's the code

 using UnityEngine;
 using System.Collections;
 #if UNITY_EDITOR 
 using UnityEditor;
 #endif
 
 /*
 Attach this script as a parent to some game objects. The script will then combine the meshes at startup.
 This is useful as a performance optimization since it is faster to render one big mesh than many small meshes. See the docs on graphics performance optimization for more info.
 
 Different materials will cause multiple meshes to be created, thus it is useful to share as many textures/material as you can.
 */
 [ExecuteInEditMode()]
 [AddComponentMenu("Mesh/Combine Children")]
 public class CombineChildren : MonoBehaviour {
     
     /// Usually rendering with triangle strips is faster.
     /// However when combining objects with very low triangle counts, it can be faster to use triangles.
     /// Best is to try out which value is faster in practice.
     public int frameToWait = 0;
     public bool generateTriangleStrips = true, combineOnStart = true, destroyAfterOptimized = false, castShadow = true, receiveShadow = true, keepLayer = true, addMeshCollider = false;
     
     void Start()
     {
         if (combineOnStart && frameToWait == 0) Combine();
         else StartCoroutine(CombineLate());
     }
     
     IEnumerator CombineLate()
     {
         for (int i = 0; i < frameToWait; i++ ) yield return 0;
         Combine();
     }
     
     [ContextMenu("Combine Now on Childs")]
     public void CallCombineOnAllChilds()
     {
         CombineChildren[] c = gameObject.GetComponentsInChildren<CombineChildren>();
         int count = c.Length;
         for (int i = 0; i < count; i++) if(c[i] != this)c[i].Combine();
         combineOnStart = enabled = false;
     }
     
     /// This option has a far longer preprocessing time at startup but leads to better runtime performance.
     [ContextMenu ("Combine Now")]
     public void Combine () {
         Component[] filters  = GetComponentsInChildren(typeof(MeshFilter));
         Matrix4x4 myTransform = transform.worldToLocalMatrix;
         Hashtable materialToMesh= new Hashtable();
         
         for (int i=0;i<filters.Length;i++) {
             MeshFilter filter = (MeshFilter)filters[i];
             Renderer curRenderer  = filters[i].renderer;
             MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance ();
             instance.mesh = filter.sharedMesh;
             if (curRenderer != null && curRenderer.enabled && instance.mesh != null) {
                 instance.transform = myTransform * filter.transform.localToWorldMatrix;
                 
                 Material[] materials = curRenderer.sharedMaterials;
                 for (int m=0;m<materials.Length;m++) {
                     instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1);
                     
                     ArrayList objects = (ArrayList)materialToMesh[materials[m]];
                     if (objects != null) {
                         objects.Add(instance);
                     }
                     else
                     {
                         objects = new ArrayList ();
                         objects.Add(instance);
                         materialToMesh.Add(materials[m], objects);
                     }
                 }
                 if (Application.isPlaying && destroyAfterOptimized && combineOnStart) Destroy(curRenderer.gameObject);
                 else if (destroyAfterOptimized) DestroyImmediate(curRenderer.gameObject);
                 else curRenderer.enabled = false;
             }
         }
         
         foreach (DictionaryEntry de  in materialToMesh) {
             ArrayList elements = (ArrayList)de.Value;
             MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance));
             
             // We have a maximum of one material, so just attach the mesh to our own game object
             if (materialToMesh.Count == 1)
             {
                 // Make sure we have a mesh filter & renderer
                 if (GetComponent(typeof(MeshFilter)) == null)
                     gameObject.AddComponent(typeof(MeshFilter));
                 if (!GetComponent("MeshRenderer"))
                     gameObject.AddComponent("MeshRenderer");
                 
                 MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter));
                 if (Application.isPlaying) filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips);
                 else filter.sharedMesh = MeshCombineUtility.Combine(instances, generateTriangleStrips);
                 renderer.material = (Material)de.Key;
                 renderer.enabled = true;
                 if (addMeshCollider) gameObject.AddComponent<MeshCollider>();
                 renderer.castShadows = castShadow;
                 renderer.receiveShadows = receiveShadow;
 
                 #if UNITY_EDITOR
                 //Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh);
                 //Unwrapping.GeneratePerTriangleUV(filter.sharedMesh);
                 Vector2[] uvs = new Vector2[mesh.vertices.Length];
                 int i = 0;
                 while (i < uvs.Length) 
                 {
                     uvs[i] = new Vector2(vertices[i].x, vertices[i].z);
                     i++;
                 }
                 mesh.uv = uvs;
                 #endif
             }
             // We have multiple materials to take care of, build one mesh / gameobject for each material
             // and parent it to this object
             else
             {
                 GameObject go = new GameObject("Combined mesh");
                 if (keepLayer) go.layer = gameObject.layer;
                 go.transform.parent = transform;
                 go.transform.localScale = Vector3.one;
                 go.transform.localRotation = Quaternion.identity;
                 go.transform.localPosition = Vector3.zero;
                 go.AddComponent(typeof(MeshFilter));
                 go.AddComponent("MeshRenderer");
                 go.renderer.material = (Material)de.Key;
                 MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter));
                 if(Application.isPlaying)filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips);
                 else filter.sharedMesh = MeshCombineUtility.Combine(instances, generateTriangleStrips);                    
                 go.renderer.castShadows = castShadow;
                 go.renderer.receiveShadows = receiveShadow;
                 if (addMeshCollider) go.AddComponent<MeshCollider>();
                 #if UNITY_EDITOR
                 //Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh);
                 //Unwrapping.GeneratePerTriangleUV(filter.sharedMesh);
                 Vector2[] uvs = new Vector2[mesh.vertices.Length];
                 int i = 0;
                 while (i < uvs.Length) 
                 {
                     uvs[i] = new Vector2(vertices[i].x, vertices[i].z);
                     i++;
                 }
                 mesh.uv = uvs;
                 #endif
             }
         }    
     }    
 }
Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by James900 · Jan 21, 2014 at 07:25 AM

After you've generated the mesh, try this:

  Vector2[] uvs = new Vector2[mesh.vertices.Length];
         int i = 0;
         while (i < uvs.Length) 
         {
             uvs[i] = new Vector2(vertices[i].x, vertices[i].z);
             i++;
         }
         mesh.uv = uvs;
Comment
Add comment · Show 2 · 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
avatar image Exalia · Jan 21, 2014 at 07:37 AM 0
Share

I'll try this in a bit when I get to work :) Thanks

avatar image Exalia · Jan 21, 2014 at 09:06 AM 0
Share

Thanks for the help but this doesn't work either :(

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

19 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

Related Questions

Lightmap Android Problem 1 Answer

Why Is my baked lightmap looking so weired?? 0 Answers

Android game does not work when lightmap included (black screen instead) 0 Answers

How to crank up beast ambient occlusion quality? 0 Answers

[AR Foundation][URP] AR Occlusion Soft Edges, iOS & Android 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