Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

One draw call for each shader, with dynamic meshes : The Bob script.

Discussion in 'Made With Unity' started by Ippokratis, May 9, 2011.

  1. Mark-Sweeney

    Mark-Sweeney

    Joined:
    Feb 21, 2010
    Posts:
    172
    Yes - I quit, relaunched, created a new project, set bone weights to zero. But as soon as I add the Bob script to the project I get that error.

    BTW - It's Unity 3.3 I'm using, not 3.0.
     
  2. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Bone weights to one :)
    You create a new javascript file and paste the contents.
    I am also on Unity 3.3, IOS Basic. Everything goes smooth.
    Restart, perhaps you leaved Unity open for long time.
    Simply follow the steps in the blog post (remember, they are not optional).
     
  3. Mark-Sweeney

    Mark-Sweeney

    Joined:
    Feb 21, 2010
    Posts:
    172
    I meant to type bones weights at 1.

    I've tried it several times, even with starting unity with a new, blank project, quitting, then restarting it. Every time I copy and paste the Bob js to the script in Unity, I get the same Internal Compiler error I posted above.
     
  4. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    I am sorry, when I said restart I meant restart your computer.
    Look, I appreciate the interest on this project and I know that such issues are frustrating.
    The thing is that I cannot reproduce what you describe locally. I do the steps you describe and no errors appears. So, since we have similar settings, I suppose it is something related to the editor. The unity editor to my experience occasionally exhibits errors "just because" when the computer is open for days. Hence the restart suggestion.
    For convenience I can upload a sample project that contains those two scripts. I haven't done it so far 'cause I thought it is fairly straightforward but if you think this could help, I 'll upload it.
    Just let me know.
     
    Last edited: Jul 17, 2011
  5. Mark-Sweeney

    Mark-Sweeney

    Joined:
    Feb 21, 2010
    Posts:
    172
    Sorry to get back to you so late, I've been away for most of the weekend with no internet access.

    Restarting the computer didn't work, but what I did was download Unity 3.3 and do a complete re-install. I launched Unity, and got no more errors with the Bob script, and it works like you said it would.

    Thanks for your effort and help, especially since the problem had nothing to do with your script or instructions.
     
  6. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    I am glad that you figured it out, I know how frustrating can those errors be. I noticed that they appear much less frequent in Mac and what is annoying is that it is hard to say what is wrong ( for my level of understanding at least ).

    To anybody else who needs clarifications / help : I will be back in the mid September. Until then, have a nice summer :)
     
  7. Catman

    Catman

    Joined:
    Jul 16, 2011
    Posts:
    47
    Hello. Your scripts looks quite promising and I am starting to use it for my project.
    I noticed that the TexturePacker, even the static one, gave me errors unless I did exactly what you wrote (with a new project, scene, cubes and etc.).

    I think I found one possible cause of the error, as I can reproduce the behaviour with or without it. The tiling of the texture must be set to 1 or the combined mesh and the atlas won't be created at all.

    I hope this can help.

    Michele
     
  8. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    As I see it there is not an universal solution for every conceivable shader. Once someone has decided which shaders needs to use, ideally one texturepacker per shader should be created. Despite it's name, texturepacker is actually a way to merge multiple materials that use the same shader. The current implementation supports certain shaders and to overcome it's constrains you should code. The properties of each shader should be packed eg colors, textures, e.t.c. Hope that this explanation might help you. Thanks for the feedback, if you wish to further discuss we could do so after mid September.
     
  9. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    has anyone tested this alongside tools that are already batching materials, like SpriteManager2 EZGui, seems like there could be some conflicts. Thus far, testing has been great, this is the type of functionality I would hope Unity would natively support, thankfully you've share this VERY useful solution with the community, thank you again!
     
  10. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    @Ippokratis you might wanna check out your site, looks like it might have a virus, or at least thats what my chrome browser "Says". I'd like to test the newly updated script, if you, or anyone else has it available online.
     
  11. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,203
    Safari says it has malware also.
     
  12. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi,
    I just returned and found that my site is hacked.
    I am working on it. Thanks for bringing this to my attention and sorry for the inconvenience.
     
  13. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Site is clear and posts are back. Thanks again for notifying me about that issue.
     
  14. EricD

    EricD

    Joined:
    Sep 7, 2011
    Posts:
    128
    I love this script. However. I can't seem to get the lightmap of the combined meshes right. It's completely distorted. Can you help me with this problem?
     
  15. MrBurns

    MrBurns

    Joined:
    Aug 16, 2011
    Posts:
    378
  16. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    @EricD :
    Perhaps you should modify the script so it packs the uv2 component of the mesh. If you are interested in a custom solution, contact me via PM.

    @MrBurns :
    I like your avatar.
    You seem to have a demanding project, draw call wise. The improved skinned mesh performance in unity 3.4 may help. Have you tried the Bob script besides dynamic batching ?
     
  17. MrBurns

    MrBurns

    Joined:
    Aug 16, 2011
    Posts:
    378
    Yes I want to blow everything into pieces ^^. Or at least it should be possible or is already so to speak...

    I am not sure about that skinned mesh thing... I got it working without one. No I didn't try it. Also from what I have read it does not seem to do what I needed anyway.
     
  18. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    @ Ippokratis Thanks for sharing this!

    Storing an object that has been optomized by TexturePackerStatic.cs as a prefab doesnt work. Has anyone found a way to store the optomized object as prefab? To do that the Packed texture and combined mesh would have to be stored somewhere in the project folder instead of the scene.

    Thanks for any help!
     
  19. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    I found this on the wiki

    http://www.unifycommunity.com/wiki/index.php?title=ObjExporter


    This is really useful and allows exporting the obj so it can be edited in a 3D app or used as a prefab. All the Packed UVs information gets exported too. However it does not sucessfully export the texture.

    Does anyone know of a way to export the Packed Texture generated by TexturePackerStatic.CS?
     
  20. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    I made a small script that can help
    Code (csharp):
    1.  
    2. // TextureExport.js by Ippokratis Bournellis September 2011
    3. // Exports the main texture from a gameobject's material in the
    4. //  project folder
    5. // Place it in Editor folder
    6. // Use : select menu -> Assets -> Export Texture
    7. import System.IO;
    8. @MenuItem("Assets/Export Texture")
    9.  
    10. static function DoIt()
    11. {
    12.    if (Selection.activeObject.renderer.material.mainTexture !=null)
    13.    {
    14.        var texture : Texture2D = Selection.activeObject.renderer.material.mainTexture as Texture2D;
    15.        var path : String = AssetDatabase.GetAssetPath(texture);
    16.        var textureImporter : TextureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
    17.        textureImporter.isReadable = true;  
    18.        AssetDatabase.ImportAsset(path);
    19.    }
    20.    else
    21.    {
    22.       EditorUtility.DisplayDialog("Select gameObject", "You Must Select a gameObject that has a material with a texture first!", "Ok");
    23.       return;
    24.    }
    25.    
    26.    var bytes = texture.EncodeToPNG();
    27.    File.WriteAllBytes(Application.dataPath + "/exported_texture.png", bytes);
    28. }
    29.  
     
    Last edited: Sep 13, 2011
  21. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    Thanks very much Ippokratis.

    I am looking forward to using the texture export script you just made.

    I am just getting one error: My texture are set to read and write.

    NullReferenceException: Object reference not set to an instance of an object
    TextureExport.DoIt () (at Assets/Editor/TextureExport.js:16)
     
    Last edited: Sep 13, 2011
  22. EricD

    EricD

    Joined:
    Sep 7, 2011
    Posts:
    128
    Nice exporter. If i were to be able to export the combined mesh, re-import it, I might be able to enable "generate lightmap" at the FBX importer?
     
  23. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    There is a script in the wiki, "Export to obj" that allows you exporting a generated mesh.
    You can try, I have no experience with lightmaps.
     
  24. EricD

    EricD

    Joined:
    Sep 7, 2011
    Posts:
    128
    Same error :)
     
  25. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    Yeah, the export obj works great, but the texture is still not exporting with the script you posted above.

    @EricD you can create a second uv set for the lightmaps in an external app too if Unity's generate lightmaps doesnt work after exporting as an .obj.
     
  26. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    This one could help ?
    Code (csharp):
    1.  
    2. // TextureExport.js by Ippokratis Bournellis September 2011
    3. // Exports the main texture from a gameobject's material in the
    4. //  project folder
    5. // Place it in Editor folder
    6. // Use : select menu -> Assets -> Export Texture
    7. import System.IO;
    8. @MenuItem("Assets/Export Texture")
    9.  
    10. static function DoIt()
    11. {
    12.    if (Selection.activeObject.renderer.material.mainTexture !=null)
    13.    {
    14.         var texture : Texture2D = Selection.activeObject.renderer.material.mainTexture as Texture2D;
    15.         var bytes = texture.EncodeToPNG();
    16.         File.WriteAllBytes(Application.dataPath + "/exported_texture.png", bytes);
    17.    }
    18.    else
    19.    {
    20.       EditorUtility.DisplayDialog("Select gameObject", "You Must Select a gameObject that has a material with a texture first!", "Ok");
    21.       return;
    22.    }
    23.    
    24. }
    25.  
     
  27. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    Thanks Ippokratis.

    I am getting these errors now, even when just trying to export a texture on a unity cube. There is a texture called exported_texture.png that gets generated but is an empty png with only 0kb file size.

    Instantiating material due to calling renderer.material during edit mode. This will leak materials into the scene. You most likely want to use renderer.sharedMaterial instead.
    UnityScript.Lang.UnityRuntimeServices:GetProperty(Object, String)
    TextureExport: DoIt() (at Assets/Editor/TextureExport.js:11)

    Unsupported image format - the texture needs to be ARGB32 or RGB24
    UnityEngine.Texture2D:EncodeToPNG()
    TextureExport: DoIt() (at Assets/Editor/TextureExport.js:14)

    NullReferenceException: Object reference not set to an instance of an object
    System.IO.File.WriteAllBytes (System.String path, System.Byte[] bytes)
    TextureExport. DoIt () (at Assets/Editor/TextureExport.js:15)

    .
     
  28. fghajhe

    fghajhe

    Joined:
    Jan 6, 2009
    Posts:
    145
    Has anyone got the texture exporrter working? Having trouble with it myself
     
  29. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Ok, new version.
    Bob script v 0.3
    What it does :

    -Takes gameObjects that contain meshes and combines them in one mesh. It makes a texture atlas from their textures that can be saved in the Assets folder. The result is that you have n objects that can be moved independently with a single drawcall.

    What it does not support :
    -Any shader with more than one Main texture.
    -Any shader with other properties ( i.e color )
    -Skinned meshes.
    -Lightmaps.
    -Submeshes.
    -GameObjects with parents - children ( nested gameObjects ).
    -Working in web build. Change in standalone.
    -Cannot handle meshes that added result in more than 65000 total vertices

    [edit]
    In my initial post I wrote
    Luckily, Airship explained to me that some of these features can be useful not for optimization but for artists involved in content creation.
    Therefore, i will start developing some new features in a new commercial product ( see below ).

    Usage :
    1. Make a new gameObject at 0,0,0 and name it root.
    2. Add the gameObjects you wish to combine in root.
    3. Add the Bob script.
    4. Hit Combine.
    Now you can
    -Save the texture
    -revert to the previous uncombined state.
    5. Before you hit play, deactivate the script.



    Code (csharp):
    1.  
    2. ///Copyright 2011  by Bournellis Ippokratis
    3. //
    4. //Permission is hereby granted, free of charge, to any person obtaining a copy
    5. //of this software and associated documentation files (the "Software"), to deal
    6. //in the Software without restriction, including without limitation the rights
    7. //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    8. //copies of the Software, and to permit persons to whom the Software is
    9. //furnished to do so, subject to the following conditions:
    10. //
    11. //The above copyright notice and this permission notice shall be included in
    12. //all copies or substantial portions of the Software.
    13.  
    14. //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15. //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16. //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17. //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18. //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19. //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    20. //THE SOFTWARE.
    21. //
    22. //
    23. //
    24. //If you find the code provided useful, consider a donation at my site http://ippomed.com
    25. //Thanks.
    26. #pragma strict
    27. import System.IO;
    28. import System.Linq;
    29. import System.Collections.Generic;
    30. @script ExecuteInEditMode()
    31.  
    32. private var _add : boolean; //Remember to erase AddGameObjects() from CombineMeshes and modify Update in order to debug
    33. var combine : boolean;
    34. var reset : boolean;
    35. var saveTexture : boolean;
    36. private var readyToCombine : boolean;
    37. private var readyToSave : boolean;
    38. private var partMat: Material;
    39. private var mesh : Mesh;
    40. private var newMesh: Mesh;  
    41. private var gameObjects:List.<GameObject>;
    42. private var _renderer : SkinnedMeshRenderer;
    43. private var triangles:List.<int>;
    44. private var vertices:List.<Vector3>;
    45. private var uv: List.<Vector2>;
    46. private var uv2: List.<Vector2>;
    47. private var weights:List.<BoneWeight>;
    48. private var bones:List.<Transform>;
    49. private var bindposes : List.<Matrix4x4>;
    50. private var meshes:List.<Mesh>;
    51. private var transforms:List.<Transform>;
    52. private var inactiveGO:List.<GameObject>;
    53. private var shader: List.<Shader>;
    54. private var packedTexture: Texture2D;
    55. private var textures: List.<Texture2D>;
    56. private var texturesAr: Texture2D[];
    57. private var uvs : Rect[];
    58. private var uva : Vector2[];
    59. private var uvb : Vector2[];
    60.  
    61. function Start ()
    62. {
    63.     ResetAll();
    64. }
    65.  
    66. function AddGameObjects()
    67. {
    68.     // Detect erroneous user input--------------------------------------------------------------
    69.     if (GetComponentsInChildren.<MeshRenderer>()==null)
    70.     {
    71.         Debug.LogError("You should supply gameObjects with MeshRenderer components. Try again.");
    72.         return;
    73.     }
    74.     if (GetComponentsInChildren.<MeshRenderer>()==null)
    75.     {
    76.         Debug.LogError("You should supply gameObjects with MeshFilter components. Try again.");
    77.         return;
    78.     }
    79.     var mr:MeshRenderer[]  = GetComponentsInChildren.<MeshRenderer>();
    80.     var sh:Shader[]= new Shader[mr.Length];
    81.    
    82.     for (var idx:int = 0; idx<mr.Length; ++idx)
    83.     {
    84.         sh[idx] = mr[idx].sharedMaterial.shader ;
    85.     }
    86.    
    87.     var bibi :int= Enumerable.Count(Enumerable.Distinct(sh));
    88.     if (bibi > 1)
    89.     {
    90.         Debug.LogError("All the supplied gameObjects should share the same shader. Try again");
    91.         return;
    92.     }
    93.     //End of erroneous user input detection-------------------------------------------------------
    94.    
    95.     partMat.CopyPropertiesFromMaterial(mr[0].sharedMaterial);
    96.     var mf:MeshFilter[]  = GetComponentsInChildren.<MeshFilter>();
    97.     textures = new List.<Texture2D>();
    98.    
    99.     //If not already, make textures readable, eliminate mipmaps, store them in a List
    100.     //Gather textures
    101.     for (var item1 : MeshFilter in mf )
    102.     {
    103.         var texture : Texture2D = item1.renderer.sharedMaterial.mainTexture as Texture2D;
    104.         var path : String = AssetDatabase.GetAssetPath(texture);
    105.         var textureImporter : TextureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
    106.         if( textureImporter.isReadable == false||textureImporter.mipmapEnabled ==true)
    107.         {
    108.             Debug.Log("Bob disables mipmaps, sets texture " +texture.name+ " to Readable and reimports it. This takes a while");
    109.             textureImporter.isReadable = true;
    110.             textureImporter.mipmapEnabled = false;
    111.             AssetDatabase.ImportAsset(path);
    112.         }  
    113.         textures.Add(texture);  
    114.     }
    115.     //Pack textures, store uvs, assign packed texture to partMat
    116.     texturesAr = new Texture2D[textures.Count];
    117.     texturesAr = textures.ToArray();
    118.     packedTexture = new Texture2D(1024, 1024, TextureFormat.ARGB32, false);
    119.     uvs  = packedTexture.PackTextures(texturesAr,2,1024);
    120.     packedTexture.Apply();
    121.     partMat.mainTexture = packedTexture;
    122.    
    123.     for (var j:int =0; j < mf.Length; j++)
    124.     {
    125.         uva  = mf[j].sharedMesh.uv;
    126.         uvb = new Vector2[uva.Length];
    127.        
    128.         for (var k : int = 0; k < uva.Length; k++)
    129.         {
    130.             uvb[k] = new Vector2 ( (uva[k].x*uvs[j].width) + uvs[j].x, (uva[k].y*uvs[j].height) + uvs[j].y);
    131.         }
    132.        
    133.         for ( var item:Vector2 in uvb)
    134.         {
    135.             uv.Add(item);
    136.         }
    137.     }      
    138.     //
    139.     for (var item : MeshFilter in mf)
    140.     {
    141.         meshes.Add(item.sharedMesh);
    142.         transforms.Add(item.transform);
    143.         var myGo :GameObject = new GameObject (item.gameObject.name );
    144.         gameObjects.Add(myGo);
    145.         inactiveGO.Add(item.gameObject);
    146.         item.gameObject.active = false;
    147.     }
    148.     readyToCombine = true;  
    149. }
    150. function CombineMeshes()
    151. {  
    152.     AddGameObjects();
    153.     if (!readyToCombine)
    154.     {
    155.         return;
    156.     }
    157.     //Create new lists for everything but the bones
    158.     triangles = new List.<int>();
    159.     vertices = new List.<Vector3>();
    160.     uv2 = new List.<Vector2>();  
    161.     weights = new List.<BoneWeight>();
    162.     bindposes = new List.<Matrix4x4>();
    163.  
    164.     //Add the gameObject's mesh to the mesh list
    165.     var vertIdx:int = 0;
    166.     var idx:int = 0;
    167.     var __weights : BoneWeight[] = new BoneWeight[vertIdx];
    168.     //Rebuild the combined mesh from the array of the meshes
    169.     newMesh = new Mesh();
    170.     var trianglesIdx:int = 0;
    171.     var _bonesIdx:int = 0;
    172.     var bonesA : Transform[] = new Transform[gameObjects.Count];
    173.     var bindPosesA : Matrix4x4[] = new Matrix4x4[gameObjects.Count];
    174.     var _meshes : Mesh[];
    175.     _meshes = meshes.ToArray();
    176.    
    177.       for (var item:Mesh in _meshes )
    178.       {
    179.         for(var _item: Vector3 in item.vertices)
    180.         {  
    181.             vertices.Add(_item);
    182.         }
    183. //        for(var _item: Vector2 in item.uv)
    184. //        {  
    185. //            uv.Add(_item);
    186. //        }
    187.         for(var _item: Vector2 in item.uv2)
    188.         {  
    189.             uv2.Add(_item);
    190.         }
    191.         for(var _item: int in item.triangles)
    192.         {  
    193.             triangles.Add(_item + trianglesIdx);
    194.         }
    195.  
    196.         vertIdx = item.vertices.Length;
    197.         idx = 0;
    198.         __weights  = new BoneWeight[vertIdx];
    199.        
    200.         for ( idx = 0; idx<vertIdx; ++idx )
    201.         {  
    202.             __weights[idx].boneIndex0 = _bonesIdx;
    203.             __weights[idx].weight0 = 1.0;
    204.             weights.Add(__weights[idx]);
    205.         }
    206.  
    207.         newMesh.vertices = vertices.ToArray();
    208. //        newMesh.uv = uv.ToArray();
    209.         newMesh.uv2 = uv2.ToArray();
    210.         trianglesIdx = vertices.Count;
    211.        
    212.         gameObjects[_bonesIdx].transform.localPosition = transforms[_bonesIdx].localPosition;
    213.         bonesA[_bonesIdx] = gameObjects[_bonesIdx].transform;
    214.         bonesA[_bonesIdx].parent = transform;
    215.         bonesA[_bonesIdx].localRotation = Quaternion.identity;
    216.         bonesA[_bonesIdx].localPosition = Vector3.zero;
    217.         bindPosesA[_bonesIdx] = bonesA[_bonesIdx].worldToLocalMatrix * transform.localToWorldMatrix;
    218.         //
    219.         gameObjects[_bonesIdx].transform.localPosition = transforms[_bonesIdx].localPosition;
    220.         gameObjects[_bonesIdx].transform.localRotation = transforms[_bonesIdx].localRotation;
    221.         gameObjects[_bonesIdx].transform.localScale = transforms[_bonesIdx].localScale;
    222.         ++_bonesIdx;
    223.       }
    224.     newMesh.uv = uv.ToArray();
    225.     newMesh.triangles = triangles.ToArray();
    226.     newMesh.RecalculateNormals();
    227.     newMesh.boneWeights = weights.ToArray();
    228.     newMesh.bindposes = bindPosesA;
    229.     newMesh.RecalculateBounds();  
    230.     newMesh.Optimize();
    231.  
    232.     mesh = newMesh;
    233.     _renderer.bones = bonesA;
    234.     _renderer.sharedMaterial  = partMat;
    235.     _renderer.sharedMesh = mesh;
    236.    
    237.     readyToSave = true;
    238. }
    239.  
    240. function ResetAll()
    241. {
    242.     if( transform.position != Vector3(0,0,0)||
    243.         transform.rotation != Quaternion.identity||
    244.         transform.localScale != Vector3(1,1,1) )
    245.     {
    246.         Debug.LogError("Please modify the transform of this gameObject to Pos 0 0 0, Rot 0 0 0, Scale 1 1 1. It is designed to work this way only. Thanks");
    247.         return;
    248.     }  
    249.    
    250.     triangles = new List.<int>();
    251.     vertices = new List.<Vector3>();
    252.     uv = new  List.<Vector2>();
    253.     uv2 = new  List.<Vector2>();
    254.     weights = new List.<BoneWeight>();
    255.     bones = new List.<Transform>();
    256.     bindposes  = new  List.<Matrix4x4>();
    257.     meshes = new List.<Mesh>();
    258.     transforms = new List.<Transform>();
    259.     texturesAr = null;// new Texture2D[];
    260.     textures = new List.<Texture2D>();
    261.     uvs = null;//new Rect[];
    262.     uva = null;//new Vector2[];
    263.     uvb = null;//new Vector2[];
    264.     packedTexture = null;//new Texture2D(1024, 1024, TextureFormat.ARGB32, false);
    265.     if (gameObjects!=null)
    266.     {
    267.         if (gameObjects.Count > 0)
    268.         {
    269.             for (var item : GameObject in gameObjects)
    270.             {
    271.                 DestroyImmediate (item);
    272.             }
    273.         }
    274.     }  
    275.    
    276.     gameObjects = new List.<GameObject>();
    277.     if  (gameObject.GetComponent.<SkinnedMeshRenderer>()==null)
    278.     {
    279.         gameObject.AddComponent.<SkinnedMeshRenderer>();
    280.     }
    281.     else
    282.     {
    283.         DestroyImmediate (GetComponent.<SkinnedMeshRenderer>());
    284.         gameObject.AddComponent.<SkinnedMeshRenderer>();
    285.     }
    286.     _renderer  = GetComponent.<SkinnedMeshRenderer>();
    287.     _renderer.quality = SkinQuality.Bone1;
    288.     MakeDummyMesh();
    289.     _renderer.sharedMaterial  = new Material( Shader.Find("Diffuse") );
    290.     partMat = new Material( Shader.Find("Diffuse") );
    291.     _renderer.sharedMesh = mesh;
    292.     newMesh = new Mesh();
    293.     for (var item : GameObject in inactiveGO)
    294.     {
    295.         item.active = true;
    296.     }
    297.     inactiveGO =null;
    298.     inactiveGO = new List.<GameObject>();
    299.     shader = new List.<Shader>();
    300.     textures = new List.<Texture2D>();
    301.     readyToSave = false;    
    302. }
    303.  
    304. function MakeDummyMesh()
    305. {
    306.     mesh = new Mesh ();
    307.     mesh.vertices = [Vector3(-1, 0, 0), Vector3(1, 0, 0), Vector3(-1, 5, 0),
    308.     Vector3(1, 5, 0)];
    309.     mesh.uv = [Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)];
    310.     mesh.triangles = [0, 1, 2, 1, 3, 2];
    311.     mesh.RecalculateNormals();
    312.     var weights : BoneWeight[] = new BoneWeight[4];
    313.     weights[0].boneIndex0 = 0;
    314.     weights[0].weight0 = 1;
    315.     weights[1].boneIndex0 = 0;
    316.     weights[1].weight0 = 1;
    317.     weights[2].boneIndex0 = 1;
    318.     weights[2].weight0 = 1;
    319.     weights[3].boneIndex0 = 1;
    320.     weights[3].weight0 = 1;
    321.     mesh.boneWeights = weights;
    322. }
    323. function SaveTexture()
    324. {
    325.     Debug.Log("Saving texture. This takes a while");
    326.     var bytes = packedTexture.EncodeToPNG();
    327.     File.WriteAllBytes(Application.dataPath + "/exported_texture.png", bytes);
    328.     Debug.Log("Saved as exported_texture.png. Please refresh in project view to see it.");
    329. }
    330. function Update()
    331. {
    332. //    if(_add)
    333. //    {
    334. //        AddGameObjects();
    335. //        _add=false;
    336. //    }
    337.      if(reset)
    338.     {
    339.         ResetAll();
    340.         reset=false;
    341.     }
    342.         if(combine)
    343.     {
    344.         CombineMeshes();
    345.         combine=false;
    346.     }
    347.     if(saveTexture)
    348.     {
    349.         if(readyToSave)
    350.         {
    351.             SaveTexture();
    352.             saveTexture=false;
    353.         }
    354.         else
    355.         {
    356.             saveTexture=false;
    357.             Debug.LogError("Please combine meshes first");
    358.         }  
    359.     }
    360. }
    361.  
     
    Last edited: Nov 18, 2016
  30. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    is there a planned (tentative) release date for the the commercial version of the Bob script? Will you be releasing it on the Unity3D AssetStore?
     
  31. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi zhx,
    Thanks for the interest.
    I am building a tool that combines 3d models in Unity.
    It is intended to facilitate 3d artists and programmers that are importing their models in unity.
    It combines them to lower drawcalls, making the game faster.
    The app can :
    -combine 3d models resulting in 1 drawcall instead of many.
    -export created object and atlas to a 3d modelling app - photoshop for further modifications.
    -handle submeshes.

    I work now on how to combine 3d models that have more than 65k vertices ( after you add them together ).
    Still have to do user interaction smoother ( less clicks to complete the goal ).
    I also have to find how to describe it better.
    Estimated time 1-2 weeks. Estimated price 25 dollars.
    The feature list is open to suggestions. I have no experience in 3d modelling and I am not so aware on what problems artists face.
    If you have any suggestion, I am all ears.
     
  32. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,364
    @Ippokratis,
    Useful, that tool will be sold like pancakes! ^^
    I'm keeping an eye over your commercial version of Bob "the drawcall crusher!" :D
    Cheers,
     
  33. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,364
    Hey Ippokratis do the Bob (free version) script works with tilled textures?
    I got it working and my mobile game mapping is completed messed up.

    EDIT: Looks like the current Bob version does not add any real performance improvement for me.

    Here are some shots of each profiler (one normal and one with Bob skinned combine):

    Normal:



    Bob:


    As you can see the normal scene (nothing combined) i have 145-58 drawcalls (batched). It's a real game with enemies, menus, AI, etc and the rendering speed is very very similar to the scene combined into one skinned mesh. Also notice how batching decreases on the skinnedMesh scene due to the fact that the whole object is just one huge skinned mesh. There's no real sub-meshes over there, only part of a mesh skinned to bones. An other plus, Umbra don't work anymore (because of the entire scene being one huge skinned mesh).

    As already stated in various threads, drawcalls isn't the only thing that counts for rendering performance. Do you really think drawcalls in this situation matters? I can't even notice one single fps addition.
    Cheers,
     
    Last edited: Oct 19, 2011
  34. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi,
    Thanks for the feedback and the interest in Bob. There are many parameters that one should take into consideration on choosing what to combine. If you combine everything into one skinned mesh, you get at best equal performance, if not worse. In your case, the performance is worse ( frametime 42 msec vs 37 msecs ). So, to achieve better performance, you should select what to combine. Also, you shouldn't combine static meshes into a skinned mesh, it will only slow things down.

    Lighting, proximity, intended behaviour are among the parameters that define what to combine.
    I.e one room/area has 5 moving objects, it makes sense to combine them. If the game has 10 rooms/areas and each one of them 5 moving objects, you get a performance penalty if you combine them all 500 moving objects together. Combine them in groups of five instead.
    Do not combine items that are not visible at the same moment. Do not combine items that are not lit at the same moment by the same light source. And more. (Note to self : I have to make some guidelines before I ship the product to explain all that stuff ! ).

    Intended audience :

    Unity Pro users already have access to dynamic and static batching, which represent better alternatives at the moment. This solution should be of interest to
    - Unity free users
    - Artists who wish to simplify their content preparation.

    I plan to post some examples once the tool is ready, with profiling data to demonstrate the Bob results. Also, I wish to supply some free to download example scenes with / without combined meshes, so you can judge for yourself if it is useful for your needs.
    What I wish to clarify is that Bob is not a silver bullet that resolves everything. It can prove useful in certain situations, as any tool.

    Roadmap :

    I believe that a first version will be ready by Monday, this version addresses static mesh creation. Also, I must compose guidelines and example scenes. Right now I put emphasis in smoothing user interaction, with no more "follow 100 steps exactly" requirements. One - click for :

    - Combining meshes and materials, with automatic backup of the original meshes.
    - Reset button - original meshes back to the previous positions.
    - Export - for further processing, both mesh (.obj) and atlas (texture).
     
    Last edited: Oct 18, 2011
  35. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    I finished some modules, as well as their GUI.

    -combine static meshes : Combines any number of meshes with many materials ( that use one shader from the supported ones ) into one mesh with one material. If the combined mesh has more than 65k vertices, creates another one, e.t.c.

    -export : Exports mesh, material and texture of a given gameobject separately.
    [Edit] .obj files do not support vertex colors !
    ----mesh as .obj with 2 pairs of uvs (uv, uv2), normals.
    ----texture as ARGB32

    TODO :

    -reset button
    -documentation
    -examples

    I would like to hear if you have any suggestions, thanks.
     
    Last edited: Nov 5, 2011
  36. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi,
    I found a name : Bob tools. I have some pictures of the current GUI :)

    $Screen shot 2011-10-26 at 8.22.29 AM.png

    I have added some more modules

    -Combine materials only : For use with native batching system
    -Reset : Reverts the objects in their uncombined state
    -Expand submeshes : Creates a mesh and a material per mesh's submesh ( so you can combine them later )
    -Control of maximum atlas size, padding, naming of the object created
    -Implemented Undo
    -Added some helper classes for quick prototyping.
    -Tooltip help.

    As I started working on building some examples, I found some bugs. I managed to straight them out and I decided not to release the Bob tools before making more examples and tests. Release date is postponed for another 1 - 2 weeks.

    It would help me a lot if you could send me simple < 5mb some example scenes to combine. The more examples I try to solve, the more robust the final version will be. Just keep in mind that currently I try to refine static options, i.e. batch things that do not move.
    Thanks :)
     
    Last edited: Oct 26, 2011
  37. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    Hope all is well with you in Athens, I've heard of the wild news.

    !Excellent work on refining the script! Thank you.
    All of the scenes on my current project rely on skinned meshrenderers, so I cant send one your way(wish we could combine skinned meshrenderers).
     
  38. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi zhx,
    We all live in interesting times indeed...
    Nice to hear that it is useful. I work full time for the last 3 weeks on the new version, still in every new test I find new problems to solve.

    I started importing a scene from google 3d warehouse. This will be used as a showcase.
    New method added : Create monochrome texture tiles for diffuse materials with a color, that do not have a texture.
    In the picture you can see Susan, a model from sketchup.
    $Screen shot 2011-10-31 at 5.48.41 PM.png

    I currently try to improve export speed and build the example.
     
  39. crafTDev

    crafTDev

    Joined:
    Nov 5, 2008
    Posts:
    1,820
    2 questions...

    1. I have always been curious, why the name "Bob Script"? Is it named after you?

    2. Does this work with skinned meshes since Unity doesn't batch them anymore?
     
  40. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi jrricky,
    No, my name is Ippokratis. I asked in the irc a suggetsion for naming
    " a tool that can combine many meshes with many materials that share the same shader into one skinned mesh with one shared material resulting in one drawcall per shader".
    Mike responded "Bob" and it seemed ok, so I used it.
    Could you please give some more details ? I am not aware of this issue actually, do you have any links ? I was under the impression that skinned meshes run faster now due to multithreading, am I mistaken ?
     
  41. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,364
    Ippokratis,
    I've tried to create an universal material combiner tool (similar to yours) but it only works with non tilled textures (doesn't work on overlapping seams mind you). Do your Bob tool combine tilled textures too?
    If so, i'll buy it! ;)
     
  42. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi tatoforever,

    No plans for supporting uv offset, mip - map, overlaping uvs, uv tiling.
    A good reason to buy it ( when it will be for sale ) will be that one lucky customer will receive a digital pair of non - square pants. I am thinking about adding unicorn tears but I am not so sure about how people will receive it.
    Jokes aside, one paper from Nvidia explains why offset and tilling are not a good idea. Also why mip - maping is not so easy ( but possible ).
    I 've spend many hours today trying to figure out what was actually the overlap issue, couldn't you post here earlier ? :p
    Have you had any luck with your project after all those suggestions regarding batching in the previous post ?
    Remember, there are links to static batching solutions in the first pages of this thread ( non paid ). I am curious to know if you manage to achieve some improvements.
     
    Last edited: Oct 31, 2011
  43. Dreeka

    Dreeka

    Joined:
    Jul 15, 2010
    Posts:
    507
    Hey,

    When are you going to release the comerical version?
     
  44. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hey Dreeka,
    Thanks for the interest. I am trying to send it for approval this week.

    Update:

    -Implemented lightmap support
    -Shaders supported : Diffuse, Unlit/Texture, Unlit/Transparent, Mobile/Diffuse, Mobile/Unlit (Supports Lightmap).
     
  45. Dreeka

    Dreeka

    Joined:
    Jul 15, 2010
    Posts:
    507
    Is it going to support objectes with 2 materials (both material are diffuse).
     
  46. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi Dreeka,
    Yes, Bob Tools supports diffuse materials.

    Update : It is almost finished ( ! ).
    I added a progress bar, system error messages, native file save panel.
    Now I try to make a specs sheet, and a demonstration video.
    $Screen shot 2011-11-08 at 10.30.28 AM.png
    $Screen shot 2011-11-08 at 10.31.51 AM.png
    $Screen shot 2011-11-08 at 9.48.18 AM.png
     
    Last edited: Nov 8, 2011
  47. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi,
    Some news :

    1. New name : Batching Tools ( Bye bye Bob). It just occurred me that "Bob Tools" is not so funny for others, could be offending for some
    and is non self - describing at all. So Batching Tools is the new name.

    2. I decided to support more mobile shaders, including Bumped and Bumped Specular. First results ( not extensively tested ) are very promising.

    3. I managed to learn basic imovie skills and I made a small video tutorial. It takes me some hours to produce some seconds at the moment, plus it is too funny to hear me speaking English : ) The process of creating the video tutorial was very educational and helped me a lot to clear up my goals regarding this product.

    4.I wish to thank Airship for all the assets he offered that made the creation of the script possible. Also, elias_t for offering many models for free in his site and AcidArrow for explaining me some essential 3d modelling tricks . I tried to create some examples files and I found myself seriously bounded by my lack of 3d modelling skills. It is not possible to properly test the script without many assets and the only practical way to have assets for testing is to make them by myself. So, I decided to postpone further development for some weeks in order to learn some basic modelling skills. If it takes longer for me to create a chair, a table, a specular map, a normal map, how to deal with uv overlap and how to replace tiling textures with geometry then I will postpone the development as needed.

    5. I have good results both with custom static and custom dynamic batching. I found out though that from building a working prototype until publishing a polished paid script there is a big distance. I also believe that the public awareness regarding batching is low. I decided to concentrate my efforts in combining materials for use with Unity built- in batching, dynamic and static. I hope that this will make it possible to release sooner and to make more people aware about batching. I do not find a good idea trying to sell a custom batching system to people that are not aware of what batching is ( sadly, the vast majority ). So the first version of Batching Tools will be able to create shared materials for the Unity's built-in batching system only and future revisions ( if any ) will offer custom batching options.

    6. I am having a great time making this script ! I learned many things about Unity Editor in the last 5 weeks. I hope that anyone who is interested in this script will excuse the delays. I just find it unfair to others to publish something that is not well made and to me to work for something that does not have good chances to bring a profit. I also have a hard time to estimate the needed time, making wrong assumptions is very annoying for me and for everyone. I am sorry if you feel disappointed that the script is not released yet and I assure you that I am doing my best to release it as soon as I can. It is now clear to me though that I cannot estimate how long it will take to finish. I am trying to complete it before Christmas and I hope that I will make it.

    Thanks a lot for your time,
    -Ippokratis
     
  48. Schlumpfsack

    Schlumpfsack

    Joined:
    May 30, 2010
    Posts:
    608
    hmmm...if you want i can slap something together (modelling).
    what do you need? some kind of "dungeon construction kit"? tilable textures used? non-tileable? would produce something with diff + NM, if you want some rushed spec map too.
     
  49. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi Sclumpfsack,
    Thanks for the offer ! If you find the time , all I really need is


    • 1 low poly item i.e a fish or a simple spaceship under 250 vertices with normal and specular map ( as alpha in the main texture ).
    • 1 barrel ( up to 1000 vertices ) with normal and specular map ( as alpha in the main texture ).
    • 1 table ( up to 1000 vertices ) with normal and specular map ( as alpha in the main texture ).

    If you could provide the fish with one - color stripes as a separate material it would be extra helpful !
    Thanks for the interest, best luck with your Medieval Pack,
    -Ippokratis
     
  50. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Ippokratis... could this be used to stitch together sub meshes of an animated fbx with skinned mesh renderers? Eg: an animated person with sub-meshes like shirt, pants, each with their own skinned mesh renderer and seperate texture. Could I use batch tools to combine the shirt and pants into one object and one texture atlas for one draw call, and still have it animate?