A procedural tree generation system based on the Lindenmayer System (L-system), developed as a research project with mesh optimization for improved rendering.
Before rendering the Lindenmayer system or Lindenmayer tree, a string for Lindenmayer System should be generated with applying the rules of the system. This generation process is performed basically replacing the characters that are suitable for replacements. As the iterations go higher, the string length and size increases. The final string generated after all the iterations applied while draw rules being applied to the string, gives the Lindenmayer tree.
Generation of the tree is the simple process of parsing string to gain axioms and operators. Parsing is done via iterating over the string to obtain characters inside of it. Each character gives a specific behaviour about the tree. If there are any additional parameters given by the user such as but not limited to: 3D mode or stochastic angle, the tree render behaviour will be changed according to additional parameters given by the user.
Lindenmayer systems are based on simple nodes connected to each other with rules. Although nodes are simple when it comes to displaying or generating Lindenmayer systems if optimization of the application is not considered, as the iteration and node count increases, this can create a problem for performance.
This is due to true nature of graphical APIs, since each graphical API requires engine to pass an information called draw call. This draw call includes the object which will be rendered to the screen. As the node count increases, CPU starts making cache misses, loses time on memory calls and CPU-GPU bridge gets loaded heavily On the other hand, this problem can be solved with a very basic but powerful solution, sending less draw calls or buffered information to the GPU.
In order to reduce the draw calls, all simple nodes can be combined to larger structures which will have much more information stored together. Since CPU can catch this information only once and send it to GPU as long as combined node information size is lower than the limit of cache size and CPU-GPU transfer limit.
Unity and most of the game engines, renders game objects using meshes. Unity provides functionality to fetch meshes of game objects, combine them under a single mesh and attach a material to it. This functionality becomes handy for the optimization problem that Lindenmayer systems face.