Performance Optimization

Revision as of 07:28, 13 April 2010 by Aloys (Talk | contribs) (Shazam!)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Introduction

If you find that your Age is 'lagging' or having various performance issues, it may be the time to learn some optimizations tricks. Performance optimisation is a vast topic, but an important one. Especially for large Ages who are more prone to performance drops than smaller Ages. But for new Writers even small Ages can have some unsuspected performance troubles. This article covers the most common and most useful tricks.

Note: This is a ‘work in progress’ article.


Things to always keep in mind

As much as possible it is better to have in mind performance issues before starting work on an Age. If you find yourself needing to optimize an Age after it is already done you will find yourself retouching or even losing weeks of works; and that is not an enjoyable thing to do. Therefore here are a couple things to always have in mind:

Top things to avoid:

Decent performance can usually be accomplished in most Ages by avoiding in a couple key issues. Here are the top performance killers; keep them in mind at all times. In no specific order:

  • Polygon counts : ”Yay! my Age has more polygons than Riven! oh.. wait.."
  • Texture sizes : Plasma can handle texture sizes up to 1024*1024. That doesn't mean that all textures should be that size.
  • Age size / design : An open Age will always be more difficult to optimise. You need to think of ways to block the view at times.
  • Excessive shaders : Fancy effects and multi texturing are nice, but only up to a certain point.
  • Too many trees : Many people like forests, but trees are the death of performance: Polygons, transparency... Use them sparingly.
  • Collisions everywhere : Never enable collisions on all your meshes. Hand made collisions meshes are a necessity.

Do not be excessive: not too many polygons/textures/objects etc.. It is perfectly possible to have an Age that is both 'reasonnable' and nice looking.

Measuring Performance

The first step to enhancing performance is to measure it. First of all know you computer. Is it old? Is it new? Once you know that install FRAPS. This tool will allow you to measure the framerate in Uru. It is free, small, and easy to configure. Your target is to keep it the framerate above 30FPS on all computers. Uru was released in late 2003, computers of this time are our baseline. Computer power tend to double every two years (roughly); if your Age runs at 120 FPS on your computer but you bought it in 2009 then divide that number by 6...

Design your Age with view blockers

This cannot be stressed enough: Ages must be designed with performance in mind. It is possible to have a large Age perform correctly as long as it is designed correctly. That means keep in mind Visibility issues. Cut up your Age in various sections so that you can never see the whole Age at a time. The City is a large Age but it is cut in different sections, with tunnels and small paths joining them. But try to use the FlyMode to see the whole City at a time and you'll notice the performance difference... This can also be used to make smaller Ages more detailed. For instance Eder Kemo is cut in small sections but they are very detailed. Blocking the view with large objects (walls, mountains, tunnels) at strategical spots is critical.
>> see 'visibility' management section


First things to take care of

Polygon & texture budgets

When actually modelling the Age, this is the first step to decent performance. Judging the 'correct' polygon count for an object is not always easy. Used together with Visregion (see bellow) try to keep the polygons in view bellow 150.000.

Again looking at the Cyan Ages is your best start. Here are a few metrics:

  • Relto Age: Polys: around 110.000 / Textures : xx MB
  • Teledahn: Polys: around 150.000 / Textures : xx MB
  • Ae'gura (the City): Polys: above 550.000 / Textures : xx MB
  • Male avatar (at max resolution) : around 5.000 / Textures : xx MB

Judging texture size is a little easier : the larger an object the larger the texture. A small book on a desk do not need to have 1024x1024 textures. There are some tricks to save up textures though:

  • Re-use textures : Don't create a unique textures for each object -- do you really need 20 different 'wood' textures in your Age?
  • Use multi-texturing or stencils for large objects (terrains) : To avoid repettitive textures on large surfaces use multitexturing.
  • Use vertex painting or multitexturing for color variety : If you have a texture you want to re-use with need different colors.

Collisions

Collisions can be the worst performance hit, but they are pretty easy to take care of. Never enable collision on all your meshes. Especially if you have complex meshes. It is a better idea to build low-poly custom collider meshes. Have a look a Cyan's Ages (use the PyPRP importer version). For many objects it is not even necessary to model a custom collider, often a simple 'box' 'hull' or 'cylinder' collision (depending on the mesh) will do the trick. For instance on a tree a 'cylinder' collision setting might do a decent approximation. 'Static triangle mesh' setting should be avoided unless absolutely necessary (for instance on a complex terrain object). Remember : if there is an object that you cannot reach in game it shouldn't have collisions.
>> http:// wiki link ?

Shadow buffers

By default in Blender dynamic shadows are enabled for all materials; this is the 'ShadowBuff' button. It uses up tons of performance and should be disabled for most objects except for some rare dynamic objects (animated objects/kickables). Shadows can (and should) be done with lightmaps or approximated with vertex painting.
>> http:// wiki link ?


Visibility Management

Vis regions

On large Ages this is the most important performance optimization. Visregions allow you to 'remove' objects from the scene depending on the camera position. If you are in one part of a large Age you may not see the rest of the Age but it is still loaded and it takes up memory. A vis region can be used to unload that. For instance if you are inside a tunnel you do not need to have the rest of the Age loaded; use a vis region here. Used with a good Age design and visibility blockers, this will save a lot of performance and allow you to make detailed Ages.
>> http://www.guildofwriters.com/wiki/Soft_Volumes#Visregions

Occluders

(to be confirmed / expanded) These are a kind of 'automatic vis region' system: when the camera enters the volume of the occluder everything that is outside the occluder is automatically hidden.
>> Occluders are not currently available in PyPRP 1.6

Page swapping

This is a pretty extreme measure, and no Cyan Age use it. This is used to totally load or unload a whole Age page via Python. This saves up memory, and shortens loading times; but the tradeback is that when you load/unload a page it freezes the game for several seconds. This is an 'old' method and has only ever been used on one Age (Ahra Pahts).
>> http:// wiki link ?


Misc. things

Kickables

Kickables are fun, just make sure to use custom collider meshes. (alternatively, 'box' 'cylinder' collision settings can work)

Transparency Overdraw reduction

Too many transparent textures on the screen at the same time ('overdraw') can quickly lead to performance drop. If possible when designing an Age, avoid having too many transparent textures on top of each other. (for instances: a glass in front of a tree in front of water etc)
>> http:// wiki link ?

Mesh LODs

For large objects that can be seen from a long distance it is a good idea to create LOD (Level Of Detail) low-poly versions. For instance this is done by Cyan in the City for most buildings. Those can be displayed/hidden with Vis regions or 'soft distance' softvolumes.
>> http:// wiki link ?

Loading times

page swapping?
PRP vertext compression?