UnigineEditor
Interface Overview
Assets Workflow
Settings and Preferences
Adjusting Node Parameters
Setting Up Materials
Setting Up Properties
Landscape Tool
Using Editor Tools for Specific Tasks
FAQ
Programming
Fundamentals
Setting Up Development Environment
Usage Examples
UnigineScript
C++
C#
UUSL (Unified UNIGINE Shader Language)
File Formats
Rebuilding the Engine and Tools
GUI
Double Precision Coordinates
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
CIGI Client Plugin
Rendering-Related Classes

Adding Grass

The article provides the tips and tricks how to create animated grass, swaying and moving as if with the wind. Your grass will also realistically vary in color across the field, so that it does not look unnatural like a freshly-painted lawn. Moreover, you will keep the frame rate high when rendering all these polygons. No matter how big your grass field should be (it can cover the whole terrain), grass appears only around the camera. And here is a first tip: grass looks better upon a hilly terrain. As for planes, low and non-dense grass would be a reasonable choice.

Required Textures#

The textures that are required to set up grass (within this tutorial) are the following:

Notice
The textures used in this tutorial are taken from the Tank demo and the Samples 2 demo. The demos can be added via UNIGINE SDK Browser. However, you can use your own textures if any.
  • Diffuse textures. Within this tutorial, we will use 2 diffuse textures: one for regular grass and one for grass of various types. The first texture has 1 x 4 slots and the second texture - 4 x 4 slots. As we are going to use the image mask for specifying the grass density distribution, the diffuse texture can contain less than 4 columns. The textures are obtained from the Tank demo.
    Diffuse Texture for Regular Grass
    Diffuse Texture for Grass of Various Types
  • Spatial noise texture (RGB). It will cover the whole terrain and allows you to color grass differently in all locations.

    Notice
    The texture does not have the same size as the terrain, but should meet the following requirements:
    • Dimensions of the texture should be equal to some power of two (for example, 1024 × 1024, 2048 × 2048 and so on).
    • Dimensions of the texture should be proportional to the terrain size. For example, if you have the 4096 × 4096 terrain, the texture should not be 256 × 512.
    • Dimensions of the texture should be chosen so that to get the result of appropriate quality after mapping pixels to the terrain. For example, if you have the 4096 × 4096 terrain and the 1024 × 1024 texture, 1 pixel of this texture will be mapped to cover 4 units of the terrain. If such quality is enough, you can use this texture. Otherwise, you should create a new one of an appropriate size.
    Within this tutorial, for the 4097 × 4097 terrain, 2048 × 2048 texture will be used (1 pixel will be mapped to cover 2 units). The texture is obtained from the Tank demo.

  • Image mask that determines spreading of grass across the terrain. Each channel of the mask (R, G, B and A) controls if the grass from the 1st, 2nd, 3rd and 4th columns (respectively) is rendered or not. The grass will grow only across areas with a channel color value.

    Within this tutorial, we will use 2 image masks taken from the Samples 2 demo:

    • R8 texture for the regular grass, as its diffuse texture contains only 1 vertical column. The regular grass will be rendered where the red color is.
    • RGBA8 texture for the grass of various types, as its diffuse texture contains 4 columns. The grass of various types will be rendered where the white color is.
    Image Mask for Regular Grass
    Image Mask for Grass of Various Types
  • Translucent texture that stores information on grass material translucency. It is represented by the R8 texture atlas, and the number of rows and columns is determined by the number of grass chunks in the diffuse texture. Within this tutorial, we will use the translucent texture for the regular grass, so it will contain 4 vertical slots. This texture can be used instead of tweaking the Translucent parameter of the material: the texture specifies areas of the grass blades that permit light to pass through, and the parameter allows scaling of such translucence effect.

    The texture is taken from the Tank demo.

Step 1. Prepare World#

Before adding and setting up grass, you should prepare the world. If you have a set up world with the terrain, the sun and the atmosphere, you can use it. If you don't have one, you can slightly modify the vegetation/forest.world in the Samples 2 demo (can be added via UNIGINE SDK Browser): delete all child nodes of the landscape node in the World Hierarchy.

Within this tutorial the modified forest.world will be used.

Step 2. Add Grass#

