Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

Mesh Baker by Digital Opus [RELEASED]

Discussion in 'Assets and Asset Store' started by Phong, Nov 20, 2012.

  1. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,081
    Question.

    So lets say I have a mesh with like 100 different materials on it, as in 100 different submeshes.

    Can this take all those different materials, and their textures, and atlas all those textures, and make a mesh with no submeshes and one material with all the uv's of the resulting mesh aligned to match the atlas?

    Also about the lightmapping feature. Lets say in an external program I have a scene with like 500 objects, and I bake that scene so that each object then ends up with it's own lightmap, so 500 different lightmaps. Is there someway I could then import that scene, hook up those lightmaps. Then use this to combine all the diffuse textures into an atlas, and also all the lightmaps into an atlas, resulting in 1 mesh?
     
  2. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,081
    NM about that first question, I bought your asset and yes it can combine multiple submeshes into one and atlas them. Still curious about the lightmap question though.

    However this has brought another issue to mind, is there anyway to force the atlas to be square? As in 1024x1024, the atlas it makes is 1024x512 which can't be compressed to pvr.
     
  3. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    The only limit will be the size of the atlas. If all those textures fit into the maximum atlas size for your target platform then MeshBaker can do it.

    I don't think so. Does unity support importing lightmaps? Also objects must share the same lightmap in order to bake the meshes together and preserve existing lightmapping.
     
  4. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Interesting question. I think the only way to do it would be to add more textures (objects to be combined) until the TexturePacker is forced to bump the 512 up to the next size.
     
  5. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,081
    If you were in the mood to do additional features, something that I think would be a step up is to do away with packTextures and use a open sourced texture packing alghorithm. There is one here: http://wiki.unity3d.com/index.php?title=MaxRectsBinPack Although I think there might be better ones floating around the net.

    Also what would be the awesome is if you could somehow import sprite sheets from texturepacker http://www.codeandweb.com/texturepacker
    And then run a function that does something like "If texture exists in imported sheet from texturepacker, then combine mesh, and use texture in the sprite sheet".

    Awesome work though, this is definantely a new core step in my pipeline.

    Just in case anyone is wondering, I stress tested the submesh thing... it can combine like like 100 different submeshes with 512x512 textures int one, and interestingly RAM usage did not rise too much on the unity editor.
     
    Last edited: Mar 31, 2013
  6. Rajmahal

    Rajmahal

    Joined:
    Apr 20, 2011
    Posts:
    2,051
    Hi, just bought it and started playing around with it. However, I'm running into some problems and would appreciate some guidance.

    I have a scene where I'm using Killstar's medieval scenery pack. I'm trying to combine all of the rocks in that scene into a combined mesh. This is similar to the example video where you combine all the tree prefab and platform prefabs into two combined meshes. All of the rocks use the shader "Enviro/BumpedDiffuseOverlaySM2". I confirmed this through visual inspection and the "List Shaders in Scene" function.

    However, when I press the "Bake Materials into Combined Material", I get warnings in the console that say that the rocks do not use the afore mentiond shader and I also get some warnings that say certain textures will be baked into a texture with a maxSize: 1024. Here are the console outputs for two such examples:

    Game object Rock1E (UnityEngine.GameObject) does not use shader Enviro/BumpedDiffuseOverlaySM2 (UnityEngine.Shader) it may not have the required textures. If not empty textures will be generated.
    UnityEngine.Debug:LogWarning(Object)
    MB2_TextureBaker:CreateAtlases(ProgressUpdateDelegate) (at Assets/MeshBaker/scripts/MB2_TextureBaker.cs:79)
    MB2_TextureBakerEditorInternal:_bakeTexturesOnly(MB2_TextureBaker) (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:204)
    MB2_TextureBakerEditorInternal:bake(MB2_TextureBaker) (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:180)
    MB2_TextureBakerEditorInternal:DrawGUI(MB2_TextureBaker) (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:167)
    MB2_TextureBakerEditor:OnInspectorGUI() (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:21)
    UnityEditor.DockArea:OnGUI()


    Texture Rockdetail2 (UnityEngine.Texture2D)is tiled by (8.0, 8.0) tiling will be baked into a texture with maxSize:1024
    UnityEngine.Debug:LogWarning(Object)
    MB_TextureCombiner:__combineTexturesIntoAtlases(ProgressUpdateDelegate, MB_AtlasesAndRects, List`1, List`1, List`1, Int32, Boolean, Boolean, Int32) (at Assets/MeshBaker/scripts/MB_TextureCombiner.cs:337)
    MB_TextureCombiner:_combineTexturesIntoAtlases(ProgressUpdateDelegate, MB_AtlasesAndRects, Material[], List`1, List`1, Int32, List`1, Boolean, Boolean, Int32) (at Assets/MeshBaker/scripts/MB_TextureCombiner.cs:191)
    MB_TextureCombiner:combineTexturesIntoAtlases(ProgressUpdateDelegate, MB_AtlasesAndRects, Material[], List`1, List`1, Int32, List`1, Boolean, Boolean, Int32) (at Assets/MeshBaker/scripts/MB_TextureCombiner.cs:105)
    MB2_TextureBaker:CreateAtlases(ProgressUpdateDelegate) (at Assets/MeshBaker/scripts/MB2_TextureBaker.cs:104)
    MB2_TextureBakerEditorInternal:_bakeTexturesOnly(MB2_TextureBaker) (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:204)
    MB2_TextureBakerEditorInternal:bake(MB2_TextureBaker) (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:180)
    MB2_TextureBakerEditorInternal:DrawGUI(MB2_TextureBaker) (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:167)
    MB2_TextureBakerEditor:OnInspectorGUI() (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:21)
    UnityEditor.DockArea:OnGUI()


    The result is that the combined material does not have textures for two of the shader's 4 textures. Specifically, the "Color under (RGBA)" and "Normalmap Under" are blank. This results in the creation of a combined mesh that doesn't have the right textures and is completely white.

    Can you let me what I'm doing wrong or does Meshbaker not work with this particular shader?
     
  7. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Interesting. I did look into writing my own texture packer at one point. It would be nice to offer the user a choice of texture packers.
    Another user has requested being able to import atlases. Will consider adding this in the future.
     
  8. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Check the shader on the Combined Mesh Material and the shader on the rock in the warning above. The only way you could get this warning is if they are different.
    This is to let you know that the tiling is being baked, and that quality may be lost if the baking exceeds 1024.
    Mesh Baker contains a list of texture property names that it look for in the Combined Mesh Material shader: "_MainTex", "_BumpMap", "_BumpSpecMap", "_DecalTex", "_Detail", "_GlossMap", "_Illum", "_LightTextureB0", "_ParallaxMap","_ShadowOffset", "_TranslucencyMap", "_SpecMap", "_TranspMap". It creates an atlas for each one that it finds. It sounds like your shader has some texture properties that are not on this list. You will need to open the shader and look at its properties (look for 2D properties) and add the missing ones to the "Custom Shader Property Names". Mesh Baker will then create atlases for these.
     
    Last edited: Mar 31, 2013
  9. Rajmahal

    Rajmahal

    Joined:
    Apr 20, 2011
    Posts:
    2,051
    I'm not sure what's going on. I've checked and the Rocks and the Combined Mesh Material are using the same shader. I can provide a screenshot if you like.

    I tried this but it didn't work. I ended up having the same result where the combined mesh shader didn't have textures for the _MainTex2 and _BumpMap2 properties in the rock's shader. Just to confirm that what I did was that I looked at the code for the Shader and I took the Properties names for the two textures that were not created (_MainTex2 and _BumpMap2) and added those names to the "Custom Shader Property Names" boxes by first setting the value to 2.

    I ran it again and I came across the following error in the console log:

    UnityEngine.MissingReferenceException: The object of type 'Texture2D' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    at (wrapper managed-to-native) UnityEngine.Texture:Internal_GetWidth (UnityEngine.Texture)
    at UnityEngine.Texture.get_width () [0x00000] in C:\BuildAgent\work\7535de4ca26c26ac\Runtime\ExportGenerated\Editor\Graphics.cs:682
    at MB_TextureCombiner.__combineTexturesIntoAtlases (.ProgressUpdateDelegate progressInfo, .MB_AtlasesAndRects results, System.Collections.Generic.List`1 texPropertyNames, System.Collections.Generic.List`1 objsToMesh, System.Collections.Generic.List`1 sourceMaterials, Int32 atlasPadding, Boolean resizePowerOfTwoTextures, Boolean fixOutOfBoundsUVs, Int32 maxTilingBakeSize) [0x0091f] in C:\Users\Raj\SkyDrive\Private\Wizards Duel\Assets\MeshBaker\scripts\MB_TextureCombiner.cs:408
    at MB_TextureCombiner._combineTexturesIntoAtlases (.ProgressUpdateDelegate progressInfo, .MB_AtlasesAndRects results, UnityEngine.Material[] resultMaterials, System.Collections.Generic.List`1 objsToMesh, System.Collections.Generic.List`1 sourceMaterials, Int32 atlasPadding, System.Collections.Generic.List`1 customShaderPropNames, Boolean resizePowerOfTwoTextures, Boolean fixOutOfBoundsUVs, Int32 maxTilingBakeSize) [0x000b7] in C:\Users\Raj\SkyDrive\Private\Wizards Duel\Assets\MeshBaker\scripts\MB_TextureCombiner.cs:191
    at MB_TextureCombiner.combineTexturesIntoAtlases (.ProgressUpdateDelegate progressInfo, .MB_AtlasesAndRects results, UnityEngine.Material[] resultMaterials, System.Collections.Generic.List`1 objsToMesh, System.Collections.Generic.List`1 sourceMaterials, Int32 atlasPadding, System.Collections.Generic.List`1 customShaderPropNames, Boolean resizePowerOfTwoTextures, Boolean fixOutOfBoundsUVs, Int32 maxTilingBakeSize) [0x00002] in C:\Users\Raj\SkyDrive\Private\Wizards Duel\Assets\MeshBaker\scripts\MB_TextureCombiner.cs:105
    UnityEngine.Debug:LogError(Object)
    MB_TextureCombiner:combineTexturesIntoAtlases(ProgressUpdateDelegate, MB_AtlasesAndRects, Material[], List`1, List`1, Int32, List`1, Boolean, Boolean, Int32) (at Assets/MeshBaker/scripts/MB_TextureCombiner.cs:107)
    MB2_TextureBaker:CreateAtlases(ProgressUpdateDelegate) (at Assets/MeshBaker/scripts/MB2_TextureBaker.cs:104)
    MB2_TextureBakerEditorInternal:_bakeTexturesOnly(MB2_TextureBaker) (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:204)
    MB2_TextureBakerEditorInternal:bake(MB2_TextureBaker) (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:180)
    MB2_TextureBakerEditorInternal:DrawGUI(MB2_TextureBaker) (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:167)
    MB2_TextureBakerEditor:OnInspectorGUI() (at Assets/MeshBaker/scripts/Editor/MB2_TextureBakerEditor.cs:21)
    UnityEditor.DockArea:OnGUI()

    I didn't get this the first time. Do you know why this happens?
     
  10. Rajmahal

    Rajmahal

    Joined:
    Apr 20, 2011
    Posts:
    2,051
    Hi Phong, can you let me know your thoughts on the error above? I've tried many different options but this error keeps popping up.

    thanks,
     
  11. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    This error showed up for the first time last week and appears to be limited to 4.1 and 4.1 (possibly 4.0). I have been struggling with that error all weekend. I think it is caused by a bug with garbage collection in the Unity 4 Editor that sometimes destroys all Texture2D instances in the scene when operations are performed on the Asset Database. It is intermittent and it only appears to happen in Unity 4 and so far I have only seen it in 4.1 and 4.2.

    I did make some progress re-organizing the code this weekend so that it is much more defensive about how temporary textures are used. That eliminated the error in all cases where I was able to reproduce it. This new code has been submitted to the asset store, I will let you know as soon as it is live (probably 1-2 days). Unfortunately I can't guarantee that the error is gone because it was intermittent.

    Sorry for the inconvenience. Please let me know if you continue getting this error when the new version is available.

    Regarding the error about the shader being different on one of your rocks. Try replacing the line 80 of file MB_TextureBaker with this:

    Code (csharp):
    1.  
    2. Debug.LogWarning("Game object " + objsToMesh[i] + " does not use shader " + targShader + " it uses " + m.shader + " it may not have the required textures. If not empty textures will be generated.");
    3.  
    It won't fix the warning but it will tell you what shader it is finding in addition to what shader it is looking for. Please let me know if they are the same.

    Again, sorry for the inconvenience about the MissingReference problem. Up until last week Mesh Baker was very, very reliable. Hope to get it back to that state soon.
     
    Last edited: Apr 2, 2013
  12. Rajmahal

    Rajmahal

    Joined:
    Apr 20, 2011
    Posts:
    2,051
    Thanks Phong ... that's really helpful. I'll try the suggestion about the warning message but will otherwise focus on some other areas until the update arrives.
     
  13. RedVonix

    RedVonix

    Joined:
    Dec 13, 2011
    Posts:
    356
    *Edit: And like absolute magic - it's working now. Never fails - if something is acting weird, go and complain to someone, and it works instantly. Thank you magic chaos angels! And Phong. :)

    Pretty close to having a full implementation of Mesh Baker in a game. Saving hundreds of draw calls! Receiving a bit of an odd issues now though... I'm not even really sure what info to share to help with this. I have a scene where all skinned enemies are baked into a combined mesh. The mesh displays just fine in the Scene View, however in the Game View, it doesn't render. It will render if I hand-adjust any setting on the combined mesh object (like turn off shadows). Making the same adjustments in code have no effect.

    Any thoughts on what could cause such an issue?
     
  14. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Hmmm. It might be related to the render bounds of the skinned mesh renderer. I would try to get the bounds and render it in OnGizmos to see if it is in the camera's fustrum. .Also see what the "updateWhenOffscreen" setting is set to. Could it be a layer issue? Is the camera configured to only render certain layers?
     
  15. sicga123

    sicga123

    Joined:
    Jan 26, 2011
    Posts:
    780
    HI Phong

    Just a quick question basically to get it sorted in my head. If I combine a lot of meshes all with the same shader, if textures combined are greater than 4096 by 4096 - say there are 10 2048 by 2048 textures, does mesh baker create multiple atlases or do I need to create 2 mesh baker objects with a different atlas each?
     
  16. Rajmahal

    Rajmahal

    Joined:
    Apr 20, 2011
    Posts:
    2,051
    Hi Phong,

    I tried the latest update and it doesn't seem to have changed much. I'm still getting the same error. I did get it to successfully work on some of the objects but only when the objects are already using the same material. As soon as I try to bake two meshes that are using different materials, I get the error about the Texture being destroyed. Hope that's helpful.
     
  17. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    The texture packer will shrink the textures as they are being added. If you don't want your textures resized then you will need to create two mesh baker objects.
     
  18. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Thanks for the heads up. I worked on this all weekend and uploaded another version which fixed the missing reference problem in all the tests I tried. It is still pending review. Will post hear as soon as it is up. I was able to bake the Hard Surfaces shader with this version so I think that hard surfaces shader is probably O.K. I was able to generate the error in the AngryBots scene which should definitely have valid shaders. I am pretty sure this is a bug with the Unity garbage collection. It seems to be collecting objects that are still in use. I submitted a bug report to Unity about the problem.
     
  19. sicga123

    sicga123

    Joined:
    Jan 26, 2011
    Posts:
    780
    Hi Phong
    So is it possible to use 4.1.2 with the hardsurface shaders and Mesh Baker or would it be wiser just to stay with 4.01?
     
  20. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    I was able to get it bake without errors with the version of MeshBaker still pending review in the asset store. However you might want to install 4.1 in a separate folder and do a test bake before trying to migrate your whole project. Because this is an intermittent bug I can't guarantee that it has been fixed. Out of curiosity are you currently using 4.0 and not getting the missing reference errors?
     
  21. sicga123

    sicga123

    Joined:
    Jan 26, 2011
    Posts:
    780
    Hi Phong
    I haven't tried to bake anything with 4.01 after these problemsbecuase for various reasons the optimisation has been put off until next week.
     
  22. tinman

    tinman

    Joined:
    Jan 8, 2011
    Posts:
    229
    Hi there,

    I have a soldier character which is made of several skinned meshes, (boots, pants, shirt etc) each with their own material. I have it that was so the player can customize him. However, once customized, I'd like to combine all these (at runtime) in order to improve performance once the player starts playing.
    How would I go about doing this? Is this possible with your tool?
    Thank you!
     
  23. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Yes, this is pretty much exactly what the tool is designed to do. Your situation is very similar to the Combining Skinned Meshes example video. That example is included in the asset and the sript bakes those meshs at runtime. The baking is split into two separate tasks:

    • Baking of atlases and creation of a combined material
    • Combining the meshes

    If possible I would recommend baking the materials into a combined material in the editor. This takes a long time and doing it at runtime has limitations such as none of the textures can be compressed. Baking meshes is very fast and efficient. If meshes are reasonably small you can combine on every frame.
     
  24. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,081
    So I have discovered that if I start trying to pack more textures into an atlas than can fit, it will begin to crop the textures. This is really unideal behavior for me. It would be much better if instead of cropping textures to make them fit, it instead scaled the whole texture down.

    Is there some option to do that already or am I doing something wrong, or encountering odd behavior?
     
  25. tinman

    tinman

    Joined:
    Jan 8, 2011
    Posts:
    229
    Thank you Phong. I have a couple more questions:
    Will the performance improvement be minimal if I keep the different materials? (My platform is WebPlayer).
    Also, I know this has nothing to do directly with your tool but maybe you came across it - I want to use the "Cruncher" tool to reduce the number of polys of the mesh (I have tried it and it works). Do you have experience with your tool running with the "Cruncher" tool together? I believe the "Cruncher" I need to use in the Editor.

    Thank you!

    Edit: (BTW I noticed that I didn't mention that my character is animated with bones, I assume your replies would still be the same?)
     
    Last edited: Apr 4, 2013
  26. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    I don't think your doing anything wrong. MeshBaker uses the built Texture3D.PackTextures to build the atlases. The documentation says:

    The resulting texture atlas will be as large as needed to fit all input textures but only up to maximumAtlasSize in each dimension. If the input textures can't all fit into a texture atlas of the desired size then they will be scaled down to fit.

    Not sure if I can do much about this one other than writing my own texture packer. On the todo list but is a ways off.
     
  27. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    I think it will be minimal. The expensive thing in Unity is making a drawcall and if you keep all the materials separate then you will have a separate drawcall for each material.
    Bones and animations are no problem. The new mesh uses the old bones with their animations.

    Cruncher should not be a problem. You will want to use it first, then use MeshBaker to combine the result.
     
  28. tinman

    tinman

    Joined:
    Jan 8, 2011
    Posts:
    229
    Thanks very much Phong. I purchased it today :)
     
  29. tabor

    tabor

    Joined:
    Nov 29, 2011
    Posts:
    42
    Hey Phong, I wanted to get your input on the best way to optimize my scene.

    A room with many object, lights, materials. Everything lightmapped just how I like. Most objects have 3 LOD's.

    Let's say I have a group a 5 high poly apples close to the camera and the same 5 apples far from the camera. So I am seeing both the LOD0 and LOD2 at the same time.

    I assume I could not mesh bake them all together first then create LODs because then the far apple group would show LOD0 as well. Correct?

    So should I bake each group of apples separately and then create LOD's? And then bake their materials together?

    Or would I be better off combining as many meshes as possible and forgetting LODs?

    And finally, if I had 3 objects each lit with a pixel light and combined them it would be one object with 3 pixel lights. And thoughts on which is better performance wise?

    Thanks!
     
  30. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Correct.
    This would probably be a good way to do it. However I would recommend experimenting.
    If you are using LOD then you have Unity Pro. I would think that static batching should work well in this case.
    MeshBaker also has a "bake mesh assets in place" feature which will help static and dynamic batching by making more of your meshes batchable with each other. You should be able to "bakeAssetsInPlace" all three LODs together so they can all share the same material. Then static/dynamic batching should be able to combine whatever is visible.
    I think the previous option would work better but it is worth an experiment.
    I think you would see almost the same performance with three objects vs one objects but it is worth a test. If each light can hit all three objects then you would have 9 drawcalls vs 3 drawcalls which would be much slower.

    Honestly in my experience you need to experiment. There are so many variables lights, shaders, render path, shadow projectors, static/dynamic batching, occlusion culling, UV1 channel on a mesh seems to generate an extra drawcall. I would suggest:

    • Get rid of as many lights as possible
    • Combine meshes that are close together
    • Use the 'bake mesh assets in place' so that as many objects as possible use the same material. Then static and dynamic batching can really help.
    • Use occlusion culling if there will be occluded parts of your scene
     
  31. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    This is an important upgrade for 4.1.0 and 4.1.2 users.

    It fixes the "MissingReferenceException" problem in all cases where I was able to reproduce it. If anyone gets the "MissingReferenceException" with version 2.5.3 please let me know.

    Note that there is a minor API change to the MB_TextureCombiner and MB2_TextureBaker components. The old code saved the texture atlases after all the texture combining was done. The new code saves the atlases as soon as they are created.

    This also fixes a bug setting the format of textures if a platform override is present.
     
  32. tabor

    tabor

    Joined:
    Nov 29, 2011
    Posts:
    42
    Thanks for your detailed answer
     
  33. anwserman

    anwserman

    Joined:
    Feb 13, 2012
    Posts:
    36
    Hey Phong,
    I bought Mesh Baker 2 and I have a couple questions regarding texture usage. I'm making levels in a BSP-styled editor, and most textures are stand-alone. So let's say I make a lamp-post out of four textures in my map, and create 3 copies of it through out the map. How does Mesh Baker handle this? Ideally, the texture atlas generated should reference four textures and share em between the models, or does it create multiple copies of each original texture?
     
  34. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Each texture will be included once in the atlas provided it has the same tiling offset and scale. If the same texture has different tiling offset and scale Mesh Baker will bake the offset and scale and each result will be included separately in the atlas.
     
  35. Rajmahal

    Rajmahal

    Joined:
    Apr 20, 2011
    Posts:
    2,051
    I tried the update and it appears to be working. Thanks for the hard work. I'll let you know if I run into any other issues.
     
  36. RedVonix

    RedVonix

    Joined:
    Dec 13, 2011
    Posts:
    356
    Hey Phong!

    Came across another question for you. I have a scene where all of my enemies are SkinnedMeshRenderers and are being added to MeshBaker. Everything is working very well, one draw call, one mesh, etc. The one problem I'm having now however is when the final mesh is removed from the meshbaker.

    So it goes like this...

    1.) Add and removes enemies as needed to MeshBaker.
    2.) Whenever an enemy is added or removed, we call AddDeleteGameObjects.
    3.) If a situation occurs where there are no enemies currently active, and we remove the last entry in meshbaker causing its contents to be zero, then MeshBaker freaks out on AddDeleteGameObjects with the following...

    First it shows this error:
    - No bones in SkinnedMeshRenderer. Could not UpdateSkinnedMeshApproximateBounds.

    Then it repeats this about 20 times:
    - SkinnedMeshRenderer requires a mesh with skinning information.


    I'm thinking there is something special I'm supposed to do whenever the count reaches 0? Here is what my code looks like for adding and removing enemies...

    Code (csharp):
    1.  
    2.     public void addEnemyToManager(GameObject thisObject)
    3.     {
    4.         Debug.Log("Enemy Baker Adding: " + thisObject);
    5.         GameObject[] addList = new GameObject[1];
    6.        
    7.         addList[0] = thisObject.GetComponentInChildren<SkinnedMeshRenderer>().gameObject;
    8.  
    9.         objsInCombined.Add(addList[0]);
    10.        
    11.         meshBaker.AddDeleteGameObjects(addList, null);
    12.         meshBaker.ApplyAll();
    13.     }
    14.    
    15.     public void enemyRemoved(GameObject thisObject)
    16.     {  
    17.         Debug.Log("Enemy Baker Removing: " + thisObject);
    18.        
    19.         GameObject[] remList = new GameObject[1];
    20.        
    21.         remList[0] = thisObject.GetComponentInChildren<SkinnedMeshRenderer>().gameObject;
    22.        
    23.         objsInCombined.Remove(remList[0]);
    24.        
    25.         meshBaker.AddDeleteGameObjects(null, remList);
    26.         meshBaker.ApplyAll();
    27.     }
    28.  
    Thank you for any help you can give! :)
     
  37. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    2,274
    When I try to build for iOS I get this error:


    Assets/MeshBaker/scripts/MB_TextureCombiner.cs(41,24): error CS0246: The type or namespace name `TextureImporterFormat' could not be found. Are you missing a using directive or an assembly reference?


    Any idea how I can fix this?
     
  38. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Was able to reproduce the problem. This is actually the SkinnedMeshRenderer component freaking out, not the MeshBaker component. I would try disabling the SkinneMeshRenderer component when the number of objects in combined reaches zero and re-enabling when adding the first object.

    Code (csharp):
    1.  
    2.                 //after removing each object
    3.         if (meshBaker.meshCombiner.GetObjectsInCombined().Count == 0){
    4.             SkinnedMeshRenderer smr = meshBaker.resultSceneObject.GetComponentInChildren<SkinnedMeshRenderer>();
    5.             if (smr != null) smr.enabled = false;
    6.         }
    7.  
    8.                 //when adding new objects again
    9.                 if (meshBaker.resultSceneObject != null){
    10.             SkinnedMeshRenderer smr = meshBaker.resultSceneObject.GetComponentInChildren<SkinnedMeshRenderer>();
    11.             if (smr != null)  smr.enabled = true;
    12.                 }
    13.  
     
    Last edited: Apr 9, 2013
  39. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Hi Lars,

    I forgot a step in my testing checklist. To fix this, in file MB_TextureCombiner

    Search for "class TextureFormatInfo" and wrap it in #if UNITY_EDITOR like so:

    Code (csharp):
    1.  
    2. #if UNITY_EDITOR
    3.      class TextureFormatInfo{
    4.              ...
    5.      }
    6. #endif
    7.  
    Do the same thing with function "void setTextureFormat"

    Code (csharp):
    1.  
    2. #if UNITY_EDITOR
    3.      void setTextureFormat{
    4.              ...
    5.      }
    6. #endif
    7.  
    This fix is now available in the asset store.
     
    Last edited: Apr 12, 2013
  40. RedVonix

    RedVonix

    Joined:
    Dec 13, 2011
    Posts:
    356
    This is unfortunately causing a delay in a client build I need to submit, so if there is anything I could do to help feel free to PM me. We can get on Skype as well and I would be happy to help review and hunt it down with you!
     
  41. toto2003

    toto2003

    Joined:
    Sep 22, 2010
    Posts:
    505
    hi phong
    i purchase your awesome tool, so far it works fine, and reduce a lot of my drawcall scene, but i have some issue trying to bake my skin characters with skinnedmeshrenderer option, my characters are just skin with bones, i succesfully bake material with it as they all have a skinmeshrenderer, then i press the selection skinmeshrenderer , it create my bakemesh but without any animation on it, i try to check the prefab from the exemple scene, and i notice that all the skinmeshrenderer are located on the root bones, wich is really strange as it should be on the mesh itself, nomrally on any 3d package the skin should be on the 3d mesh not on the bones, do i miss something here?

    thanks
     
  42. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    Check the Culling option on the Animation components. It is probably set to Renderers. You probably need to set it to "Always Animate" or one of the other options.

    Regarding the location of the SkinnedMeshRender components in relation to the bones. This doesn't mater in Unity. They are usually grouped in a hierarchy for convenience, so that the bones and Renderer can be baked into a prefab, and so that the Animation component can cull animations based on renderers. But the bones array is just an array of transforms and these transforms can be located anywhere in the scene.
     
  43. toto2003

    toto2003

    Joined:
    Sep 22, 2010
    Posts:
    505
    holysh.... it works!!!!! just checked always animate and it simply work.
    phong u made my day!

    thanks again
     
  44. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,081
    Has anyone done tests on iOS with the realtime mesh combining function?

    I'm really curious to know how much RAM gets used during the peak of combining a mesh with 64k vertices and how long does that take in ms?

    Also, if you combine a mesh, then change that mesh a little, produce a new combined mesh, then do that over and over. How does the freeing of memory from the old meshes get dealt with? Do you end up with a bunch of meshes floating in memory? Or is there somehow to append and delete objects from a combined mesh without it leaving the old meshes floating in memory?
     
    Last edited: Apr 17, 2013
  45. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    I have done some tests on iOS, although I have not tried with a 64k mesh. I tested updating a mesh 2-3 times second on a 4th Generation iPod. I found that a 10k mesh takes about 1/20th of a second to Combine and Apply. I found meshes larger than 10k were producing noticeable stuttering on mobile.

    Regarding the freeing of memory. The Mesh itself is re-used when Apply is called, so you won't get a bunch of meshes floating around. However, updating meshes causes a lot of temporary arrays to be created. Reading the vertices and channels of the source meshes creates arrays and updating a mesh's vertices, triangles, uvs, normals etc... causes the old vertices to be freed. This produces a lot of cleanup for the garbage collector.

    Some performance observations:
    • Replacing a tiny part of a mesh is only slightly faster than updating everything in a mesh. It is best to batch changes.
    • It is best to collect everything to be added and deleted and call "AddDeleteGameObjects" once. Try to call this once and call Apply once.
    • "Update" is much much faster than "AddDeleteGameObjects", it preserves the vertex layout. So if you just want to move an object in the combined mesh (number of vertices is the same) then use Update. This has almost no memory footprint.
    • The MeshBaker component stores a set of arrays for triangles, vertices etc... this basically doubles the memory footprint of the mesh. If you arn't going to update a combined mesh you are best off to delete the MeshBaker object after baking.
    • Combining the meshes "AddDeleteGameObjects" takes roughly the same amount of time as updating the mesh by calling "Apply"
    • The amount of time scales linearly with the number of channels for both "AddDeleteGameObjects" and "Apply". So a mesh with Vertices and Colors is twice as fast to bake and apply as one with Vertices, UV, Normal, Tangents

    Unity 4 has added a flag to the Mesh API "MarkMeshForFrequentUpdates". I have not added this flag to the code yet although it would be very easy to do. I am curious what difference it would make.
     
  46. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,081
    Thank you, great information. Should post that in your FAQ as well.

    I too would be very curious to know what difference the 'MarkMeshForFrequentUpdates' flag makes.
     
  47. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,317
    Hi Phong,

    Q: Is it possible to move the individual meshes after they baked into one mesh.

    While studying the included examples, it seems that in "Scene1", I cannot select and move individual meshes after baking. However, in the SceneRuntimeExample", the individual meshes can be moved.

    Can you give more explanation of how to move objects even after baking.

    Thanks.
     
  48. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,317
    Found the UpdateGameObjects() in MB_Example.cs

    void LateUpdate(){
    //Apply changes after this and other scripts have made changes
    //Only to vertecies, tangents and normals
    //Only want to call this once per frame since it is slow
    meshbaker.UpdateGameObjects(objsToCombine);
    meshbaker.Apply(false,true,true,true,false,false,false,false);
    }

    And in MB_ExampleMover.cs
    void Update () {
    Vector3 v1 = new Vector3(5f,5f,5f);
    v1[axis] *= Mathf.Sin(Time.time);
    transform.position = v1;
    }

    It looks like that the code above moves only the Original game objects.

    What I don't understand is how the game objects in the Combined Mesh is being moved.

    Also, how much of a performance hit is the transform operation on Mobile (IOS/Android)?

    Thanks.
     
    Last edited: Apr 21, 2013
  49. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    There are three ways to move meshes in the combined mesh.
    1. Remove an object from the combined mesh, enable the renderer, move it and re-add it to the combined mesh.
    2. Move the source object and call the Update function on the source mesh
    3. Bake the object into a skinned mesh and move the source objects around (they become bones)

    If it is basically a static mesh with objects you want to move once in a while use 1 or 2. If you want to move the objects all the time try option 3.
     
  50. Phong

    Phong

    Joined:
    Apr 12, 2010
    Posts:
    1,590
    The object in the combined mesh is updated with the calls to UpdateGameObjects and Apply. To move an object in the combined mesh move the source object and call UpdateGameObjects/Apply. The MeshBaker object keeps track of the objects that have been added and where the vertices, triangles etc.. of each source object were copied to in the combined. When UpdateGameObjects is called it refreshes the vertices, normals, tangents for that object in the combined mesh.

    The performance is about 20% as fast as a using a SkinnedMeshRenderer, however there is only overhead incurred on the frames where you actually move something. If you want to update the combined mesh every frame then try setting renderer to "skinned mesh". If you want to occasionally move some objects use UpdateGameObjects.