Amazon Game Tech Blog

Getting Started with Dynamic Vegetation in Lumberyard: Sample Now Available

Amazon Lumberyard 1.19 introduced over 150 new features, bug fixes, and improvements so you can create beautiful, dense worlds, faster. Included with this release is Dynamic Vegetation, our new workflow to help you procedurally generate a diverse and detailed biome faster and more efficiently than manually placing and painting vegetation.

The Dynamic Vegetation workflow enables you to define and distribute customized plant vegetation across large areas of game levels with greater consistency and editing ability. Built upon our component entity system, this tool uses a diverse library of component types to help custom design and propagate the type of vegetation biomes required for modern game development.

To help you quickly get to grips with this tool, we’ve created a quick start guide, and a Dynamic Vegetation Sample – available for download now.

But first, let’s explain a little more about Lumberyard Dynamic Vegetation.

About Dynamic Vegetation

Lumberyard customers told us that it’s difficult and time-consuming to create high-fidelity content in large-scale game environments. As game world sizes have increased exponentially, manual workflows like painting or placing individual plant instances doesn’t scale well with production needs. When we approached the challenge of building a new vegetation system, we worked directly with our customers to identify essential requirements including:

  • Solving for scaled environment sizes
  • Consistent visual fidelity and quality
  • Blending proceduralism with ability to art direct the outcome
  • WYSIWYG live editing and rapid iteration
  • Environment content that can be altered dynamically

We built the new workflow for vegetation upon the Lumberyard component entity system. This adds flexibility and unlocks easier world building options. The Dynamic Vegetation workflow allows you to author both smaller areas of vegetation like a garden, to large biomes distributed across vast areas of a game level. The diverse vegetation component library provides you with the mechanisms needed to author visually complex vegetation biomes for modern high-fidelity games.

Once biomes are established, you can define vegetation coverage of the entire level, or specified regions on the terrain, mesh entities, roads, rivers, water volumes, and even arbitrary shapes. Once placement areas are defined, simple modifications to the components and parameters for each biome entity allows for real-time updates and edits. The workflow supports multiple biome layers with rule sets that can mask, blend, or exclude other dynamic vegetation biome entities in the level.

The resulting visual consistency and easy modification allows for a more reliable course of production from concept to final product. Because every biome is defined using the entity component and slice system, settings are saved exactly as designed and can be used in other levels, or distributed as desired across different areas of a large world. Edits and changes to any vegetation slice are then updated across all instances and maintain consistent visual direction.

Getting Started

The Dynamic Vegetation workflows allow users to create artistically expressive vegetation areas through our library of vegetation components.

There are two primary types of areas:

Background layer Coverage intended to cover large swaths or the entire level with default ground cover.

Foreground layer Clusters intended for smaller local areas, which replace the ground cover they are placed over.

This quick start guide will cover the basics of dynamic vegetation. To familiarize you with the basic components and workflow, we will walk you through creating a simple version of each primary layer. Once you’re through the basics, we encourage you to try out some of the other components and if you have questions reach out to us on our forums.

Note: This quick start guide assumes at least some basic familiarity with the Lumberyard Editor. If a term or a tool is unfamiliar you may want to go through the tutorials and samples in the Lumberyard general ‘Getting Started’ and ‘User Guide’.

Setup

We have provided examples of the tasks outlined in this document, you may use them as reference and to follow along or compare your results.  Those examples are provided in the ‘DyanmicVegetationSample’ project. Before we get started make sure that the project is activated:

  1. Unzip the ‘DynamicVegetationSample.zip’ file
  2. Move the project folder ‘DynamicVegetationSample’ into your Lumberyard 1.19 location:[drive]:\Amazon\Lumberyard1.19\dev\DynamicVegetationSample
  3. Start the ‘Lumberyard Project Configurator’
  4. Click to select the ‘DynamicVegetationSample’ project
  5. Then in the upper-right, click on the button labeled ‘Set as Default’
  6. Close the ‘Project Configurator’
  7. The project will need to be built before you can run it. Click here for instructions on building your game project.

New Level

Steps:

  1. Start the Lumberyard Edtor.exe
  2. On the launch screen, use the button labeled ‘New Level…’ to create a new empty level.
  3. We named ours:
    1. ExampleBiome
  4. We used ‘Heightmap Resolution’:
    1. 128 x 128
  5. For ‘Texture Dimensions’:
    1. 512 x 512

Result:

