A single realistic tree model has enormous geometric complexity, dozens of thousands of polygons. The methods of choice are billboards for distant trees, and manually modelled polygon mesh-based alpha-textured trees up close. Billboards do not really appear 3D, and manual modelling of trees is time consuming, resulting in limited diversity of vegetation in the scene.
Our brains are able to neither discern nor remember the full complexity of the geometric detail of the tree crown from moderate distances. The main perceptual cues are parallax and the general shape of the object. Parallax can be achieved by representing the object with a set of textured parallel layers, or slices. The slice textures are generated from a detailed polygonal model of the tree. A slice is rendered as a textured quad.
A single set of slices is not sufficient for rendering the tree from all the viewpoints around it. The obvious approach is to create multiple sets of slices, or slicings, each for a different viewpoint.
To prevent abrupt flipping between slicings, and to reduce their number, it is possible to render two slicings at once, and use blending to smoothen the transitions. This works fine as long as the tree is sufficiently far away. The tree in the image on this page is a blend between two 60-degree separated 5-slice slicings, one of them is bordered by yellow, the other by white. Note that this is the worst-case situation for the method, and it's not obvious from the simplicity of the method that it actually works.
Such shortcuts are not applicable for the solid elements of the tree, the limbs and the trunk, which are rendered as a polygonal mesh. Because of the relatively smooth shape, such meshes look good with relatively few polygons. It is simple enough to segment tree elements into the slicing-rendered and the mesh-rendered set.
You can examine how the approach works in practice by downloading the 3.4 Mb demo for Windows machines with OpenGL. A snapshot of a grove is available here. I do not recommend attempting to run it on a machine without hardware accelerated OpenGL. Do send me feedback to the e-mail address written at the top of this page (don't forget to spam-unprotect it). By all means do tell me if you would like to use the method, because I could help.
The tree in the demo is composed of 6 slicings (spaced 60 degrees apart) with 5 slices each. This means that the tree crown is never rendered with more than 10 polygons. More than 100 trees can be rendered at 25 fps with the current off-the-shelf hardware. Use the '-borders' option to understand how the method works. Borders will be drawn around each slice, while each slicing has a different color.
Note that the trees in the demo are placed at a random location, and you might have to turn around to see them (by holding the left mouse button and dragging around). Also note that the method is not appropriate for close-up viewing, although the demo does not prevent the viewer from closing up. Ideally, you should view the trees from distances of approximately 20 meters and more. If you move sideways you will be able to notice the 3D parallax effect, which is missing with billboards.
The display bit depth can be reduced to 16bpp, and options for display lists, smaller texture sizes, 16-bit textures can be used for better performance. Note that default 32-bit textures are both slow and fuzzy (but compatible). Feel free to ramp up the '-number' of trees. For example, on my GeForce, I'd run the demo as 'treedemo -width 800 -height 600 -number 100 -full -bit16 -lists' . Also note that you shouldn't use textures larger than 128x128 in practice. If such texture dimensions are insufficient for you, you're probably too close to the slicing anyway.
I have not intended the trees to be viewed from close up and from above, and artifacts appear in such cases. These artifacts could be removed by providing additional slicings and a greater number of slices per slicing. To maintain the performance, levels of detail would have to be implemented, and I have not yet done this.
I have limited access to hardware, and there are compatibility issues. Sometimes it helps to run it with option '-lists', especially if the tree trunks are not rendered. A file named 'test.log' contains the error log.