Overdraw performance hit prohibits foliage rendering

Rendering foliage such as grass is commonly done using low-poly meshes and alpha-tested materials, which UE4 supports with masked materials.
However, overdraw causes such an enormous performance hit that rendering this kind of foliage is almost impossible without massive FPS drops.
In this example scene, a small patch of grass takes up 8 ms at 1920x1200 on a GTX560Ti.

I don’t think this problem was as significant on a forward rendering path and other modern engines seem to support the same kind of foliage without the same performance hit. I would imagine those engines use some kind of hybrid to solve these issues.
Since foliage is such an essential ingredient for creating all sorts of environments, I was wondering if 1) there exists a solution e.g. by using a different rendering path for foliage and 2) if Epic is interested in solving this (if it can be solved).

I’d also like to hear if other users had similar experiences with foliage.

This is a common problem on all engines, it’s just due to the massive number of pixels that have to be shaded. I remember when I first played Oblivion on my PC with a Geforce 6800, the grass would halve my framerate.

The usual solution is to use more triangles to cut out the masked shape better, but it looks like you already did that pretty well. There’s a tradeoff between overdraw and triangle count as well, going too high on triangle count can introduce cost as well.

One thing we might be able to do is add a cheaper foliage shading model which allows for more overdraw which foliage typically has.

Thanks for clearing that up. I know that overdraw always existed, but it suprised me just how big the impact is. But maybe that’s also because we try to put so much more foliage in and the shading models have gotten more complex over the years. Now that you mention it, I also remember that Oblivion foliage made the framerate drop quite a bit :slight_smile: Probably shouldn’t have put this in the feedback section then.

This isn’t as much a common problem with all modern engines, as it’s a common problem in UnrealEngine 3+4. Take a look at the free Unity based game:
The engine renders insane ammounts of grass planes over eachother without killing the framerate on modern PCs. I’m using a laptop with a GTX560M, but get ~60FPS with the far grass setting and the highest quallity.
With the near grass setting that’s similar to the screenshot above I get ~80fps. This is with dynamic shadows btw, without them the framerate is doubled.

I tried this in UDK and got like 3-4FPS, I’m not sure how much the overdraw cost has been reduced in UE4, but the screenshot suggests it’s still bad.
The technique you described is necessary in the UnreaEngine and I tried it in Unity too, but it doesn’t add a benefit there since the cost of overdraw is incredibly low in comparison to UE.

Comparing performance between engines is like comparing apples and oranges, but I think it’s pretty clear that the overdraw cost of foliage is something that needs to be worked on asap in UE4.

I think it’s not really problem with overdraw or some other mysterious magical issues. The problem is, that foliage in UE3/4 is using exactly the same shading path as everything else. Those shaders I guess were not made in mind with using them over possibly thousands upon thousands of objects overlaying each other.

To make it work what is needed is separate very simplified path for massive foliage rendering.

That’s unfortunate. I really wanted to play around with an outdoor prototype.

How involved would it be to apply a custom shader to the geometry? I recall Ehamloptiran does it in his FluidSurface Plugin.

Adding new shading model is not very complicated.
Unfortunately just adding new shading model will not fix issue with foliage, as you will be probably building upon existing foundation.
The point is that existing rendering path is to complex for massive foliage rendering. I guess there needs to be more underlaying changes to make it really viable in engine.

Maybe a combination of a custom lightweight mesh (minimal properties) + shader, drawing in instanced batches, and a custom lightweight lighting model could potentially improve performance.

We’re working on a very foliage heavy scene at the moment and have encountered this issue.

We’ve tried many things to try and solve the issue:

Fewer clusters/many meshes
Fewer meshes/many clusters
Fewer meshes/fewer clusters
More mesh/less alpha
More alpha/less mesh
LODS with reduced/no alpha texture

We always knew it was going to be a trade off, but for virtually pure foliage scenes (and quite static gameplay) it presents a real problem.

If anybody has any more ideas, I’d love to hear them.

Sorry to hear you’re running into issues as well. Did performance improve by eliminating alpha? It should, but I’m not sure it does.

It still is a significant problem for us as well. And it’s not just grass, trees and other types of foliage cause the same problems.
And as others have pointed out, there are many examples of games showing that foliage heavy environment scenes can be rendered efficiently, so it’s definitely an issue of the engine.

From my experience, reducing alpha doesn’t really help much unless you start the fade distance kind of close, and I don’t think there is a way to not make it look bad.

I got same problem painting instances of grass bushes. Does UE4 have a special instancing system for foliage ?
As open source engine i think somone will bring a faster solution soon.

What performance do you think you should get, and what performance are you getting?

Did you look at the OP? 8 ms to render such a small amount of foliage… isn’t something you can work with.

Yeah, I did I am just not sure what is expected. That seems really low, I had done a little testing and don’t get such terrible results. So was wondering what is expected on that system

Eliminating alpha looked terrible. LODing to a solid texture with a very thin shred of alpha at the top (to maintain some silhouette) was equally ugly.

Reducing the amount of alpha with more geometry got heavy very quickly, even with foliage instancing.

We’re leaning towards using much more grass per patch, so we cover a much wider area with each patch, but it doesn’t solve overdraw problems, and it gives us less control unless we also use smaller individual patches too.

I’m afraid it’s not an adequate solution.

Well I did a quick test 2000 trees and a whole load of foliage with speeedtree (nothing else but a heightmap), in Unity 60 FPS 15ms latency in Unreal 4 FPS 83ms latency… That did include occlusion culling from umbra on Unity’s side. But no lightmapping in either…

@Daniel, the speedtree meshes for grass are only 32 tris after some tweaking.

If you take a look at all UE4 main demos you will see these are indoor levels or only small terrain demo not so populated , UE4 is not build from ground for big outdoors with foliage like Crysis engine is. This will come soon from Epic or from community members that will push some tech for that purpose in the open source pandora box, you must be a bit patient.

We have a team here and some engine developers, whilst it’s fine for us to implement our own backend and upgrades when we can settle on a stable version. A year on from when we first started testing out the engine, these basic things should of been covered by now.

I’m fine with being patient, I’ll even lend a hand if needed. But there is too much at the moment for a small team of 10 to handle, so I hope Epic manage to get all the niggly’s sorted and pull the engine out of what I class it to be “Beta”. It’s an amazing engine, don’t get me wrong… Personally I think they need a couple of bug and improvement releases as opposed to shiny new features.

We will be using UE4 long term and were still getting to grips with it in places, just looking for the dust to settle.

We have the same problem. We’re highly dependent on foliage but there’s just too many issues with it now. Bad performance, bad lighting and the foliage mode UI needs a revamp as well. Epic have said that they’re working on some foliage related stuff for 4.6, I really hope they see the importance of all this.