System vegetation

From Open Metaverse Wiki

Opensimulator: Documentation: Asset types: System Vegetation

System vegetation is a special form of procedural models intended to create plants with a lower streaming cost than those made from prims, sculpts or mesh.

The models are generated by the viewer, mostly from predefined values and data stored in two xml files, grass.xml and trees.xml. that are included in the viewer download package and located in the viewer's app_settings subfolder. Only a few parameters are delivered from the server. This of course means that the load the plants put on the servers is all but negligible. This is however not quite true for the viewer. System vegetation is always farily simplistic and not likely any serious stress to any modern client computer. But even so, neither the code nor the mesh generated are well optimized.

There are two basic kinds of system vegetation "Trees" (really any single plants) and "Grass" (really any multi plant ground cover).

The main problem with system vegetation, however, is that it's way outdated. It was developed as early as 2002 and apart from the addition of one more ground coverage option it has never been updated. A lot has changed to computer graphics since then and although system vegetation isn't completely irrelevant most of the variants do not meet the expectations to visual quality people tend to have today.


Physics

System vegetation is always phantom.

Textures

Textures are one of the main shortcomings of system vegetation. Alpha cutout texture were harder to make and rarer to find back in 2002 than they are today. Linden Lab had to make do with whatever they could scrape together which resulted in a rather mixed bag of styles and qualities. Most of the textures seem to be based on hand-colored illustrations from old public domain botany books, some are cutouts from photos and only a few seem to be specifically created for textures.

Alpha

System vegetation uses alpha masking and was the only element of Second Life and Opensimulator to do so until new materials were implemented in 2013.

UUIDs

The UUIDs for the various variants are the same in Second Life and Opensimulator and can be found in the xml files.

Grass

A piece of system grass is a linkset consisting of 32 flat panels with a picture of some sort of vegetation on them. Apart from position, rotation and minor size differences, the panels are all identical. The panels will always be aligned with the system terrain and can not be moved vertically. Nor can the panels be resized; changing the vertical (z axis) scale has no effect and changing the horizontal (x and y axis) scale will change the distance between the panels.

Variants

There are six (really only five) system grass variants:

  • Grass 0 Yellowish-green grass with straws.
  • Grass 1 Dense cluster of poorly masked grass.
  • Grass 2 For most practiucal pruposes identical to Grass 0. It uses the same texture but is slightly bigger.
  • Grass 3 Similar to Grass 1 but lighter color and bigger.
  • Grass 4 An "autumn variant" of Grass 0/Grass 2. Bigger and with reddish-brown colors
  • undergrowth_1 Small alder(?) shrubs.

Parameters

The parameters delivered by the server are type, location, scale and rotation. The parameters stored in the grass.xml file are:

  • name
    • The name the plant is given in the edit/build palette.
  • species_id
    • A unique number for each type of plant on the list.
  • texture_id
    • As the name implies: the UUID of the texture to be used.
  • blade_size_x
  • blade_size_y

The exact placement of each panel relative to the others is random. All other parameters are predefined and can not be altered.

UV mapping

The UV mapping for the grass is simple, just a single texture covering the whole map.

Level of Detail

System grass does not seem to have any LOD simplifications, it's render in full at any view distance.

Trees

A system tree is a single plant. The term is a bit of a misnomer since not all of the variants are trees. There are 21 variants. Most of the names are self-explanatory:

  • Pine 1
  • Oak This is not actually an oak at all but a small maple with orange autumn leaves.
  • Tropical Bush 1 Looks like some sort of palm shrub.
  • Palm 1
  • Dogwood
  • Tropical Bush 2
  • Palm 2
  • Cypress 1 Not really a cypress. The texture used for the foliage is from a cypress but the canopy shape is typical for generic hardwood trees and not like any common type of cypress.
  • Cypress 2 Not really a cypress. The texture used for the foliage is from a cypress but the canopy shape is typical for generic hardwood trees and not like any common type of cypress.
  • Pine 2
  • Plumeria A seriously oversized flowering shrub.
  • Winter Pine 1
  • Winter Aspen
  • Winter Pine 2
  • Eucalyptus
  • Fern
  • Eelgrass
  • Sea Sword
  • Kelp 1
  • Beach Grass 1
  • Kelp 2

Terminology

