Foliage causing massive FPS drop

Has anyone had any luck using foliage (bushes or trees) in scenes and maintaining a higher FPS? Every time I have tried to use trees or plants, specifically from Speedtree, they cause my FPS to drop so much that I just have to end up deleting them. I can leave them in if I am just rendering still images or animations, but anything with realtime rendering like VR, they make the scene unusable. I was wondering if anyone was having better luck than I am.

We are not using speed tree but foliage is just fine. On mobile we have thousands of trees, millions of grass patches etc. Performance is solid. You just need sane lods, draw distances, densities and so on. Fortnite is good example of that. There is 2.5 * 2.5 km map. Most of the terrain is grass and there is grass everywhere. Still run fine.

How many trees and which landscape size they are covering?

Is it LoDs set properly on Speedtree for each tree model?

Ok, maybe I just need to practice more on optimizing my foliage. Is there any difference, or a significant performance difference, between placing individual actors or using the foliage tool to paint them?

There is. The foliage paint tool basically group them as a single actor. The experimental feature: foliage spawner volume (need to enable in project settings) also does the same. There is also an option where you select on your level two or more instances of any actor (don’t need to be the same type) and you can merge them (there is a huge optimization aswel).

yes, a massive one, it’s called instancing. every actor you place manually causes its own set of draw calls (cpu asks the gpu to draw). each actor, in this case a tree, could have say 2-3 calls for the different material, one for the mesh. these stack with every actor you place. get to around 2000-3000 and you will get massive fps drops. then comes along instancing, where we group all the “instances” of the same mesh, and THEN ask the gpu to draw it. say you have 1000 trees each with 4 calls for a total of 4000 calls, if they are instanced, its 4 calls. basically the gpu and cpu get bogged down talking to each other on 1000s of small requests and not on the actual work they should be doing

sounds amazing right? why isn’t it the default behavior then you might ask? it comes with one catch.
say you have a huge forest, and you decide to have a cave, and in that cave you have 1 tree from the forest.
even though you can’t see that forest from in the cave, that one tree will cause the whole instance of all the trees to be drawn. in a case like this, you place that tree manually, and the main instance of them will be properly culled