Frame Rate Optimization
The frame rate is the number of video frames per second (fps), and determines the 'smoothness' of game play. It is dependent on:
of the engine;
- the speed of the video drivers and
the number of entities, polygons, and pixels drawn on the screen;
the complexity of the scene - animation, lighting, shadows, and shaders;
the time for running your scripts every frame;
- and an artificial delay for keeping the frame rate in sync with the monitor.
These factors must be balanced to keep the frame rate well above 25 fps for a smooth gameplay. The good news is that you've got one of the fastest engines available today, able to manage huge scenes with up to 100,000 entities. With a given scene, the major framerate influence factor is the speed of your graphics card and the number of pixels drawn per frame. You can
test the performance of your hardware with the infinite terrain example that renders 9 views with about 6600 entities each. Even on old PCs, the total of 60,000 entities should be rendered with 20..30 fps. You can see how the frame rate drops when you increase the camera.clip_far range so that more entities are actually drawn, or when you increase the scale of the models and thus draw more pixels. This should give you an idea how many entities you can put in your game for a given graphics hardware.
The fps contribution of certain elements
can be seen in the [F11] panel in ms per frame. In some cases it can be larger than the real rendering time
by the engine and hardware, especially in fullscreen mode in which the
frame rate is limited by the monitor frequency (mostly 60 Hz on LCD screens
70..80 Hz on CRT monitors).
Monitor frequency and fps
In fullscreen mode, DirectX keeps the frame rate always in sync with the
monitor frequency between 60 and 80 Hz in order to avoid tearing artifacts.
refresh is artificially delayed for matching the time when the monitor has
finished its video cycle.
This delay is visible in the 'screen
refresh' time in the [F11] panel.
Thus you'll never get a higher frame rate than
your monitor can display. Your frame rate will be an integer
division of the monitor frequency (such as 60, 30, 20, or 15 Hz when the monitor frequency is 60 Hz). When the frame rate is close to the monitor
frequency, a small change of the rendering
time will cause the frame rate to suddenly jump from 60
to 30 fps
or vice versa.
Some hints for increasing the frame rate in your games
- Don't use a single big model for a level. When the engine renders the whole level as a single model,
it can't use it's scene management, and renders even the parts of the
level that are not visible. That will result in a bad frame rate.
When editing the level in external editors such as MAX, MAYA, or Blender, use the WED FBX Level Import that automatically imports the level as separate meshes and models.
use Mesh Mode for compiling your level.
Activate the Single Mesh flag for all groups that contain about 100 polygons. Use Mesh Size in Map Properties for automatically combining several blocks to single meshes.
If you want to create a BSP tree, use Detail block flag for all small detail blocks that don't obscure parts of the level.
- Deactivate the mouse if you don't need it. Mouse detection in a 3D view can reduce the frame rate remarkably.
- Reduce the number of sounds audible at the same time. Some sound cards
without hardware mixer reduce the frame rate remarkably when many sounds
- 2D functions, like draw_textmode,
can reduce the frame rate remarkably.
- The smaller the clipping range (camera.clip_far),
the faster the rendering especially in outdoor levels.
Activate fog if you want to cover the clipping border.
Use the CLIP0/CLIP1 flags for reducing the clipping range for less important entities, such as grass sprites.
- Old 3D cards work best with 256x256 texture sizes. The bigger the textures,
the slower the rendering.
Terrain renders faster than models -
especially when it's chunked.
Do not use models for terrain.
A medium number of medium sized meshes renders faster than a huge number of small meshes, or a small number of huge meshes. With today's 3D hardware, the best mesh size is in the range of 500..1500 polygons.
If possible, split bigger models in several parts.
The best block mesh size is somewhat smaller, about 100 polygons, because lightmapped blocks usually consist of several subsets and require more rendering passes than models.
When constructing a
model, have it's origin as close to it's center as possible. Models
with bad placed origins require more space in the scene management tree,
and cause slower rendering.
A model with a single big texture renders faster than a model with several small textures.
- Nonanimated models
render faster than animated models. For a forest, use several tree models
rather than several frames of one single tree model.
The opposite is true for sprites:
many frames of the same sprite render faster than many separate sprites.
- With A7, vertex animation
is faster than bones animation
(but requires more memory).
With A8, bones animation is faster than vertex animation when using the bones animation shader.
Nontransparent or overlay textures are faster than transparent or alpha channel textures, especially when you have many entities in the level.
Some functions, such as c_move, c_trace, or ent_animate, can be slow. If you call them in an entity function, consider using the CLIPPED flag for calling them only when the entity is visible.
- Setting an object's x/y/z coordinates directly is faster than using c_move. c_move is faster without GLIDE , and c_trace is
faster without USE_BOX. IGNORE_ flags can greatly speed up c_move and c_trace. Moving UNLIT objects is faster than moving lit objects.
Static entities are faster than dynamic entities.
Use WED for setting up entity properties, rather than an entity action.
If an action is required only for setting up an entity, reset its DYNAMIC emask flag
at the end of the action.
Decal shadows are faster than stencil shadows. With the Pro Edition, always use accelerated shadows. Despite rumors to the contrary, accelerated shadows have the same quality as non-accelerated shadows.
- Bitmap fonts
are faster than Truetype fonts. Truetype fonts are reported to render very
slow in some PC configurations.
- Sky cubes render faster than sky models and sky domes.
Vertex shaders render faster than pixel shaders. Shift as many calculations as possible from the pixel shader to the vertex shader.
The bigger a model or sprite is scaled, and the closer it is to the camera, the slower it is rendered. The rendering time depends on the number of pixels that the object covers on the monitor.
The more polygons a model consists of, the slower it is rendered. Use LOD steps for huge models, especially in outdoor levels.
Internal LOD steps render faster than switching external LOD models.
- Mipmapping increases the frame rate. Always create mipmaps for model
and terrain skins - it's just a mouse click in MED.
Last but not least:
The A8 engine is faster than the A7 engine, which is
faster than the A6 engine, which is faster than the A5 engine. Always use the latest engine version.
Some hints that will NOT increase the frame rate in your games
Sometimes you encounter strange advices on the user forum about how users increased their frame rate. The following advices will most likely not improve your game:
- Use models instead of blocks. (Models render exactly as fast as blocks).
- Use models instead of terrain. (Models render slower than terrain).
- Edit block surfaces in WED and set the textures on all back surfaces to NONE. (Back sides are not rendered anyway).
- Let your action check the entitys' distance to the camera. (Use the CLIPPED flag).
Some hints for decreasing the frame rate in your games
Why would you want to decrease the frame rate? There are three reasons. Your script functions might only work properly within a certain frame rate range, and fail at 1000 fps. You won't want your application to consume all the CPU cycles. And most important, you want to avoid stuttering. Stuttering means a camera and actor movement that appears unsteady. It won't be noticeable in a game with complex levels and medium frame rate, but mostly in games with almost empty levels, little content, and consequently very high frame rate that is then capped by fps_max.
The main reason for stuttering is a coarse PC scheduler resolution that leads to inaccurate task start times, especially when many tasks are running on a particular PC.
This problem can be avoided by limiting the frame rate not only with fps_max that just gives task time back to the Windows task scheduler, but by really burning CPU cycles in some or the other way. Fortunately, this is easily done. If your game experiences stuttering, just place some more details in your levels for avoiding a too-high frame rate.