Level Inspector ‘Vegetation System Settings’ Component

Let’s do one more setup step and use the ‘Level Inspector’ to add a ‘Vegetation System Settings’ component to the level, this component will allow us to configure the system:

  1. Open the ‘Level Inspector’ with this menu
    1. Editor > Tools > Level Inspector
    2. Note: we recommend docking this behind the Entity Inspector
  2. Use the ‘Add Component’ button and add the ‘Vegetation System Settings’ component
  3. Turn on the setting ‘Override Instance Time Slicing’, this improves the live editing performance of vegetation while in the editor.

Note: you’ll also see we modified a few more numbers that allow you to configure the draw distance (view area grid size), density of placement (Sector Point Density), and control over vegetation LOD switching (LOD Distance Ratio, View Distance Ratio).

 

Creating Basic Coverage (Grass micro-biome)

Let’s create a grass biome patch.

Steps

  1. Create an Entity and name it BasicCoverage
    • Make sure it’s positioned to the center of the terrain
    • That would be setting the Entity’s Translate to:
      x 64.0 m, y 64.0 m, z 32.0 m

    Entity Outliner:

    Entity Inspector:

  2. In the ‘Entity Inspector’ panel use the ‘Add Component’ palette to add a ‘Vegetation Layer Spawner’ Component
    • This is the core component that initializes the ‘planting engine’ to spawn vegetation.
    • That component have additional component dependencies that are required to make it functional – the system will guide you through these needs.

    Entity Inspector:

  3. The first thing it requires is a shape which will define the area where to plant
    • In the ‘Entity Inspector’ panel, on the ‘Vegetation Layer Spawner’, use the button labeled ‘Add Required Component’, then select to add the ‘Vegetation Reference Shape’.
    • This shape type actually just references another entity that has a shape (allowing you to re-use shapes, which is common to this workflow, and we will get to that later in this exercise)
    • So in the next section we will want to add another entity that has an actual Shape-type Component, which shape will inform what area to plant in.
    • (but continue here briefly for now so we consolidate steps)

    Entity Inspector:

  4. Next the entity will require a ‘Vegetation Asset List’ which will define a set of what to plant
    • In the ‘Entity Inspector’ panel, on the ‘Vegetation Spawner’, use the on the button labeled ‘Add Required Component’, three options will come up – for this example select ‘Vegetation Asset List’
    • This component defines the list of vegetation models to place within this area, along with some metadata about each type (this metadata can later be used by other components to define placement behavior procedurally)
    • Right now let’s just add a single item to this list
    • In the ‘Vegetation Asset List’ there is a currently empty list called ‘Embedded Assets’, it is already populated with a single empty entry which is expanded (we just need to use this to specify an asset to plant.)
    • There is a field labeled ‘Mesh Asset’ (which is currently empty) to add a mesh click on the button labeled “…” which will open a dialog labeled ‘Pick Static Mesh’
    • You can use this dialog to browse the list of .cgf assets that can be placed
    • Use the Search Field at the top of the dialog and type in ‘grass’ and select one of the models, we used ‘am_grass_03_seeds_group.cgf’
    • You will see this entire level fill with that grass type (not very interesting yet, but it is a start!)
    • The entire level fills, because our ‘Reference Shape’ is empty (we will fix that next.)

    Entity Inspector:

  5. The last thing we want to do in this set this ‘Vegetation Layer Spawner’ Component to ‘Layer Priority: background’
    Result:

Let’s Make it a Patch

Steps

  1. Create a Child Entity with a Box Shape
    • Select the parent entity ‘BasicCoverage’
    • Right-click and select ‘Create Child Entity’ from the context menu
    • Rename the child entity ‘32m_Box(Patch)’
    • In the Entity Inspector, use the ‘Add Component’ button to create a ‘Box Shape’
    • Use the Box Shape: Dimensions to change the size of the box:
      x: 32.0 m, y: 32.0 m, z: 16.0 m

    Entity Outliner:

    Entity Inspector:

  2. Set the Box as the Placement Area
    • Select the parent entity ‘BasicCoverage’ in the Entity Outliner
    • In the Entity Inspector use the on the ‘Vegetation Reference Shape’ and pin a reference to the child entity ‘32m_Box(Patch)’
    • You will now notice that the vegetation planting is confined to the referenced Box Shape from the child entity ‘32m_Box(Patch)’

    Entity Outliner:

    Entity Inspector:

    Result:

