AXEL FRANZÉN

SYSTEMS & ENGINE PROGRAMMER

GRASS RENDERING

The goal of this project is to get more familiar with instanced rendering and optimizing the rendering of a large amount of meshes. I also just wanted to make something that looks pretty as I’ve been down in the engine mines for a while now and working on something more graphics related felt like a nice change of pace. I’ve listed the references I used at the bottom of the page.

To render all these grass meshes I’ll be using instance buffers (in my engine, which uses DirectX11) and vertex animation to make ’em wiggle around.

a better look at the Mesh

A big part of how the field will look is of course based on the mesh its built out of. I figured I’d try out the “old school” approach of using textured planes but I ended up not being a fan of the way the vertex animation moved the mesh.

This mesh is a very cheap way of creating a dense field but as you can tell from the image it suffers from very obvious repeating patterns since they’re all just one texture. One solution to this could be to use a texture array that the pixel shader randomly picks from based on some hash value, but it doesn’t look quite right to me anyways so we’re going to try another approach.

The new grass mesh is a bit cartoonier/stylized but will work well for my purposes. This time I won’t be using a texture and simply lerping between two color values based on the vertex color to create a gradient. This vertex color gradient is also what we’ll be using to animate the vertices to simulate wind movement.

grass chunks

Since the new grass mesh is only one blade of grass rather than a whole tuft like the previous one it will require a much higher density to populate. To allow culling to work I decided to split up the whole field into multiple chunks of grass, each with its own instance buffer.

Size Variation

A field of grass where all the blades are of equal height is gonna look pretty strange, so giving them some difference in size will help make it look more natural. For this I figured sampling a perlin noise function to control the scale of the instances would work well. Which it did… After some attempts.

Make sure the contrast of the noise isn’t too high or the result will be that of the image to the left, and sample the noise with the world position of each instance matrix rather than the position relative to its owner or you’ll get these odd-looking cutoffs in height between every chunk of grass. After some finetuning it ended up looking the way I wanted.

The code for creating the instance matrices of an instanced mesh. The amount of instance rows is decided by the density of the grass which is a tweakable parameter.

Wind Movement

The shader code to animate the grass uses a sum of sinewaves, the height of the grassblade to control the amount of sway, and a random value with the instance ID as a seed to create some variation between each mesh. These factors are multiplied by the vertex color so that the top is fully influenced while the bottom is kept still.

normals & light

To give the grassblades some shininess and to prevent their backfaces from being in shadow from the directional light, we can alter the normals based on the same vertex color gradient we used for the wind animation to point upwards. This creates some nice highlights when looking towards a light source.

stresstest & conclusion

Currently the test scene is rendering nine of these grass chunks, chugging along at a pretty solid 250 fps, but to achieve the visual I’m looking for I found that 25 chunks makes a big enough field, which takes us down to around 180 fps. I also tried spawning 125 chunks of grass, but that’s about the limit where we start dipping under 60 fps.

The biggest problem here is the load time, since I create all these instances sequentially at start up and each instance buffer takes around a second to initialize which is pretty unacceptable. The obvious solution here would be to multi-thread these tasks but since the code for generating the field of grass isn’t really that usable for anything outside of this project I’ll live with the load times for now.

References:
“Rendering Countless Blades of Waving Grass”, by Kurt Pelzer, Nvidia GPU Gems 2004
“How Do Games Render So Much Grass?”, by Acerola, 2021
“Grass Rendering Series”, by Karl Bittner, 2025