I designed and developed a robust GPU-based vegetation system capable of handling thousands of plants efficiently in real-time.
Description
In small environments, the decoration is typically handled by artists or designers, enabling precise control and aesthetically pleasing results. Nevertheless, as the environment size grows, this approach becomes increasingly time-consuming and impractical. To address this challenge, procedural solutions are often used, offering significant time savings. In this context, I have developed a solution that implements best practices for efficiently distributing and rendering thousands of trees and small plants in real-time.
Features:
Little or not explored:
Below we have some visual results.
Below it is possible to see the rendering of several plants in a long-distance view.
Below we have a short performance demonstration (Ryzen 3, GTX 1070, 16GB RAM, Full HD). In this demonstration, the terrain spans 80km on its larger side, while trees are visible at distances of up to 8km.
High-level details about the solution
The solution distributes vegetation procedurally on-demand in regions delimited by quadtree’s nodes. Nodes outside the camera’s frustum are destroyed as well as the plants of it. The plants remain in memory as long as the nodes are visible. If needed, the plants are deterministically redistributed as the nodes are recreated.
For distribution, the solution considers the influence of different aspects, such as terrain (e.g., slope and moisture), environmental (e.g., forest, lakes, and rivers zones), and human (e.g., villages and roads) aspects. These aspects must be normalizable values into [0, 1] for any scenario’s portion, encoded in 2D maps and/or vector data. Any other information discretized into [0-1] can be integrated.
Plants are grouped using the concept of presets, characterized by a set of plants that share the same needs, considering distribution aspects and other fields used to exist in some scenario’s position. For example, a presets of plants that exist in 1) forest zones, 2) not in steep regions, and 3) in higher altitude regions. The system analyzes many presets in real-time and defines which preset best fits a particular scenario’s position. After determining the best presets for the analyzed position, any plant from that can be randomly selected to be placed.
For efficiency purposes, plants are analyzed frame-by-frame to establish a LOD to balance performance and visuals. The LOD is defined from the distance of each plant to the camera –artists have control over it. Also, plants outside the frustum are discarded before rendering. Finally, the plant data is organized properly for use of GPU-instancing to speed up rendering.
Even though vegetation processing takes place mainly on the GPU, other processes on the CPU can still interact with plants. Objects can deform grass and small bushes, keeping them bent for long periods with acceptable memory demands (see more details here). Plants' colliders are instanced on-demand based on physics objects' positions to allow collisions with large and medium-sized trees using the physics engine.
As a result, A scalable GPU-based solution was developed to deal with any type of plant (e.g., trees, bushes, and grass) in real-time. It is possible to save different configurations –equivalent to biomes– and use them in different scenarios. Artists can intuitively edit these configurations to get different layouts for plant placement, previewing the result immediately. In addition, artists can edit LOD parameters to get a trade-off between visuals and performance. The solution also extracts maximum parallelism and processing from modern GPUs.