Thanks for the replies.
Some more information on what my generation does so far:
I am currently using phong shading and normal mapping. There is LOD, but it looks terrible. I do have shadows, but I turned off terrain self-shadowing; the shadows work with other objects.
The textures are generated based on slope.
The terrain generation uses perlin noise, but there is no bias in locations (all locations currently use the same noise functions and frequency / amplitude combinations). I am brainstorming methods to have an additional noise function compute the type of terrain at each spot which then chooses which frequencies and amplitudes to use.
The textures are placeholders that were the first I found from searching google image search.
There are no trees or grass pieces in the first video; In my original post, I linked the separate video showing how I generate plants and trees.
It subdivides the world into a quad tree and tries to keep track of the virility of the land in each cell. It randomly seeds the terrain with a couple plants and trees to start with, then each frame simulates their growth and allows them to spread seeds. The plants compete for resources until the simulation converges locally.
This works fine for the grass and in my tests can support 100,000 individual grass pieces in a single cell being dynamically updated and spread each frame, as well as searching through them to render.
The grass is fine. The problem is the trees are also dynamically grown and their mesh is generated on the fly. I can't figure out how to solve the issue that each tree takes anywhere from a couple megabytes to 10's of megabytes per tree. It's not going to work at all because the memory just runs out. I'm not sure how to solve this.