Within this tutorial, we are going to add 2 types of grass: the regular grass and the grass of various types.

  1. In the Menu bar, choose Create -> Grass -> Base and drop the grass somewhere in the world.

    Grass object added to world
  2. In the World Hierarchy window, clone the added Grass Object. Rename the objects as follows:

  3. Select the added Grass Objects in the World Hierarchy window. In the Node tab of the Parameters window, go to the Surfaces section and define the area of visibility for the future grass field. All grass blades cannot be rendered at once, especially, if the field is huge. Instead, they are going to be rendered in a small area around the camera.
    • Set the Maximum Visible distance to 4 units. Within this distance from the camera all grass blades are visible.
    • Set the Maximum Fade distance to 90 units. Over this distance the grass will gradually fade out according to the alpha channel value of its diffuse texture.
    As a result, you will see that the grass polygons appear and fade out within the set distance (94 units).

  4. In the Grass section of the Node tab, set the real size of the grass field: select both grass objects and set Size X (along the X axis) and Size Y (along the Y axis) to repeat the size of the 4097 × 4097 terrain.

  5. Add the grass objects as child nodes to the terrain, so the grass can grow upon the terrain repeating its relief: select the grass nodes and drag them to the terrain node with the left mouse button pressed.

  6. Check Intersection option to enable intersection with a parent node.

    Now the grass grows upon the terrain (repeats its relief), but the field is still not positioned properly:

  7. In the Node tab of the Parameters window, reset position of the grass objects to 0 relative to its parent in the Common section.

    Position of the grass object becomes synchronized with the terrain:

  8. Currently, coordinates of the grass quads of both objects are coincide. To avoid grass quads flickering, position grass quads of the grass_regular object differently: click Randomize (Node tab -> Grass section) to generate a random seed.

Step 3. Set Up Grass Material#

Now you should create materials for the grass objects before tweaking their spread any further.

  1. In the World Hierarchy window, select the regular_grass and variation_grass nodes and go to the Node tab of the Parameters window.
  2. Go to the Material section of the Node tab: currently, the base grass_base material is assigned to the grass nodes. Click inherit or to create a new child material. The new material will be automatically assigned to both grass nodes.

  3. Rename the new material grass_regular in the Name field.

  4. In the World Hierarchy window, select the variation_grass node and go to the Node tab of the Parameters window. In the Material section, click to inherit a new material.
    Notice
    In this case, a new material will inherit all settings of the grass_regular material (e.g. slope, stem noise and so on). Anyway, you still can inherit a material for the 2nd grass object from the base grass_base material and set specific settings for it.
    The material will be assigned automatically to the selected variation_grass node. Rename the new material grass_variation in the Name field.

  5. Adjust the materials of the grass objects: for each material, go to the Textures tab and drag the diffuse texture to the corresponding field.

    Notice
    You may want to manually edit the alpha channel of the mipmaps, because on automatically generated mipmaps thin blades may disappear incorrectly or unpleasantly.
    Diffuse Texture for regular_grass
    Diffuse Texture for variation_grass
  6. Go to the Grass section of the Node tab. For both grass objects, set the proper number of horizontal rows in the diffuse textures in the Num Textures field. For example, we have 4 rows for both grass objects, so the Num Textures must be set to 4.
    Notice
    As you can see, the regular_grass node isn't rendered properly because there is no image mask. The diffuse texture of the regular grass contains only 1 column, so the 1-channelled image mask (R8) should be set.
  7. Drag the correct R8 image mask from the Asset Browser to the corresponding field in the Grass section of the Node tab to fix rendering of the regular_grass node. We will set up all related parameters later.

  8. Go to the States tab of the Material section (Node tab, Parameters window). Check the Noise option for the grass_regular material. It will allow you to color blades of the regular grass differently across the whole field. The Noise option will also be set for the grass_variation material.

  9. For the grass_variation material, go to the States tab of the Material section and uncheck the Noise option. It will allow the grass of various types to differ from the regular grass.
  10. For the grass_regular material, go to the Textures tab and drag the spatial noise texture from the Asset Browser to the Noise field.

  11. Go to the Parameters tab of the grass_regular material. To the right of the Noise Transform field, click to edit the values (or modify the expression right in this field).

  12. Set the scale of texture coordinates by X and Y axes to 1: in this case, the spatial noise texture will cover the entire terrain.

    You can see patches of light green and yellow grass:

  13. The colors are too vivid to match the terrain colors. Drop the Scale to 0.38 to dim the noise color.

  14. The blades are quite thin, so make them a little bit more transparent to light when it shines from behind: increase the Translucent parameter up to 0.7 for the grass_regular material. For the grass_variation material it will be applied automatically.

    The grass will become more transparent and lighter:

  15. Go to the States tab and enable the Translucent option for the regular grass. This will activate the Translucent Map in the Textures tab that allows specifying translucent areas of the grass blades.

  16. In the Textures tab, drag the translucent texture from the Asset Browser to the Translucent Map field.

    According to the texture, the translucence effect applied to the grass blades will be gradient.
  17. Disable the Translucent option for the grass_variation material.
  18. Increase the Alpha Intensity to 1.5 to scale the alpha channel of the diffuse texture of the regular grass. In the result, the grass field will look denser.

  19. For now, transparency and diffuse coloring values are the same for the grass_regular and grass_variation materials. Change these settings for the grass_variation: set the Translucent parameter to 0.5 and the Alpha Intensity to 0.8.

