How to implement density maps with instanced rendering

643 Views Asked by At

I came across this amazing blog about rendering grass by Kévin Boulanger.

In his project he has used a certain density map:

enter image description here

The black areas represent places in 3D world where grass is to be rendered. And white areas are where the grass is not present.

My question is-- I am rendering grass in my scene using instanced rendering feature of OpenGL. But the grass is spanned pretty much across the whole terrain. I have not been able to map such density map with the positions of the grass that I am rendering.

How do I use such density maps with instanced rendering?

1

There are 1 best solutions below

0
On

What Kevin did was basically reading that density map (on the cpu) when generating the grass patch meshes and stored the value in the vertices (the same value in all the vertices of 1 blade). Then when the patch was rendered, in the pixel shader, if this value was less than some threshold, he discarded the pixel. The system is a little bit different patches made of billboards, density is stored in a texture instead. So basically you render grass everywhere but the grass becomes invisible on the road.

It's explained in his thesis, page 67-71.

But what he describes doesn't work with instancing because each patch is a different mesh or uses different textures so you can't draw them with instancing.

A solution would be to store this density value per instance of grass blade in a uniform buffer instead. So that each grass patch is the same mesh and can be instanced.

For the patches made of billboards it's more complicated, you would need to have "1 texture" per billboard. You could make a big texture (or a texture array) that contains the equivalent of several billboards and store a texture coordinate offset per billboard in the constant buffer. Be sure to reuse the same part of the texture for billboards that look identical in this case.