Some terms used by L-system trees may be unfamiliar to most people and some terminology specific to system trees had to be invented specially for this article so some brief explanations may be needed:

  • Axiom The base of an L-system tree. On a system tree this will be the trunk of a (sub)tree.
  • Branch segment The mesh that makes up a length of a branch between two split points.
  • Foliage panel The mesh panels the foliage texture is applied to Foliage panels always come in pairs with two panels crossing each other at a 90 degree angle.
  • L-system tree An algorithm for generating branching "quasi-fractal" structures. Second Life/Opensimulator's system trees uses a fairly basic implementation of the algorithm with a few special modifications.
  • Recursion 0-n The various levels of branches, side branches and foliage panels.
  • Subtree A system tree can be made from several L-system trees stacked on top of each other. In this article these are referred to as subtrees.
  • Trunk segment The mesh that makes the trunk of a tree/subtree.

Structure

A system tree's is based on a Lindemayer system ("L-system") fractal tree structure with some modifications. A simple explanation of an L-system tree is that it's made from a single line (the "axiom") which is split into two or more lines ("first recursion") which again can be split into two or more lines ("second recursion") and so on.

The simplest possible L-system fractals trees with 0-4 recursions.
Source: https://en.wikipedia.org/wiki/L-system
License: Commons Attribution 3.0 Unported

The number of splits at each recursion level, the angle between the splits and several other factors are adjusted by paramaters from the trees.xml file.

On a system tree the axiom is represented by a trunk segment mesh, each of the highest recursion lines by a pair of crossed foliage panel sheets and the recursion lines in between by branch segment meshes.

An example of stacked L-system trees, color coded for clarity.
Stacked L-system trees

One important modification system trees have is that they can be made from several L-system trees at progressively smaller size stacked on top of each other. The number of additional L-system trees is determined by the trunk_depth paramenter and the relative size from one level to the next probably by scale_step (this needs to be confirmed).

Joints

Another less important but still significant modification is that the trunk and branch segments do not meet at their end points but at the second edgeloop from the end.

The trunk

All system "trees" have trunks but for those that aren't actual trees they are scaled down and hidden inside the foliage.

Outline of a basic tree trunk segment with no taper or noise.

The basic trunk segment is a cylinder with a narrow waist and pointed ends. Some trees have several trunk segments of diminishing sizes stacked on top of each other others have only one. The number of segments is set with trunk_depth. The scale of consecutive trunk segments relative to the previous is probably set with scale_step but this needs to be confirmed.

A trunk segment has 10 edgeloops, each with nine edges and ten vertices (the ends of the edgeloops are not joined and seem to overlap slightly). The vertices of the top and bottom edge loops are collapsed but not joined. This is what gives the segment the pointed ends. The total number of vertices and triangles are 100 and 162 respectively.

The branches

The branches are located around the second highest edgeloop of each trunk segment and spaced evenly around the circumference of the tree. The branch mesh is essentially the same as a trunk segment one but it does not have the noise parameters and the taper is fixed to a value slightly lower than 1.

Sidebranches are arranged around the second to highest edgeloop of branches of the previous level in the same way that main branches are arranged around the trunk.

The foliage

The foliage consists of one or more pairs of crossed panels ("billboards") arranged around the second to highest edgeloop of the highest level sidebranches (or around the trunk segment if there are no branches) the same way as branches are arranged around the trunk segments.

Size

In Second Life system trees are assigned a random size when rezzed, on opensim the nominal size is always 4x4x4 m or 4x4x10 m depending on the tree type. In either case the tree can be easily rezised after rezzing

