Frame rate boosters
|Top Previous Next|
This month's article was inspired by a question that was posted at the forum: "I've got about 400 models in my building, each one of them having about 5000 polygons. I am trying to increase the frame rate a bit and was wondering if adding a code that makes any entities not visible on the screen disappear would increase the frame rate".
First of all, I'd like to say that I don't encourage people to create levels that have 2,000,000 polygons, unless they create an application that will be run by a company on one or several super-computers. However, the question remains: what can we do in order to increase the frame rate in our games, while keeping as many details as possible?
Let's start by running this month's demo: start Wed, open lod_level.wmp from the \boosters folder, and then run it using main.wdl; you will see the following window.
I have created four different demos, each one of them showing a method that increases the frame rate significantly. Press "1" to load the first demo; you will see the following image.
The level includes several spheres, each one of them having 9,800 polygons. The entire scene has 147,000 polygons, as indicated by the "Engine polygons" counter at the bottom of the screen. Press and hold the "space" key to bring on the mouse pointer, and then click and drag the slider from the top of the screen to the left, until the "Clip_far" indicator displays a number that's close to 3,000.
You can now see that the spheres that are far away have disappeared and the number of rendered entity polygons has decreased from 147,000 to 49,000. This has increased the frame rate from 21 to 62 fps on my PC. If you think that the fog does the magic by itself, increasing the frame rate because the entities are covered by it, think again: the fog is just hiding the job done by clip_far, as indicated by this small function taken from boosters.wdl:
fog_color = 1; // show the white fog (RGB = 255 set in Wed's File -> Map Properties -> Fog -> Fog1)
camera.fog_end = camera.clip_far * 0.9; // set fog_end to a value that's 90% of camera.clip_far
camera.fog_start = camera.fog_end * 0.01; // set fog_start to 1% of fog_end (play with 0.01 = 1%)
The engine removes all the objects that are more than clip_far quants away from the camera automatically; our slider simply adjusts the clip_far value and the starter function computes a proper fog range (which ends at 90% of camera's clip_far value), making sure that you'll never get to see clip_far doing its dirty works. If you don't believe me, remove the white fog from the level and you'll see clip_far in action. Oh, and please use the same color for the background (bg_color.red, green, blue) and for the fog; otherwise, you'll see some nasty graphical artifacts.
Move towards the invisible spheres and you'll see them appearing when you get closer; this technique is the best that you can use if you can have fog in your levels. But what happens if you can't use fog, or if you'd have to use a way-too-thick fog in order to obtain a decent frame rate?
Exit the level, and then run the demo again. Press "2" to load the lod booster demo.
I have used an extremely detailed wmb building for this demo. In fact, there are two copies of it: the darker one that is seen in the picture from above, and another (brighter) one that can be seen if you rotate the camera toward the left side of the screen.
Don't move yet; look at the dark building, memorize the frame rate, and then rotate to your left and see the brighter building and the new frame rate. My PC shows 45 fps for the dark building and 18 fps for the white building, even though they are identical. Why is that happening? Well, the dark building uses LOD and the white one doesn't use anything.
Move away from the darker building; you will see that the frame rate increases even more when the LOD system replaces the current building entity with one that's got even less details. Move close to the darker building and it will be replaced with a highly detailed entity. Keep an eye on the "Map polygons" counter and on the frame rate; LOD can boost your frame rate a lot indeed!
My demo shows A6's built-in LOD system in action; however, for those of you that own A6 Standard and can't use it, I have also included a slightly modified version of my "Lod for all" snippet from Aum53 inside the same boosters.wdl script. To use my script, attach the action named "lod_booster" to your entities and then set the entity morphing distances (skill1 and skill2) in Wed. Make sure to name the building entities this way: building-1.wmb, building-2.wmb, building-3.wmb. Oh, and I guess that you knew that already: A6's built-in LOD system is (of course) faster than my code.
Ready for another frame rate booster? Restart the level, and then press the "3" key to load the vec_dist booster demo.
Move forward; you'll see many trees appearing in front of the camera, fading in gently as you approach them and fading out as you move away from them.
The invisible entities aren't rendered, so if we hide the ones that are away from the camera, we will get a good frame rate increase. Place any entity in the level, and then attach it the action named "dist_booster". Set its skill1 (culling_distance) to the value that will trigger the invisibility - that's all!
Before moving on, you should be aware of the fact that the engine doesn't render the entities that aren't visible on the screen; if you've got many buildings that are placed behind the camera, it's almost as if they didn't exist in the level, as far as the frame rate is concerned.
Let's restart the level one more time; it's time to press the "4" key in order to load the c_trace booster demo. You will see the following picture:
You are looking at a wall that is in fact a moveable wmb entity; press the left and right arrow keys to move it around.
You can now see 147,000 polygons on the screen. Move the wall a bit, hiding some of the spheres; you will see that the engine will render fewer "Entity polygons". If (once again) you believe that this is happening automatically, think again.
A6 is a bsp (binary space partition) engine; when you build the level, it splits the level in smaller, irregular level parts, determined by the level walls. This method works great for indoor levels, because it allows us to have great frame rates even if the indoor levels are huge. As an example, if I would put all the spheres inside a "cage" made of level blocks, the engine wouldn't render them at all because they wouldn't be visible under normal conditions.
However, in big outdoor levels, a bsp engine will render even some of the entities that aren't visible, and my demo would work, under normal conditions, just like that. The sphere models would eat precious resources even if the wall would be in the way and even if it would be a regular level block, and not a wmb entity. To fix this, I have created an action that traces between each sphere model and the camera and shows the model only if it can be seen by the camera. To use my method, place any entity in the level and attach it the "trace_booster" action.
The results speak for themselves: the panel displays "Entity polygons: 0" when the wall hides all the spheres. This leads, as you can imagine, to a consistent frame rate increase. The entities fade in and out gently as they appear or disappear; you have seen this technique being used in many modern games. Examine the booster.wdl script to learn more about the code and feel free to use and mix any of these methods - if you do that, your projects will run faster for sure!