Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • entries
  • comments
  • views

Vegetation Research - Pt 2



The Leadwerks 2 vegetation system used a grid of "cells" that each contained a quantity of vegetation instances. If the cell was close enough, each instance was checked against the camera frustum like a regular entity and then all visible instances were rendered in a batch. Cells that were further away were collapsed into a single surface consisting of a quad for each instance. This is how we were able to draw massive amounts of foliage in the distance at a fast framerate:



This was good, but limited by the scene management performed by the CPU. It also used very large amounts of memory to store all the 4x4 matrices of the individual instances. The above map used about half a gigabyte of data to store all positions for each tree int he scene.


The Leadwerks 3 vegetation system is being designed around modern hardware capabilities, taking advantage of the features of OpenGL 4. This has two goals:

  • Remove the overhead of scene management performed on the CPU.
  • Reduce memory usage of vegetation data.

Transform Feedback

One of the most interesting things OpenGL 4 supports is transform feedback, which allows you to render data to an arbitrary buffer. This can be combined with a geometry shader to selectively output information in ways a normal render-to-texture can't. This schematic from RasterGrid's OpenGL blog shows how the system works:




Below you can see my implementation working. The scene consists of 91 million polygons, with about 28 million visible at any given time. (This number will be reduced through the use of billboards.) The edges of the camera frustum are pulled in to make the culling visible.



Use of the transform feedback feature in OpenGL 4 relieves the CPU from the expensive overhead of large-scale scene management.

Tiling Matrices

The need for individual instance matrices is being totally eliminated by using a tiling grid of 4x4 matrices. This creates a repeating pattern of rotations across the scene. I think when the trees are placed on a hilly terrain the tiling appearance won't be visible, but there are other tricks I can use to increase the randomness. The physics system will work by dynamically retrieving the relevant 4x4 matrices of nearby instances, totally eliminating the need to store any of this massive data in memory. The fact that no instance data is being sent over the PCIE bridge also means this system will be much faster than Leadwerks 2.


Vegetation in Leadwerks 3 will be a virtually zero-overhead system and allow for much greater volumes of geometry than Leadwerks 2 could render, at effectively no cost on most hardware.

  • Upvote 4


Recommended Comments

What's the downside? There is always a downside to these things it seems. Just curious because everything you say so far is the upside to this but there must be a trade off somewhere as there always seems to be with this stuff.

Link to comment

No occlusion culling on the vegetation, since it's only frustum-culled on the GPU.


Also, it uses a query that has to return the number of instances to draw back to the CPU. OpenGL 4.3 has some additional functionality that can avoid that.


All in all, there's no disadvantage to this technique. We just had to wait for the hardware capabilities to appear.

Link to comment

Perhaps adding an ability to switch the vegetation on or off (and control its density) would be nice. This way occlusion culling can be done manually (e.g. portal in a doorway which switches the veg off when the camera moves into an enclosed space).

Link to comment

This is really amazing.

How does this scale with lighting and physics?

I would assume that there is not much overhead involved in the lighting calculations, which should be basically independent from the number of objects.

However, the physics for all the trees at once would be a major problem.

Do you have any tests or thoughts on this subject?

Link to comment

Yes, I am going to implement a system where the surrounding vegetation objects' collision are dynamically generated as needed. This will relieve the engine from having to store each object's 4x4 matrix, so memory usage will remain low.

  • Upvote 3
Link to comment
where the surrounding vegetation objects'


What does that mean? Surrounding from the camera? Would that mean AI not in a range of a camera would walk through trees?

Link to comment

No, I mean that when an object moves in the physics system, all surrounding instances are dynamically calculated and tested for collision. The navmesh data is precalculated, so it only requires the data to be present during the build step.

Link to comment

If I might make a couple of suggestions based on things I would have liked to have had; Support for serializing and deserializing vegetation data so it can be loaded/streamed when working with tiles or tiled terrain.


And the implementation of world modifiers; primitives such as spheres that add an offset to vegetation, simulating movement though tall grass, or localized wind movement (such as a large fan).


Seems to me you can use this for clouds and general ground clutter. Clutter doesn't need to interact, just be there to present visual noise; e.g leaves, small rocks.

  • Upvote 2
Link to comment

Because the vegetation data no longer needs to be loaded, the only thing that has to be loaded is a new texture for the mask of where instances are allowed to appear. So that should be a lot faster.

  • Upvote 2
Link to comment

Coverage masks for vegetation are exported directly out of GROME and easily generated in World Machine. So that's a big thumbs up from me.

Link to comment
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...