This is probably the most important screens post ever, followed by the one introducing spherical harmonics rendering. Because it introduces my attempts at terrain LOD.
I have a very low view distance in my engine. This is because I have no LOD system and rendering a lot of terrain at full resolution quickly get's out of hand. At the default view size of 7 you can get up to 1.1 million triangles with terrain only. At the maximum view size of 19, you can get up to 2.8 million triangles. This is quite a bit and has lead to the my default and maximum values still having a relatively low view distance.
So it is time to add a LOD system. I won't be going for now with any established LOD scheme, because they are either too difficult, use too recent technology developments like geometry shaders, would take too much time to implement or, in some cases, come with a demo and I really didn't like the way the system looked in action. So I'll be rolling my own based on what I have read. That's right!
It's time for ghetto ass programming! Today we'll be going for a ghetto version of geo mip-mapping.
Since this method is meant to be implemented in a few hours, it won't have all the bells and whistles of the true method, nor will it have the same level of quality. I predict that it will handle natural generated terrain very well and the terrain edited by hand by the player very poorly.
We'll start first by dropping 3/4 of the polygons in terrain, going from this:
... to this:
Now we only have 1/4 of the original number of polygons. Next we need to change which vertices are used for the creation of the polygons, in order to fill up the holes.
This was easy but I ran into some large problems. My engine is meant to run on both XNA Reach and XNA HiDef. This means that there is a limit on how many vertices you can render in one draw call, thus the size of a chunk has a maximum. I wanted to make good use of this limit, so I decided to have a chunk be 128x128 vertices, thus covering an area of 127x127 logical units. This was done before any thoughts of LOD so I didn't think that having an area of odd size would be a problem. But it is for going to a lower LOD level, which works by division of two. In order to keep the odd size, I would have had to move around vertices at a LOD change and I did not want this. So I changed the chunk to 127x127 vertices covering an area of 126x126. The same area can be covered by a lower LOD chunk with 65x65 vertices. Most of the engine is parametrized with these values, but some parts were not and I had to track down and fix those spots.
So, after all these fixes, I added a secret hotkey to instantly switch from high LOD to low LOD. Before:
And now with grass:
As you can see, the lower LOD is pretty close to the high one. You can tell the difference with ease close by, but the farther the terrain is, the smaller the difference is. LOD is meant to be used with distance chunks only. So I enhance the debug mini-map to show LOD levels and add a fair distance of high LOD chunks:
We went from 1.174 million polygons at 30 FPS to 0.722 million polygons with 39 FPS and no noticeable decrease in quality. I increased the aggressiveness of the LOD distribution and did some tests with edited terrain. As I predicted, edited terrain with a distinct shape will have troubles with this implementation:
The bump can be seen clearly popping in. The effect is not as bad with strong fog:
But the real benefit come when trying to render higher view distances. Here is a shot without LOD at the current maximum view distance:
It runs at 23 FPS and tries to render 2.698 million triangles. But with LOD, it runs at 33 FPS and 0.920 million triangles:
This is of course on a Intel on-board chip. My dedicated high end GPU has no problems running the above scene without LOD, high quality and 4x MSAA at around 150 FPS. I'm curios on how it will behave with LOD.
This is only the first attempt at a LOD system. It won't be featured in Snapshot 10, which is due out tomorrow. There are lots of things to improve. First, while the engine tries to render less, it still uses the same amount of memory. I need to update it to use less memory for low LOD chunks, so I expect memory to also be reduced 3 times.
As a hobbyist engine developer, I do a lot of research and stumble upon other people who try to solve the same problems that I do. Most of them try to implement terrain. And a lot of them, once they begin to implement LOD, create a solution that has seams, wow to fix the seams in a future update, but never do. I have wowed to never do that. My LOD system is theoretically capable of showing seams. It has no seam compensation implemented. In over an hour of testing, I never saw one, but they could appear. So I will need to implement seam compensation and only after that will I include the LOD system into a public build! But there will be a secret key you can press to try it out, but I won't tell you which one :).
SAY NO TO SEAMS!