Minimesh grass
In this tutorial we will add some grass to the landscape. There was already some sort of grass-like texture on the landscape, but there were no real geometrical grass blades. When we add all of those blades to our scene, you can imagine it will be quite slow if we don’t optimize it, since there are a lot of polygons involved in this. Luckily for us, it has already been optimized for us in the engine, by something called minimeshes. This is a kind of instancing implementation for meshes, so only the position and rotation have to be send to the graphics card instead of all the vertices every time. Of course there are more optimizations, but I won’t go in depth with them now.

What do we need?
- Of course we need a model of the grass blade with some sort of texture.
- We need the minimesh system, which is just a TVMinimesh object created by the TVScene object.
- We also need positions for the grass blades. We are going to generate those with a random number generator, but place them right on to the landscape.
How do we set this up?
- We need to load the grass blade, which you’ve seen a couple times already, so I’m not explaining that any more. One thing worth noticing though. A minimesh can only be lit by 1 directional light source. That limit has been forced for performance reasons. You can circumvent it by writing your own shader, but we’ll talk about that later in another tutorial.
- Now we need to create the minimesh object. We do that by calling:
Instancer.CreateFromMesh(Grass, false);
Instancer.SetAlphaTest(true, 128, true);
Instancer.SetColorMode(true);
The first line is self-explainatory. It created a minimesh object with 9999 instances.
The second line actually sets the mesh of the instancing system to the grass mesh we already loaded. We pass ‘false’ as a second argument to make sure we can scale the blades to make them look more real.
The third line makes sure the blades’ alpha channel of the texture does work. It tests if the alpha value of your texture is higher than 128. If it is, it will show, if it’s less, it won’t show.
The last line will as you’d imagine tell that it should be colored.
- To be able to place the instances on the appropriate spot, we need to know the height of the landscape, or the blades will be placed below or above the landscape instead of right on it. We can do that by calling:
This is really easy to explain, the function returns the float height of the land at the position x,y.
- Now we need to place all of the instances on an appropriate spot. We do that in the next couple of lines:
Instancer.SetScale(S, S, S,i);
Instancer.EnableMiniMesh(i, true);
Instancer.SetRotation(0, (float)rY, 0, i);
Instancer.SetColor(new TV_COLOR(1, 1, 1, 1).GetIntColor(), i);
The first one sets the position of the instance to the right position. Note that the last parameter is the index of the instance, we’re looping through all of the instance.
The second line sets the scale of the blade, to make it look more real. Of course the last parameter is the index again.
For some odd reason, the EnableMiniMesh function has the index at front. It works as it sais it does however, if you enable the minimesh, it will be rendered.
At the fourth line, we set the rotation of the blade to some random value around the y-axis (up axis). This will make it look more real as well.
The last line defines the material diffuse color of the minimesh.
How do we render this?
- We only need to call
to make it render. You don’t need to loop through all the instances yourself, it will do that for you, according to the enabled status of the instances. The rest of the rendering is the same as in the landscape tutorials.
Things you can add/change yourself
- Try substituting the blades for other meshes, to see the full potential of this system. It renders fast!
- Try to position the instances in a special pattern or rotate them in a pattern, to grasp the full way of how it works.
- Try to make the blades wave by adjusting the rotation of the blades in the loop. This might be quite slow depending on your system however, but it is fun to watch!