Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Definitive thread on import pipeline best practices

Discussion in 'External Tools' started by Joe ByDesign, Dec 1, 2006.

  1. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Hi all, there seems a lot of displaced general tips on getting assets into Unity so performance is high, typically at the cost of editing flexibility.

    I'd like this thread to be a definitive list of concrete trade-offs when importing assets to gain best performance. OTEE / SG guys please chime in here also! :)

    I'm currently refining my pipeline and I've spent a lot of time doing and re-doing the assets trying to get the best FPS and still don't feel I know reliably what to do here. I don't want to spend any more time than necessary repeating work (it takes away from doing more important gameplay features)

    By following the general tips available, and after much trial-and-error juggling, I find my performance is only about 30fps but the scene is not very detailed at all, there are only about 5 object types each about 2k and it is not at all detailed like the palestine shots. I haven't even added characters yet and already am at 30fps.

    SG how *exactly* did you get those palestine shots so detailed without killing framerate?" I need details! :)

    -------

    Example scenario; a more or less realistic park scene where you have essentially re-used objects; signs, benches, sidewalks, trees, paths, garbage bins, etc.

    Signs, benches and garbage bins share material + texture as do each type of object (all path objects use path material + texture, all sidewalks use sidewalk material + texture, etc.). The layout of the park scene has these objects placed all over the scene, as one would expect in a park scene.

    In such a scenario, what is the best way to get the scene running at a good fps in Unity? Assume doing the layout in the 3d editor since Unity doesn't yet have snap.

    Combine all objects of the same material before export? Or don't do the layout in the editor and import only the pieces, set them as prefabs and do the layout in Unity? Or something else I'm missing?

    In the park scenario, what is the poly cut-off where there is no longer a performance advantage for combining objects of the same material type? Is it really 2k? Imagine the signs, garbage bins, and benches spread out over the entire scene, when is it no longer efficient to have those all as 1 mesh?

    Here's a confusing example. It is generally considered that fewer objects and materials are better. So I created 1 big plane for the floor of about 6k polys and noted the performance. Then i tried another approach using GameObject -> Create Other -> Plane (about 400 tris) setting the plane as a prefab, then duplicating the prefab over the same area and adding the combine children script (total about 25,600 tris). Within the view frustrum of the camera there were again about 6k tris visible (out of 25,600). However using this small prefab option and the mesh combine script, performance was about 20 FPS faster despite the increased number of objects and higher combined number of polys.

    Until there is a 3D tool that lets us layout objects with their own mapping and materials then slice big chunks of the scene based on poly count + take all the mapping textures of the elements in each chunk and put them all into 1 texture (such a tool would be a game makers dream!), I'd like some more clarification on "best practices" in the above palestine / park scenarios, where objects are re-used in the scene.

    Thanks!

    *edit: hmm seems to be a bug between preview and submit if "" is used in title.
     
  2. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    First, let me be frank - in the GC shots, framerate was not stellar - around 10 FPS (which is ok for cutscenes). Ingame we have a much more downward looking view.

    Here's what we do:

    We join things as much as possible, and use large texture sheets (so we have say, 8, wall textures in one image). This means a building only has two textures, a tree only one


    We place the individual buildings in Unity, on top of a ground plane that is approx 20 objects. Duplicating the buildings in Maya would waste too much VRAM as each building would get its own mesh.

    The other thing we've done is to cheat with lighting: we pre-bake all lights (so it can't change while playing). This means that all objects are rendered in one pass using custom shaders.

    For more speed, we have a layered camera approach, where we use culling masks so we don't render details on far-away objects.
     
  3. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Thanks Nicholas for the good info. Right now I'm using more or less 512x512 textures for the various textures in use. I'll try texture sheets to reduce the number of textures in use and post the results here.

    It seems the best way forward is as you suggest to yeah create objects in the 3D editor and lay them out in Unity as prefabs. Unity could *really* use some simple Snap to aid this... :)

    Any other takes on some of the other specific questions? Would like some concrete best practices info as for "what optimizations work best when" if such info exists.
     
  4. drJones

    drJones

    Joined:
    Oct 19, 2005
    Posts:
    1,352
    i'm sorry but could you clarify this? i'm wondering particularly about your last line, is this only with regards to combined meshes that share materials? in my case i have a blender file that has around 15K verticies with many objects (because they need to be positioned exactly) that basically contains 90% of my current scene. so would it be better for me to split it into 1 obect per file - or is this only if you are to be combining them in unity?
     
  5. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    I think what is being expressed here is that the buildings are the same meshes so it makes better sense to import 1 and make it a prefab rather than duplicate it in Maya (where instances do not export as 1 mesh but as many)
     
  6. drJones

    drJones

    Joined:
    Oct 19, 2005
    Posts:
    1,352
    ok, that makes sense now. i just wanted to make sure.

    somewhat OT but a little while ago i finally put an FPS counter in my scene and couldn't figure out why my game was running so slow - i tore my hair out trying to optimize everything, changing physics, reducing poly count, tweaking particle systems yada yada - it turns out at some point i was fooling around with the quality settings and left them way too high, anisotropy on things that didn't need it, and a couple of giant textures that i thought i had removed from the scene.

    live learn...
     
  7. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    You say that giant textures caused a slow down, but Nicholas' post suggests that it's a good optimization! :)

    This is exactly why this thread was created, to try to pinpoint what the truth is and the specific conditions that make those statements true.
     
  8. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,435
    Please correct me if I'm wrong, but I think Nicholas was referring to combining multiple smaller textures into one big one. I've done that in my vehicle sim. It has 4 parts and I UV mapped each part to one of 4 512x512 corner of a 1024x1025 texture map.

    I'm still learning the whole "speed up and optimize" thing in Unity, it's a "dark art" IMHO. Hope to pick up some tips here as well.
     
  9. drJones

    drJones

    Joined:
    Oct 19, 2005
    Posts:
    1,352
    i imagine its because they weren't texture sheets just large single textures, and were appied to multiple objects that could all be in view at once. i was just testing sizes at that point - seeing what makes the scene choke - and of course forgot that i never replaced them with appropriate sized ones.

    i really can't say how much the changes helped individually, but once i made them all the scene went from 10 FPS to 30-40.
     
  10. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    No I think you're right bigkahuna, but there are perhaps some conditions where drJones is correct, and hopefully together we can pinpoint those conditions here in this thread once and for all.

    I've run into a little export problem so it's taking me a little longer than i expected to post results from making my "multiple 512x512 textures" into a single big texture, but I'll post once I've got the results.
     
  11. anachreon

    anachreon

    Joined:
    Sep 12, 2005
    Posts:
    67
    Not sure if it's viable: The Developer Tools (free from Apple) include OpenGL Profiler and Sampler. I haven't touched these so I can't say much as regards their ability to hook into Unity or their usefulness in these circumstances. Don't know if it would be worth someone incorporating them as plugins in order to profile your game from within Unity.

    Cheers,

    Luis.
     
  12. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Indeed a profiler would be handy, and I'm pretty sure it's on the OTEE list of things to do eventually (naturally). Until then, let's try for some more concrete technical data going on exactly what / when to do specific optimizations.

    Following the above, I spent a good part of yesterday converting appropriate meshes to re-use a single material + texture sheet and I found that I'm still hovering around 33FPS. (This is without characters and behaviors, as i have only a modified FPS walker in the scene and a rigidbody camera).

    Maybe someone from OTEE can chime in here, when exactly is it "best" to use a texture sheet vs. multiple separate textures in Unity? I haven't noticed a major change in doing so and need to know why.

    I have about 11 bump mapped objects comprised of 24 pieces (@12k tris total) and of those 22 about 12 use the same material (8 materials total) with a total of about 5 diffuse textures and 5 bump textures. Objects that do not use the same texture are typically because the texture used is tiled. I have 1 small point light (range = 5) and 1 directional light.

    I'm selectively using Combine Children to get meshes that share material down to the target 1500 tris 'sweet spot' mentioned in the docs. I find this aspect of the work a bit more manual than needed and am considering updating the Combine Children script to automagically do combines based on the 1500 poly count cut-off and object proximity (will share this if it happens).

    Another confusing point. I have 1 object that is about 330 tris. I have 20 of them spead about the scene and split them into 2 empty parents of 10 each (about 1500 tris per parent). The results confuse as that it didn't matter whether I do a Combine Children for each parent, or for all or for none; I noticed no change in performance in any case (measured in FPS FWIIW).

    I don't want the focus here to turn to being about my scene specifically but more about what are some concrete conditions IF / When it is best to do X Y to get performance up in Unity. We can start with the texture sheet and the children scenarios. Why didn't these optimizations have a noticeable effect? Clearly the reasons can be varied, but that is exactly the kind of solid information sought... 'when is it best to do this or that?'

    I feel the (otherwise excellent) documentation on optimization covers high level points well, but by example, the tips haven't helped me bring my more or less simple scene up to a better FPS. Let's get some concrete tips based on hard data going to reliably follow.

    *edit: update # of textures to include trees.
     
  13. Garen

    Garen

    Joined:
    Apr 24, 2006
    Posts:
    97
    This thread is great! I have a question regarding my own ignorance. If I want to have many of the same objects in a scene, like rocks or trees, would it be best to (Function D) duplicate that object in Unity then place them were i want or would it be better to duplicate that object in my external 3D app and combine the many objects into one mesh that share the same material? Does it matter?
     
  14. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    After continued research and lengthy trial and error, it seems that the best performance is gained by having the objects cloned in Unity (using Prefabs) instead of doing this in your 3D editor app. This may change depending on how low your target machine is. I wish we had some more "concrete" data to describe where the cut off is, but as of today, it looks like it info is long coming (we'll see when Unity gets a performance analyzer).

    If polygons are not crushing your framerate, then the next big killer seems the number of different materials you have, so combine materials as much as you can in your editor. It cannot be overstated. I've seen performance gains as much as 30% by doing this on 1 single object, but likely the cut-off depends on a number of factors like your machine, the vram, texture size, poly count, etc.

    The above points has been previously given by OTEE, but I've also found confusing results depending on unknown factors, the performance results can lead to some confusion in the course of developing your level. Example, sometimes things that shouldn't make much a difference in performance makes a world of difference (like having a moving object's inspector open while your game is running can slow it down, or combining some relatively low poly objects using Mesh Combine can actually cause a decrease in performance).

    Sadly, trial and error is, for now, likely still your best bet, given the number of variables involved.
     
  15. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,735
    Combining meshes in your modeller or combing them from code in Unity does make zero performance difference at runtime.
    The important thing is that you do the combining!

    I think in the case of instancing a bunch of exact copies of the same object, it is better to create a single .mb file with the one model. Then instantiate it in Unity and use the mesh combiner to optimize performance.
    This is because you can then tweak performance in Unity by combining your objects there. Also you can move / and test things out faster in Unity than if you move your objects in Maya then have to reimport the whole scene.


    The important part here is, that this .mb file (eg. a plant, tree, big rock, pile of small rocks) is itself as combined as it can be. And DOES NOT use multiple materials and uses as few meshes as absolutely possible.

    Sure i use the word absolute a lot here and of course sometimes you want to have that special shader on only the eyes of the character, and if the visuals look a lot better with it it's probably worth it, but it's something else to just add another material out of convenience because it would take a bit longer to get the uv coordinates right and combine some textures. Having one material instead of 2 materials, can mean that your performance halves! (Given that you are bound by draw calls of course)


    Performance increases of 30% by properly combining is nothing. You can easily prove this to yourself. Place 300 cubes in a scene. Move the camera far away (So that you are not bound by fillrate). Then add a mesh combiner. Once you see frame rate jump by 500% you become a believer.

    Now thats an extreme case, performance on todays graphics cards depends on many things. The three most important bottle necks are:
    * Fillrate
    * Draw calls
    * vertex trhoughput
    * texture memory

    If you are fillrate bound, you have too much overdraw. You are probably using too many expensive shaders on a graphics card that cant handle it. Solution is to reduce overdraw, by culling objects that are not visible. Use vertex lit shaders. Use fewer pixel lights. (Every pixel light will make the object that is lit by it be rendered twice -> This might halve your frame rate)

    If you are draw call bound you are probably rendering too many small meshes. You solve it by combining objects, by sharing materials. By being a good artist, who never uses multiple materials unless he really has to. And never uses extra meshes, unless he has to.

    Vertex through put, means you are drawing too many vertices. This is rather uncommon except if you are on a intel extreme graphics card. Those cards do the vertex processing on the cpu, so it costs you extra performance. Solution is to use fewer triangles. On intel cards, it can also be solved by using vertex lit shaders and no pixel lights because that code path is more optimized in Apple's OpenGL.

    Texture memory. Sometimes the graphics card runs out of texture memory. You should always aim for never having more textures used during one frame than fit in the vram. There is a page on the wiki for calculating how much a texture takes up. Thing is, if you have only 32 mb, you will lose a lot already to the screen, depth and color buffers. Add a couple of 1024*1024 textures compressed with alpha channels (thats 2mb a pop) and you can see why this can quickly become a bottleneck. (12 1024x1024 compressed rgba textures and you are out of vram on a 32 mb graphics card)
     
  16. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,735
    And of course in general, measuring actual performance in the editor is not a very good approach. The editor does have overhead. Eg. when an object moves, the inspector needs to be updated to reflect the change in the gui. If an arbitrary value in a script changes, the editor needs to detect that. Having the scene view and game view visible means two cameras are drawing your scene. Etc
    In short: For real performance measuring. Build a standalone player.
     
  17. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Thank you Joachim for taking time to give some real data to these concepts. We're well on our way to concrete data here!

    Just a note; the 30% was referring to combining materials not meshes, but you covered both very well.

    Perhaps the next steps we can take are to start mapping such data to popular mac hardware targets and configs (and later for dx versions on win systems) for eventually cross referencing to # of macs in the field.

    Such info comes with experience, but at least some of it is already known, and I see no harm in documenting it, even if the data is 'loose'.

    In the past month alone, I've debated several times internally whether to do this or that optimization (each of which takes time) based on a weak perception of hardware targets "in the field" so to speak. Having such data, then mapping it (loosely even) to potential targets (with margins) would help loads, I think.
     
  18. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,735
    Start a page about it on the Wiki. If you ask the right questions on the page, i'd be happy to answer them in detail.
     
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,155
    My object routines (from the Wilderness Walk demo) really showed this...when I started, I had a separate object for every plant, but when I switched to building combined meshes, the fps typically went from 10-20fps to 150-200fps. It went from many hundreds of objects on-screen at once down to dozens. Of course it was significantly more complex to implement the combining routines, but that kind of performance increase made it worthwhile. It was basically unusable otherwise.

    It does seem like the Intel iMacs/Macbook Pros (not sure about the Mac Pros) suffer much less from the effects of having lots of separate objects, though. Is that a hardware thing, or is it something with the Intel build of OpenGL or what?

    --Eric
     
  20. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,837
    In those figures, are you including texture memory taken up by the OS? Or does the OS even take any VRAM if you're running in fullscreen?