The actual size is more complicated though. A system tree is a [[Linksets|linkset] with the trunk (or each trunk segment is there are several), each branch/sidebranch and each foliage panel being a separate object. The nominal size is the size of the bounding box of the root of the linkset which is the trunk or lowest trunk segment if there are several. The other parts are scaled according to the root size and various parameters.

The bounding box isn't the actual size of the root object either. With trunk_length set to 1.0, the visual model extends slightly above and below the bounding box. With a lower trunk_length value, the actual size is smaller than the nominal.

To complicate the matter further, the proportions of a tree can not be changed and all three scale parameters affect the size along all three axises.

The formula for the length of the root seems to be L=(x+y+z)/3*trunk_length/10*n where x, y and z are the nominal scales along the three axises and n is a constant slightly higher than 1.0. This formula needs to be confirmed but even if it's not correct, it seems to be close enough for all practical purposes.

The actual size of the tree as a whole depends on several parameters and it's far too complicated to go into details here.

Parameters

The parameters delivered by the server are type, location, scale and rotation.

The parameters stored in the trees.xml file are:

  • tree name
    • The name the plant is given in the edit/build palette. In Second Life tree name is also used as the default name for the rezzed tree.
  • species
    • A unique number for each type of plant on the list.
  • texture_id
    • As the name implies: the UUID of the texture to be used.
  • droop
    • The (vertical) angle of the branches, both the main branches relative to the trunk and the side branches relative to their parent. The exact range needs to be determined either by tests or by examining the code but -20 gives branches pointing upwards parallel to the trunk and 150 branches ointing downwards parallel to the trunk. The value for branches pointing outwards at a perfect 90 degree angle is slightly higher than 60 but lower than 75, probably about 65.
  • twist
    • Alters the distribution of branches around the trunk and sidebranches and foliage panels arnoud their parent branches. The exact effect needs further testing but with twist set to 0 branches and foliage panels are spaced evenly around the parent's circumference.
  • branches
    • The number of branches at each level.
  • depth
    • The number of recursions.
  • scale_step
    • Sets the relative size between levels in the branch structure and scale of subtrees in a stack.
  • trunk_depth
    • The number of trunk segments. Each trunk segment seems to be rotated c. 70 degrees relative to the previous one but this needs to be confirmed by further testing.
  • branch_length
    • The aproximate length of the main branch segments relative to the nominal size.
  • trunk_length
    • The aproximate length of the main trunk segment relative to the nominal size.
  • leaf_scale
    • The aproximate size of the foliage panels relative to the nominal size.
  • billboard_scale
    • Presumably the scale of the billboard impostor. However, this can not currently be confirmed since the billboard function doesn't seem to have ever been implemented.
  • billboard_ratio
    • Presumably the proportions of the billboard impostor. However, this can not currently be confirmed since the billboard function doesn't seem to have ever been implemented.
  • trunk_aspect
    • Width to height ratio of the trunk segments and also the branch segments. 0.00 give a very wide trunk but is not really useful since it will nearly always be rendered at low LOD. 1.00 results in zero width (that is invisible) trunks and branches. Values higher than 1.00 give some rather strange results. Values for existing system trees with trunks range from 0.035 to 0.15. The ones without trunks have trunk_aspect 1.0 except for the two kelp variants which have 0.04 and 0.025 respectively.
  • branch_aspect
  • leaf_rotate
  • noise_mag
  • noise_scale
  • taper
    • A float determining how much a trunk segment tapers towards the top. With the value set to 0.0 the trunk segment will taper all the way to a cone like shape, taper 1.0 seems to give a very slight taper with the top marginally narrower than the bottom. With values higher than 1.0 the trunk will taper outwards making the top wider than the bottom.
  • repeat_z
    • The nominal number of verticle texture repeats along each trunk and branch segment. The actual number of repeats is slightly higher than the nominal but not significantly so.

Level of Detail

Due to their excessive geometry trunks and branches need to be heavily LOD reduced and collapse into flat sheets even at a moderate view distance. Canopies don't seem to have any LOD reduction at all.

The trees has a "impostor" function, that is a flat sheet with a picture of the whole plant used as the lowest LOD model. This function isn't currently enabled though and may never have been implemented.

UV mapping

A system tree texture atlas.

Trees use a texture atlas. The bark texture, used for the trunk segment(s) and branches, takes up the left half of the map. The foliage texture is assigned to the upper right quarter but for some plants only a small part in the middle is actually used. The lower right quarter is reserved for the impostor texture; see the Level of Detail section above.

The UV maps for trunk and branches are upside down.

Animation

System trees used to have an optional wind animation feature. It was a very simple function, just the whole plant rocking back and forth around its lowest point. According to Linden Lab, the effect has been described as "disturbing" and it was disabled long ago. Singularity eventually reintroduced it but it seems to have been intended more as a fun effect than anything else and no other viewers have followed up.

Creating System Vegetation

Technically it's very easy to create new system vegetation variants although since there is no documentation it may take a bit of trial and error, especially to figure out the exact UV mapping for the tree foliage.

To add your new plant(s) to your viewer, simply add the data to the appropriate xml file and it will show up both it the list of options in the build window and in-world. However, it will only show up in viewers that has the same modified xml files so this is not recommended unless it is for a private place with no visitors. If a viewer comes across a variant it doesn't recognise, it will render it as a Pine 1 for trees or Grass 0 for grass.