Let’s Get Procedural

We can begin to make this area more visually interesting and craft a biome by adding some procedural noise and rules to it.

Steps

  1. Extend the list of assets to be planted
    • With the parent entity ‘BasicCoverage’ still selected
    • In the Entity Inspector use the ‘Vegetation Asset List’ to add some more vegetation assets to the list of things to plant in this area.
    • On the upper-right edge of the line ‘Embedded Assets’ there is a button. Click that button twice, to add two new 2 new entries.
    • Add the following ‘Mesh Assets’ to those entries:
      Am_grass_tall_02_group
      Am_grass_tall_01_group
    • Notice that what is planted doesn’t change; we need a way to describe how to select what to plant from the list

    Entity Inspector:

  2. Weighted Selection
    • With the parent ‘BasicCoverage’ still selected, with the Entity Inspector use the ‘Add Component’ button to add the ‘Vegetation Asset Weight Selector’.
    • This component will allow us to reference a ‘gradient signal’ like procedural noise, and we can use that signal to drive selection.
    • To do that, we will need to build a procedural ‘gradient signal’ generator we can reference in this component.

    Entity Inspector:

  3. Create the FastNoise (procedural noise)
    • With the parent entity ‘BasicCoverage’ selected, in the Entity Outliner right-click and select ‘create child entity’
    • Rename this entity ‘FastNoise’
    • With this new child entity selected, in the Entity Inspector use the ‘Add Component’ button to add a ‘FastNoise Gradient’ component.
    • This component requires a few other components to function, let’s add those now using the ‘Add Required Component’ add the ‘Gradient Transform Modifier’ component.
    • We also require a shape, so use the ‘Add Required Component’ again and select the ‘Vegetation Reference Shape’ component. Now the components will operate properly. Expand the ‘Preview’ to see the noise signal being generated.

    Entity Outliner:

    Entity Inspector:

  4. Tune the Noise Visuals
      • Before we hook this up to the ‘Weight Selector’ let’s first tune the noise to be a little more interesting.
      • Make the following changes to the parameters of the FastNoise component:
        • Set ‘Noise Type’ to ‘Simplex Fractal’
        • Expand the ‘FastNoise Advanced Settings’
        • Set the ‘Fractal Type’ to ‘Billow’
        • Set the ‘Frequency’ to ‘0.1’

    Entity Inspector:

  5. Connect the noise to ‘Weight Selector’
    • In the Entity Outliner select the parent entity ‘BasicCoverage’
    • In the Entity Inspector use the button on the ‘Vegetation Asset Weight Selector’ and pin a reference to the child entity ‘FastNoise’
    • You should see the planting pattern change, as the values of the FastNoise are driving the selection criteria.
    • If you expand the ‘Advanced’ settings on the ‘Weight Selector’, and ‘Enable Levels’, you can tweak the inbound noise signal which will further tune the selection.
    • Set the ‘Input Mid’ value to ‘1.3’

    Entity Outliner:

    Entity Inspector:

  6. Pattern based Selection and Placement.
    The area should now look something like this image:

Procedural Modifiers

We can continue to add additional rules to this ‘Layer Spawner’ to refine its look-and-feel. These bolt-on’s are Filter and Modifier type components. Before we add those, we’re going to make one more child entity with a different noise pattern we will use to hook them up.

Steps

  1. Repeat the steps for ‘FastNoise’ to create ‘RandomNoise’
    • Right-click on ‘BasicCoverage’ and ‘create child entity’
    • Rename this child ‘RandomNoise’
    • Add the ‘FastNoise’ and it’s required components, just like the previous noise use the ‘Reference Shape’ and use it to pin a reference to the ‘32m_Box(Patch)’
    • Set the ‘Noise Type’ to ‘White Noise’ (this is a type of random noise)
    • That’s it…

    Entity Outliner:

    Entity Inspector:

  2. Add the Modifier Components
    • With the parent entity ‘BasicCoverage’ selected, add the following components:
      • – ‘Vegetation Scale Modifier’
      • – ‘Vegetation Rotation Modifier’
      • – ‘Vegetation Position Modifier’
    • Let’s go through setting up each of these individually
  3. Scale Modifier
    • Simply use the button on the ‘Scale Modifier’ to pin a reference for the ‘Gradient Entity Id’ to ‘RandomNoise’.
    • Set the ‘Range Min’ to ‘0.75’
    • Set the ‘Range Max’ to ‘1.25’

    Entity Outliner:

    Entity Inspector:

  4. Rotation Modifier
    • Use the button on the ‘Rotation Modifier’ to pin a reference for the ‘Rotation Z’ ‘Gradient Entity Id’ to ‘RandomNoise’.
    • This component already has good default settings, so no configuration is necessary.
    • (Don’t change Rotation X, or Y)

    Entity Outliner:

    Entity Inspector:

  5. Position Modifier
    • This one requires a little bit more configuration to unlock its full potential.
    • Use the button on the ‘Position Modifier’ ‘Postion X’:’Gradient’:’Gradient Entity Id’ to pin a reference for ‘RandomNoise’.
    • Use the button on the ‘Position Modifier’ ‘Postion Y’:’Gradient’:’Gradient Entity Id’ to pin a reference for ‘RandomNoise’.
    • Under the ‘Position Y’ expand the ‘Advanced’ settings group and ‘Enable Transform’
    • Then put in the following settings:

    Entity Outliner:

    Entity Inspector:

