When I was first introduced to L-Systems I was suprised at how simple the concept was to wrap my head around. You just take a set of things and apply a rule to them a number of times. I felt silly for not having thought of it before I had heard of it from my Professor. Well after Learning about them, and creating a 2D version that drew basic trees, I decided I wanted to take it a step further. These 2D Trees from Aesthetic Beauty of Plants served as my basic inspriation for wanting to see L-Systems come to life in 3D.
I desperatly desired to see these in 3D, but I wanted to create them out of real 3D meshes. Do undertake this task, I utilized a Game Engine that I had been working on in C++. Utilizing this engine and OpenGL I would try to recreate the Turtle System used to create the examples above, but with 3D meshes instead. I was immidietly faced with many questions, for example:What shape should the "lines" be? How Many sides should they have? How do I work with the angles now that there are more ways to rotate?
Well I greeted these challenges with plenty of excitement and got ready to crack down on making my L-System. The first thing I did was create a generic L-System class in C++. There would be no contracted connectin between this class and anything else. This way I would be able to apply it to something else later if I wanted to. You can view the header and source files on my github.
I subsequently developed the Mesh Generator. This would contain an L-System for which to utilize and then create Meshes based on the Axioms and Iterations of the L-System. I developed logic to create n-sided shapes(becoming Cylinders past 5 sides) that would be able to form given any number of points and radii. This enabled me then to deduce the mechanism for actually generating the mesh. All I needed to do was decide how to add center vertices and radii to the Mesh Generator so it could then create the faces needed. I took some inspiration from 2D, and added some core functions, such as Push and Pop, translate forward, and rotate. I later needed to add many other rotate functions to allow control over which type of rotation was to be done. Here is the finished Command list:
case 't': //translate Center Downard
case 'T': //translate Center Upward
case 's': //scale radius smaller
case 'S': //scale radius larger
case 'x': //Counter-Clockwise around X axis
case 'X': //Clockwise around X axis
case 'y': //Counter-Clockwise around Y axis
case 'Y': //Clockwise around Y axis
case 'z': //Counter-Clockwise around Z axis
case 'Z': //Clockwise around Z axis
case '[': //push point onto the stack
case ']': //pop point from the stack
case 'C': //'Closes' a point to stop it from drawing bad geometry
case '+': //Adds a center point for mesh Generation
case 'F': //Combines 'T' and '+' for continuity with L-System
The one that might stand out the most is 'C' which is used to close off mesh geometry. This became essential in my approach to 3D geometry because when popping points off of the stack, the Mesh Generator would attempt to connect the leaf node back to the popped point, creating terrible geometry. Since one of the Mesh Generators jobs is to connect and create faces, a means to tell it to skip an index became neccassary. You can view the header and source for the Mesh Generator on my github.
Finally, after ensuring every command worked as intended I created things using my Mesh Generator. I created Several Trees, some better than others, combined them in my engine and created a forest! You can check out the L-Systems I used here. I used those trees to create a forest you can walk through as shown below.
Doing this all in C++, and inside an engine whose integration with OpenGL I designed not only allowed me to create a beautiful Forest, but also allowed me to understand the limitations and issues with doing this the way I did. Generally, in games, Trees are done with very few polygons, and a well made texture. This gives the Tree a good appearence of a Tree, but not the structure of one. I have no experienced first hand how much geometry a real(or mostly real tree) would have, and how it would impact a game that tried to use ultra realistic or high quality generated trees. Although my Engine can typically support thousands of Game Objects in a single scene, the sheer ammount of Faces on the trees brought my GPU to 100% usage at only 100 trees on my Intel Integrated Graphics.
In the future I plan on looking into optimizing the system and adding a part that enables an interesting use of shaders. I am currently just coloring the entire tree instead of doing anything more complicated. This is something I will happily explore when I have more time. I would also like to add these trees to any future games I create, and additionally add the abilty to export the meshes to a file to be used in other Engines or applications.
If you are interested in traversing the forest yourself you may download a working windows executable here. Control the Camera look with WASD and the camera movement with the arrow keys. I plan on adding OSX support in the future.