I’m not certain whether today’s shot is noticeably different than yesterday’s. But regardless, I’ve made some pretty massive changes under the hood (with some more still to come).
The big exciting new thing from my point of view is that I’ve flipped the switch, and made the generated ground clutter be generated in tiles, the same way that height map data is, just smaller.
The upshot of this is that the game once again runs at well over 60 fps on my old laptop (it had been down to about 40), and with far more visual detail than before. I’m quite pleased.
Technical discussion follows:
Previously, edge clutter (the grass that was seen in older screenshots) was being generated as part of the height map. Each ground quad would select one of its edges and sprout another quad of surface detail there. That surface detail quad was carefully set up to almost exactly match the shade of the ground, just to try to hide or soften the edge. This worked great, but doubled the amount of geometry being generated whenever I needed to load up a new section of height map, and doubled the number of triangles being drawn. Additionally, it ended up looking a little “samey”; all grass everywhere in the world was being blown from east to west, for example.
The other system present was a big list of “ground clutter” triangles, which I was checking every frame, and re-orienting to best face the camera. This was a big time-sink for the game, moving all those vertices around every frame.
Now, ground clutter and edge clutter are both being generated by a common system, which generates them in blocks around the camera. This is a big improvement for edge clutter because it means that I can only draw the edge clutter that’s relatively close to the camera (edge clutter is currently in 64×64 meter ’tiles’), and not bother drawing the edge clutter that’s a long distance away. I was doing this already with the old system, but the height map’s 256×256 tile size made it impossible to draw only the clutter that would really be visible.
Additionally, this is a massive improvement for ground clutter because it means that I don’t need to test every piece of ground clutter each frame; there are only nine tiles of it (32×32 meters on a side), and I can just decide for each tile whether to keep it or whether to throw it away and generate a new tile somewhere closer to the camera, instead.
The best thing is that I’ve factored out the whole “generating the nearest tiles” behaviour, so a single logic engine is now driving both types of ground clutter, and it’ll be easy to add more things which get created around the player in this way.
I haven’t converted the current height map tiling over to this new system; the height map tiling works based upon using tiles to fill a circle centred on the camera, while the system powering the clutter works based on using tiles to fill a square. The square is much, much simpler to handle, but causes the system to create things diagonally more often than straight north/south/east/west. For ground clutter this is unnoticeable. For mountains, you really need to see mountains at a particular distance, regardless of which direction they’re in, so the height maps themselves need to stay on the old system.
There’s also some exciting news in the near future. Can’t talk about it yet, but real soon. :)