Terrain trees, game object trees and draw calls

Hi all,

so why is it that when i have say approx 1000 tree game objects placed in a scene my draw calls are approx 4000 and yet unity’s painted terrain detail trees when i use the same mesh to paint in roughly the same amount the draw calls is more like 250. Even when the trees are mass placed with 10 times the amount of game objects the draw calls are still only fought 500-600.

thanks

If Unity’s trees are far enough away, they become billboards instead of full mesh trees and are combined into as few meshes as possible, this saves a lot of draw calls. So only the ones close that are “full” trees create a draw call. Even if you have 10000 trees in the distance, they can combined into only a few meshes.

As far as your gameobjects having 4x the draw calls as gameobjects, someone correct me if I am wrong but I think here is how it works:

Each tree you have usually takes up two draw calls: 1 for the trunk submesh, and one for the leaves submesh. So right there, if you have 1000 trees, you get 2000 draw calls.

Now, if you have a light in the scene, this adds another “pass” to show the lighting. So it has to draw each tree AGAIN. This means those 2000 draw calls? Double it. 1000 trees = 4000 draw calls.

Again, someone please correct me if I am off :slight_smile:

Anyway, there are some things you can do to help with this. Here are some thoughts/suggestions:

  1. Make your trees as simple as possible to get the look you want…no extra/unneeded leaves. This will help no matter what.
  2. Do the same thing as Unity…batch your distant trees.
  3. Combine your tree meshes into one draw call. This means you’ll combine the two materials (leaf and bark) into one texture, and just use one shader to draw the whole thing. Unity does this also with the built in trees.
  4. Another option…if your trees are not dynamic (you need to add and remove them)…you can batch your trees also. I guess it depends on how many detail trees you need to show at once.

Do we really care as much about draw calls as we do about FPS?
jc, you said in another thread that with some testing, a forest of meshes actually didn’t perform worse than LODing to billboards?

Does that mean that with a scene like a typical forest, the processes trying to save draw calls hit the frame rate about the same as the draw calls they are trying to clean up?

Thanks jc_lvngstn , I should have mentioned that i understood why I have 4000 draw calls, multiple meshes, materials, lights, shadows, etc. I know that these increase the draw call count. What I really was curious about was why unity’s draw calls were so low … so all the billboarded trees are combined as much as possible, thanks for clarifying that, I suspected something like that might be the case but i wasn’t sure. So does that mean that they are doing a similar combine with grass?

I could be totally wrong on this, and I haven’t done in-depth testing so please take this with a few pinches of salt.

I believe they are batching grass and distant trees (not together, but you know what I mean). Anything you don’t batch means you have to draw each.grass.quad or each.tree.billboard. You would hit your drawcall bottleneck before your fillrate bottleneck, especially with grass. If you have a 100m by 100m area of grass. With just one grass poly per meter that’s 10,000 individual draw calls. Same with billboard trees. So there is no way Unity is doing that, unless it is hiding it from the stats window. Even using Graphics.DrawMesh() generates a drawcall.

So I suspect they batch grass and billboard trees together. I’d like to see their grass shader code, because it can handle individual polygon rotation for grass to faced the camera which is nice, shadows, tinting and waving in the wind. I wish they would release a generic one to work with any batch of grass that people could use on their own.

Honestly, it seems to me that FPS is what really matters, and with things like forests fill rate kicks it in the gut, and draw calls will creep up behind and stab it in the back if you let them.

But…the “testing” I did with forests of meshes and billboards…I can’t speak for everyone else’s hardware, but on mine…I could put out a lot of trees with brute force (using Graphics.DrawMesh() ) for mid-distance trees, and still get what I felt was decent performance before I had to start billboarding them.

Honestly, now that I think about it…I can’t help but wonder if 1) Unity is not batching distant trees and grass, and they hide it from the stats window or 2) They ARE, but the batching isn’t very “optimal”…like maybe very small batches.

Did you see my thread on terrains with dense forests?

http://forum.unity3d.com/threads/188495-Procedural-Terrain-with-Dense-Forests/page3

I think if I tried to get forests that dense with Unity’s billboarding, the performance would take a huge hit. Granted, my solution is more “simple” but I even use 4 quads per distant trees, instead of one billboarded one. I wish I could get someone from UT, who knows how it works, to chime in and offer any insight or such. It could be helpful.

I batch those trees into pretty big batches. There definitely was a sweet spot between many small batches that could be culled from visibility, and a few large batches to reduce draw calls.
Anyway…to me, another prime candidate for batching are plants, rocks, that sort of thing.

For some reason, my brain has trouble processing this question. If you mean does batching cost more than just flat out drawing the trees…there are tools on the asset store (loom, and even some free stuff) where you can kick the mesh vertices, normals, etc creation to another thread. So…mmm I think I’d have to have some pretty heavy batching going on before I worried about that.