Let’s Do a Visual Comparison

Below is a visual comparison of the same ‘Layer Spawner’ before and after the modifiers where applied and set up.

Before:

After:

Save as Slice

OK we are nearly done, there are just two things left – 1) save our patch as a slice, and 2) extend its placement bounds to fill the world.

    • Right-click on ‘BasicCoverage’ and select ‘Create Slice…’
    • We saved our example to the following path:
dev\DynamicVegetationSample\Levels\DynamicVegetationSample\Slices\BasicCoverage.slice

Fill Er’ Up!

Now let’s create a ‘World Box’ and fill up the world.

Steps

  1. Create the WorldBox
    • In the Entity Outliner create a new entity and rename it ‘World Box’
    • Position its Transform at:
      x: 64.0 m, y: 64.0 m, z: 32.0 m
    • Add Component:
      Box Shape
    • Set it’s dimensions to:
      x:128, y: 128, z:64
    • That should look like this

    Entity Outliner:

    Entity Inspector:

  2. Override Placement area with WorldBox
    • Select the ‘BasicCoverage’ slice
    • In the Entity Inspector use the button of the ‘Vegetation Reference Shape’ to create a reference override, by pinning the reference to ‘WorldBox’

    Entity Outliner:

    Entity Inspector:

You should see the placement of vegetation extend across the entire world – and that is a wrap. We hope you see the potential and can think of the many ways this workflow could be leveraged to quickly fill up your world with interesting vegetation content.

Debug Boxes Outlines:

Box Outlines Hidden:

Creating a Basic Foreground Cluster

Let’s create a dead tree to place in the foreground layer, with a blocker and local placement area around its base that will override the grass coverage in the background layer.

