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

Terrain rocks, draw calls and CombineChildren

Discussion in 'Editor & General Support' started by Charles Gill, Sep 6, 2008.

  1. Charles Gill

    Charles Gill

    Joined:
    Aug 1, 2008
    Posts:
    142
    NOTE: My observations were in error, though the practice of combining meshes for optimal performance remains a constant, my testing of the detail mesh painter was in error, see thread below.



    After reading up on the advantages of combining meshes to reduce draw calls I ran a little test to demonstrate to myself I understood the process and the advantage.

    Duplicated 200 rock meshes, ran the sand box noted 205 draw calls (200 rocks + gui + terrain + character + skybox + unknown)

    I placed all of them as children to a parent object with the CombineChildren script and saw my draw calls reduce to 5. Awesome.

    But I was a little surprised to find that if use the terrain detail painter to paint the rocks, they appear to have no such optimization.

    Next I thought I could iterate the terrain data at runtime and place all the rocks under a similar combined children parent, but could not find a way to reference these items via TerrainData.

    The docs imply I should be able to;

    However I only find methods for accessing the heightmap array.

    I hope I'm not "that guy" who asks a question without due diligence, but I couldn't find anything on the Wiki (aside from the terrain OBJ exporter) and could not find a match in the forums. In fact this post;

    http://forum.unity3d.com/viewtopic.php?t=12350&highlight=terraindata

    ...implies maybe it's not an obvious thing afterall.

    As it stands, it appears using the terrain mesh detail painter is fun and easy, but maybe not really practical, in terms of performance?

    Charles
     
  2. Charles Gill

    Charles Gill

    Joined:
    Aug 1, 2008
    Posts:
    142
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The rocks aren't all made at once; they are created and destroyed dynamically from a texturemap around the player's position. Hence doing a combined children parent is impossible. What would be theoretically possible is to have a single mesh that the rocks are "put into" when instantiated, instead of having each one be a separate object, like what's done with the billboarded trees. However it would be more complicated since detail objects can have an arbitrary number of polygons. That would have to be something for UT to do, though, if they're interested (either that or you could buy a source code license and implement it yourself ;) ).

    --Eric
     
  4. Charles Gill

    Charles Gill

    Joined:
    Aug 1, 2008
    Posts:
    142
    Heh.. thanks Eric. I'll just randomly instantiate them when I load the level and combine them then. Ultimately the random versus pre-painted approach is really what I need anyways. Thanks!

    Charles
     
  5. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    Actually the detail meshes are combined, just not into one big clump. Instead they are combined based on sections of the detail map. I'm have have no knowledge of the math behind this technique, but you can do a simple test yourself... paint a ridiculous amount of detail meshes into a small section of a terrain and you'll see the draw count plateau as you keep on painting in more objects.
     
  6. Charles Gill

    Charles Gill

    Joined:
    Aug 1, 2008
    Posts:
    142
    AT,

    Yes sir, you are correct. Although strangely if I paint what looks like roughly 150 rocks my draw call is about 150, at which point it does plateau regardless how much more I paint; however the "damage" is somewhat done by that point.

    Meaning I duplicated 600-800 rocks within 2 combined meshes (because once you exceed 65k vertices in a single combined mesh it gives an error) and my draw calls were at 5 and my FPS were between 98-100.

    I read that certain scalings could result in extra vertex buffers uploaded but I did not see that. I scaled, rotated and played with a dozen or so rocks without any visible change in the performance metrics.

    By comparison, while the detail mesh painting plateaus at 150, as soon as I paint those first 150 rocks I'm already at 30-40 FPS.

    All of this bears witness to the first rule of optimization that OTEE lays down, that being Combine, Combine, Combine.

    I first noticed this techniques while studying the Island Demo which has all of it's rocks combined in a single mesh (and, in fact it does appear to be the same rock used over and over again with various rotations and scaling to disguise this fact).

    I'm just surprised by the dramatic difference. It makes me wonder if grass were done by hand with combined meshes would you see a similar gain in performance? I'll play with that some later.

    Thanks!
    Charles
     
  7. Charles Gill

    Charles Gill

    Joined:
    Aug 1, 2008
    Posts:
    142
    Oops. Big goof by myself, noted at the start of this thread.

    I wrote a script to instantiate 1000 rock meshes and combine them into single mesh resulting in a single draw call and 100 FPS.

    I painted what appears to be 1000 rocks which resulted in 90 draw calls and.... 100 FPS.

    I traced my steps backwards and found that my ORIGINAL use of the detail mesh painter had accidentally used the GRASS shader for painting the rocks, rather than the vertex lit shader.

    In addition, it appears that the detail mesh painter not only DOES combine it's details, but appears (based on quick math) to combine them smartly into the optimum batch size to be served to the GPU.

    I apologize for my hasty, inaccurate conclusions. = )

    Charles
     
  8. Mingo

    Mingo

    Joined:
    Nov 14, 2010
    Posts:
    39
    I'm digging up a very old thread here, but I'm asking myself a similar question at the moment:

    Do trees painted on the terrain batch, and if so how do I enable that?

    If I paint a dense clump of low-poly trees (141 verts, 100 tris) using the terrain system and disable billboarding, I see no batching in the stats window and a very high draw call number.

    If I place roughly the same number of trees manually the trees batch and the draw calls are much lower.

    The game I'm working on is using an RTS-style viewpoint and a lot of trees, and no matter how much easier it is to paint the trees than place them, a combination of performance concerns and terrible-looking billboards from this camera angle are making me reconsider things. Why don't painted trees batch, even with the billboard fading and size/colour variations disabled? Are they not the same mesh/material? I'm not even seeing the billboard version batch.