In this chapter you learned a lot about rendering complex 3D objects like the landscape, the track, and the many 3D models used to create the levels in the racing game you are creating here. It will hopefully be useful for other games too, but there are a couple of things you might want to remember when creating landscapes for games:
Always figure out first how the player looks at the landscape in the game later. It does not make sense to have a great looking landscape, which only looks good at a close distance and only covers 50×50 meters if in reality you need huge terrains for strategy, role playing, or racing games. You need something bigger for these kinds of games and this means you either have to repeat textures or have clever rendering techniques combining detail textures with big textures, or use splatting to “paint” the landscape ground this way.
Splatting is a great technique for huge terrains. Most games go with texture splatting and use many different ground textures and additional special textures, tracks, and so on for great looking terrains. If you don’t have much development time or if you don’t really need huge terrains you might find simpler solutions like the one from the last chapter, which was ok for a shoot’em-up kind of game.
Additional layers, shaders, and effects, especially water shaders and shadow mapping, can be a very time-consuming task. I intentionally left out water from the game because in my last couple of projects it always took several weeks to get great looking water and I know myself - if it does not look good I will keep fixing it, even if I really don’t have time for that.
There are many tips and tricks you can learn from other people; good resources are many tutorials on the Internet and books like the Game Programming Gems or ShaderX series.
For the track generation you have similar rules, and the rule to create unit tests first is always important. Always test your performance, especially if you get into high polygon areas like you did this chapter, with more than 130,000 polygons just for the landscape and up to 24,000 polygons for the road plus maybe 50,000 polygons for additional road data like guard rails, tunnels, and the cement columns the road stands on. This means even without any additional landscape objects you already have more than 200,000 polygons each frame, which means to even achieve a frame rate of 100 frames per second you need to push more than 20 million polygons per second to the GPU just for the landscape and the track. The car has about 25,000 polygons and the landscape objects all have several thousand polygons too, which means that you can end up with several million polygons per frame if you have 1000 landscape objects or more in the scene. This may sound like a lot, but if you take a look at the screenshots from the TestRenderLandscape unit test you can see that you have almost 2000 objects in all of them.
You can probably guess that the GPU will not be able to push 2–3 million polygons each frame to the screen and still run at over 60 frames per second on the Xbox 360. On the PC it is even worse because 75 Hz is the most-used screen refresh rate and the GPU of most players is much slower, not able at all to handle that much 3D geometry each frame. To make sure the game still runs great even on mid to low spec PCs, the following tricks are used:
Never render anything that is not visible. Well, the landscape and the track are always visible, so you can’t just skip them. But many of the landscape models might be behind you or just not in your field of view and can be easily skipped. Another trick is to skip any models that are just too far away to be noticed anymore. Especially smaller 3D models can be skipped after 100 meters. This is the biggest performance gain in the whole game. Check out the Model class and the Render method to learn more about this trick.
Render the GPU-heavy data at the beginning of each frame. This way you can prepare the landscape models and other rendering data while the GPU is still working with the many landscape and track polygons.
Always sort rendering by shaders. You already saw in the previous games how the MeshRender Manager is used and how it can greatly improve the performance. In the many performance tests I did with the racing game (see the Model class for some of them) I constantly improved the performance of the MeshRenderManager class. Especially for many objects of the same type using the same shader the performance can be really astonishing in the engine. Check out the TestRenderManyModels unit test, which pushes more than 100 million polygons to the GPU on the Xbox 360 (and your PC if your GPU is fast enough).
Use short shaders! In the original Rocket Commander game everything used the ParallaxShader, which just has a few extra instructions compared to the NormalMapping shader, but it will still take more time to render a parallax mapped 3D object than just a normal mapped 3D object. For that reason you only use normal mapping in the racing game and it does not make any visual difference. Only the landscape uses a more complex shader to add the detail map effect (see Figure 12-7; it is really worth the effort).
Okay, before your brain explodes with all this new knowledge, relax for a while. Chapter 13 is about physics and involves a lot of math. By the time you read Chapter 14, the final chapter, you will finally be able to put everything together for the racing game - and you can drive a few test rounds!