Specialization
GPU Rendered Grass
About
For my specialization at TGA I programmed grass entirely rendered on the GPU using the methods that Eric Wohllaib from Sucker Punch Productions talk about in this GDC talk .
In the demo video below more than 2 million grass straws are being rendered on a GTX 1060 3GB card.
That count is excessive and was purely to test and demonstrate the capabilities of the system.
Demo video
Details
The grass is generated in a number of different steps most of which are completely on the graphics card, which reduces the performance cost of needing to sync between the GPU and the CPU.
Step one
The first step is to divide the world into a grid. each tile in the grid is then subdivided depending on how close it is to the player. The tiles are subdivided recursively until they have reached their smallest possible or desired size. This is a light enough task to be done at the CPU.
Step two
The second step is dispatch a compute shader to generate the data of each grass blade.
The shader is dispatched on four of the world tiles at a time. After the compute shader is dispatched those four tiles are rendered.
This is repeated untill every tiles grass blade has been rendered. The point of the tiles though is that each one contains the same amount of grass blades, no matter the size.
This works quite well as you can see in the demo video, the far away grassblades, although sparse still cover enough on a flat landscape to make it look endless.
Step three
Every grass blades mesh is generated in the vertex shader.
Each blade is made of 15 vertices. Based on the vertexID coming into the vertex shader i calculate where on the blade it should be placed. They are then mapped to follow a cubic bezier curve to bend it. This is the curve that is modified by the Tilt and Bend values.
The wind being shown in the demo video is simply scrolling noise that modifies the tilt and bend of the blades.
The pixel shader is simply outputting to our deffered rendering GBuffer, so the shading is just standard PBR.
Conclusion:
This was a really fun project to make. I learned a ton of things that I had no real notion that I was missing before.
I've always been kind of fascinated by compute shaders, but never had the time or confidence to actually learn more about them, so it felt really good to actually implement them from start to finish and have them work this well.
The fact that it is such a visual result speaks to me a lot to. It makes it feel easier to feel good about my accomplishment.
In fact the results were so good that for the last project at TGA my own group and an other group is going to make use of this grass.
Latest update to the grass, it can now follow a heightmap