# Efficient foliage rendering with OpenGL

Rendering foliage usually involves "hanging" triangles and textures that have completely transparent areas. I'm interested in knowing how are these usually handled by a 3D engine.

The first thing that comes into mind is blending, but the issue with blending is that it requires depth sorting and while on a per-object basis this isn't an issue, proper foliage drawing would require that all triangles on the object are depth sorted otherwise parts of the foliage object behind the transparent parts of branches or leaves could potentially not get rendered at all. Even with per-triangle depth sorting, the issue wouldn't go away completely.

Another approach would be to use discard in the fragment shader, however that could prevent the GPU from performing the early depth test. Is this an issue though? Maybe foliage is usually rendered with basic fragment shaders, so the performance impact is negligible?

As you can see, i have a few ideas on how this could be done, what i'm looking for though is how it is actually done. I'm sure that lots of people have hands-on experience with this, so please share practical solutions.

Another way of doing it is with alpha test; in GL terms is looks like this:

glEnable (GL_ALPHA_TEST);
glAlphaFunc (GL_GREATER, 0.5);


With this setup, any fragment with an alpha <= 0.5 will be discarded. Don't forget to glDisable (GL_ALPHA_TEST) when done.

Is this compatible with early Z? Maybe, maybe not. Historically it wasn't but more modern hardware may be able to do e.g. a coarser depth test based on the triangle being drawn; this would be very hardware-dependent of course (but then again so is traditional early Z) and I don't have a reference for it.

Does it actually matter though? Again, maybe and maybe not. Alpha test (or discard) offers a tradeoff in another direction, where you can save on color buffer writes (and you commonly see glDepthMask (GL_FALSE) with alpha testing too, so you also save on depth buffer writes) if used, so maybe you'll come out on the right side of that tradeoff.

The nice thing about using alpha test is that you don't need to write another shader variation for it.

It's worth noting at this stage that under D3D10 and 11 alpha test no longer exists and you are expected to emulate it by using the D3D equivalent of the discard instruction; that obviously comes at the expense of needing another shader combination, but it does indicate that sometimes you can expect alpha test to be emulated in drivers by patching the fragment shader with discard instrcutions.

• I'm fairly sure that glAlphaFunc is deprecated, so you have to (if you're using core specification or OpenGL ES 2 or WebGL) substitute it using discard, so that doesn't change much. The issue is that there's tons of bad rep floating around about discard, so i REALLY would like to know how do people solve this in production, because for me, discard is the perfect solution because it requires no additional sorting and produces no artifacts, it's just that whenever i read about discard, people talk about performance losses unanimously. – dreta Jun 18 '13 at 12:03
• I think that unless you use geometry to define the shape of your leaves, there's no getting away from using discard. Another thing to consider is using signed distance in your alpha channel instead of opacity (it's what all the cool kids are doing these days). This does requires you to have a high-res version of your texures to begin with though. – GuyRT Jun 18 '13 at 15:07
• Using discard at the end of your shader should be fine. Most of the bad rep comes from clueless coders who try to do non-uniform discard early in a shader without realizing that the whole shader runs anyway (though without effect) due to how a GPU works (it's the same deal with non-uniform branching and non-uniform loops) – Sean Middleditch Sep 16 '13 at 18:20
• @SeanMiddleditch this observation should be written in bold even!! – teodron Oct 16 '13 at 12:52