Step 4. Set Up Grass Density and Spread#

  1. First, set up the density of the grass. For the regular grass, go to the Grass section of the Node tab and drop the Step to 17. It will make the cells which are used to render the grass field smaller, however, this value is not so large to hit the performance when the cell is created.

    The Subdivision should be set to 1 to avoid additional subdivision of the grass cells: higher values of this parameter are usually used when the grass is used as a low-poly distant LOD of a forest created by using World Clutter or Mesh Clutter.

    The grass is regenerated. The density also changed, because it is defined for one cell. As we made the cell smaller, the grass turned out to be slightly more dense.

  2. Increase the Density of the regular grass in a cell to 2.5 to add more grass blades on the field. For the various grass, set this value to 0.5.

  3. Now tweak the spread of the grass. For the regular grass, we have already set the image mask. Now you should set it for the grass of various types: drag the RGBA8 image mask to the Mask Image field in the Grass section of the Node tab.

    The grass no longer grows on mountains peaks and stony areas:

    Notice
    To paint the image mask directly in the scene, use Mask Editor.
  4. Set the Threshold to 0.3 to increase the mask intensity.
    Notice
    Perform this step for both grass objects.

    This will decrease the area that the grass covers:

  5. Usually the grass does not grow on the steep hillsides. Increase the Angle to 0.85 to make steep areas grassless.
    Notice
    Perform this step for both grass objects.

    Now the spread of the grass is more realistic:

  6. Currently, all types of the grass of various types (in other words, slots of the diffuse texture of the grass_variation node) are spread uniformly across the grass field. However, in nature, one type of grass can predominate over the others or grow in small groups. To achieve this, change the Probability parameter so that one type of the grass will predominate over the other types according to the diffuse texture.

    For example, you can set the probability factor to 4 for the 3rd column of the diffuse texture:

Step 5. Set Up Grass Shape and Orientation#

  1. When changing from bare areas to grassy ones, our grass starts to grow as small and thinned out. But on the stones, it does not look too good: Increase the Min height up to 1.2. In areas with low density (according to the mask) the grass will be higher. You can set different height values for each of four columns in the diffuse texture, or leave it the same for all.
    Notice
    Perform this step for both grass objects. For the regular grass, setting the value for the first column is enough.

  2. Increase the Max height of the grass blades to 1.7 units. In areas with high density (according to the mask) the grass becomes higher. We'll use the same height for all four columns in the diffuse texture as well.
    Notice
    Perform this step for both grass objects. For the regular grass, setting the value for the first column is enough.

  3. Unlike trees, the grass is usually grows perpendicular to the terrain. Check the Orientation in the Grass tab of the Parameters window to orient the grass objects along the normal of the terrain. Perform it for both regular and variation grass.

  4. From above the grass seems too flat. In the Material section of the Node tab (the Parameters window), go to the Parameters tab and increase the Slope to 0.5 to make it more billboard-like.
    Notice
    The slope will be the same for both the grass_regular and grass_variation materials.

  5. Grass blades are too thin and sometimes appear in dashed lines. Increase the Alpha intencity up to 2 to make the blades look thicker and the grass denser.

Step 6. Set Up Grass Animation#

In nature, grass isn't static. So, it is necessary to set up grass animation. It can be set via animation settings of the grass material, so that all grass polygons are animated uniformly. Or you can animate some specific area of the grass field by using animation fields.

Within this tutorial, only the first method will be used. The example on using grass with animation fields can be found here.

Notice
Perform this step for the grass_regular material. The inherited grass_variation material will have the same values.
  1. In the Parameters tab of the Material section (the Node tab, Parameters window), set the Stem noise to 0 to make all the grass blades move uniformly. It will help to learn how to adjust the animation.

  2. Decrease the Stem offset to 0.1 to make the grass sway and stretch horizontally to a lesser degree.

  3. Decrease the Stem radius to 0.1 so that the grass does not bend down to the ground.

  4. Increase the Stem scale to 2 to make the grass move two times faster.

  5. Increase the Stem noise to 2 to make the blades movement more random.

Grass Optimization#

Grass optimization means reducing the number of grass polygons rendered each frame and the number of DIP calls. To optimize the grass that we added and set up above, we have already set the Step value to 17: the Size of the grass field is divided by this value exactly, with no remainder by division. This allows avoiding visual artifacts and unexpected visual effects. Also such value stays within the recommended optimal range.

The Thinning option is set for the grass objects by default: it allows reducing the number of grass polygons rendered across the grass Fade distance.

After changing the settings mentioned above, you can compare the previous and the current number of grass triangles: simply check the Triangles counter.

Last update: 2019-08-16