Steps

  1. Create an Entity and name it DeadTreeWithBasicCluster
    • Make sure it’s positioned to the center of the terrain. That would be setting the Entity’s Translate to:
      x 64.0 m, y 64.0 m, z 32.0 m

    Entity Outliner:

  2. Add a Mesh Component
    • In the ‘Mesh Asset’ field, use the button and load the asset named ‘am_dead_tree’

    Entity Inspector:

  3. Create a child entity named ‘BasicCluster’
    Entity Outliner:
  4. Add Vegetation Asset List component
    • Add the following assets to the element list:
      • Am_grass_flower_red_group
      • Am_grass_03_seeds_group
      • Am_rocks_small_01
      • Am_grass_tall_01_group
    • You’ll see the box fill up, so like the biome, we need to setup a mechanism to drive selection for asset placement.

    Entity Inspector:

  5. Add Vegetation Layer Spawner component
    • Set the ‘Layer Priority’ to: ‘Foreground’, this setting is what allows this area override the grass in the background layer.
  6. Add a Box Shape Component
    • Set the Box Shape: Dimensions to:
      x: 13.0 m, y: 13.0 m, z: 13.0 m
    • This contains the placement area

    Entity Inspector:

  7. Create a child entity of BasicCluster named RandomNoise
    • We will setup a random noise gradient signal on this entity, and use that to feed a weighted selection
  8. Add the Random Noise Gradient
  9. Add the Gradient Transform Component
  10. Add a Vegetation Reference Shape
    • Pin the ‘Shape Entity id’ to reference the parent ‘BasicCluster’.
    • Now reselect ‘BasicCluster’ so we can extend it.

    Entity Outliner:

    Entity Inspector:

  11. Add a Vegetation Asset Weight Selector component
    • Pin the ‘Gradient Entity Id’ to reference the ‘RandomNoise’ child entity.

    Entity Outliner:

    Entity Inspector:

  12. Add a Vegetation Rotation Modifier
    • Pin the ‘Gradient Entity Id’ to also reference the ‘RandomNoise’ child entity.

    Entity Outliner:

    Entity Inspector:

  13. Add a Vegetation Scale Modifier
    • Pin the ‘Gradient Entity Id’ to also reference the ‘RandomNoise’ child entity.
      • Set ‘Range Min’ to 0.6
      • Set ‘Range Max’ to 0.85

    Entity Outliner:

    Entity Inspector:

  14. Add a Vegetation Position Modifier
    • Pin the ‘Gradient Entity Id’ for both ‘Position X’ to also reference the ‘RandomNoise’ child entity.
    • Do the same for ‘Position Y’ gradient
    • Don’t forget to expand ‘Advanced’ and ‘Enable Transform’ and edit the inbound signal to get better random results without requiring an additional noise entity. Set scale:
      x:-1.0, y: -1.0, z: 1.0

      and

      rotate: z:45.0

    Entity Outliner:

    Entity Inspector:

  15. Add a Vegetation Slope Alignment Modifier
    • You can leave this with its default values (everything gets full slope alignment.)
    • Go ahead and hide the ‘BasicCoverage’ grass biome
    • You should see a boxy placement like this now
    • And we would like to confine the placement to something more organic like a ring shape
    • (next step)

    Entity Outliner:

    Entity Inspector:

  16. Create a child entity named ImageGradient
    • We will setup an image asset based gradient signal on this entity, and use that to feed distribution filter

    Entity Outliner:

  17. Add the Image Gradient component
    • You’re missing a few components to make this one work
  18. Add the Gradient Transform Component
  19. Add a Vegetation Reference Shape
    • Pin the ‘Shape Entity Id’ to reference the parent ‘BasicCluster’.
  20. Select the Image Gradient component again
    • Under image assets load the asset:
      ‘blured_circle_gsi’

      found under the path:

      Gems/Vegetation/ImageGradients/LargeWorldExamples
    • ProTip: add the suffix ‘_gsi’ to any image to inform the Asset Processor to cook it into data the Dyn Veg system can use. This suffix stands for ‘Gradient Signal Image’.
    • Now reselect ‘BasicCluster’ so we can extend it again

    Entity Inspector:

  21. Add a Vegetation Distribution Filter
    • This component uses a threshold on the inbound signal to filter out placement.
    • Pin the ‘Gradient Entity Id’ to reference the ‘ImageGradient’ child entity.
    • Instead of boxy placement we can see that the placement has been confined to circular area around the stump.
    • Go ahead and unhide the ‘BasicCoverage’ grass biome
    • We can clearly see that this local area around the stump is overriding and placing new vegetation.
    • (We also turned off the debug rendering of the Boxes and other Shapes.)
    • There is one more step we’d like to cover…
    • One additional tweak we can make is to create a ‘Blocker’ area at the base, this will keep both the foreground and background layers from placing vegetation.

    Entity Outliner:

    Entity Inspector:

  22. Create a new child entity named Blocker
    Entity Outliner:
  23. Add the Cylinder Shape component
    • Set the Height to 4.0 m and Radius to 1.6 m
    • Set the Shape Color

    Entity Inspector:

  24. Add the Vegetation Layer Blocker
    • Set the ‘Layer Priority’ to : ‘Foreground’. We can see that this has created a small clear patch at the base of the stump.
    • (If you toggle the visibility of the shape entity in the Entity Outliner, when hidden you’ll see the blocker doesn’t function and the patch is filled back in)
    • And if we turn off the debug drawing of Shapes in the viewport, we can see the final results.
    • This ‘DeadTreeWithBasicCluster’ entity, can now be saved as a slice allowing you to instantiate many copies to be scattered across and environment.
    • This is how we build a library of interesting modular environment pieces.

 

That’s it, you’ve completed the first steps to learn how to use our new Dynamic Vegetation system. In time, we’ll add more advanced lessons and dive into the huge range of possibilities that are available.

As always, we want to hear from you. Send your comments, questions, or even feature requests via our forums.

 

This blog was co-authored by Lumberyard Creative Director Christo Vuchetich, and Product Manager, Jonny Galloway.